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

Reply via email to