Yet another installment in the ongoing tar saga
authorErik Andersen <andersen@codepoet.org>
Tue, 28 Mar 2000 00:58:14 +0000 (00:58 -0000)
committerErik Andersen <andersen@codepoet.org>
Tue, 28 Mar 2000 00:58:14 +0000 (00:58 -0000)
 -Erik

12 files changed:
archival/tar.c
chmod_chown_chgrp.c
coreutils/rm.c
cp_mv.c
find.c
findutils/find.c
internal.h
rm.c
swaponoff.c
tar.c
util-linux/swaponoff.c
utility.c

index 37a28a3..af0e4f8 100644 (file)
@@ -228,6 +228,7 @@ extern int tar_main(int argc, char **argv)
 
                case 'O':
                        tostdoutFlag = TRUE;
+                       tarName = "-";
                        break;
 
                case '-':
@@ -439,7 +440,7 @@ static long getOctal(const char *cp, int size)
 
 /* Parse the tar header and fill in the nice struct with the details */
 static int
-parseTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
+readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
 {
        int i;
        long chksum, sum;
@@ -502,7 +503,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
        while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {
 
                /* First, try to read the header */
-               if ( parseTarHeader(&rawHeader, &header) == FALSE ) {
+               if ( readTarHeader(&rawHeader, &header) == FALSE ) {
                        close( tarFd);
                        if ( *(header.name) == '\0' ) {
                                goto endgame;
@@ -661,25 +662,80 @@ static int putOctal (char *cp, int len, long value)
        return TRUE;
 }
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+/* Write out a tar header for the specified file */
+static int
+writeTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
 {
-       fprintf(stdout, "%s\n", fileName);
+       int i;
+       long chksum, sum;
+       unsigned char *s = (unsigned char *)rawHeader;
+
+       struct TarHeader header;
+
+       strcpy(header.name, fileName); 
+       putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 0777);
+       putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
+       putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
+       putOctal(header.size, sizeof(header.size), statbuf->st_size);
+       putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
+
+       if (S_ISLNK(statbuf.st_mode)) {
+               header.type  = LNKTYPE;
+               // Handle SYMTYPE
+       } else if (S_ISDIR(statbuf.st_mode)) {
+               header.type  = DIRTYPE;
+       } else if (S_ISCHR(statbuf.st_mode)) {
+               header.type  = CHRTYPE;
+       } else if (S_ISBLK(statbuf.st_mode)) {
+               header.type  = BLKTYPE;
+       } else if (S_ISFIFO(statbuf.st_mode)) {
+               header.type  = FIFOTYPE;
+       } else if (S_ISSOCK(statbuf.st_mode)) {
+               header.type  = S_ISSOCK;
+       } else if (S_ISLNK(statbuf.st_mode)) {
+               header.type  = LNKTYPE;
+       } else if (S_ISLNK(statbuf.st_mode)) {
+               header.type  = REGTYPE;
+       }
+#if 0  
+       header->linkname  = rawHeader->linkname;
+       header->devmajor  = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor));
+       header->devminor  = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor));
+
+       /* Write out the checksum */
+       chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum));
+#endif
+
+       return ( TRUE);
+}
+
+
+static int fileAction(const char *fileName, struct stat *statbuf, void* userData)
+{
+       int *tarFd=(int*)userData;
+       dprintf(*tarFd, "%s\n", fileName);
        return (TRUE);
 }
 
 static int writeTarFile(const char* tarName, int extractFlag, int listFlag, 
                int tostdoutFlag, int verboseFlag, int argc, char **argv)
 {
-       int tarFd=0;
+       int tarFd=-1;
        //int errorFlag=FALSE;
        //TarHeader rawHeader;
        //TarInfo header;
        //int alreadyWarned=FALSE;
-       char *directory = ".";
        //int skipFileFlag=FALSE;
+       struct stat tarballStat;
+       dev_t tarDev = 0;
+       ino_t tarInode = 0;
+
+       /* Make sure there is at least one file to tar up.  */
+       if (argc <= 0)
+               fatalError("tar: Cowardly refusing to create an empty archive\n");
 
        /* Open the tar file for writing.  */
-       if (!strcmp(tarName, "-"))
+       if (tostdoutFlag == TRUE)
                tarFd = fileno(stdout);
        else
                tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
@@ -687,19 +743,25 @@ static int writeTarFile(const char* tarName, int extractFlag, int listFlag,
                errorMsg( "Error opening '%s': %s\n", tarName, strerror(errno));
                return ( FALSE);
        }
+       /* Store the device and inode of the tarball, so we can be sure
+        * not to try and include it into itself....  */
+       if (fstat(tarFd, &tarballStat) < 0)
+               fatalError(io_error, tarName, strerror(errno)); 
+       tarDev = tarballStat.st_dev;
+       tarInode = tarballStat.st_ino;
 
        /* Set the umask for this process so it doesn't 
         * screw up permission setting for us later. */
        umask(0);
 
        /* Read the directory/files and iterate over them one at a time */
-       if (recursiveAction(directory, TRUE, FALSE, FALSE,
-                                               fileAction, fileAction) == FALSE) {
-               exit(FALSE);
+       while (argc-- > 0) {
+               if (recursiveAction(*argv++, TRUE, FALSE, FALSE,
+                                       fileAction, fileAction, (void*) &tarFd) == FALSE) {
+                       exit(FALSE);
+               }
        }
 
-
-       // TODO: DO STUFF HERE
        close(tarFd);
        return( TRUE);
 }
index e197ee3..00c6b34 100644 (file)
@@ -60,7 +60,7 @@ static const char chmod_usage[] =
        "\nOptions:\n\t-R\tchange files and directories recursively.\n";
 
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        switch (whichApp) {
        case CHGRP_APP:
@@ -169,9 +169,8 @@ int chmod_chown_chgrp_main(int argc, char **argv)
                fatalError( "%s: too few arguments\n", invocationName);
        }
        while (argc-- > 1) {
-               if (recursiveAction
-                       (*(++argv), recursiveFlag, TRUE, FALSE, fileAction,
-                        fileAction) == FALSE)
+               if (recursiveAction (*(++argv), recursiveFlag, TRUE, FALSE, 
+                                       fileAction, fileAction, NULL) == FALSE)
                        exit(FALSE);
        }
        exit(TRUE);
index 41afeda..683bf8b 100644 (file)
@@ -42,7 +42,7 @@ static int forceFlag = FALSE;
 static const char *srcName;
 
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        if (unlink(fileName) < 0) {
                perror(fileName);
@@ -51,7 +51,7 @@ static int fileAction(const char *fileName, struct stat *statbuf)
        return (TRUE);
 }
 
-static int dirAction(const char *fileName, struct stat *statbuf)
+static int dirAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        if (rmdir(fileName) < 0) {
                perror(fileName);
@@ -95,7 +95,7 @@ extern int rm_main(int argc, char **argv)
                        /* do not reports errors for non-existent files if -f, just skip them */
                } else {
                        if (recursiveAction(srcName, recursiveFlag, FALSE,
-                                                               TRUE, fileAction, dirAction) == FALSE) {
+                                                               TRUE, fileAction, dirAction, NULL) == FALSE) {
                                exit(FALSE);
                        }
                }
diff --git a/cp_mv.c b/cp_mv.c
index 8dbc4e8..72b0791 100644 (file)
--- a/cp_mv.c
+++ b/cp_mv.c
@@ -105,7 +105,7 @@ fill_baseDest_buf(char *_buf, size_t * _buflen) {
 }
 
 static int
-cp_mv_Action(const char *fileName, struct stat *statbuf)
+cp_mv_Action(const char *fileName, struct stat *statbuf, void* junk)
 {
        char            destName[PATH_MAX + 1];
        size_t          destLen;
@@ -165,7 +165,7 @@ cp_mv_Action(const char *fileName, struct stat *statbuf)
 }
 
 static int
-rm_Action(const char *fileName, struct stat *statbuf)
+rm_Action(const char *fileName, struct stat *statbuf, void* junk)
 {
        int status = TRUE;
 
@@ -310,11 +310,11 @@ extern int cp_mv_main(int argc, char **argv)
                        mv_Action_first_time = 1;
                        if (recursiveAction(baseSrcName,
                                                                recursiveFlag, followLinks, FALSE,
-                                                               cp_mv_Action, cp_mv_Action) == FALSE) goto exit_false;
+                                                               cp_mv_Action, cp_mv_Action, NULL) == FALSE) goto exit_false;
                        if (dz_i == is_mv &&
                                recursiveAction(baseSrcName,
                                                                recursiveFlag, followLinks, TRUE,
-                                                               rm_Action, rm_Action) == FALSE) goto exit_false;
+                                                               rm_Action, rm_Action, NULL) == FALSE) goto exit_false;
                }               
                if (flags_memo)
                        *(baseDestName + baseDestLen) = '\0';
