/* vi: set sw=4 ts=4: */
/*
 * Mini tar implementation for busybox 
 *
 * Modifed to use common extraction code used by ar, cpio, dpkg-deb, dpkg
 *  Glenn McGrath <bug1@optushome.com.au>
 *
 * Note, that as of BusyBox-0.43, tar has been completely rewritten from the
 * ground up.  It still has remnents of the old code lying about, but it is
 * very different now (i.e., cleaner, less global variables, etc.)
 *
 * Copyright (C) 1999,2000,2001 by Lineo, inc.
 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
 *
 * Based in part in the tar implementation in sash
 *  Copyright (c) 1999 by David I. Bell
 *  Permission is granted to use, distribute, or modify this source,
 *  provided that this copyright notice remains intact.
 *  Permission to distribute sash derived code under the GPL has been granted.
 *
 * Based in part on the tar implementation from busybox-0.28
 *  Copyright (C) 1995 Bruce Perens
 *  This is free software under the GNU General Public License.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */

#include <fcntl.h>
#include <getopt.h>
#include <search.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fnmatch.h>
#include <string.h>
#include <errno.h>
#include "busybox.h"

#ifdef BB_FEATURE_TAR_CREATE

/* Tar file constants  */
# define TAR_MAGIC          "ustar"        /* ustar and a null */
# define TAR_VERSION        "  "           /* Be compatable with GNU tar format */

# ifndef MAJOR
#  define MAJOR(dev) (((dev)>>8)&0xff)
#  define MINOR(dev) ((dev)&0xff)
# endif

static const int TAR_BLOCK_SIZE = 512;
static const int TAR_MAGIC_LEN = 6;
static const int TAR_VERSION_LEN = 2;

/* POSIX tar Header Block, from POSIX 1003.1-1990  */
enum { NAME_SIZE = 100 }; /* because gcc won't let me use 'static const int' */
struct TarHeader
{                            /* byte offset */
	char name[NAME_SIZE];         /*   0-99 */
	char mode[8];                 /* 100-107 */
	char uid[8];                  /* 108-115 */
	char gid[8];                  /* 116-123 */
	char size[12];                /* 124-135 */
	char mtime[12];               /* 136-147 */
	char chksum[8];               /* 148-155 */
	char typeflag;                /* 156-156 */
	char linkname[NAME_SIZE];     /* 157-256 */
	char magic[6];                /* 257-262 */
	char version[2];              /* 263-264 */
	char uname[32];               /* 265-296 */
	char gname[32];               /* 297-328 */
	char devmajor[8];             /* 329-336 */
	char devminor[8];             /* 337-344 */
	char prefix[155];             /* 345-499 */
	char padding[12];             /* 500-512 (pad to exactly the TAR_BLOCK_SIZE) */
};
typedef struct TarHeader TarHeader;

/*
** writeTarFile(),  writeFileToTarball(), and writeTarHeader() are
** the only functions that deal with the HardLinkInfo structure.
** Even these functions use the xxxHardLinkInfo() functions.
*/
typedef struct HardLinkInfo HardLinkInfo;
struct HardLinkInfo
{
	HardLinkInfo *next;           /* Next entry in list */
	dev_t dev;                    /* Device number */
	ino_t ino;                    /* Inode number */
	short linkCount;              /* (Hard) Link Count */
	char name[1];                 /* Start of filename (must be last) */
};

/* Some info to be carried along when creating a new tarball */
struct TarBallInfo
{
	char* fileName;               /* File name of the tarball */
	int tarFd;                    /* Open-for-write file descriptor
									 for the tarball */
	struct stat statBuf;          /* Stat info for the tarball, letting
									 us know the inode and device that the
									 tarball lives, so we can avoid trying 
									 to include the tarball into itself */
	int verboseFlag;              /* Whether to print extra stuff or not */
	char** excludeList;           /* List of files to not include */
	HardLinkInfo *hlInfoHead;     /* Hard Link Tracking Information */
	HardLinkInfo *hlInfo;         /* Hard Link Info for the current file */
};
typedef struct TarBallInfo TarBallInfo;

