void do_tar(int argc, const char ** argv) { const char * options; argc--; argv++; if (argc < 2) { fprintf(stderr, "Too few arguments for tar\n"); return; } extractFlag = FALSE; createFlag = FALSE; listFlag = FALSE; verboseFlag = FALSE; tarName = NULL; tarDev = 0; tarInode = 0; tarFd = -1; /* * Parse the options. */ options = *argv++; argc--; for (; *options; options++) { switch (*options) { case 'f': if (tarName != NULL) { fprintf(stderr, "Only one 'f' option allowed\n"); return; } tarName = *argv++; argc--; break; case 't': listFlag = TRUE; break; case 'x': extractFlag = TRUE; break; case 'c': createFlag = TRUE; break; case 'v': verboseFlag = TRUE; break; default: fprintf(stderr, "Unknown tar flag '%c'\n", *options); return; } } /* * Validate the options. */ if (extractFlag + listFlag + createFlag != 1) { fprintf(stderr, "Exactly one of 'c', 'x' or 't' must be specified\n"); return; } if (tarName == NULL) { fprintf(stderr, "The 'f' flag must be specified\n"); return; } /* * Do the correct type of action supplying the rest of the * command line arguments as the list of files to process. */ if (createFlag) writeTarFile(argc, argv); else readTarFile(argc, argv); }
extern int tar_main(int argc, char **argv) { char** excludeList=NULL; char** extractList=NULL; const char *tarName="-"; const char *cwd=NULL; #if defined BB_FEATURE_TAR_EXCLUDE int excludeListSize=0; FILE *fileList; char file[256]; #endif #if defined BB_FEATURE_TAR_GZIP FILE *comp_file = NULL; int unzipFlag = FALSE; #endif int listFlag = FALSE; int extractFlag = FALSE; int createFlag = FALSE; int verboseFlag = FALSE; int tostdoutFlag = FALSE; int status = FALSE; int opt; #if defined BB_FEATURE_TAR_GZIP pid_t pid; #endif if (argc <= 1) show_usage(); if (argv[1][0] != '-') { char *tmp = xmalloc(strlen(argv[1]) + 2); tmp[0] = '-'; strcpy(tmp + 1, argv[1]); argv[1] = tmp; } while ( #ifndef BB_FEATURE_TAR_EXCLUDE (opt = getopt(argc, argv, "cxtzvOf:pC:")) #else (opt = getopt_long(argc, argv, "cxtzvOf:X:pC:", longopts, NULL)) #endif > 0) { switch (opt) { case 'c': if (extractFlag == TRUE || listFlag == TRUE) goto flagError; createFlag = TRUE; break; case 'x': if (listFlag == TRUE || createFlag == TRUE) goto flagError; extractFlag = TRUE; break; case 't': if (extractFlag == TRUE || createFlag == TRUE) goto flagError; listFlag = TRUE; break; #ifdef BB_FEATURE_TAR_GZIP case 'z': unzipFlag = TRUE; break; #endif case 'v': verboseFlag = TRUE; break; case 'O': tostdoutFlag = TRUE; break; case 'f': if (*tarName != '-') error_msg_and_die( "Only one 'f' option allowed"); tarName = optarg; break; #if defined BB_FEATURE_TAR_EXCLUDE case 'e': excludeList=xrealloc( excludeList, sizeof(char *) * (excludeListSize+2)); excludeList[excludeListSize] = optarg; /* Tack a NULL onto the end of the list */ excludeList[++excludeListSize] = NULL; case 'X': fileList = xfopen(optarg, "r"); while (fgets(file, sizeof(file), fileList) != NULL) { excludeList = xrealloc(excludeList, sizeof(char *) * (excludeListSize+2)); chomp(file); excludeList[excludeListSize] = xstrdup(file); /* Tack a NULL onto the end of the list */ excludeList[++excludeListSize] = NULL; } fclose(fileList); break; #endif case 'p': break; case 'C': cwd = xgetcwd((char *)cwd); if (chdir(optarg)) { printf("cd: %s: %s\n", optarg, strerror(errno)); return EXIT_FAILURE; } break; default: show_usage(); } } /* * Do the correct type of action supplying the rest of the * command line arguments as the list of files to process. */ if (createFlag == TRUE) { #ifndef BB_FEATURE_TAR_CREATE error_msg_and_die( "This version of tar was not compiled with tar creation support."); #else #ifdef BB_FEATURE_TAR_GZIP if (unzipFlag==TRUE) error_msg_and_die("Creation of compressed not internally support by tar, pipe to busybox gunzip"); #endif status = writeTarFile(tarName, verboseFlag, argv + optind, excludeList); #endif } if (listFlag == TRUE || extractFlag == TRUE) { int tarFd; if (argv[optind]) extractList = argv + optind; /* Open the tar file for reading. */ if (!strcmp(tarName, "-")) tarFd = fileno(stdin); else tarFd = open(tarName, O_RDONLY); if (tarFd < 0) perror_msg_and_die("Error opening '%s'", tarName); #ifdef BB_FEATURE_TAR_GZIP /* unzip tarFd in a seperate process */ if (unzipFlag == TRUE) { comp_file = fdopen(tarFd, "r"); /* set the buffer size */ setvbuf(comp_file, NULL, _IOFBF, 0x8000); if ((tarFd = fileno(gz_open(comp_file, &pid))) == EXIT_FAILURE) { error_msg_and_die("Couldnt unzip file"); } } #endif status = readTarFile(tarFd, extractFlag, listFlag, tostdoutFlag, verboseFlag, extractList, excludeList); close(tarFd); #ifdef BB_FEATURE_TAR_GZIP if (unzipFlag == TRUE) { gz_close(pid); fclose(comp_file); } #endif } if (cwd) chdir(cwd); if (status == TRUE) return EXIT_SUCCESS; else return EXIT_FAILURE; flagError: error_msg_and_die( "Exactly one of 'c', 'x' or 't' must be specified"); }