diff --git a/find.c b/find.c
index 2c1039b..c23ac5f 100644 (file)
--- a/find.c
+++ b/find.c
@@ -42,7 +42,7 @@ static const char find_usage[] = "find [PATH...] [EXPRESSION]\n\n"
        "\t-print\n\t\tprint the full file name followed by a newline to stdout.\n";
 
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        if (pattern == NULL)
                fprintf(stdout, "%s\n", fileName);
@@ -109,7 +109,7 @@ int find_main(int argc, char **argv)
        }
 
        if (recursiveAction(directory, TRUE, FALSE, FALSE,
-                                               fileAction, fileAction) == FALSE) {
+                                               fileAction, fileAction, NULL) == FALSE) {
                exit(FALSE);
        }
 
index 2c1039b..c23ac5f 100644 (file)
@@ -42,7 +42,7 @@ static const char find_usage[] = "find [PATH...] [EXPRESSION]\n\n"
        "\t-print\n\t\tprint the full file name followed by a newline to stdout.\n";
 
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        if (pattern == NULL)
                fprintf(stdout, "%s\n", fileName);
@@ -109,7 +109,7 @@ int find_main(int argc, char **argv)
        }
 
        if (recursiveAction(directory, TRUE, FALSE, FALSE,
-                                               fileAction, fileAction) == FALSE) {
+                                               fileAction, fileAction, NULL) == FALSE) {
                exit(FALSE);
        }
 
index c54480e..e69e625 100644 (file)
@@ -191,8 +191,9 @@ void freeChunks(void);
 int fullWrite(int fd, const char *buf, int len);
 int fullRead(int fd, char *buf, int len);
 int recursiveAction(const char *fileName, int recurse, int followLinks, int depthFirst,
-         int (*fileAction) (const char *fileName, struct stat* statbuf),
-         int (*dirAction) (const char *fileName, struct stat* statbuf));
+         int (*fileAction) (const char *fileName, struct stat* statbuf, void* userData),
+         int (*dirAction) (const char *fileName, struct stat* statbuf, void* userData),
+         void* userData);
 const char* timeString(time_t timeVal);
 
 extern int createPath (const char *name, int mode);
@@ -227,8 +228,6 @@ extern void cmdedit_init(void);
 #if defined BB_INIT || defined BB_SYSLOGD
 extern int device_open(char *device, int mode);
 #endif
-extern void whine_if_fstab_is_missing();
-
 #if defined BB_FEATURE_MOUNT_LOOP
 extern int del_loop(const char *device);
 extern int set_loop(const char *device, const char *file, int offset, int *loopro);
diff --git a/rm.c b/rm.c
index 41afeda..683bf8b 100644 (file)
--- a/rm.c
+++ b/rm.c
@@ -42,7 +42,7 @@ static int forceFlag = FALSE;
 static const char *srcName;
 
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+static int fileAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        if (unlink(fileName) < 0) {
                perror(fileName);
@@ -51,7 +51,7 @@ static int fileAction(const char *fileName, struct stat *statbuf)
        return (TRUE);
 }
 
-static int dirAction(const char *fileName, struct stat *statbuf)
+static int dirAction(const char *fileName, struct stat *statbuf, void* junk)
 {
        if (rmdir(fileName) < 0) {
                perror(fileName);
@@ -95,7 +95,7 @@ extern int rm_main(int argc, char **argv)
                        /* do not reports errors for non-existent files if -f, just skip them */
                } else {
                        if (recursiveAction(srcName, recursiveFlag, FALSE,
-                                                               TRUE, fileAction, dirAction) == FALSE) {
+                                                               TRUE, fileAction, dirAction, NULL) == FALSE) {
                                exit(FALSE);
                        }
                }
