From ecd512453ce8f7a7c8a3b5d523855a2b52d626c5 Mon Sep 17 00:00:00 2001 From: Erik Andersen Date: Sat, 8 Apr 2000 03:08:21 +0000 Subject: [PATCH] Latest and greatest -Erik --- Makefile | 2 +- archival/tar.c | 174 ++++++++++++++++++++++++++++++++++----------------------- tar.c | 174 ++++++++++++++++++++++++++++++++++----------------------- 3 files changed, 207 insertions(+), 143 deletions(-) diff --git a/Makefile b/Makefile index fc6ed96a2..d647a5139 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ BUILDTIME := $(shell TZ=UTC date --utc "+%Y.%m.%d-%H:%M%z") # Set the following to `true' to make a debuggable build. # Leave this set to `false' for production use. # eg: `make DODEBUG=true tests' -DODEBUG = false +DODEBUG = true # If you want a static binary, turn this on. I can't think # of many situations where anybody would ever want it static, diff --git a/archival/tar.c b/archival/tar.c index 91baa2ddb..49d4d2ecf 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -55,24 +55,27 @@ #ifdef BB_FEATURE_TAR_CREATE static const char tar_usage[] = - "tar -[cxtvOf] [tarFileName] [FILE] ...\n\n" + "tar -[cxtvOf] [tarFile] [-X excludeFile] [FILE] ...\n\n" "Create, extract, or list files from a tar file. Note that\n" "this version of tar packs hard links as separate files.\n\n" "Options:\n" "\tc=create, x=extract, t=list contents, v=verbose,\n" - "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; + "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n" + "\tX=exclude file\n"; #else static const char tar_usage[] = - "tar -[xtvOf] [tarFileName] [FILE] ...\n\n" + "tar -[xtvO] [-f tarFile] [-X excludeFile] [FILE] ...\n\n" "Extract, or list files stored in a tar file. This\n" "version of tar does not support creation of tar files.\n\n" "Options:\n" "\tx=extract, t=list contents, v=verbose,\n" - "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; + "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n" + "\tX=exclude file\n"; + #endif @@ -157,90 +160,106 @@ static const unsigned long TarChecksumOffset = (const unsigned long)&(((TarHeade /* Local procedures to restore files from a tar file. */ static int readTarFile(const char* tarName, int extractFlag, int listFlag, - int tostdoutFlag, int verboseFlag); + int tostdoutFlag, int verboseFlag, char** excludeList); #ifdef BB_FEATURE_TAR_CREATE /* Local procedures to save files into a tar file. */ static int writeTarFile(const char* tarName, int tostdoutFlag, - int verboseFlag, int argc, char **argv); -static int putOctal(char *cp, int len, long value); - + int verboseFlag, int argc, char **argv, char** excludeList); #endif extern int tar_main(int argc, char **argv) { + char** excludeList=NULL; + int excludeListSize=0; const char *tarName=NULL; - const char *options; int listFlag = FALSE; int extractFlag = FALSE; int createFlag = FALSE; int verboseFlag = FALSE; int tostdoutFlag = FALSE; + int stopIt; - argc--; - argv++; - - if (argc < 1) + if (argc <= 1) usage(tar_usage); - /* Parse options */ - if (**argv == '-') - options = (*argv++) + 1; - else - options = (*argv++); - argc--; - - for (; *options; options++) { - switch (*options) { - case 'f': - if (tarName != NULL) - fatalError( "Only one 'f' option allowed\n"); - - tarName = *argv++; - if (tarName == NULL) - fatalError( "Option requires an argument: No file specified\n"); - argc--; - - break; - - case 't': - if (extractFlag == TRUE || createFlag == TRUE) - goto flagError; - listFlag = TRUE; - break; - - case 'x': - if (listFlag == TRUE || createFlag == TRUE) - goto flagError; - extractFlag = TRUE; - break; - case 'c': - if (extractFlag == TRUE || listFlag == TRUE) - goto flagError; - createFlag = TRUE; - break; - - case 'v': - verboseFlag = TRUE; - break; - - case 'O': - tostdoutFlag = TRUE; - tarName = "-"; - break; - - case '-': - usage(tar_usage); - break; - - default: - fatalError( "Unknown tar flag '%c'\n" - "Try `tar --help' for more information\n", *options); + /* Parse any options */ + while (--argc > 0 && **(++argv) == '-') { + stopIt=FALSE; + while (stopIt==FALSE && *(++(*argv))) { + switch (**argv) { + case 'f': + if (--argc == 0) { + fatalError( "Option requires an argument: No file specified\n"); + } + if (tarName != NULL) + fatalError( "Only one 'f' option allowed\n"); + tarName = *(++argv); + if (tarName == NULL) + fatalError( "Option requires an argument: No file specified\n"); + stopIt=TRUE; + break; + + case 't': + if (extractFlag == TRUE || createFlag == TRUE) + goto flagError; + listFlag = TRUE; + break; + + case 'x': + if (listFlag == TRUE || createFlag == TRUE) + goto flagError; + extractFlag = TRUE; + break; + case 'c': + if (extractFlag == TRUE || listFlag == TRUE) + goto flagError; + createFlag = TRUE; + break; + + case 'v': + verboseFlag = TRUE; + break; + + case 'O': + tostdoutFlag = TRUE; + tarName = "-"; + break; + case 'X': + if (--argc == 0) { + fatalError( "Option requires an argument: No file specified\n"); + } + excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+1)); + excludeList[excludeListSize] = *(++argv); + /* Remove leading "/"s */ + if (*excludeList[excludeListSize] =='/') { + excludeList[excludeListSize] = (excludeList[excludeListSize])+1; + } + if (excludeList[excludeListSize++] == NULL) + fatalError( "Option requires an argument: No file specified\n"); + stopIt=TRUE; + break; + + case '-': + usage(tar_usage); + break; + + default: + fatalError( "Unknown tar flag '%c'\n" + "Try `tar --help' for more information\n", **argv); + } } } +#if 0 + for (i=0; iexcludeList; tmpList && *tmpList; tmpList++) { + printf( "comparing '%s' and '%s'", *tmpList, header.name); + if (strcmp( *tmpList, header.name)==0) + printf( ": match\n"); + else + printf( "\n"); + } +#endif + putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); @@ -868,12 +900,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* } static int writeTarFile(const char* tarName, int tostdoutFlag, - int verboseFlag, int argc, char **argv) + int verboseFlag, int argc, char **argv, char** excludeList) { int tarFd=-1; int errorFlag=FALSE; ssize_t size; - //int skipFileFlag=FALSE; struct TarBallInfo tbInfo; tbInfo.verboseFlag = verboseFlag; @@ -890,6 +921,7 @@ static int writeTarFile(const char* tarName, int tostdoutFlag, errorMsg( "tar: Error opening '%s': %s\n", tarName, strerror(errno)); return ( FALSE); } + tbInfo.excludeList=excludeList; /* Store the stat info for the tarball's file, so * can avoid including the tarball into itself.... */ if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) diff --git a/tar.c b/tar.c index 91baa2ddb..49d4d2ecf 100644 --- a/tar.c +++ b/tar.c @@ -55,24 +55,27 @@ #ifdef BB_FEATURE_TAR_CREATE static const char tar_usage[] = - "tar -[cxtvOf] [tarFileName] [FILE] ...\n\n" + "tar -[cxtvOf] [tarFile] [-X excludeFile] [FILE] ...\n\n" "Create, extract, or list files from a tar file. Note that\n" "this version of tar packs hard links as separate files.\n\n" "Options:\n" "\tc=create, x=extract, t=list contents, v=verbose,\n" - "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; + "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n" + "\tX=exclude file\n"; #else static const char tar_usage[] = - "tar -[xtvOf] [tarFileName] [FILE] ...\n\n" + "tar -[xtvO] [-f tarFile] [-X excludeFile] [FILE] ...\n\n" "Extract, or list files stored in a tar file. This\n" "version of tar does not support creation of tar files.\n\n" "Options:\n" "\tx=extract, t=list contents, v=verbose,\n" - "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; + "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n" + "\tX=exclude file\n"; + #endif @@ -157,90 +160,106 @@ static const unsigned long TarChecksumOffset = (const unsigned long)&(((TarHeade /* Local procedures to restore files from a tar file. */ static int readTarFile(const char* tarName, int extractFlag, int listFlag, - int tostdoutFlag, int verboseFlag); + int tostdoutFlag, int verboseFlag, char** excludeList); #ifdef BB_FEATURE_TAR_CREATE /* Local procedures to save files into a tar file. */ static int writeTarFile(const char* tarName, int tostdoutFlag, - int verboseFlag, int argc, char **argv); -static int putOctal(char *cp, int len, long value); - + int verboseFlag, int argc, char **argv, char** excludeList); #endif extern int tar_main(int argc, char **argv) { + char** excludeList=NULL; + int excludeListSize=0; const char *tarName=NULL; - const char *options; int listFlag = FALSE; int extractFlag = FALSE; int createFlag = FALSE; int verboseFlag = FALSE; int tostdoutFlag = FALSE; + int stopIt; - argc--; - argv++; - - if (argc < 1) + if (argc <= 1) usage(tar_usage); - /* Parse options */ - if (**argv == '-') - options = (*argv++) + 1; - else - options = (*argv++); - argc--; - - for (; *options; options++) { - switch (*options) { - case 'f': - if (tarName != NULL) - fatalError( "Only one 'f' option allowed\n"); - - tarName = *argv++; - if (tarName == NULL) - fatalError( "Option requires an argument: No file specified\n"); - argc--; - - break; - - case 't': - if (extractFlag == TRUE || createFlag == TRUE) - goto flagError; - listFlag = TRUE; - break; - - case 'x': - if (listFlag == TRUE || createFlag == TRUE) - goto flagError; - extractFlag = TRUE; - break; - case 'c': - if (extractFlag == TRUE || listFlag == TRUE) - goto flagError; - createFlag = TRUE; - break; - - case 'v': - verboseFlag = TRUE; - break; - - case 'O': - tostdoutFlag = TRUE; - tarName = "-"; - break; - - case '-': - usage(tar_usage); - break; - - default: - fatalError( "Unknown tar flag '%c'\n" - "Try `tar --help' for more information\n", *options); + /* Parse any options */ + while (--argc > 0 && **(++argv) == '-') { + stopIt=FALSE; + while (stopIt==FALSE && *(++(*argv))) { + switch (**argv) { + case 'f': + if (--argc == 0) { + fatalError( "Option requires an argument: No file specified\n"); + } + if (tarName != NULL) + fatalError( "Only one 'f' option allowed\n"); + tarName = *(++argv); + if (tarName == NULL) + fatalError( "Option requires an argument: No file specified\n"); + stopIt=TRUE; + break; + + case 't': + if (extractFlag == TRUE || createFlag == TRUE) + goto flagError; + listFlag = TRUE; + break; + + case 'x': + if (listFlag == TRUE || createFlag == TRUE) + goto flagError; + extractFlag = TRUE; + break; + case 'c': + if (extractFlag == TRUE || listFlag == TRUE) + goto flagError; + createFlag = TRUE; + break; + + case 'v': + verboseFlag = TRUE; + break; + + case 'O': + tostdoutFlag = TRUE; + tarName = "-"; + break; + case 'X': + if (--argc == 0) { + fatalError( "Option requires an argument: No file specified\n"); + } + excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+1)); + excludeList[excludeListSize] = *(++argv); + /* Remove leading "/"s */ + if (*excludeList[excludeListSize] =='/') { + excludeList[excludeListSize] = (excludeList[excludeListSize])+1; + } + if (excludeList[excludeListSize++] == NULL) + fatalError( "Option requires an argument: No file specified\n"); + stopIt=TRUE; + break; + + case '-': + usage(tar_usage); + break; + + default: + fatalError( "Unknown tar flag '%c'\n" + "Try `tar --help' for more information\n", **argv); + } } } +#if 0 + for (i=0; iexcludeList; tmpList && *tmpList; tmpList++) { + printf( "comparing '%s' and '%s'", *tmpList, header.name); + if (strcmp( *tmpList, header.name)==0) + printf( ": match\n"); + else + printf( "\n"); + } +#endif + putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); @@ -868,12 +900,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* } static int writeTarFile(const char* tarName, int tostdoutFlag, - int verboseFlag, int argc, char **argv) + int verboseFlag, int argc, char **argv, char** excludeList) { int tarFd=-1; int errorFlag=FALSE; ssize_t size; - //int skipFileFlag=FALSE; struct TarBallInfo tbInfo; tbInfo.verboseFlag = verboseFlag; @@ -890,6 +921,7 @@ static int writeTarFile(const char* tarName, int tostdoutFlag, errorMsg( "tar: Error opening '%s': %s\n", tarName, strerror(errno)); return ( FALSE); } + tbInfo.excludeList=excludeList; /* Store the stat info for the tarball's file, so * can avoid including the tarball into itself.... */ if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) -- 2.11.0