Latest and greatest

-Erik
This commit is contained in:
Erik Andersen 2000-04-08 03:08:21 +00:00
parent 5dd853ad2a
commit ecd512453c
3 changed files with 195 additions and 131 deletions

View File

@ -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. # Set the following to `true' to make a debuggable build.
# Leave this set to `false' for production use. # Leave this set to `false' for production use.
# eg: `make DODEBUG=true tests' # eg: `make DODEBUG=true tests'
DODEBUG = false DODEBUG = true
# If you want a static binary, turn this on. I can't think # If you want a static binary, turn this on. I can't think
# of many situations where anybody would ever want it static, # of many situations where anybody would ever want it static,

View File

@ -55,24 +55,27 @@
#ifdef BB_FEATURE_TAR_CREATE #ifdef BB_FEATURE_TAR_CREATE
static const char tar_usage[] = 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" "Create, extract, or list files from a tar file. Note that\n"
"this version of tar packs hard links as separate files.\n\n" "this version of tar packs hard links as separate files.\n\n"
"Options:\n" "Options:\n"
"\tc=create, x=extract, t=list contents, v=verbose,\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 #else
static const char tar_usage[] = 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" "Extract, or list files stored in a tar file. This\n"
"version of tar does not support creation of tar files.\n\n" "version of tar does not support creation of tar files.\n\n"
"Options:\n" "Options:\n"
"\tx=extract, t=list contents, v=verbose,\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 #endif
@ -157,90 +160,106 @@ static const unsigned long TarChecksumOffset = (const unsigned long)&(((TarHeade
/* Local procedures to restore files from a tar file. */ /* Local procedures to restore files from a tar file. */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, 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 #ifdef BB_FEATURE_TAR_CREATE
/* Local procedures to save files into a tar file. */ /* Local procedures to save files into a tar file. */
static int writeTarFile(const char* tarName, int tostdoutFlag, static int writeTarFile(const char* tarName, int tostdoutFlag,
int verboseFlag, int argc, char **argv); int verboseFlag, int argc, char **argv, char** excludeList);
static int putOctal(char *cp, int len, long value);
#endif #endif
extern int tar_main(int argc, char **argv) extern int tar_main(int argc, char **argv)
{ {
char** excludeList=NULL;
int excludeListSize=0;
const char *tarName=NULL; const char *tarName=NULL;
const char *options;
int listFlag = FALSE; int listFlag = FALSE;
int extractFlag = FALSE; int extractFlag = FALSE;
int createFlag = FALSE; int createFlag = FALSE;
int verboseFlag = FALSE; int verboseFlag = FALSE;
int tostdoutFlag = FALSE; int tostdoutFlag = FALSE;
int stopIt;
argc--; if (argc <= 1)
argv++;
if (argc < 1)
usage(tar_usage); usage(tar_usage);
/* Parse options */ /* Parse any options */
if (**argv == '-') while (--argc > 0 && **(++argv) == '-') {
options = (*argv++) + 1; stopIt=FALSE;
else while (stopIt==FALSE && *(++(*argv))) {
options = (*argv++); switch (**argv) {
argc--; 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;
for (; *options; options++) { case 't':
switch (*options) { if (extractFlag == TRUE || createFlag == TRUE)
case 'f': goto flagError;
if (tarName != NULL) listFlag = TRUE;
fatalError( "Only one 'f' option allowed\n"); break;
tarName = *argv++; case 'x':
if (tarName == NULL) if (listFlag == TRUE || createFlag == TRUE)
fatalError( "Option requires an argument: No file specified\n"); goto flagError;
argc--; extractFlag = TRUE;
break;
case 'c':
if (extractFlag == TRUE || listFlag == TRUE)
goto flagError;
createFlag = TRUE;
break;
break; case 'v':
verboseFlag = TRUE;
break;
case 't': case 'O':
if (extractFlag == TRUE || createFlag == TRUE) tostdoutFlag = TRUE;
goto flagError; tarName = "-";
listFlag = TRUE; break;
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 'x': case '-':
if (listFlag == TRUE || createFlag == TRUE) usage(tar_usage);
goto flagError; break;
extractFlag = TRUE;
break;
case 'c':
if (extractFlag == TRUE || listFlag == TRUE)
goto flagError;
createFlag = TRUE;
break;
case 'v': default:
verboseFlag = TRUE; fatalError( "Unknown tar flag '%c'\n"
break; "Try `tar --help' for more information\n", **argv);
}
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);
} }
} }
#if 0
for (i=0; i<excludeListSize; i++) {
printf( "%s\n", excludeList[i]);
fflush(stdout);
}
#endif
/* /*
* Do the correct type of action supplying the rest of the * Do the correct type of action supplying the rest of the
@ -250,10 +269,10 @@ extern int tar_main(int argc, char **argv)
#ifndef BB_FEATURE_TAR_CREATE #ifndef BB_FEATURE_TAR_CREATE
fatalError( "This version of tar was not compiled with tar creation support.\n"); fatalError( "This version of tar was not compiled with tar creation support.\n");
#else #else
exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv)); exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv, excludeList));
#endif #endif
} else { } else {
exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag)); exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, excludeList));
} }
flagError: flagError:
@ -486,7 +505,7 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
* If the list is empty than all files are extracted or listed. * If the list is empty than all files are extracted or listed.
*/ */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, static int readTarFile(const char* tarName, int extractFlag, int listFlag,
int tostdoutFlag, int verboseFlag) int tostdoutFlag, int verboseFlag, char** excludeList)
{ {
int status, tarFd=0; int status, tarFd=0;
int errorFlag=FALSE; int errorFlag=FALSE;
@ -675,6 +694,7 @@ struct TarBallInfo
tarball lives, so we can avoid trying tarball lives, so we can avoid trying
to include the tarball into itself */ to include the tarball into itself */
int verboseFlag; /* Whether to print extra stuff or not */ int verboseFlag; /* Whether to print extra stuff or not */
char** excludeList; /* List of files to not include */
}; };
typedef struct TarBallInfo TarBallInfo; typedef struct TarBallInfo TarBallInfo;
@ -719,6 +739,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
{ {
long chksum=0; long chksum=0;
struct TarHeader header; struct TarHeader header;
char** tmpList;
const unsigned char *cp = (const unsigned char *) &header; const unsigned char *cp = (const unsigned char *) &header;
ssize_t size = sizeof(struct TarHeader); ssize_t size = sizeof(struct TarHeader);
@ -735,6 +756,17 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
else { else {
strcpy(header.name, fileName); strcpy(header.name, fileName);
} }
#if 0
/* Now that leading '/''s have been removed */
for (tmpList=tbInfo->excludeList; 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.mode, sizeof(header.mode), statbuf->st_mode);
putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); 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, 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 tarFd=-1;
int errorFlag=FALSE; int errorFlag=FALSE;
ssize_t size; ssize_t size;
//int skipFileFlag=FALSE;
struct TarBallInfo tbInfo; struct TarBallInfo tbInfo;
tbInfo.verboseFlag = verboseFlag; 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)); errorMsg( "tar: Error opening '%s': %s\n", tarName, strerror(errno));
return ( FALSE); return ( FALSE);
} }
tbInfo.excludeList=excludeList;
/* Store the stat info for the tarball's file, so /* Store the stat info for the tarball's file, so
* can avoid including the tarball into itself.... */ * can avoid including the tarball into itself.... */
if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)