/* A nice enum with all the possible tar file content types */
enum TarFileType 
{
	REGTYPE  = '0',            /* regular file */
	REGTYPE0 = '\0',           /* regular file (ancient bug compat)*/
	LNKTYPE  = '1',            /* hard link */
	SYMTYPE  = '2',            /* symbolic link */
	CHRTYPE  = '3',            /* character special */
	BLKTYPE  = '4',            /* block special */
	DIRTYPE  = '5',            /* directory */
	FIFOTYPE = '6',            /* FIFO special */
	CONTTYPE = '7',            /* reserved */
	GNULONGLINK = 'K',         /* GNU long (>100 chars) link name */
	GNULONGNAME = 'L',         /* GNU long (>100 chars) file name */
};
typedef enum TarFileType TarFileType;

/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
static void
addHardLinkInfo (HardLinkInfo **hlInfoHeadPtr, dev_t dev, ino_t ino,
		short linkCount, const char *name)
{
	/* Note: hlInfoHeadPtr can never be NULL! */
	HardLinkInfo *hlInfo;

	hlInfo = (HardLinkInfo *)xmalloc(sizeof(HardLinkInfo)+strlen(name)+1);
	if (hlInfo) {
		hlInfo->next = *hlInfoHeadPtr;
		*hlInfoHeadPtr = hlInfo;
		hlInfo->dev = dev;
		hlInfo->ino = ino;
		hlInfo->linkCount = linkCount;
		strcpy(hlInfo->name, name);
	}
	return;
}

static void
freeHardLinkInfo (HardLinkInfo **hlInfoHeadPtr)
{
	HardLinkInfo *hlInfo = NULL;
	HardLinkInfo *hlInfoNext = NULL;

	if (hlInfoHeadPtr) {
		hlInfo = *hlInfoHeadPtr;
		while (hlInfo) {
			hlInfoNext = hlInfo->next;
			free(hlInfo);
			hlInfo = hlInfoNext;
		}
		*hlInfoHeadPtr = NULL;
	}
	return;
}

/* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */
static HardLinkInfo *
findHardLinkInfo (HardLinkInfo *hlInfo, dev_t dev, ino_t ino)
{
	while(hlInfo) {
		if ((ino == hlInfo->ino) && (dev == hlInfo->dev))
			break;
		hlInfo = hlInfo->next;
	}
	return(hlInfo);
}

/* Put an octal string into the specified buffer.
 * The number is zero and space padded and possibly null padded.
 * Returns TRUE if successful.  */ 
static int putOctal (char *cp, int len, long value)
{
	int tempLength;
	char tempBuffer[32];
	char *tempString = tempBuffer;

	/* Create a string of the specified length with an initial space,
	 * leading zeroes and the octal number, and a trailing null.  */
	sprintf (tempString, "%0*lo", len - 1, value);

	/* If the string is too large, suppress the leading space.  */
	tempLength = strlen (tempString) + 1;
	if (tempLength > len) {
		tempLength--;
		tempString++;
	}

	/* If the string is still too large, suppress the trailing null.  */
	if (tempLength > len)
		tempLength--;

	/* If the string is still too large, fail.  */
	if (tempLength > len)
		return FALSE;

	/* Copy the string to the field.  */
	memcpy (cp, tempString, len);

	return TRUE;
}

