/* vi: set sw=4 ts=4: */
/*
 * Mini tar implementation for busybox 
 *
 * 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 <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <utime.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#include <getopt.h>
#include <fnmatch.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "busybox.h"

/* Tar file constants  */
#ifndef MAJOR
#define MAJOR(dev) (((dev)>>8)&0xff)
#define MINOR(dev) ((dev)&0xff)
#endif

enum { NAME_SIZE = 100 }; /* because gcc won't let me use 'static const int' */

/* POSIX tar Header Block, from POSIX 1003.1-1990  */
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;


/* A few useful constants */
#define TAR_MAGIC          "ustar"        /* ustar and a null */
#define TAR_VERSION        "  "           /* Be compatable with GNU tar format */
static const int TAR_MAGIC_LEN = 6;
static const int TAR_VERSION_LEN = 2;
static const int TAR_BLOCK_SIZE = 512;

/* 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;

/* This struct ignores magic, non-numeric user name, 
 * non-numeric group name, and the checksum, since
 * these are all ignored by BusyBox tar. */ 
struct TarInfo
{
	int              tarFd;          /* An open file descriptor for reading from the tarball */
	char *           name;           /* File name */
	mode_t           mode;           /* Unix mode, including device bits. */
	uid_t            uid;            /* Numeric UID */
	gid_t            gid;            /* Numeric GID */
	size_t           size;           /* Size of file */
	time_t           mtime;          /* Last-modified time */
	enum TarFileType type;           /* Regular, directory, link, etc */
	char *           linkname;       /* Name for symbolic and hard links */
	long             devmajor;       /* Major number for special device */
	long             devminor;       /* Minor number for special device */
};
typedef struct TarInfo TarInfo;

/* Local procedures to restore files from a tar file.  */
static int readTarFile(int tarFd, int extractFlag, int listFlag, 
		int tostdoutFlag, int verboseFlag, char** extractList,
		char** excludeList);

#ifdef BB_FEATURE_TAR_CREATE
/* Local procedures to save files into a tar file.  */
static int writeTarFile(const char* tarName, int verboseFlag, char **argv,
		char** excludeList);
#endif

#if defined BB_FEATURE_TAR_EXCLUDE
static struct option longopts[] = {
	{ "exclude", 1, NULL, 'e' },
	{ NULL, 0, NULL, 0 }
};
#endif