162
tar.c
View File

@ -55,24 +55,27 @@
#ifdef BB_FEATURE_TAR_CREATE #ifdef BB_FEATURE_TAR_CREATE
static const char tar_usage[] = 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" "Create, extract, or list files from a tar file. Note that\n"
"this version of tar packs hard links as separate files.\n\n" "this version of tar packs hard links as separate files.\n\n"
"Options:\n" "Options:\n"
"\tc=create, x=extract, t=list contents, v=verbose,\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 #else
static const char tar_usage[] = 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" "Extract, or list files stored in a tar file. This\n"
"version of tar does not support creation of tar files.\n\n" "version of tar does not support creation of tar files.\n\n"
"Options:\n" "Options:\n"
"\tx=extract, t=list contents, v=verbose,\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 #endif
@ -157,90 +160,106 @@ static const unsigned long TarChecksumOffset = (const unsigned long)&(((TarHeade
/* Local procedures to restore files from a tar file. */ /* Local procedures to restore files from a tar file. */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, 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 #ifdef BB_FEATURE_TAR_CREATE
/* Local procedures to save files into a tar file. */ /* Local procedures to save files into a tar file. */
static int writeTarFile(const char* tarName, int tostdoutFlag, static int writeTarFile(const char* tarName, int tostdoutFlag,
int verboseFlag, int argc, char **argv); int verboseFlag, int argc, char **argv, char** excludeList);
static int putOctal(char *cp, int len, long value);
#endif #endif
extern int tar_main(int argc, char **argv) extern int tar_main(int argc, char **argv)
{ {
char** excludeList=NULL;
int excludeListSize=0;
const char *tarName=NULL; const char *tarName=NULL;
const char *options;
int listFlag = FALSE; int listFlag = FALSE;
int extractFlag = FALSE; int extractFlag = FALSE;
int createFlag = FALSE; int createFlag = FALSE;
int verboseFlag = FALSE; int verboseFlag = FALSE;
int tostdoutFlag = FALSE; int tostdoutFlag = FALSE;
int stopIt;
argc--; if (argc <= 1)
argv++;
if (argc < 1)
usage(tar_usage); usage(tar_usage);
/* Parse options */ /* Parse any options */
if (**argv == '-') while (--argc > 0 && **(++argv) == '-') {
options = (*argv++) + 1; stopIt=FALSE;
else while (stopIt==FALSE && *(++(*argv))) {
options = (*argv++); switch (**argv) {
argc--; 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;
for (; *options; options++) { case 't':
switch (*options) { if (extractFlag == TRUE || createFlag == TRUE)
case 'f': goto flagError;
if (tarName != NULL) listFlag = TRUE;
fatalError( "Only one 'f' option allowed\n"); break;
tarName = *argv++; case 'x':
if (tarName == NULL) if (listFlag == TRUE || createFlag == TRUE)
fatalError( "Option requires an argument: No file specified\n"); goto flagError;
argc--; extractFlag = TRUE;
break;
case 'c':
if (extractFlag == TRUE || listFlag == TRUE)
goto flagError;
createFlag = TRUE;
break;
break; case 'v':
verboseFlag = TRUE;
break;
case 't': case 'O':
if (extractFlag == TRUE || createFlag == TRUE) tostdoutFlag = TRUE;
goto flagError; tarName = "-";
listFlag = TRUE; break;
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 'x': case '-':
if (listFlag == TRUE || createFlag == TRUE) usage(tar_usage);
goto flagError; break;
extractFlag = TRUE;
break;
case 'c':
if (extractFlag == TRUE || listFlag == TRUE)
goto flagError;
createFlag = TRUE;
break;
case 'v': default:
verboseFlag = TRUE; fatalError( "Unknown tar flag '%c'\n"
break; "Try `tar --help' for more information\n", **argv);
}
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);
} }
} }
#if 0
for (i=0; i<excludeListSize; i++) {
printf( "%s\n", excludeList[i]);
fflush(stdout);
}
#endif
/* /*
* Do the correct type of action supplying the rest of the * Do the correct type of action supplying the rest of the
@ -250,10 +269,10 @@ extern int tar_main(int argc, char **argv)
#ifndef BB_FEATURE_TAR_CREATE #ifndef BB_FEATURE_TAR_CREATE
fatalError( "This version of tar was not compiled with tar creation support.\n"); fatalError( "This version of tar was not compiled with tar creation support.\n");
#else #else
exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv)); exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv, excludeList));
#endif #endif
} else { } else {
exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag)); exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, excludeList));
} }
flagError: flagError:
@ -486,7 +505,7 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
* If the list is empty than all files are extracted or listed. * If the list is empty than all files are extracted or listed.
*/ */
static int readTarFile(const char* tarName, int extractFlag, int listFlag, static int readTarFile(const char* tarName, int extractFlag, int listFlag,
int tostdoutFlag, int verboseFlag) int tostdoutFlag, int verboseFlag, char** excludeList)
{ {
int status, tarFd=0; int status, tarFd=0;
int errorFlag=FALSE; int errorFlag=FALSE;
@ -675,6 +694,7 @@ struct TarBallInfo
tarball lives, so we can avoid trying tarball lives, so we can avoid trying
to include the tarball into itself */ to include the tarball into itself */
int verboseFlag; /* Whether to print extra stuff or not */ int verboseFlag; /* Whether to print extra stuff or not */
char** excludeList; /* List of files to not include */
}; };
typedef struct TarBallInfo TarBallInfo; typedef struct TarBallInfo TarBallInfo;
@ -719,6 +739,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
{ {
long chksum=0; long chksum=0;
struct TarHeader header; struct TarHeader header;
char** tmpList;
const unsigned char *cp = (const unsigned char *) &header; const unsigned char *cp = (const unsigned char *) &header;
ssize_t size = sizeof(struct TarHeader); ssize_t size = sizeof(struct TarHeader);
@ -735,6 +756,17 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
else { else {
strcpy(header.name, fileName); strcpy(header.name, fileName);
} }
#if 0
/* Now that leading '/''s have been removed */
for (tmpList=tbInfo->excludeList; 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.mode, sizeof(header.mode), statbuf->st_mode);
putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); 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, 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 tarFd=-1;
int errorFlag=FALSE; int errorFlag=FALSE;
ssize_t size; ssize_t size;
//int skipFileFlag=FALSE;
struct TarBallInfo tbInfo; struct TarBallInfo tbInfo;
tbInfo.verboseFlag = verboseFlag; 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)); errorMsg( "tar: Error opening '%s': %s\n", tarName, strerror(errno));
return ( FALSE); return ( FALSE);
} }
tbInfo.excludeList=excludeList;
/* Store the stat info for the tarball's file, so /* Store the stat info for the tarball's file, so
* can avoid including the tarball into itself.... */ * can avoid including the tarball into itself.... */
if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)