/* Write out a tar header for the specified file/directory/whatever */
static int
writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name,
		const char *real_name, struct stat *statbuf)
{
	long chksum=0;
	struct TarHeader header;
	const unsigned char *cp = (const unsigned char *) &header;
	ssize_t size = sizeof(struct TarHeader);
		
	memset( &header, 0, size);

	strncpy(header.name, header_name, sizeof(header.name)); 

	putOctal(header.mode, sizeof(header.mode), statbuf->st_mode);
	putOctal(header.uid, sizeof(header.uid), statbuf->st_uid);
	putOctal(header.gid, sizeof(header.gid), statbuf->st_gid);
	putOctal(header.size, sizeof(header.size), 0); /* Regular file size is handled later */
	putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
	strncpy(header.magic, TAR_MAGIC TAR_VERSION, 
			TAR_MAGIC_LEN + TAR_VERSION_LEN );

	/* Enter the user and group names (default to root if it fails) */
	my_getpwuid(header.uname, statbuf->st_uid);
	if (! *header.uname)
		strcpy(header.uname, "root");
	my_getgrgid(header.gname, statbuf->st_gid);
	if (! *header.uname)
		strcpy(header.uname, "root");

	if (tbInfo->hlInfo) {
		/* This is a hard link */
		header.typeflag = LNKTYPE;
		strncpy(header.linkname, tbInfo->hlInfo->name, sizeof(header.linkname));
	} else if (S_ISLNK(statbuf->st_mode)) {
		char *lpath = xreadlink(real_name);
		if (!lpath) /* Already printed err msg inside xreadlink() */
			return ( FALSE);
		header.typeflag  = SYMTYPE;
		strncpy(header.linkname, lpath, sizeof(header.linkname)); 
		free(lpath);
	} else if (S_ISDIR(statbuf->st_mode)) {
		header.typeflag  = DIRTYPE;
		strncat(header.name, "/", sizeof(header.name)); 
	} else if (S_ISCHR(statbuf->st_mode)) {
		header.typeflag  = CHRTYPE;
		putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
		putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
	} else if (S_ISBLK(statbuf->st_mode)) {
		header.typeflag  = BLKTYPE;
		putOctal(header.devmajor, sizeof(header.devmajor), MAJOR(statbuf->st_rdev));
		putOctal(header.devminor, sizeof(header.devminor), MINOR(statbuf->st_rdev));
	} else if (S_ISFIFO(statbuf->st_mode)) {
		header.typeflag  = FIFOTYPE;
	} else if (S_ISREG(statbuf->st_mode)) {
		header.typeflag  = REGTYPE;
		putOctal(header.size, sizeof(header.size), statbuf->st_size);
	} else {
		error_msg("%s: Unknown file type", real_name);
		return ( FALSE);
	}

	/* Calculate and store the checksum (i.e., the sum of all of the bytes of
	 * the header).  The checksum field must be filled with blanks for the
	 * calculation.  The checksum field is formatted differently from the
	 * other fields: it has [6] digits, a null, then a space -- rather than
	 * digits, followed by a null like the other fields... */
	memset(header.chksum, ' ', sizeof(header.chksum));
	cp = (const unsigned char *) &header;
	while (size-- > 0)
		chksum += *cp++;
	putOctal(header.chksum, 7, chksum);
	
	/* Now write the header out to disk */
	if ((size=full_write(tbInfo->tarFd, (char*)&header, sizeof(struct TarHeader))) < 0) {
		error_msg(io_error, real_name, strerror(errno)); 
		return ( FALSE);
	}
	/* Pad the header up to the tar block size */
	for (; size<TAR_BLOCK_SIZE; size++) {
		write(tbInfo->tarFd, "\0", 1);
	}
	/* Now do the verbose thing (or not) */
	if (tbInfo->verboseFlag==TRUE) {
		FILE *vbFd = stdout;
		if (tbInfo->tarFd == fileno(stdout))	// If the archive goes to stdout, verbose to stderr
			vbFd = stderr;
		fprintf(vbFd, "%s\n", header.name);
	}

	return ( TRUE);
}

static int exclude_file(char **excluded_files, const char *file)
{
	int i;

	if (excluded_files == NULL)
		return 0;

	for (i = 0; excluded_files[i] != NULL; i++) {
		if (excluded_files[i][0] == '/') {
			if (fnmatch(excluded_files[i], file,
						FNM_PATHNAME | FNM_LEADING_DIR) == 0)
				return 1;
		} else {
			const char *p;

			for (p = file; p[0] != '\0'; p++) {
				if ((p == file || p[-1] == '/') && p[0] != '/' &&
						fnmatch(excluded_files[i], p,
							FNM_PATHNAME | FNM_LEADING_DIR) == 0)
					return 1;
			}
		}
	}

	return 0;
}