extern int tar_main(int argc, char **argv)
{
	char** excludeList=NULL;
	char** extractList=NULL;
	const char *tarName="-";
#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;
	pid_t pid;

	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:"))
#else
			(opt = getopt_long(argc, argv, "cxtzvOf:X:", 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
				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");
			if ((tarFd = 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 (status == TRUE)
		return EXIT_SUCCESS;
	else
		return EXIT_FAILURE;

  flagError:
	error_msg_and_die( "Exactly one of 'c', 'x' or 't' must be specified");
}
					
static void
fixUpPermissions(TarInfo *header)
{
	struct utimbuf t;
	/* Now set permissions etc for the new file */
	chown(header->name, header->uid, header->gid);
	chmod(header->name, header->mode);
	/* Reset the time */
	t.actime = time(0);
	t.modtime = header->mtime;
	utime(header->name, &t);
}
				
static int
tarExtractRegularFile(TarInfo *header, int extractFlag, int tostdoutFlag)
{
	size_t  writeSize;
	size_t  readSize;
	size_t  actualWriteSz;
	char    buffer[BUFSIZ];
	size_t  size = header->size;
	int outFd=fileno(stdout);

	/* Open the file to be written, if a file is supposed to be written */
	if (extractFlag==TRUE && tostdoutFlag==FALSE) {
		/* Create the path to the file, just in case it isn't there...
		 * This should not screw up path permissions or anything. */
		create_path(header->name, 0777);
		if ((outFd=open(header->name, O_CREAT|O_TRUNC|O_WRONLY, 
						header->mode & ~S_IFMT)) < 0) {
			error_msg(io_error, header->name, strerror(errno)); 
			return( FALSE);
		}
	}

	/* Write out the file, if we are supposed to be doing that */
	while ( size > 0 ) {
		actualWriteSz=0;
		if ( size > sizeof(buffer) )
			writeSize = readSize = sizeof(buffer);
		else {
			int mod = size % 512;
			if ( mod != 0 )
				readSize = size + (512 - mod);
			else
				readSize = size;
			writeSize = size;
		}
		if ( (readSize = full_read(header->tarFd, buffer, readSize)) <= 0 ) {
			/* Tarball seems to have a problem */
			error_msg("Unexpected EOF in archive"); 
			return( FALSE);
		}
		if ( readSize < writeSize )
			writeSize = readSize;

		/* Write out the file, if we are supposed to be doing that */
		if (extractFlag==TRUE) {

			if ((actualWriteSz=full_write(outFd, buffer, writeSize)) != writeSize ) {
				/* Output file seems to have a problem */
				error_msg(io_error, header->name, strerror(errno)); 
				return( FALSE);
			}
		} else {
			actualWriteSz=writeSize;
		}

		size -= actualWriteSz;
	}

	/* Now we are done writing the file out, so try 
	 * and fix up the permissions and whatnot */
	if (extractFlag==TRUE && tostdoutFlag==FALSE) {
		close(outFd);
		fixUpPermissions(header);
	}
	return( TRUE);
}

static int
tarExtractDirectory(TarInfo *header, int extractFlag, int tostdoutFlag)
{

	if (extractFlag==FALSE || tostdoutFlag==TRUE)
		return( TRUE);

	if (create_path(header->name, header->mode) != TRUE) {
		perror_msg("%s: Cannot mkdir", header->name); 
		return( FALSE);
	}
	/* make the final component, just in case it was
	 * omitted by create_path() (which will skip the
	 * directory if it doesn't have a terminating '/') */
	if (mkdir(header->name, header->mode) < 0 && errno != EEXIST) {
		perror_msg("%s", header->name);
		return FALSE;
	}

	fixUpPermissions(header);
	return( TRUE);
}

static int
tarExtractHardLink(TarInfo *header, int extractFlag, int tostdoutFlag)
{
	if (extractFlag==FALSE || tostdoutFlag==TRUE)
		return( TRUE);

	if (link(header->linkname, header->name) < 0) {
		perror_msg("%s: Cannot create hard link to '%s'", header->name,
				header->linkname); 
		return( FALSE);
	}

	/* Now set permissions etc for the new directory */
	fixUpPermissions(header);
	return( TRUE);
}

static int
tarExtractSymLink(TarInfo *header, int extractFlag, int tostdoutFlag)
{
	if (extractFlag==FALSE || tostdoutFlag==TRUE)
		return( TRUE);

#ifdef	S_ISLNK
	if (symlink(header->linkname, header->name) < 0) {
		perror_msg("%s: Cannot create symlink to '%s'", header->name,
				header->linkname); 
		return( FALSE);
	}
	/* Try to change ownership of the symlink.
	 * If libs doesn't support that, don't bother.
	 * Changing the pointed-to-file is the Wrong Thing(tm).
	 */
#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
	lchown(header->name, header->uid, header->gid);
#endif

	/* Do not change permissions or date on symlink,
	 * since it changes the pointed to file instead.  duh. */
#else
	error_msg("%s: Cannot create symlink to '%s': %s", 
			header->name, header->linkname, 
			"symlinks not supported"); 
#endif
	return( TRUE);
}

static int
tarExtractSpecial(TarInfo *header, int extractFlag, int tostdoutFlag)
{
	if (extractFlag==FALSE || tostdoutFlag==TRUE)
		return( TRUE);

	if (S_ISCHR(header->mode) || S_ISBLK(header->mode) || S_ISSOCK(header->mode)) {
		if (mknod(header->name, header->mode, makedev(header->devmajor, header->devminor)) < 0) {
			perror_msg("%s: Cannot mknod", header->name); 
			return( FALSE);
		}
	} else if (S_ISFIFO(header->mode)) {
		if (mkfifo(header->name, header->mode) < 0) {
			perror_msg("%s: Cannot mkfifo", header->name); 
			return( FALSE);
		}
	}

	/* Now set permissions etc for the new directory */
	fixUpPermissions(header);
	return( TRUE);
}

/* Parse the tar header and fill in the nice struct with the details */
static int
readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
{
	int i;
	long chksum, sum=0;
	unsigned char *s = (unsigned char *)rawHeader;

	header->name  = rawHeader->name;
	/* Check for and relativify any absolute paths */
	if ( *(header->name) == '/' ) {
		static int alreadyWarned=FALSE;

		while (*(header->name) == '/')
			++*(header->name);

		if (alreadyWarned == FALSE) {
			error_msg("Removing leading '/' from member names");
			alreadyWarned = TRUE;
		}
	}

	header->mode  = strtol(rawHeader->mode, NULL, 8);
	header->uid   = strtol(rawHeader->uid, NULL, 8);
	header->gid   = strtol(rawHeader->gid, NULL, 8);
	header->size  = strtol(rawHeader->size, NULL, 8);
	header->mtime = strtol(rawHeader->mtime, NULL, 8);
	chksum = strtol(rawHeader->chksum, NULL, 8);
	header->type  = rawHeader->typeflag;
	header->linkname  = rawHeader->linkname;
	header->devmajor  = strtol(rawHeader->devmajor, NULL, 8);
	header->devminor  = strtol(rawHeader->devminor, NULL, 8);

	/* Check the checksum */
	for (i = sizeof(*rawHeader); i-- != 0;) {
		sum += *s++;
	}
	/* Remove the effects of the checksum field (replace 
	 * with blanks for the purposes of the checksum) */
	s = rawHeader->chksum;
	for (i = sizeof(rawHeader->chksum) ; i-- != 0;) {
		sum -= *s++;
	}
	sum += ' ' * sizeof(rawHeader->chksum);
	if (sum == chksum )
		return ( TRUE);
	return( FALSE);
}

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 extract_file(char **extract_files, const char *file)
{
	int i;

	if (extract_files == NULL)
		return 1;

	for (i = 0; extract_files[i] != NULL; i++) {
		if (fnmatch(extract_files[i], file, FNM_LEADING_DIR) == 0)
			return 1;
	}

	return 0;
}

/*
 * Read a tar file and extract or list the specified files within it.
 * If the list is empty than all files are extracted or listed.
 */
static int readTarFile(int tarFd, int extractFlag, int listFlag, 
		int tostdoutFlag, int verboseFlag, char** extractList,
		char** excludeList)
{
	int status;
	int errorFlag=FALSE;
	int skipNextHeaderFlag=FALSE;
	TarHeader rawHeader;
	TarInfo header;

	/* Set the umask for this process so it doesn't 
	 * screw up permission setting for us later. */
	umask(0);

	/* Read the tar file, and iterate over it one file at a time */
	while ( (status = full_read(tarFd, (char*)&rawHeader, TAR_BLOCK_SIZE)) == TAR_BLOCK_SIZE ) {

		/* Try to read the header */
		if ( readTarHeader(&rawHeader, &header) == FALSE ) {
			if ( *(header.name) == '\0' ) {
				goto endgame;
			} else {
				errorFlag=TRUE;
				error_msg("Bad tar header, skipping");
				continue;
			}
		}
		if ( *(header.name) == '\0' )
				goto endgame;
		header.tarFd = tarFd;

		/* Skip funky extra GNU headers that precede long files */
		if ( (header.type == GNULONGNAME) || (header.type == GNULONGLINK) ) {
			skipNextHeaderFlag=TRUE;
			if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
				errorFlag = TRUE;
			continue;
		}
		if ( skipNextHeaderFlag == TRUE ) { 
			skipNextHeaderFlag=FALSE;
			error_msg(name_longer_than_foo, NAME_SIZE); 
			if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
				errorFlag = TRUE;
			continue;
		}

#if defined BB_FEATURE_TAR_EXCLUDE
		if (exclude_file(excludeList, header.name)) {
			/* There are not the droids you're looking for, move along */
			/* 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 */
			if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
				if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
					errorFlag = TRUE;
			}
			continue;
		}
#endif

		if (!extract_file(extractList, header.name)) {
			/* There are not the droids you're looking for, move along */
			/* 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 */
			if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
				if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
					errorFlag = TRUE;
			}
			continue;
		}

		if (listFlag == TRUE) {
			/* Special treatment if the list (-t) flag is on */
			if (verboseFlag == TRUE) {
				int len, len1;
				char buf[35];
				struct tm *tm = localtime (&(header.mtime));

				len=printf("%s ", mode_string(header.mode));
				my_getpwuid(buf, header.uid);
				if (! *buf)
					len+=printf("%d", header.uid);
				else
					len+=printf("%s", buf);
				my_getgrgid(buf, header.gid);
				if (! *buf)
					len+=printf("/%-d ", header.gid);
				else
					len+=printf("/%-s ", buf);

				if (header.type==CHRTYPE || header.type==BLKTYPE) {
					len1=snprintf(buf, sizeof(buf), "%ld,%-ld ", 
							header.devmajor, header.devminor);
				} else {
					len1=snprintf(buf, sizeof(buf), "%lu ", (long)header.size);
				}
				/* Jump through some hoops to make the columns match up */
				for(;(len+len1)<31;len++)
					printf(" ");
				printf(buf);

				/* Use ISO 8610 time format */
				if (tm) { 
					printf ("%04d-%02d-%02d %02d:%02d:%02d ", 
							tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, 
							tm->tm_hour, tm->tm_min, tm->tm_sec);
				}
			}
			printf("%s", header.name);
			if (verboseFlag == TRUE) {
				if (header.type==LNKTYPE)	/* If this is a link, say so */
					printf(" link to %s", header.linkname);
				else if (header.type==SYMTYPE)
					printf(" -> %s", header.linkname);
			}
			printf("\n");
		}

		/* List contents if we are supposed to do that */
		if (verboseFlag == TRUE && extractFlag == TRUE) {
			/* Now the normal listing */
			FILE *vbFd = stdout;
			if (tostdoutFlag == TRUE)	// If the archive goes to stdout, verbose to stderr
				vbFd = stderr;
			fprintf(vbFd, "%s\n", header.name);
		}
			
		/* Remove files if we would overwrite them */
		if (extractFlag == TRUE && tostdoutFlag == FALSE)
			unlink(header.name);

		/* If we got here, we can be certain we have a legitimate 
		 * header to work with.  So work with it.  */
		switch ( header.type ) {
			case REGTYPE:
			case REGTYPE0:
				/* If the name ends in a '/' then assume it is
				 * supposed to be a directory, and fall through */
				if (!last_char_is(header.name,'/')) {
					if (tarExtractRegularFile(&header, extractFlag, tostdoutFlag)==FALSE)
						errorFlag=TRUE;
					break;
				}
			case DIRTYPE:
				if (tarExtractDirectory( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
			case LNKTYPE:
				if (tarExtractHardLink( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
			case SYMTYPE:
				if (tarExtractSymLink( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
			case CHRTYPE:
			case BLKTYPE:
			case FIFOTYPE:
				if (tarExtractSpecial( &header, extractFlag, tostdoutFlag)==FALSE)
					errorFlag=TRUE;
				break;
#if 0
			/* Handled earlier */
			case GNULONGNAME:
			case GNULONGLINK:
				skipNextHeaderFlag=TRUE;
				break;
#endif
			default:
				error_msg("Unknown file type '%c' in tar file", header.type);
				close( tarFd);
				return( FALSE);
		}
	}
	close(tarFd);
	if (status > 0) {
		/* Bummer - we read a partial header */
		perror_msg("Error reading tar file");
		return ( FALSE);
	}
	else if (errorFlag==TRUE) {
		error_msg( "Error exit delayed from previous errors");
		return( FALSE);
	} else 
		return( status);

	/* Stuff to do when we are done */
endgame:
	close( tarFd);
	if ( *(header.name) == '\0' ) {
		if (errorFlag==TRUE)
			error_msg( "Error exit delayed from previous errors");
		else
			return( TRUE);
	} 
	return( FALSE);
}


#ifdef BB_FEATURE_TAR_CREATE

/*
** 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;


/* 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);
		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 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

	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)); 

	/* Set the umask for this process so it doesn't 
	 * screw up permission setting for us later. */
	umask(0);

	/* 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

