copyFile could call chmod on a symlink, changing the perms
authorErik Andersen <andersen@codepoet.org>
Thu, 27 Jan 2000 19:50:47 +0000 (19:50 -0000)
committerErik Andersen <andersen@codepoet.org>
Thu, 27 Jan 2000 19:50:47 +0000 (19:50 -0000)
of the pointed to file.  Minor fix to tar for directory handling.
 -Erik

Changelog
archival/tar.c
tar.c
utility.c

index 8dc40ca..6581b5c 100644 (file)
--- a/Changelog
+++ b/Changelog
@@ -25,7 +25,8 @@
            contributed Friedrich Vedder <fwv@myrtle.lahn.de>
        * Cosmetic fix to busybox.c (Don't print a comma at the
            end of line if there are no more application names).
-       * Fixed a stupid bug in "head" option handling ("head -n" would segfault).
+       * Fixed a stupid bug in "head" option handling ("head -n" 
+           would segfault).
        * Moved commonly used functions "xmalloc()" and "exit()"
            to utility.c (with proper #ifdef's).
        * Created a tiny tail implementation, removing -c, -q, -v, and making
        * Fixed mount and umount.  Previously they could leak loop device 
            allocations, causing the system to quickly run out.  Fix for umount
            by Ben Collins <bcollins@debian.org>, and mount was fixed by me.
-       * ls formatting on 8 char user names fixed by Randolph Chung <tausq@debian.org>.
+       * ls formatting on eight charactor user names fixed by 
+           Randolph Chung <tausq@debian.org>.
+       * cp could, when copying symlinks, change permissions of the
+           files pointed to by the symlinks.
 
 
        -Erik Andersen
index aedb36a..0fa09ff 100644 (file)
@@ -596,6 +596,7 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
            chmod(outName, mode);
            return;
        }
+       return;
     }
 
     /* 
diff --git a/tar.c b/tar.c
index aedb36a..0fa09ff 100644 (file)
--- a/tar.c
+++ b/tar.c
@@ -596,6 +596,7 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable)
            chmod(outName, mode);
            return;
        }
+       return;
     }
 
     /* 
index 5ff03d7..69637c4 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -131,6 +131,7 @@ copyFile( const char *srcName, const char *destName,
     struct stat dstStatBuf;
     struct utimbuf times;
 
+    /* Grab the source file's stats */
     if (followLinks == FALSE)
        result = stat(srcName, &srcStatBuf);
     else 
@@ -140,6 +141,7 @@ copyFile( const char *srcName, const char *destName,
        return FALSE;
     }
 
+    /* Grab the dest file's stats */
     if (followLinks == FALSE)
        result = stat(destName, &dstStatBuf);
     else 
@@ -223,18 +225,18 @@ copyFile( const char *srcName, const char *destName,
     }
 
     if (setModes == TRUE) {
-       //fprintf(stderr, "Setting permissions for %s\n", destName);
-       chmod(destName, srcStatBuf.st_mode);
+       if (! S_ISLNK(srcStatBuf.st_mode)) {
+           chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid);
+           /* Never chmod a symlink; it follows the link */
+           chmod(destName, srcStatBuf.st_mode);
+       }
 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
-       if (followLinks == FALSE)
+       else { 
            lchown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid);
-       else
+       }
 #endif
-           chown(destName, srcStatBuf.st_uid, srcStatBuf.st_gid);
-
        times.actime = srcStatBuf.st_atime;
        times.modtime = srcStatBuf.st_mtime;
-
        utime(destName, &times);
     }
 
@@ -414,6 +416,7 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir
        status = lstat(fileName, &statbuf);
 
     if (status < 0) {
+       fprintf(stderr, "status=%d followLinks=%d TRUE=%d\n", status, followLinks, TRUE);
        perror(fileName);
        return (FALSE);
     }
@@ -515,14 +518,11 @@ extern int createPath (const char *name, int mode)
        cp = strchr (cp + 1, '/');
        *cpOld = '\0';
        retVal = mkdir (buf, cp ? 0777 : mode);
-       *cpOld = '/';
-    }
-    /* Return the result from the final directory, as that
-     * is the one that counts */
-    if( retVal!=0) {
-       if ( errno!=EEXIST) {
+       if (retVal != 0 && errno != EEXIST) {
+           perror( buf);
            return( FALSE);
        }
+       *cpOld = '/';
     }
     return( TRUE);
 }