static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData)
{
	struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData;
	const char *header_name;

	/*
	** Check to see if we are dealing with a hard link.
	** If so -
	** Treat the first occurance of a given dev/inode as a file while
	** treating any additional occurances as hard links.  This is done
	** by adding the file information to the HardLinkInfo linked list.
	*/
	tbInfo->hlInfo = NULL;
	if (statbuf->st_nlink > 1) {
		tbInfo->hlInfo = findHardLinkInfo(tbInfo->hlInfoHead, statbuf->st_dev, 
				statbuf->st_ino);
		if (tbInfo->hlInfo == NULL)
			addHardLinkInfo (&tbInfo->hlInfoHead, statbuf->st_dev,
					statbuf->st_ino, statbuf->st_nlink, fileName);
	}

	/* It is against the rules to archive a socket */
	if (S_ISSOCK(statbuf->st_mode)) {
		error_msg("%s: socket ignored", fileName);
		return( TRUE);
	}

	/* It is a bad idea to store the archive we are in the process of creating,
	 * so check the device and inode to be sure that this particular file isn't
	 * the new tarball */
	if (tbInfo->statBuf.st_dev == statbuf->st_dev &&
			tbInfo->statBuf.st_ino == statbuf->st_ino) {
		error_msg("%s: file is the archive; skipping", fileName);
		return( TRUE);
	}

	header_name = fileName;
	while (header_name[0] == '/') {
		static int alreadyWarned=FALSE;
		if (alreadyWarned==FALSE) {
			error_msg("Removing leading '/' from member names");
			alreadyWarned=TRUE;
		}
		header_name++;
	}

	if (strlen(fileName) >= NAME_SIZE) {
		error_msg(name_longer_than_foo, NAME_SIZE);
		return ( TRUE);
	}

	if (header_name[0] == '\0')
		return TRUE;

# if defined BB_FEATURE_TAR_EXCLUDE
	if (exclude_file(tbInfo->excludeList, header_name)) {
		return SKIP;
	}
# endif //BB_FEATURE_TAR_EXCLUDE

	if (writeTarHeader(tbInfo, header_name, fileName, statbuf)==FALSE) {
		return( FALSE);
	} 

	/* Now, if the file is a regular file, copy it out to the tarball */
	if ((tbInfo->hlInfo == NULL)
	&&  (S_ISREG(statbuf->st_mode))) {
		int  inputFileFd;
		char buffer[BUFSIZ];
		ssize_t size=0, readSize=0;

		/* open the file we want to archive, and make sure all is well */
		if ((inputFileFd = open(fileName, O_RDONLY)) < 0) {
			error_msg("%s: Cannot open: %s", fileName, strerror(errno));
			return( FALSE);
		}
		
		/* write the file to the archive */
		while ( (size = full_read(inputFileFd, buffer, sizeof(buffer))) > 0 ) {
			if (full_write(tbInfo->tarFd, buffer, size) != size ) {
				/* Output file seems to have a problem */
				error_msg(io_error, fileName, strerror(errno)); 
				return( FALSE);
			}
			readSize+=size;
		}
		if (size == -1) {
			error_msg(io_error, fileName, strerror(errno)); 
			return( FALSE);
		}
		/* Pad the file up to the tar block size */
		for (; (readSize%TAR_BLOCK_SIZE) != 0; readSize++) {
			write(tbInfo->tarFd, "\0", 1);
		}
		close( inputFileFd);
	}

	return( TRUE);
}

static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
		char** excludeList)
{
	int tarFd=-1;
	int errorFlag=FALSE;
	ssize_t size;
	struct TarBallInfo tbInfo;
	tbInfo.verboseFlag = verboseFlag;
	tbInfo.hlInfoHead = NULL;

	/* Make sure there is at least one file to tar up.  */
	if (*argv == NULL)
		error_msg_and_die("Cowardly refusing to create an empty archive");

	/* Open the tar file for writing.  */
	if (!strcmp(tarName, "-"))
		tbInfo.tarFd = fileno(stdout);
	else
		tbInfo.tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0644);
	if (tbInfo.tarFd < 0) {
		perror_msg( "Error opening '%s'", tarName);
		freeHardLinkInfo(&tbInfo.hlInfoHead);
		return ( FALSE);
	}
	tbInfo.excludeList=excludeList;
	/* Store the stat info for the tarball's file, so
	 * can avoid including the tarball into itself....  */
	if (fstat(tbInfo.tarFd, &tbInfo.statBuf) < 0)
		error_msg_and_die(io_error, tarName, strerror(errno)); 

	/* Read the directory/files and iterate over them one at a time */
	while (*argv != NULL) {
		if (recursive_action(*argv++, TRUE, FALSE, FALSE,
					writeFileToTarball, writeFileToTarball, 
					(void*) &tbInfo) == FALSE) {
			errorFlag = TRUE;
		}
	}
	/* Write two empty blocks to the end of the archive */
	for (size=0; size<(2*TAR_BLOCK_SIZE); size++) {
		write(tbInfo.tarFd, "\0", 1);
	}

	/* To be pedantically correct, we would check if the tarball
	 * is smaller than 20 tar blocks, and pad it if it was smaller,
	 * but that isn't necessary for GNU tar interoperability, and
	 * so is considered a waste of space */

	/* Hang up the tools, close up shop, head home */
	close(tarFd);
	if (errorFlag == TRUE) {
		error_msg("Error exit delayed from previous errors");
		freeHardLinkInfo(&tbInfo.hlInfoHead);
		return(FALSE);
	}
	freeHardLinkInfo(&tbInfo.hlInfoHead);
	return( TRUE);
}
#endif //tar_create

