From 3364d78b18386623e7af5da18ba1bb0cc6286279 Mon Sep 17 00:00:00 2001 From: Erik Andersen Date: Tue, 28 Mar 2000 00:58:14 +0000 Subject: [PATCH] Yet another installment in the ongoing tar saga -Erik --- archival/tar.c | 86 ++++++++++++++++++++++++++++++++++++------ chmod_chown_chgrp.c | 7 ++-- coreutils/rm.c | 6 +-- cp_mv.c | 8 ++-- find.c | 4 +- findutils/find.c | 4 +- internal.h | 7 ++-- rm.c | 6 +-- swaponoff.c | 7 +++- tar.c | 86 ++++++++++++++++++++++++++++++++++++------ util-linux/swaponoff.c | 7 +++- utility.c | 32 ++++++---------- 12 files changed, 191 insertions(+), 69 deletions(-) diff --git a/archival/tar.c b/archival/tar.c index 37a28a3d0..af0e4f8ef 100644 --- a/archival/tar.c +++ b/archival/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); } diff --git a/chmod_chown_chgrp.c b/chmod_chown_chgrp.c index e197ee3e8..00c6b349a 100644 --- a/chmod_chown_chgrp.c +++ b/chmod_chown_chgrp.c @@ -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); diff --git a/coreutils/rm.c b/coreutils/rm.c index 41afedaf9..683bf8bdf 100644 --- a/coreutils/rm.c +++ b/coreutils/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); } } diff --git a/cp_mv.c b/cp_mv.c index 8dbc4e8f1..72b0791c2 100644 --- 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 2c1039b53..c23ac5f46 100644 --- 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); } diff --git a/findutils/find.c b/findutils/find.c index 2c1039b53..c23ac5f46 100644 --- a/findutils/find.c +++ b/findutils/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); } diff --git a/internal.h b/internal.h index c54480e2b..e69e62534 100644 --- a/internal.h +++ b/internal.h @@ -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 41afedaf9..683bf8bdf 100644 --- 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); } } diff --git a/swaponoff.c b/swaponoff.c index bc096ea95..dca401966 100644 --- a/swaponoff.c +++ b/swaponoff.c @@ -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 37a28a3d0..af0e4f8ef 100644 --- 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); } diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index bc096ea95..dca401966 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -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/utility.c b/utility.c index a582f708c..0d4799f2d 100644 --- 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: