diff --git a/kiss b/kiss index a31e9e4..26a7977 100755 --- a/kiss +++ b/kiss @@ -20,8 +20,9 @@ source_type() { } pkg_clean() { - rm -rf -- "$mak_dir" "$pkg_dir" \ - "$cac_dir/manifest-$$" "$cac_dir/tar" "$cac_dir/checksums-$$" + rm -rf -- "$mak_dir" "$pkg_dir" "$tar_dir" \ + "$cac_dir/manifest-$$" "$cac_dir/checksums-$$" \ + "$cac_dir/mv" "$cac_dir/mkdir" "$cac_dir/find" } pkg_search() { @@ -172,15 +173,33 @@ pkg_install() { [ -f "$bin_dir/$pkg" ] || args b "$name" pkg_conflicts + tar pxf "$bin_dir/$pkg" -C "$tar_dir/" || die "Failed to extract tarball." - # Create a backup of 'tar' so it isn't removed during - # package installation. - cp "$(command -v tar)" "$cac_dir" + # Create a backup of 'mv', 'mkdir' and 'find' so they aren't removed + # during package removal. + cp "$(command -v mv)" "$cac_dir" + cp "$(command -v mkdir)" "$cac_dir" + cp "$(command -v find)" "$cac_dir" log "Removing previous version of package if it exists." pkg_remove - "$cac_dir/tar" kpxf "$bin_dir/$pkg" -C "$sys_dir/" 2>/dev/null + cd "$tar_dir" || die "Aborting due to tar error." + + # Optimization: Only find the deepest directories. + find . -type d -links -3 -prune | while read -r dir; do + mkdir -p "$sys_dir/${dir#./}" + done + + find ./ -mindepth 1 -not -type d | while read -r file; do + rpath=${file#.} + + [ -z "${rpath##/etc/*}" ] && [ -f "$sys_dir${rpath%/*}/${file##*/}" ] && + return + + mv "$file" "$sys_dir${rpath%/*}" + done + "$sys_db/$name/post-install" 2>/dev/null log "Installed ${pkg%.tar.gz}" @@ -195,17 +214,19 @@ pkg_remove() { cp "$(command -v rmdir)" "$cac_dir" while read -r file; do - [ "${file%/*}" = /etc ] && continue + [ "${file##/etc/*}" ] || continue if [ -d "$sys_dir$file" ]; then "$cac_dir/rmdir" "$sys_dir$file" 2>/dev/null || continue else "$cac_dir/rm" -f -- "$sys_dir$file" || log "Failed to remove $file." - fi && log "Removed $file" + fi done < "$sys_db/${1:-$name}/manifest" # Use the backup of 'rm' to remove 'rmdir' and itself. "$cac_dir/rm" "$cac_dir/rmdir" "$cac_dir/rm" + + log "Removed ${1:-$name}." } pkg_updates() { @@ -230,7 +251,7 @@ pkg_list() { } args() { - [ -w "$KISS_ROOT/" ] || case $1 in + [ -w "$sys_dir/" ] || case $1 in i*|r*) die "No write permissions to \$KISS_ROOT." esac @@ -285,6 +306,7 @@ main() { mkdir -p "${cac_dir:=${XDG_CACHE_HOME:=$HOME/.cache}/$kiss}" \ "${mak_dir:=$cac_dir/build-$$}" \ "${bin_dir:=$cac_dir/bin}" \ + "${tar_dir:=$cac_dir/extract-$$}" \ "${pkg_db:=${pkg_dir:=$cac_dir/pkg-$$}/var/db/$kiss}" || die "Couldn't create directories."