void append_file_to_list(const char *new_name, char ***list, int *list_count)
{
	*list = realloc(*list, sizeof(char *) * (*list_count + 2));
	(*list)[*list_count] = xstrdup(new_name);
	(*list_count)++;
	(*list)[*list_count] = NULL;
}

void append_file_list_to_list(char *filename, char ***name_list, int *num_of_entries)
{
	FILE *src_stream;
	char *line;
	char *line_ptr;
	
	src_stream = xfopen(filename, "r");
	while ((line = get_line_from_file(src_stream)) != NULL) {
		line_ptr = last_char_is(line, '\n');
		if (line_ptr) {
			*line_ptr = '\0';
		}
		append_file_to_list(line, name_list, num_of_entries);
		free(line);
	}
	fclose(src_stream);
}

#ifdef BB_FEATURE_TAR_EXCLUDE
/*
 * Create a list of names that are in the include list AND NOT in the exclude lists
 */
char **list_and_not_list(char **include_list, char **exclude_list)
{
	char **new_include_list = NULL;
	int new_include_count = 0;
	int include_count = 0;
	int exclude_count;

	if (include_list == NULL) {
		return(NULL);
	}
	
	while (include_list[include_count] != NULL) {
		int found = FALSE;
		exclude_count = 0;
		while (exclude_list[exclude_count] != NULL) {
			if (strcmp(include_list[include_count], exclude_list[exclude_count]) == 0) {
				found = TRUE;
				break;
			}
			exclude_count++;
		}

		if (found == FALSE) {
			new_include_list = realloc(new_include_list, sizeof(char *) * (include_count + 2));
			new_include_list[new_include_count] = include_list[include_count];
			new_include_count++;
		} else {
			free(include_list[include_count]);
		}
		include_count++;
	}
	new_include_list[new_include_count] = NULL;
	return(new_include_list);
}
#endif

