diff options
author | Matt Kraai | 2000-09-04 08:25:42 +0000 |
---|---|---|
committer | Matt Kraai | 2000-09-04 08:25:42 +0000 |
commit | b92223b6f5848b2cdb41c3a6b9261b47826a5816 (patch) | |
tree | 1e3243c5a24394b6c3a1030c44ee5394947862bf | |
parent | fd50c3d2f9ab76aaf3736090e278be8742155d9f (diff) | |
download | busybox-b92223b6f5848b2cdb41c3a6b9261b47826a5816.zip busybox-b92223b6f5848b2cdb41c3a6b9261b47826a5816.tar.gz |
Allow selective extraction and listing of files. And fix an unchecked
return value of realloc (with xrealloc).
-rw-r--r-- | archival/tar.c | 31 | ||||
-rw-r--r-- | tar.c | 31 |
2 files changed, 54 insertions, 8 deletions
diff --git a/archival/tar.c b/archival/tar.c index 460962e..d3b0e5c 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -125,7 +125,8 @@ typedef struct TarInfo TarInfo; /* Local procedures to restore files from a tar file. */ static int readTarFile(const char* tarName, int extractFlag, int listFlag, - int tostdoutFlag, int verboseFlag, char** excludeList); + int tostdoutFlag, int verboseFlag, char** extractList, + char** excludeList); @@ -190,7 +191,7 @@ extern int tar_main(int argc, char **argv) if (strcmp(optarg, "exclude")==0) { if (argv[optind]==NULL) fatalError( "option `--exclude' requires an argument\n"); - excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+2)); + excludeList=xrealloc( excludeList, sizeof(char**) * (excludeListSize+2)); excludeList[excludeListSize] = argv[optind]; /* Remove leading "/"s */ if (*excludeList[excludeListSize] =='/') { @@ -222,7 +223,7 @@ extern int tar_main(int argc, char **argv) #endif } if (listFlag == TRUE || extractFlag == TRUE) { - exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, excludeList)); + exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, &argv[optind], excludeList)); } flagError: @@ -477,7 +478,8 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header) * If the list is empty than all files are extracted or listed. */ static int readTarFile(const char* tarName, int extractFlag, int listFlag, - int tostdoutFlag, int verboseFlag, char** excludeList) + int tostdoutFlag, int verboseFlag, char** extractList, + char** excludeList) { int status, tarFd=-1; int errorFlag=FALSE; @@ -544,6 +546,27 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, continue; } #endif + if (*extractList != NULL) { + int skipFlag = TRUE; + for (tmpList = extractList; *tmpList != NULL; tmpList++) { + if (strncmp( *tmpList, header.name, strlen(*tmpList))==0 || ( + header.name[strlen(header.name)-1]=='/' + && strncmp( *tmpList, header.name, + MIN(strlen(header.name)-1, strlen(*tmpList)))==0)) { + /* If it is a regular file, pretend to extract it with + * the extractFlag set to FALSE, so the junk in the tarball + * is properly skipped over */ + skipFlag = FALSE; + break; + } + } + /* There are not the droids you're looking for, move along */ + if (skipFlag == TRUE) { + if ( header.type==REGTYPE || header.type==REGTYPE0 ) + tarExtractRegularFile(&header, FALSE, FALSE); + continue; + } + } /* Special treatment if the list (-t) flag is on */ if (verboseFlag == TRUE && extractFlag == FALSE) { int len, len1; @@ -125,7 +125,8 @@ typedef struct TarInfo TarInfo; /* Local procedures to restore files from a tar file. */ static int readTarFile(const char* tarName, int extractFlag, int listFlag, - int tostdoutFlag, int verboseFlag, char** excludeList); + int tostdoutFlag, int verboseFlag, char** extractList, + char** excludeList); @@ -190,7 +191,7 @@ extern int tar_main(int argc, char **argv) if (strcmp(optarg, "exclude")==0) { if (argv[optind]==NULL) fatalError( "option `--exclude' requires an argument\n"); - excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+2)); + excludeList=xrealloc( excludeList, sizeof(char**) * (excludeListSize+2)); excludeList[excludeListSize] = argv[optind]; /* Remove leading "/"s */ if (*excludeList[excludeListSize] =='/') { @@ -222,7 +223,7 @@ extern int tar_main(int argc, char **argv) #endif } if (listFlag == TRUE || extractFlag == TRUE) { - exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, excludeList)); + exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, &argv[optind], excludeList)); } flagError: @@ -477,7 +478,8 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header) * If the list is empty than all files are extracted or listed. */ static int readTarFile(const char* tarName, int extractFlag, int listFlag, - int tostdoutFlag, int verboseFlag, char** excludeList) + int tostdoutFlag, int verboseFlag, char** extractList, + char** excludeList) { int status, tarFd=-1; int errorFlag=FALSE; @@ -544,6 +546,27 @@ static int readTarFile(const char* tarName, int extractFlag, int listFlag, continue; } #endif + if (*extractList != NULL) { + int skipFlag = TRUE; + for (tmpList = extractList; *tmpList != NULL; tmpList++) { + if (strncmp( *tmpList, header.name, strlen(*tmpList))==0 || ( + header.name[strlen(header.name)-1]=='/' + && strncmp( *tmpList, header.name, + MIN(strlen(header.name)-1, strlen(*tmpList)))==0)) { + /* If it is a regular file, pretend to extract it with + * the extractFlag set to FALSE, so the junk in the tarball + * is properly skipped over */ + skipFlag = FALSE; + break; + } + } + /* There are not the droids you're looking for, move along */ + if (skipFlag == TRUE) { + if ( header.type==REGTYPE || header.type==REGTYPE0 ) + tarExtractRegularFile(&header, FALSE, FALSE); + continue; + } + } /* Special treatment if the list (-t) flag is on */ if (verboseFlag == TRUE && extractFlag == FALSE) { int len, len1; |