index bc096ea..dca4019 100644 (file)
@@ -108,7 +108,12 @@ extern int swap_on_off_main(int argc, char **argv)
                while (*++(*argv))
                        switch (**argv) {
                        case 'a':
-                               whine_if_fstab_is_missing();
+                               {
+                                       struct stat statBuf;
+
+                                       if (stat("/etc/fstab", &statBuf) < 0)
+                                               fatalError("/etc/fstab file missing\n");
+                               }
                                do_em_all();
                                break;
                        default:
diff --git a/tar.c b/tar.c
index 37a28a3..af0e4f8 100644 (file)
--- a/tar.c
+++ b/tar.c
@@ -228,6 +228,7 @@ extern int tar_main(int argc, char **argv)
 
                case 'O':
                        tostdoutFlag = TRUE;
+                       tarName = "-";
                        break;
 
                case '-':
@@ -439,7 +440,7 @@ static long getOctal(const char *cp, int size)
 
 /* Parse the tar header and fill in the nice struct with the details */
 static int
-parseTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
+readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
 {
        int i;
        long chksum, sum;
@@ -502,7 +503,7 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag,
        while ( (status = fullRead(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {
 
                /* First, try to read the header */
-               if ( parseTarHeader(&rawHeader, &header) == FALSE ) {
+               if ( readTarHeader(&rawHeader, &header) == FALSE ) {
                        close( tarFd);
                        if ( *(header.name) == '\0' ) {
                                goto endgame;
@@ -661,25 +662,80 @@ static int putOctal (char *cp, int len, long value)
        return TRUE;
 }
 
-static int fileAction(const char *fileName, struct stat *statbuf)
+/* Write out a tar header for the specified file */
+static int
+writeTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
 {
-       fprintf(stdout, "%s\n", fileName);
+       int i;
+       long chksum, sum;
+       unsigned char *s = (unsigned char *)rawHeader;
+
+       struct TarHeader header;
+
+       strcpy(header.name, fileName); 
+       putOctal(header.mode, sizeof(header.mode), statbuf->st_mode & 0777);
+       putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
+       putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
+       putOctal(header.size, sizeof(header.size), statbuf->st_size);
+       putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
+
+       if (S_ISLNK(statbuf.st_mode)) {
+               header.type  = LNKTYPE;
+               // Handle SYMTYPE
+       } else if (S_ISDIR(statbuf.st_mode)) {
+               header.type  = DIRTYPE;
+       } else if (S_ISCHR(statbuf.st_mode)) {
+               header.type  = CHRTYPE;
+       } else if (S_ISBLK(statbuf.st_mode)) {
+               header.type  = BLKTYPE;
+       } else if (S_ISFIFO(statbuf.st_mode)) {
+               header.type  = FIFOTYPE;
+       } else if (S_ISSOCK(statbuf.st_mode)) {
+               header.type  = S_ISSOCK;
+       } else if (S_ISLNK(statbuf.st_mode)) {
+               header.type  = LNKTYPE;
+       } else if (S_ISLNK(statbuf.st_mode)) {
+               header.type  = REGTYPE;
+       }
+#if 0  
+       header->linkname  = rawHeader->linkname;
+       header->devmajor  = getOctal(rawHeader->devmajor, sizeof(rawHeader->devmajor));
+       header->devminor  = getOctal(rawHeader->devminor, sizeof(rawHeader->devminor));
+
+       /* Write out the checksum */
+       chksum = getOctal(rawHeader->chksum, sizeof(rawHeader->chksum));
+#endif
+
+       return ( TRUE);
+}
+
+
+static int fileAction(const char *fileName, struct stat *statbuf, void* userData)
+{
+       int *tarFd=(int*)userData;
+       dprintf(*tarFd, "%s\n", fileName);
        return (TRUE);
 }
 
 static int writeTarFile(const char* tarName, int extractFlag, int listFlag, 
                int tostdoutFlag, int verboseFlag, int argc, char **argv)
 {
-       int tarFd=0;
+       int tarFd=-1;
        //int errorFlag=FALSE;
        //TarHeader rawHeader;
        //TarInfo header;
        //int alreadyWarned=FALSE;
-       char *directory = ".";
        //int skipFileFlag=FALSE;
+       struct stat tarballStat;
+       dev_t tarDev = 0;
+       ino_t tarInode = 0;
+
+       /* Make sure there is at least one file to tar up.  */
+       if (argc <= 0)
+               fatalError("tar: Cowardly refusing to create an empty archive\n");
 
        /* Open the tar file for writing.  */
-       if (!strcmp(tarName, "-"))
+       if (tostdoutFlag == TRUE)
                tarFd = fileno(stdout);
        else
                tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
@@ -687,19 +743,25 @@ static int writeTarFile(const char* tarName, int extractFlag, int listFlag,
                errorMsg( "Error opening '%s': %s\n", tarName, strerror(errno));
                return ( FALSE);
        }
+       /* Store the device and inode of the tarball, so we can be sure
+        * not to try and include it into itself....  */
+       if (fstat(tarFd, &tarballStat) < 0)
+               fatalError(io_error, tarName, strerror(errno)); 
+       tarDev = tarballStat.st_dev;
+       tarInode = tarballStat.st_ino;
 
        /* Set the umask for this process so it doesn't 
         * screw up permission setting for us later. */
        umask(0);
 
        /* Read the directory/files and iterate over them one at a time */
-       if (recursiveAction(directory, TRUE, FALSE, FALSE,
-                                               fileAction, fileAction) == FALSE) {
-               exit(FALSE);
+       while (argc-- > 0) {
+               if (recursiveAction(*argv++, TRUE, FALSE, FALSE,
+                                       fileAction, fileAction, (void*) &tarFd) == FALSE) {
+                       exit(FALSE);
+               }
        }
 
-
-       // TODO: DO STUFF HERE
        close(tarFd);
        return( TRUE);
 }
index bc096ea..dca4019 100644 (file)
@@ -108,7 +108,12 @@ extern int swap_on_off_main(int argc, char **argv)
                while (*++(*argv))
                        switch (**argv) {
                        case 'a':
-                               whine_if_fstab_is_missing();
+                               {
+                                       struct stat statBuf;
+
+                                       if (stat("/etc/fstab", &statBuf) < 0)
+                                               fatalError("/etc/fstab file missing\n");
+                               }
                                do_em_all();
                                break;
                        default:
index a582f70..0d4799f 100644 (file)
--- a/utility.c
+++ b/utility.c
@@ -542,9 +542,12 @@ int fullRead(int fd, char *buf, int len)
 int recursiveAction(const char *fileName,
                                        int recurse, int followLinks, int depthFirst,
                                        int (*fileAction) (const char *fileName,
-                                                                          struct stat * statbuf),
+                                                                          struct stat * statbuf,
+                                                                          void* userData),
                                        int (*dirAction) (const char *fileName,
-                                                                         struct stat * statbuf))
+                                                                         struct stat * statbuf,
+                                                                         void* userData),
+                                       void* userData)
 {
        int status;
        struct stat statbuf;
@@ -569,13 +572,13 @@ int recursiveAction(const char *fileName,
                if (fileAction == NULL)
                        return TRUE;
                else
-                       return fileAction(fileName, &statbuf);
+                       return fileAction(fileName, &statbuf, userData);
        }
 
        if (recurse == FALSE) {
                if (S_ISDIR(statbuf.st_mode)) {
                        if (dirAction != NULL)
-                               return (dirAction(fileName, &statbuf));
+                               return (dirAction(fileName, &statbuf, userData));
                        else
                                return TRUE;
                }
@@ -590,7 +593,7 @@ int recursiveAction(const char *fileName,
                        return FALSE;
                }
                if (dirAction != NULL && depthFirst == FALSE) {
-                       status = dirAction(fileName, &statbuf);
+                       status = dirAction(fileName, &statbuf, userData);
                        if (status == FALSE) {
                                perror(fileName);
                                return FALSE;
@@ -610,7 +613,7 @@ int recursiveAction(const char *fileName,
                        sprintf(nextFile, "%s/%s", fileName, next->d_name);
                        status =
                                recursiveAction(nextFile, TRUE, followLinks, depthFirst,
-                                                               fileAction, dirAction);
+                                                               fileAction, dirAction, userData);
                        if (status < 0) {
                                closedir(dir);
                                return FALSE;
@@ -622,7 +625,7 @@ int recursiveAction(const char *fileName,
                        return FALSE;
                }
                if (dirAction != NULL && depthFirst == TRUE) {
-                       status = dirAction(fileName, &statbuf);
+                       status = dirAction(fileName, &statbuf, userData);
                        if (status == FALSE) {
                                perror(fileName);
                                return FALSE;
@@ -632,7 +635,7 @@ int recursiveAction(const char *fileName,
                if (fileAction == NULL)
                        return TRUE;
                else
-                       return fileAction(fileName, &statbuf);
+                       return fileAction(fileName, &statbuf, userData);
        }
        return TRUE;
 }
@@ -1514,19 +1517,6 @@ extern int find_real_root_device_name(char* name)
 #endif
 
 
-#if defined BB_MTAB
-#define whine_if_fstab_is_missing() {}
-#else
-extern void whine_if_fstab_is_missing()
-{
-       struct stat statBuf;
-
-       if (stat("/etc/fstab", &statBuf) < 0)
-               fprintf(stderr,
-                               "/etc/fstab file missing -- install one to name /dev/root.\n\n");
-}
-#endif
-
 /* END CODE */
 /*
 Local Variables: