summaryrefslogtreecommitdiff
path: root/archival
diff options
context:
space:
mode:
authorErik Andersen <andersen@codepoet.org>2000-04-08 03:08:21 +0000
committerErik Andersen <andersen@codepoet.org>2000-04-08 03:08:21 +0000
commitecd512453ce8f7a7c8a3b5d523855a2b52d626c5 (patch)
tree85d71f517408081f99a9ad52ed3dc233c3db082e /archival
parent5dd853ad2a8da4d1e85a2221ce3e15bfb1e5885c (diff)
downloadbusybox-w32-ecd512453ce8f7a7c8a3b5d523855a2b52d626c5.tar.gz
busybox-w32-ecd512453ce8f7a7c8a3b5d523855a2b52d626c5.tar.bz2
busybox-w32-ecd512453ce8f7a7c8a3b5d523855a2b52d626c5.zip
Latest and greatest
-Erik
Diffstat (limited to 'archival')
-rw-r--r--archival/tar.c174
1 files changed, 103 insertions, 71 deletions
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 @@
55#ifdef BB_FEATURE_TAR_CREATE 55#ifdef BB_FEATURE_TAR_CREATE
56 56
57static const char tar_usage[] = 57static const char tar_usage[] =
58 "tar -[cxtvOf] [tarFileName] [FILE] ...\n\n" 58 "tar -[cxtvOf] [tarFile] [-X excludeFile] [FILE] ...\n\n"
59 "Create, extract, or list files from a tar file. Note that\n" 59 "Create, extract, or list files from a tar file. Note that\n"
60 "this version of tar packs hard links as separate files.\n\n" 60 "this version of tar packs hard links as separate files.\n\n"
61 "Options:\n" 61 "Options:\n"
62 62
63 "\tc=create, x=extract, t=list contents, v=verbose,\n" 63 "\tc=create, x=extract, t=list contents, v=verbose,\n"
64 "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; 64 "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"
65 "\tX=exclude file\n";
65 66
66#else 67#else
67 68
68static const char tar_usage[] = 69static const char tar_usage[] =
69 "tar -[xtvOf] [tarFileName] [FILE] ...\n\n" 70 "tar -[xtvO] [-f tarFile] [-X excludeFile] [FILE] ...\n\n"
70 "Extract, or list files stored in a tar file. This\n" 71 "Extract, or list files stored in a tar file. This\n"
71 "version of tar does not support creation of tar files.\n\n" 72 "version of tar does not support creation of tar files.\n\n"
72 "Options:\n" 73 "Options:\n"
73 74
74 "\tx=extract, t=list contents, v=verbose,\n" 75 "\tx=extract, t=list contents, v=verbose,\n"
75 "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"; 76 "\tO=extract to stdout, f=tarfile or \"-\" for stdin\n"
77 "\tX=exclude file\n";
78
76 79
77#endif 80#endif
78 81
@@ -157,90 +160,106 @@ static const unsigned long TarChecksumOffset = (const unsigned long)&(((TarHeade
157 160
158/* Local procedures to restore files from a tar file. */ 161/* Local procedures to restore files from a tar file. */
159static int readTarFile(const char* tarName, int extractFlag, int listFlag, 162static int readTarFile(const char* tarName, int extractFlag, int listFlag,
160 int tostdoutFlag, int verboseFlag); 163 int tostdoutFlag, int verboseFlag, char** excludeList);
161 164
162 165
163 166
164#ifdef BB_FEATURE_TAR_CREATE 167#ifdef BB_FEATURE_TAR_CREATE
165/* Local procedures to save files into a tar file. */ 168/* Local procedures to save files into a tar file. */
166static int writeTarFile(const char* tarName, int tostdoutFlag, 169static int writeTarFile(const char* tarName, int tostdoutFlag,
167 int verboseFlag, int argc, char **argv); 170 int verboseFlag, int argc, char **argv, char** excludeList);
168static int putOctal(char *cp, int len, long value);
169
170#endif 171#endif
171 172
172 173
173extern int tar_main(int argc, char **argv) 174extern int tar_main(int argc, char **argv)
174{ 175{
176 char** excludeList=NULL;
177 int excludeListSize=0;
175 const char *tarName=NULL; 178 const char *tarName=NULL;
176 const char *options;
177 int listFlag = FALSE; 179 int listFlag = FALSE;
178 int extractFlag = FALSE; 180 int extractFlag = FALSE;
179 int createFlag = FALSE; 181 int createFlag = FALSE;
180 int verboseFlag = FALSE; 182 int verboseFlag = FALSE;
181 int tostdoutFlag = FALSE; 183 int tostdoutFlag = FALSE;
184 int stopIt;
182 185
183 argc--; 186 if (argc <= 1)
184 argv++;
185
186 if (argc < 1)
187 usage(tar_usage); 187 usage(tar_usage);
188 188
189 /* Parse options */ 189 /* Parse any options */
190 if (**argv == '-') 190 while (--argc > 0 && **(++argv) == '-') {
191 options = (*argv++) + 1; 191 stopIt=FALSE;
192 else 192 while (stopIt==FALSE && *(++(*argv))) {
193 options = (*argv++); 193 switch (**argv) {
194 argc--; 194 case 'f':
195 195 if (--argc == 0) {
196 for (; *options; options++) { 196 fatalError( "Option requires an argument: No file specified\n");
197 switch (*options) { 197 }
198 case 'f': 198 if (tarName != NULL)
199 if (tarName != NULL) 199 fatalError( "Only one 'f' option allowed\n");
200 fatalError( "Only one 'f' option allowed\n"); 200 tarName = *(++argv);
201 201 if (tarName == NULL)
202 tarName = *argv++; 202 fatalError( "Option requires an argument: No file specified\n");
203 if (tarName == NULL) 203 stopIt=TRUE;
204 fatalError( "Option requires an argument: No file specified\n"); 204 break;
205 argc--; 205
206 206 case 't':
207 break; 207 if (extractFlag == TRUE || createFlag == TRUE)
208 208 goto flagError;
209 case 't': 209 listFlag = TRUE;
210 if (extractFlag == TRUE || createFlag == TRUE) 210 break;
211 goto flagError; 211
212 listFlag = TRUE; 212 case 'x':
213 break; 213 if (listFlag == TRUE || createFlag == TRUE)
214 214 goto flagError;
215 case 'x': 215 extractFlag = TRUE;
216 if (listFlag == TRUE || createFlag == TRUE) 216 break;
217 goto flagError; 217 case 'c':
218 extractFlag = TRUE; 218 if (extractFlag == TRUE || listFlag == TRUE)
219 break; 219 goto flagError;
220 case 'c': 220 createFlag = TRUE;
221 if (extractFlag == TRUE || listFlag == TRUE) 221 break;
222 goto flagError; 222
223 createFlag = TRUE; 223 case 'v':
224 break; 224 verboseFlag = TRUE;
225 225 break;
226 case 'v': 226
227 verboseFlag = TRUE; 227 case 'O':
228 break; 228 tostdoutFlag = TRUE;
229 229 tarName = "-";
230 case 'O': 230 break;
231 tostdoutFlag = TRUE; 231 case 'X':
232 tarName = "-"; 232 if (--argc == 0) {
233 break; 233 fatalError( "Option requires an argument: No file specified\n");
234 234 }
235 case '-': 235 excludeList=realloc( excludeList, sizeof(char**) * (excludeListSize+1));
236 usage(tar_usage); 236 excludeList[excludeListSize] = *(++argv);
237 break; 237 /* Remove leading "/"s */
238 238 if (*excludeList[excludeListSize] =='/') {
239 default: 239 excludeList[excludeListSize] = (excludeList[excludeListSize])+1;
240 fatalError( "Unknown tar flag '%c'\n" 240 }
241 "Try `tar --help' for more information\n", *options); 241 if (excludeList[excludeListSize++] == NULL)
242 fatalError( "Option requires an argument: No file specified\n");
243 stopIt=TRUE;
244 break;
245
246 case '-':
247 usage(tar_usage);
248 break;
249
250 default:
251 fatalError( "Unknown tar flag '%c'\n"
252 "Try `tar --help' for more information\n", **argv);
253 }
242 } 254 }
243 } 255 }
256#if 0
257 for (i=0; i<excludeListSize; i++) {
258 printf( "%s\n", excludeList[i]);
259 fflush(stdout);
260 }
261#endif
262
244 263
245 /* 264 /*
246 * Do the correct type of action supplying the rest of the 265 * Do the correct type of action supplying the rest of the
@@ -250,10 +269,10 @@ extern int tar_main(int argc, char **argv)
250#ifndef BB_FEATURE_TAR_CREATE 269#ifndef BB_FEATURE_TAR_CREATE
251 fatalError( "This version of tar was not compiled with tar creation support.\n"); 270 fatalError( "This version of tar was not compiled with tar creation support.\n");
252#else 271#else
253 exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv)); 272 exit(writeTarFile(tarName, tostdoutFlag, verboseFlag, argc, argv, excludeList));
254#endif 273#endif
255 } else { 274 } else {
256 exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag)); 275 exit(readTarFile(tarName, extractFlag, listFlag, tostdoutFlag, verboseFlag, excludeList));
257 } 276 }
258 277
259 flagError: 278 flagError:
@@ -486,7 +505,7 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
486 * If the list is empty than all files are extracted or listed. 505 * If the list is empty than all files are extracted or listed.
487 */ 506 */
488static int readTarFile(const char* tarName, int extractFlag, int listFlag, 507static int readTarFile(const char* tarName, int extractFlag, int listFlag,
489 int tostdoutFlag, int verboseFlag) 508 int tostdoutFlag, int verboseFlag, char** excludeList)
490{ 509{
491 int status, tarFd=0; 510 int status, tarFd=0;
492 int errorFlag=FALSE; 511 int errorFlag=FALSE;
@@ -675,6 +694,7 @@ struct TarBallInfo
675 tarball lives, so we can avoid trying 694 tarball lives, so we can avoid trying
676 to include the tarball into itself */ 695 to include the tarball into itself */
677 int verboseFlag; /* Whether to print extra stuff or not */ 696 int verboseFlag; /* Whether to print extra stuff or not */
697 char** excludeList; /* List of files to not include */
678}; 698};
679typedef struct TarBallInfo TarBallInfo; 699typedef struct TarBallInfo TarBallInfo;
680 700
@@ -719,6 +739,7 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
719{ 739{
720 long chksum=0; 740 long chksum=0;
721 struct TarHeader header; 741 struct TarHeader header;
742 char** tmpList;
722 const unsigned char *cp = (const unsigned char *) &header; 743 const unsigned char *cp = (const unsigned char *) &header;
723 ssize_t size = sizeof(struct TarHeader); 744 ssize_t size = sizeof(struct TarHeader);
724 745
@@ -735,6 +756,17 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st
735 else { 756 else {
736 strcpy(header.name, fileName); 757 strcpy(header.name, fileName);
737 } 758 }
759#if 0
760 /* Now that leading '/''s have been removed */
761 for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) {
762 printf( "comparing '%s' and '%s'", *tmpList, header.name);
763 if (strcmp( *tmpList, header.name)==0)
764 printf( ": match\n");
765 else
766 printf( "\n");
767 }
768#endif
769
738 putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); 770 putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
739 putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); 771 putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
740 putOctal(header.gid, sizeof(header.gid), statbuf->st_gid); 772 putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
@@ -868,12 +900,11 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
868} 900}
869 901
870static int writeTarFile(const char* tarName, int tostdoutFlag, 902static int writeTarFile(const char* tarName, int tostdoutFlag,
871 int verboseFlag, int argc, char **argv) 903 int verboseFlag, int argc, char **argv, char** excludeList)
872{ 904{
873 int tarFd=-1; 905 int tarFd=-1;
874 int errorFlag=FALSE; 906 int errorFlag=FALSE;
875 ssize_t size; 907 ssize_t size;
876 //int skipFileFlag=FALSE;
877 struct TarBallInfo tbInfo; 908 struct TarBallInfo tbInfo;
878 tbInfo.verboseFlag = verboseFlag; 909 tbInfo.verboseFlag = verboseFlag;
879 910
@@ -890,6 +921,7 @@ static int writeTarFile(const char* tarName, int tostdoutFlag,
890 errorMsg( "tar: Error opening '%s': %s\n", tarName, strerror(errno)); 921 errorMsg( "tar: Error opening '%s': %s\n", tarName, strerror(errno));
891 return ( FALSE); 922 return ( FALSE);
892 } 923 }
924 tbInfo.excludeList=excludeList;
893 /* Store the stat info for the tarball's file, so 925 /* Store the stat info for the tarball's file, so
894 * can avoid including the tarball into itself.... */ 926 * can avoid including the tarball into itself.... */
895 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0) 927 if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)