Example #1
0
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);
}
Example #2
0
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");
}