Last week was hectic for me and I finally got around to not just making the changes, but testing them too. I didn't know 'upgrade()' existed and now that I've messed with it, I really like it. Instead of just being compatible with the new package_changed_files(), any changes that are made are now committed at the very end. So... you can modify files, one after another, and if you make a mistake, just answer no at the end. I also updated expandpath() mainly because of $PKGROOT always being///, or was it ////? Boy I hated that. You still end up with //some.file because that's just what happens when the top dir is a slash; which could be changed (eg., $PKGROOT$afile, ${PKGROOT}literal.file), but, that's being too picky....I would like to get this committed soon. If anyone wants to test, please give it a try. Just make sure your busybox has 'readlink'.
--- apkg.orig 2014-09-18 23:20:09.000000000 -0700 +++ apkg 2014-10-24 13:38:52.851202831 -0700 @@ -6,20 +6,38 @@ # Upgrade code by Cedric Schieli # Rundiff code and various improvements by Paul Traina # Package dependency loading code by David M Brooke -# +# Package_changed_files() now backs up symbolic links and +# empty directories; more detailed rundiff(); upgrade() now +# prompts before committing changes and other enhancements; +# changed expandpath by Jorge Contreras +# # Licensed under the terms of the GPL-2 # --------------------------------------------------------- -# expandpath - given a path, expand it -# code from apkg by David Douthitt -expandpath () { - local D=$(dirname $1) - if `echo "$D" | grep -v "^/" > /dev/null`; then - [ `dirname $1` = "." ] && D=$PWD || D=$PWD/$(dirname $1) +# expandpath - given a path, expand it; does not expect a valid path; +# if available `readlink -m /some/path` is best, but that will canonicalize +# symlinks, which is not always desired. Now get's rid of redundant slashes +# (eg., ///dir1/dir2) and accepts null paths. +# code from apkg by David Douthitt - Modified by Jorge Contreras +expandpath() { + + if [ "$1" = "" ] || [ "$1" = "." ]; then + echo $PWD + elif [ "$1" = "/" ]; then + echo "/" + else + local DN=$(dirname $1 | sed 's#//*#/#g') + if $(echo "$1" | grep -v "^/" > /dev/null); then + [ "$DN" = "." ] && \ + echo $PWD/$(basename $1) || \ + echo $PWD/$DN/$(basename $1) + else + echo $DN/$(basename $1) fi - echo $D/$(basename $1) - } + fi + +} # --------------------------------------------------------- @@ -200,24 +218,46 @@ # figure out which files have changed from this package package_changed_files () { - local tmp + local tmp upgrade fullpkg NL tmpdir mktmpd s_syms s_dirs s_files tmp=$TMP/$SESSIONID.sha1 + tmpdir=$TMP/$SESSIONID.tar + # Hackish way of dealing with upgrades and symlinks + if [ "$1" = "-u" ]; then + upgrade=1; fullpkg=$2; SHIFT 2 + fi ( cd $PKGROOT echo > $tmp - + NL=" +" for pkg in $@ ; do - if [ -f $PKGDIR/$pkg.local ]; then - for a in $(find $(cat $PKGDIR/$pkg.local) -type f 2>/dev/null); do - ! grep -h "[ /]${a}\$" $PKGDIR/*.sha1 >>$tmp 2>/dev/null && \ - echo "0000000000000000000000000000000000000000 ${a}" >>$tmp - done - fi + if [ -f $PKGDIR/$pkg.local ] ; then + for a in $(find $(cat $PKGDIR/$pkg.local) 2>/dev/null); do + if [ -L $a ] ; then + [ "$mktmpd" != "1" ] && mkdir $tmpdir && mktmpd=1 + [ "$upgrade" != 1 ] && fullpkg=$STORAGE_MEDIA/$pkg.lrp + # if symlink doesn't exist or if it changed + if ! tar xzf $fullpkg -C $tmpdir $a 2>/dev/null || \ + [ "$(readlink $a)" != "$(readlink $tmpdir/$a)" ] ; then + s_syms=$s_syms"$a"$NL + fi + elif [ -d $a ] ; then + # Only add empty directories, non-empty dirs are always backed up + if ! [ "$(ls -A $a)" ] ; then + s_dirs=$s_dirs"$a"$NL + fi + elif [ -f $a ] ; then + ! grep -h "[ /]${a}\$" $PKGDIR/*.sha1 >>$tmp 2>/dev/null && \ + echo "0000000000000000000000000000000000000000 ${a}" >>$tmp + fi + done + [ "$mktmpd" = "1" ] && rm -rf $tmpdir && mktmpd=0 + fi done - - sha1sum -c $tmp 2>/dev/null | grep FAILED | sed -e "s/: FAILED//" | \ - sort | uniq + + s_files=$(sha1sum -c $tmp 2>/dev/null | grep FAILED | sed -e "s/: FAILED//") + echo "$s_syms$s_dirs$s_files" | sort | uniq ) rm -f $tmp @@ -225,13 +265,23 @@ } # --------------------------------------------------------- +# upg_cmdins - inserts a command into the upgrade script + +upg_cmdins() { + + if [ -n $1 ]; then + echo "$@ && [ \$? -ne 0 ] && upgexit=\$?" >> $do_upgrade + fi +} + +# --------------------------------------------------------- # upgrade - upgrades a package upgrade () { - local pkg pth + local pkg pth commit do_upgrade automated opt upgexit if [ -z "$1" ]; then - echo "No package name given." ; return 1 + echo "No package name given."; return 1 fi pth=$( makeFN $1 ) @@ -239,71 +289,121 @@ if [ -z "$pkg" ]; then echo "No package name given."; return 1 - fi - if ! list_pkgs "$pkg" >/dev/null; then + elif ! list_pkgs "$pkg" >/dev/null; then echo "$pkg not installed."; return 1 - fi - if [ ! -f "$pth" ]; then + elif ! [ -f "$pth" ]; then echo "$pth not found."; return 1 fi # ok, its there, installed... let's upgrade it... ( - if [ -f $PKGDIR/$pkg.local ]; then - package_changed_files $pkg >$TMP/$SESSIONID.changed + commit=0 + [ "$2" = "1" ] && automated=1 || automated=0 + + do_upgrade=$TMP/$SESSIONID.ucmds + # Does the OUTDATED, running package have a .local file? + if [ -f $PKGDIR/$pkg.local ]; then mkdir $TMP/$SESSIONID.tmpdir cd $TMP/$SESSIONID.tmpdir tar -zxpf $pth $LRPKG/$pkg.local + # Does the UPDATED, non-running package also have a .local file? if [ -f $LRPKG/$pkg.local ] ; then + package_changed_files -u $pth $pkg >$TMP/$SESSIONID.changed + tar -zxpf $pth -T $LRPKG/$pkg.local + + if [ $automated = 1 ]; then + # Abort if update type is "freshen" and config files have changed + for file in $(cat $TMP/$SESSIONID.changed); do + test -f $file && \\ + echo "$pkg freshen failed - config file(s) are changed, try manual freshen" && \\ + return 1 + done + fi + tar -ztf $pth >$LRPKG/$pkg.list find $(cat $LRPKG/$pkg.local) -type f | \ xargs sha1sum > $LRPKG/$pkg.sha1 - # remove local files that have not changed from - # the installed version of this package - rm -f $(cat $PKGDIR/$pkg.sha1 | sed '/ -/d' | \ - sha1sum -c 2>/dev/null | grep OK | sed 's/: OK$//') - + # If changes are detected, merge/replace changed or added + # config files, symlinks, and empty directories for file in $(cat $TMP/$SESSIONID.changed); do - if [ "$2" = 1 ]; then - test -f $file && echo "$pkg upgrade failed - config file(s) are changed, try manual upgrade" && return 1 + if [ -L $file ]; then + while [ 1 ]; do + echo -e "\nModified symbolic link:" $(echo $PKGROOT/$file | sed 's#//#/#g') + echo "Current:" $(basename $PKGROOT/$file) "->" $(readlink $PKGROOT/$file) + echo "Updated:" $(basename $PKGROOT/$file) "->" $(readlink $file) + echo -n -e "\nKeep/Replace? (k/r)" + read opt + case $opt in k|K) + break ;; + r|R) + upg_cmdins mv $file $PKGROOT/$file + break ;; + esac + done + elif [ -d $file ]; then + test -d $PKGROOT/$file && \ + upg_cmdins rmdir $PKGROOT/$file + upg_cmdins mv $file $PKGROOT/$file + elif [ -f $file ]; then + apkg.merge $PKGROOT $PWD $file + test -f $file && upg_cmdins mv $file $PKGROOT/$file fi - - test -f $file && apkg.merge $PKGROOT . $file - test -f $file && mv $file $PKGROOT/$file done - tar -zxpf $pth -X $TMP/$SESSIONID.changed -C $PKGROOT - mv $LRPKG/$pkg.list $PKGDIR - mv $LRPKG/$pkg.sha1 $PKGDIR - else - tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list - create_sha1 $pkg + upg_cmdins tar -zxpf $pth -X $TMP/$SESSIONID.changed -C $PKGROOT + upg_cmdins mv $LRPKG/$pkg.list $PKGDIR + upg_cmdins mv $LRPKG/$pkg.sha1 $PKGDIR + + else # No .local + upg_cmdins tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list + upg_cmdins rm -f $PKGDIR/$pkg.local $PKGDIR/$pkg.sha1 fi else - tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list - create_sha1 $pkg + upg_cmdins tar -zxvpf $pth -C $PKGROOT >$PKGDIR/$pkg.list + upg_cmdins create_sha1 $pkg fi - ) - if [ $? -eq 0 ]; then - echo "$pkg upgraded" - # process any package dependencies by recursively calling install()... - deplist="" - if [ -f $PKGDIR/$pkg.deplrp ] ; then - for deplrp in `cat $PKGDIR/$pkg.deplrp` ; do - [ -f "$PKGDIR/$deplrp.list" ] || deplist="$deplist $deplrp" - done - fi - [ -n "$deplist" ] && echo "Required packages that are missed: $deplist" - return 0 + + upgexit=0 + + if [ $automated = 1 ]; then + . $do_upgrade else - return $? + while [ 1 ]; do + read -p "Commit changes? (y/n)" opt + case $opt in y|Y) + commit=1 + . $do_upgrade + break ;; + n|N) + break ;; + esac + done + fi + + if [ $commit = 1 ]; then + if [ $upgexit -eq 0 ]; then + echo "$pkg upgraded." + # Display list of dependencies... + deplist="" + if [ -f $PKGDIR/$pkg.deplrp ] ; then + for deplrp in `cat $PKGDIR/$pkg.deplrp` ; do + [ -f "$PKGDIR/$deplrp.list" ] || deplist="$deplist $deplrp" + done + fi + [ -n "$deplist" ] && echo "Required packages that are missed: $deplist" + return 0 + else + echo "one or more errors while processing updates." + return $upgexit + fi fi + ) } # --------------------------------------------------------- @@ -407,7 +507,7 @@ # rundiff () { - local backup_path vs_saved saved changed interest lrp + local backup_path vs_saved saved changed interest lrp run_sym sav_sym vs_saved=$1 if [ ! -f $BACKUP_PATH/$configdb.lrp ] ; then @@ -442,14 +542,32 @@ interest=$(for file in $interest ; do echo $file ; done | sort | uniq) for file in $interest ; do - if [ ! -f running/$file ] ; then - echo "*** $file has been deleted" + if [ -L running/$file ] ; then + run_sym=$(readlink running/$file) + sav_sym=$(readlink $vs_saved/$file) + if [ "$run_sym" != "" ] && [ "$sav_sym" = "" ]; then + echo "*** $file is NEW symbolic link" + elif [ "$run_sym" != "$sav_sym" ]; then + echo "*** $file is MODIFIED symbolic link" + fi + elif [ -d running/$file ] ; then + if ! [ -d $vs_saved/$file ] && ! [ -d distribution/$file ] ; then + echo "*** $file is NEW empty directory" + fi + elif [ ! -f running/$file ] ; then + if [ -L $vs_saved/$file ] ; then + echo "*** $file is DELETED symbolic link" + else + echo "*** $file has been DELETED" + fi + elif ! [ -s running/$file ] && ! [ -f $vs_saved/$file ] ; then + echo "*** $file is NEW empty file" elif [ -f $vs_saved/$file ] ; then - diff -u $vs_saved/$file running/$file + diff -u $vs_saved/$file running/$file elif [ -f distribution/$file ] ; then - diff -u distribution/$file running/$file + diff -u distribution/$file running/$file else - diff -u /dev/null running/$file + diff -u /dev/null running/$file fi done } ------------------------------------------------------------------------------ _______________________________________________ leaf-devel mailing list leaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/leaf-devel