int tar_main(int argc, char **argv)
{
	enum untar_funct_e {
		/* These are optional */
		untar_from_file = 1,
		untar_from_stdin = 2,
		untar_unzip = 4,
		/* Require one and only one of these */
		untar_list = 8,
		untar_create = 16,
		untar_extract = 32
	};

	FILE *src_stream = NULL;
	FILE *uncompressed_stream = NULL;
	char **include_list = NULL;
	char **exclude_list = NULL;
	char *src_filename = NULL;
	char *dst_prefix = NULL;
	char *file_list_name = NULL;
	int opt;
	unsigned short untar_funct = 0;
	unsigned short untar_funct_required = 0;
	unsigned short extract_function = 0;
	int include_list_count = 0;
	int exclude_list_count = 0;
	int gunzip_pid;
	int gz_fd = 0;

	if (argc < 2) {
		show_usage();
	}

	/* Prepend '-' to the first argument if required */
	if (argv[1][0] != '-') {
		char *tmp = xmalloc(strlen(argv[1]) + 2);
		tmp[0] = '-';
		strcpy(tmp + 1, argv[1]);
		argv[1] = tmp;
	}

	while ((opt = getopt(argc, argv, "ctxT:X:C:f:Opvz")) != -1) {
		switch (opt) {

		/* One and only one of these is required */
		case 'c':
			untar_funct_required |= untar_create;
			break;
		case 't':
			untar_funct_required |= untar_list;
			extract_function |= extract_list |extract_unconditional;
			break;
		case 'x':
			untar_funct_required |= untar_extract;
			extract_function |= (extract_all_to_fs | extract_unconditional | extract_create_leading_dirs);
			break;

		/* These are optional */
		/* Exclude or Include files listed in <filename>*/
#ifdef BB_FEATURE_TAR_EXCLUDE
		case 'X':
			append_file_list_to_list(optarg, &exclude_list, &exclude_list_count);
			break;
#endif
		case 'T':
			// by default a list is an include list
			append_file_list_to_list(optarg, &include_list, &include_list_count);
			break;

		case 'C':	// Change to dir <optarg>
			/* Make sure dst_prefix ends in a '/' */
			dst_prefix = concat_path_file(optarg, "/");
			break;
		case 'f':	// archive filename
			if (strcmp(optarg, "-") == 0) {
				// Untar from stdin to stdout
				untar_funct |= untar_from_stdin;
			} else {
				untar_funct |= untar_from_file;
				src_filename = xstrdup(optarg);
			}
			break;
		case 'O':
			extract_function |= extract_to_stdout;
			break;
		case 'p':
			break;
		case 'v':
			if (extract_function & extract_list) {
				extract_function |= extract_verbose_list;
			}
			extract_function |= extract_list;
			break;
#ifdef BB_FEATURE_TAR_GZIP
		case 'z':
			untar_funct |= untar_unzip;
			break;
#endif
		default:
			show_usage();
		}
	}

	/* Make sure the valid arguments were passed */
	if (untar_funct_required == 0) {
		error_msg_and_die("You must specify one of the `-ctx' options");
	}
	if ((untar_funct_required != untar_create) && 
			(untar_funct_required != untar_extract) &&
			(untar_funct_required != untar_list)) {
		error_msg_and_die("You may not specify more than one `ctx' option.");
	}
	untar_funct |= untar_funct_required;

	/* Setup an array of filenames to work with */
	while (optind < argc) {
		append_file_to_list(argv[optind], &include_list, &include_list_count);
		optind++;
	}

	if (extract_function & (extract_list | extract_all_to_fs)) {
		if (dst_prefix == NULL) {
			dst_prefix = xstrdup("./");
		}

		/* Setup the source of the tar data */
		if (untar_funct & untar_from_file) {
			src_stream = xfopen(src_filename, "r");
		} else {
			src_stream = stdin;
		}
#ifdef BB_FEATURE_TAR_GZIP
		/* Get a binary tree of all the tar file headers */
		if (untar_funct & untar_unzip) {
			uncompressed_stream = gz_open(src_stream, &gunzip_pid);
		} else
#endif // BB_FEATURE_TAR_GZIP
			uncompressed_stream = src_stream;
		
		/* extract or list archive */
		unarchive(uncompressed_stream, stdout, &get_header_tar, extract_function, dst_prefix, include_list, exclude_list);
		fclose(uncompressed_stream);
	}
#ifdef BB_FEATURE_TAR_CREATE
	/* create an archive */
	else if (untar_funct & untar_create) {
		int verboseFlag = FALSE;

#ifdef BB_FEATURE_TAR_GZIP
		if (untar_funct && untar_unzip) {
			error_msg_and_die("Creation of compressed tarfile not internally support by tar, pipe to busybox gunzip");
		}
#endif // BB_FEATURE_TAR_GZIP
		if (extract_function & extract_verbose_list) {
			verboseFlag = TRUE;
		}
		writeTarFile(src_filename, verboseFlag, &argv[argc - 1], include_list);
	}
#endif // BB_FEATURE_TAR_CREATE

	/* Cleanups */
#ifdef BB_FEATURE_TAR_GZIP
	if (untar_funct & untar_unzip) {
		fclose(src_stream);
		close(gz_fd);
		gz_close(gunzip_pid);
	}
#endif // BB_FEATURE_TAR_GZIP
	if (src_filename) {
		free(src_filename);
	}
	if (file_list_name) {
		free(file_list_name);
	}
	return(EXIT_SUCCESS);
}
