diff options
-rw-r--r-- | Changelog | 4 | ||||
-rw-r--r-- | archival/tar.c | 27 | ||||
-rw-r--r-- | internal.h | 2 | ||||
-rw-r--r-- | tar.c | 27 | ||||
-rw-r--r-- | utility.c | 13 |
5 files changed, 47 insertions, 26 deletions
@@ -1,6 +1,8 @@ 0.42 * Made tar creation support in busybox tar optional. - You no longer _have_ to put a "-" in front of tar options. + * You no longer _have_ to put a "-" in front of tar options. + * Tar could inadvertently change permissions and ownership on + certain directories pointed to by symlinks. * Made grep and grep -h do the right thing wrt printing the file name (it failed to print files names in many cases). * Fix a namespace aliasing problem wereby if du was built in, the diff --git a/archival/tar.c b/archival/tar.c index adae6c9..21ef24d 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -542,8 +542,10 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable) printf ("x %s\n", outName); if (hardLink) { - if (link (hp->linkName, outName) < 0) + if (link (hp->linkName, outName) < 0) { perror (outName); + return; + } /* Set the file time */ utb.actime = mtime; utb.modtime = mtime; @@ -556,8 +558,10 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable) if (softLink) { #ifdef S_ISLNK - if (symlink (hp->linkName, outName) < 0) + if (symlink (hp->linkName, outName) < 0) { perror (outName); + return; + } /* Try to change ownership of the symlink. * If libs doesn't support that, don't bother. * Changing the pointed-to file is the Wrong Thing(tm). @@ -582,15 +586,16 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable) * If the file is a directory, then just create the path. */ if (S_ISDIR (mode)) { - createPath (outName, mode); - /* Set the file time */ - utb.actime = mtime; - utb.modtime = mtime; - utime (outName, &utb); - /* Set the file permissions */ - chown(outName, uid, gid); - chmod(outName, mode); - return; + if (createPath (outName, mode)==TRUE) { + /* Set the file time */ + utb.actime = mtime; + utb.modtime = mtime; + utime (outName, &utb); + /* Set the file permissions */ + chown(outName, uid, gid); + chmod(outName, mode); + return; + } } /* @@ -156,7 +156,7 @@ int recursiveAction(const char *fileName, int recurse, int followLinks, int dept int (*dirAction) (const char *fileName, struct stat* statbuf)); const char* timeString(time_t timeVal); -extern void createPath (const char *name, int mode); +extern int createPath (const char *name, int mode); extern int parse_mode( const char* s, mode_t* theMode); extern void usage(const char *usage) __attribute__ ((noreturn)); @@ -542,8 +542,10 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable) printf ("x %s\n", outName); if (hardLink) { - if (link (hp->linkName, outName) < 0) + if (link (hp->linkName, outName) < 0) { perror (outName); + return; + } /* Set the file time */ utb.actime = mtime; utb.modtime = mtime; @@ -556,8 +558,10 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable) if (softLink) { #ifdef S_ISLNK - if (symlink (hp->linkName, outName) < 0) + if (symlink (hp->linkName, outName) < 0) { perror (outName); + return; + } /* Try to change ownership of the symlink. * If libs doesn't support that, don't bother. * Changing the pointed-to file is the Wrong Thing(tm). @@ -582,15 +586,16 @@ readHeader (const TarHeader * hp, int fileCount, char **fileTable) * If the file is a directory, then just create the path. */ if (S_ISDIR (mode)) { - createPath (outName, mode); - /* Set the file time */ - utb.actime = mtime; - utb.modtime = mtime; - utime (outName, &utb); - /* Set the file permissions */ - chown(outName, uid, gid); - chmod(outName, mode); - return; + if (createPath (outName, mode)==TRUE) { + /* Set the file time */ + utb.actime = mtime; + utb.modtime = mtime; + utime (outName, &utb); + /* Set the file permissions */ + chown(outName, uid, gid); + chmod(outName, mode); + return; + } } /* @@ -495,11 +495,12 @@ recursiveAction(const char *fileName, int recurse, int followLinks, int depthFir * while all previous ones get default protections. Errors are not reported * here, as failures to restore files can be reported later. */ -extern void createPath (const char *name, int mode) +extern int createPath (const char *name, int mode) { char *cp; char *cpOld; char buf[NAME_MAX]; + int retVal=0; strcpy( buf, name); cp = strchr (buf, '/'); @@ -507,9 +508,17 @@ extern void createPath (const char *name, int mode) cpOld = cp; cp = strchr (cp + 1, '/'); *cpOld = '\0'; - mkdir (buf, cp ? 0777 : mode); + 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) { + return( FALSE); + } + } + return( TRUE); } #endif |