/*
 * Mini tar implementation for busybox based on code taken from 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 this code under the GPL has been granted.
 *
 * Modified for busybox by Erik Andersen <andersee@debian.org>
 * Adjusted to grok stdin/stdout options.
 *
 * Modified to handle device special files by Matt Porter
 * <porter@debian.org>
 *
 * 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 "internal.h"
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <sys/types.h>
#include <sys/sysmacros.h>


static const char tar_usage[] =
"tar -[cxtvOf] [tarFileName] [FILE] ...\n\n"
"Create, extract, or list files from a tar file\n\n"
"Options:\n"
"\tc=create, x=extract, t=list contents, v=verbose,\n"
"\tO=extract to stdout, f=tarfile or \"-\" for stdin\n";



/*
 * Tar file constants.
 */
#define TAR_BLOCK_SIZE	512
#define TAR_NAME_SIZE	100


/*
 * The POSIX (and basic GNU) tar header format.
 * This structure is always embedded in a TAR_BLOCK_SIZE sized block
 * with zero padding.  We only process this information minimally.
 */
typedef struct {
    char name[TAR_NAME_SIZE];
    char mode[8];
    char uid[8];
    char gid[8];
    char size[12];
    char mtime[12];
    char checkSum[8];
    char typeFlag;
    char linkName[TAR_NAME_SIZE];
    char magic[6];
    char version[2];
    char uname[32];
    char gname[32];
    char devMajor[8];
    char devMinor[8];
    char prefix[155];
} TarHeader;

#define	TAR_MAGIC	"ustar"
#define	TAR_VERSION	"00"

#define	TAR_TYPE_REGULAR	'0'
#define	TAR_TYPE_HARD_LINK	'1'
#define	TAR_TYPE_SOFT_LINK	'2'


/*
 * Static data.
 */
static int listFlag;
static int extractFlag;
static int createFlag;
static int verboseFlag;
static int tostdoutFlag;

static int inHeader; // <- check me
static int badHeader;
static int errorFlag;
static int skipFileFlag;
static int warnedRoot;
static int eofFlag;
static long dataCc;
static int outFd;
static char outName[TAR_NAME_SIZE];


/*
 * Static data associated with the tar file.
 */
static const char *tarName;
static int tarFd;
static dev_t tarDev;
static ino_t tarInode;


/*
 * Local procedures to restore files from a tar file.
 */
static void readTarFile (int fileCount, char **fileTable);
static void readData (const char *cp, int count);
static long getOctal (const char *cp, int len);

static void readHeader (const TarHeader * hp,
			int fileCount, char **fileTable);


/*
 * Local procedures to save files into a tar file.
 */
static void saveFile (const char *fileName, int seeLinks);

static void saveRegularFile (const char *fileName,
			     const struct stat *statbuf);

static void saveDirectory (const char *fileName,
			   const struct stat *statbuf);

static int wantFileName (const char *fileName,
			 int fileCount, char **fileTable);

static void writeHeader (const char *fileName, const struct stat *statbuf);

static void writeTarFile (int fileCount, char **fileTable);
static void writeTarBlock (const char *buf, int len);
static int putOctal (char *cp, int len, long value);


extern int tar_main (int argc, char **argv)
{
    const char *options;

    argc--;
    argv++;

    if (argc < 1)
	usage( tar_usage);


    errorFlag = FALSE;
    extractFlag = FALSE;
    createFlag = FALSE;
    listFlag = FALSE;
    verboseFlag = FALSE;
    tostdoutFlag = FALSE;
    tarName = NULL;
    tarDev = 0;
    tarInode = 0;
    tarFd = -1;

    /* 
     * Parse the options.
     */
    if (**argv == '-') {
	options = (*argv++) + 1;
	argc--;
	for (; *options; options++) {
	    switch (*options) {
	    case 'f':
		if (tarName != NULL) {
		    fprintf (stderr, "Only one 'f' option allowed\n");

		    exit (FALSE);
		}

		tarName = *argv++;
		argc--;

		break;

	    case 't':
		listFlag = TRUE;
		break;

	    case 'x':
		extractFlag = TRUE;
		break;

	    case 'c':
		createFlag = TRUE;
		break;

	    case 'v':
		verboseFlag = TRUE;
		break;

	    case 'O':
		tostdoutFlag = TRUE;
		break;

	    case '-':
		usage( tar_usage);
		break;

	    default:
		fprintf (stderr, "Unknown tar flag '%c'\n"
			"Try `tar --help' for more information\n", 
			*options);

		exit (FALSE);
	    }
	}
    }

    /* 
     * Validate the options.
     */
    if (extractFlag + listFlag + createFlag != (TRUE+FALSE+FALSE)) {
	fprintf (stderr,
		 "Exactly one of 'c', 'x' or 't' must be specified\n");

	exit (FALSE);
    }

    /* 
     * Do the correct type of action supplying the rest of the
     * command line arguments as the list of files to process.
     */
    if (createFlag==TRUE)
	writeTarFile (argc, argv);
    else
	readTarFile (argc, argv);
    if (errorFlag==TRUE)
	fprintf (stderr, "\n");
    exit (!errorFlag);
}


/*
 * 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 void readTarFile (int fileCount, char **fileTable)
{
    const char *cp;
    int cc;
    int inCc;
    int blockSize;
    char buf[BUF_SIZE];

    skipFileFlag = FALSE;
    badHeader = FALSE;
    warnedRoot = FALSE;
    eofFlag = FALSE;
    inHeader = TRUE;
    inCc = 0;
    dataCc = 0;
    outFd = -1;
    blockSize = sizeof (buf);
    cp = buf;

    /* 
     * Open the tar file for reading.
     */
    if ((tarName == NULL) || !strcmp (tarName, "-")) {
	tarFd = fileno(stdin);
    } else
	tarFd = open (tarName, O_RDONLY);

    if (tarFd < 0) {
	perror (tarName);
	errorFlag = TRUE;
	return;
    }

    /* 
     * Read blocks from the file until an end of file header block
     * has been seen.  (A real end of file from a read is an error.)
     */
    while (eofFlag==FALSE) {
	/* 
	 * Read the next block of data if necessary.
	 * This will be a large block if possible, which we will
	 * then process in the small tar blocks.
	 */
	if (inCc <= 0) {
	    cp = buf;
	    inCc = fullRead (tarFd, buf, blockSize);

	    if (inCc < 0) {
		perror (tarName);
		errorFlag = TRUE;
		goto done;
	    }

	    if (inCc == 0) {
		fprintf (stderr,
			 "Unexpected end of file from \"%s\"", tarName);
		errorFlag = TRUE;
		goto done;
	    }
	}

	/* 
	 * If we are expecting a header block then examine it.
	 */
	if (inHeader==TRUE) {
	    readHeader ((const TarHeader *) cp, fileCount, fileTable);

	    cp += TAR_BLOCK_SIZE;
	    inCc -= TAR_BLOCK_SIZE;

	    continue;
	}

	/* 
	 * We are currently handling the data for a file.
	 * Process the minimum of the amount of data we have available
	 * and the amount left to be processed for the file.
	 */
	cc = inCc;

	if (cc > dataCc)
	    cc = dataCc;

	readData (cp, cc);

	/* 
	 * If the amount left isn't an exact multiple of the tar block
	 * size then round it up to the next block boundary since there
	 * is padding at the end of the file.
	 */
	if (cc % TAR_BLOCK_SIZE)
	    cc += TAR_BLOCK_SIZE - (cc % TAR_BLOCK_SIZE);

	cp += cc;
	inCc -= cc;
    }

  done:
    /* 
     * Close the tar file if needed.
     */
    if ((tarFd >= 0) && (close (tarFd) < 0))
	perror (tarName);

    /* 
     * Close the output file if needed.
     * This is only done here on a previous error and so no
     * message is required on errors.
     */
    if (tostdoutFlag == FALSE) {
	if (outFd >= 0)
	    (void) close (outFd);
    }
}


/*
 * Examine the header block that was just read.
 * This can specify the information for another file, or it can mark
 * the end of the tar file.
 */
static void
readHeader (const TarHeader * hp, int fileCount, char **fileTable)
{
    int mode;
    int uid;
    int gid;
    int checkSum;
    unsigned int major;
    unsigned int minor;
    long size;
    time_t mtime;
    const char *name;
    int cc;
    int hardLink;
    int softLink;
    int devFileFlag;

    /* 
     * If the block is completely empty, then this is the end of the
     * archive file.  If the name is null, then just skip this header.
     */
    name = hp->name;

    if (*name == '\0') {
	for (cc = TAR_BLOCK_SIZE; cc > 0; cc--) {
	    if (*name++)
		return;
	}

	eofFlag = TRUE;

	return;
    }

    /* 
     * There is another file in the archive to examine.
     * Extract the encoded information and check it.
     */
    mode = getOctal (hp->mode, sizeof (hp->mode));
    uid = getOctal (hp->uid, sizeof (hp->uid));
    gid = getOctal (hp->gid, sizeof (hp->gid));
    size = getOctal (hp->size, sizeof (hp->size));
    mtime = getOctal (hp->mtime, sizeof (hp->mtime));
    checkSum = getOctal (hp->checkSum, sizeof (hp->checkSum));
    major = getOctal (hp->devMajor, sizeof (hp->devMajor));
    minor = getOctal (hp->devMinor, sizeof (hp->devMinor));

    if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) {
	if (badHeader==FALSE)
	    fprintf (stderr, "Bad tar header, skipping\n");

	badHeader = TRUE;

	return;
    }

    badHeader = FALSE;
    skipFileFlag = FALSE;
    devFileFlag = FALSE;

    /* 
     * Check for the file modes.
     */
    hardLink = ((hp->typeFlag == TAR_TYPE_HARD_LINK) ||
		(hp->typeFlag == TAR_TYPE_HARD_LINK - '0'));

    softLink = ((hp->typeFlag == TAR_TYPE_SOFT_LINK) ||
		(hp->typeFlag == TAR_TYPE_SOFT_LINK - '0'));

    /* 
     * Check for a directory.
     */
    if (name[strlen (name) - 1] == '/')
	mode |= S_IFDIR;

    /* 
     * Check for absolute paths in the file.
     * If we find any, then warn the user and make them relative.
     */
    if (*name == '/') {
	while (*name == '/')
	    name++;

	if (warnedRoot==FALSE) {
	    fprintf (stderr,
		     "Absolute path detected, removing leading slashes\n");
	}

	warnedRoot = TRUE;
    }

    /* 
     * See if we want this file to be restored.
     * If not, then set up to skip it.
     */
    if (wantFileName (name, fileCount, fileTable) == FALSE) {
	if ( !hardLink && !softLink && (S_ISREG (mode) || S_ISCHR (mode)
		    || S_ISBLK (mode) || S_ISSOCK(mode) || S_ISFIFO(mode) ) ) {
	    inHeader = (size == 0)? TRUE : FALSE;
	    dataCc = size;
	}

	skipFileFlag = TRUE;

	return;
    }

    /* 
     * This file is to be handled.
     * If we aren't extracting then just list information about the file.
     */
    if (extractFlag==FALSE) {
	if (verboseFlag==TRUE) {
	    printf ("%s %3d/%-d ", modeString (mode), uid, gid);
	    if( S_ISCHR (mode) || S_ISBLK (mode) )
		printf ("%4d,%4d %s ", major,minor, timeString (mtime));
	    else
		printf ("%9ld %s ", size, timeString (mtime));
	}
	printf ("%s", name);

	if (hardLink)
	    printf (" (link to \"%s\")", hp->linkName);
	else if (softLink)
	    printf (" (symlink to \"%s\")", hp->linkName);
	else if (S_ISREG (mode) || S_ISCHR (mode) || S_ISBLK (mode) || 
		S_ISSOCK(mode) || S_ISFIFO(mode) ) {
	    inHeader = (size == 0)? TRUE : FALSE;
	    dataCc = size;
	}

	printf ("\n");

	return;
    }

    /* 
     * We really want to extract the file.
     */
    if (verboseFlag==TRUE)
	printf ("x %s\n", name);

    if (hardLink) {
	if (link (hp->linkName, name) < 0)
	    perror (name);
	chown(name, uid, gid);
	chmod(name, mode);
	return;
    }

    if (softLink) {
#ifdef	S_ISLNK
	if (symlink (hp->linkName, name) < 0)
	    perror (name);
	chown(name, uid, gid);
	chmod(name, mode);
#else
	fprintf (stderr, "Cannot create symbolic links\n");
#endif
	return;
    }

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

    /* 
     * If the file is a directory, then just create the path.
     */
    if (S_ISDIR (mode)) {
	createPath (name, mode);
	chown(name, uid, gid);
	chmod(name, mode);

	return;
    }

    /* 
     * There is a file to write.
     * First create the path to it if necessary with default permissions.
     */
    createPath (name, 0777);

    inHeader = (size == 0)? TRUE : FALSE;
    dataCc = size;

    /* 
     * Start the output file.
     */
    if (tostdoutFlag == TRUE)
	outFd = fileno(stdout);
    else {
	if ( S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) ) {
	    devFileFlag = TRUE;
	    outFd = mknod (name, mode, makedev(major, minor) );
	}
	else if (S_ISFIFO(mode) ) {
	    devFileFlag = TRUE;
	    outFd = mkfifo(name, mode);
	} else {
	    outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);
	}
	if (outFd < 0) {
	    perror (name);
	    skipFileFlag = TRUE;
	    return;
	}
	chown(name, uid, gid);
	chmod(name, mode);
    }


    /* 
     * If the file is empty, then that's all we need to do.
     */
    if (size == 0 && (tostdoutFlag == FALSE) && (devFileFlag == FALSE)) {
	(void) close (outFd);
	outFd = -1;
    }
}


/*
 * Handle a data block of some specified size that was read.
 */
static void readData (const char *cp, int count)
{
    /* 
     * Reduce the amount of data left in this file.
     * If there is no more data left, then we need to read
     * the header again.
     */
    dataCc -= count;

    if (dataCc <= 0)
	inHeader = TRUE;

    /* 
     * If we aren't extracting files or this file is being
     * skipped then do nothing more.
     */
    if (extractFlag==FALSE || skipFileFlag==TRUE)
	return;

    /* 
     * Write the data to the output file.
     */
    if (fullWrite (outFd, cp, count) < 0) {
	perror (outName);
	if (tostdoutFlag == FALSE) {
	    (void) close (outFd);
	    outFd = -1;
	}
	skipFileFlag = TRUE;
	return;
    }

    /* 
     * If the write failed, close the file and disable further
     * writes to this file.
     */
    if (dataCc <= 0 && tostdoutFlag == FALSE) {
	if (close (outFd))
	    perror (outName);

	outFd = -1;
    }
}


/*
 * Write a tar file containing the specified files.
 */
static void writeTarFile (int fileCount, char **fileTable)
{
    struct stat statbuf;

    /* 
     * Make sure there is at least one file specified.
     */
    if (fileCount <= 0) {
	fprintf (stderr, "No files specified to be saved\n");
	errorFlag = TRUE;
    }

    /* 
     * Create the tar file for writing.
     */
    if ((tarName == NULL) || !strcmp (tarName, "-")) {
	tostdoutFlag = TRUE;
	tarFd = fileno(stdout);
    } else
	tarFd = open (tarName, O_WRONLY | O_CREAT | O_TRUNC, 0666);

    if (tarFd < 0) {
	perror (tarName);
	errorFlag = TRUE;
	return;
    }

    /* 
     * Get the device and inode of the tar file for checking later.
     */
    if (fstat (tarFd, &statbuf) < 0) {
	perror (tarName);
	errorFlag = TRUE;
	goto done;
    }

    tarDev = statbuf.st_dev;
    tarInode = statbuf.st_ino;
		
    /* 
     * Append each file name into the archive file.
     * Follow symbolic links for these top level file names.
     */
    while (errorFlag==FALSE && (fileCount-- > 0)) {
	saveFile (*fileTable++, FALSE);
    }

    /* 
     * Now write an empty block of zeroes to end the archive.
     */
    writeTarBlock ("", 1);


  done:
    /* 
     * Close the tar file and check for errors if it was opened.
     */
    if ((tostdoutFlag == FALSE) && (tarFd >= 0) && (close (tarFd) < 0))
	perror (tarName);
}


/*
 * Save one file into the tar file.
 * If the file is a directory, then this will recursively save all of
 * the files and directories within the directory.  The seeLinks
 * flag indicates whether or not we want to see symbolic links as
 * they really are, instead of blindly following them.
 */
static void saveFile (const char *fileName, int seeLinks)
{
    int status;
    int mode;
    struct stat statbuf;

    if (verboseFlag==TRUE)
	printf ("a %s\n", fileName);

    /* 
     * Check that the file name will fit in the header.
     */
    if (strlen (fileName) >= TAR_NAME_SIZE) {
	fprintf (stderr, "%s: File name is too long\n", fileName);

	return;
    }

    /* 
     * Find out about the file.
     */
#ifdef	S_ISLNK
    if (seeLinks==TRUE)
	status = lstat (fileName, &statbuf);
    else
#endif
	status = stat (fileName, &statbuf);

    if (status < 0) {
	perror (fileName);

	return;
    }

    /* 
     * Make sure we aren't trying to save our file into itself.
     */
    if ((statbuf.st_dev == tarDev) && (statbuf.st_ino == tarInode)) {
	fprintf (stderr, "Skipping saving of archive file itself\n");

	return;
    }

    /* 
     * Check the type of file.
     */
    mode = statbuf.st_mode;

    if (S_ISDIR (mode)) {
	saveDirectory (fileName, &statbuf);

	return;
    }
    if (S_ISREG (mode)) {
	saveRegularFile (fileName, &statbuf);

	return;
    }
    
    /* Some day add support for tarring these up... but not today. :) */
//  if (S_ISLNK(mode) || S_ISFIFO(mode) || S_ISBLK(mode) || S_ISCHR (mode) ) {
//	fprintf (stderr, "%s: This version of tar can't store this type of file\n", fileName);
//  }

    /* 
     * The file is a strange type of file, ignore it.
     */
    fprintf (stderr, "%s: not a directory or regular file\n", fileName);
}


/*
 * Save a regular file to the tar file.
 */
static void
saveRegularFile (const char *fileName, const struct stat *statbuf)
{
    int sawEof;
    int fileFd;
    int cc;
    int dataCount;
    long fullDataCount;
    char data[TAR_BLOCK_SIZE * 16];

    /* 
     * Open the file for reading.
     */
    fileFd = open (fileName, O_RDONLY);

    if (fileFd < 0) {
	perror (fileName);

	return;
    }

    /* 
     * Write out the header for the file.
     */
    writeHeader (fileName, statbuf);

    /* 
     * Write the data blocks of the file.
     * We must be careful to write the amount of data that the stat
     * buffer indicated, even if the file has changed size.  Otherwise
     * the tar file will be incorrect.
     */
    fullDataCount = statbuf->st_size;
    sawEof = FALSE;

    while (fullDataCount > 0) {
	/* 
	 * Get the amount to write this iteration which is
	 * the minumum of the amount left to write and the
	 * buffer size.
	 */
	dataCount = sizeof (data);

	if (dataCount > fullDataCount)
	    dataCount = (int) fullDataCount;

	/* 
	 * Read the data from the file if we haven't seen the
	 * end of file yet.
	 */
	cc = 0;

	if (sawEof==FALSE) {
	    cc = fullRead (fileFd, data, dataCount);

	    if (cc < 0) {
		perror (fileName);

		(void) close (fileFd);
		errorFlag = TRUE;

		return;
	    }

	    /* 
	     * If the file ended too soon, complain and set
	     * a flag so we will zero fill the rest of it.
	     */
	    if (cc < dataCount) {
		fprintf (stderr,
			 "%s: Short read - zero filling", fileName);

		sawEof = TRUE;
	    }
	}

	/* 
	 * Zero fill the rest of the data if necessary.
	 */
	if (cc < dataCount)
	    memset (data + cc, 0, dataCount - cc);

	/* 
	 * Write the buffer to the TAR file.
	 */
	writeTarBlock (data, dataCount);

	fullDataCount -= dataCount;
    }

    /* 
     * Close the file.
     */
    if ((tostdoutFlag == FALSE) && close (fileFd) < 0)
	fprintf (stderr, "%s: close: %s\n", fileName, strerror (errno));
}


/*
 * Save a directory and all of its files to the tar file.
 */
static void saveDirectory (const char *dirName, const struct stat *statbuf)
{
    DIR *dir;
    struct dirent *entry;
    int needSlash;
    char fullName[NAME_MAX];

    /* 
     * Construct the directory name as used in the tar file by appending
     * a slash character to it.
     */
    strcpy (fullName, dirName);
    strcat (fullName, "/");

    /* 
     * Write out the header for the directory entry.
     */
    writeHeader (fullName, statbuf);

    /* 
     * Open the directory.
     */
    dir = opendir (dirName);

    if (dir == NULL) {
	fprintf (stderr, "Cannot read directory \"%s\": %s\n",
		 dirName, strerror (errno));

	return;
    }

    /* 
     * See if a slash is needed.
     */
    needSlash = (*dirName && (dirName[strlen (dirName) - 1] != '/'));

    /* 
     * Read all of the directory entries and check them,
     * except for the current and parent directory entries.
     */
    while (errorFlag==FALSE && ((entry = readdir (dir)) != NULL)) {
	if ((strcmp (entry->d_name, ".") == 0) ||
	    (strcmp (entry->d_name, "..") == 0)) {
	    continue;
	}

	/* 
	 * Build the full path name to the file.
	 */
	strcpy (fullName, dirName);

	if (needSlash)
	    strcat (fullName, "/");

	strcat (fullName, entry->d_name);

	/* 
	 * Write this file to the tar file, noticing whether or not
	 * the file is a symbolic link.
	 */
	saveFile (fullName, TRUE);
    }

    /* 
     * All done, close the directory.
     */
    closedir (dir);
}


/*
 * Write a tar header for the specified file name and status.
 * It is assumed that the file name fits.
 */
static void writeHeader (const char *fileName, const struct stat *statbuf)
{
    long checkSum;
    const unsigned char *cp;
    int len;
    TarHeader header;

    /* 
     * Zero the header block in preparation for filling it in.
     */
    memset ((char *) &header, 0, sizeof (header));

    /* 
     * Fill in the header.
     */
    strcpy (header.name, fileName);

    strncpy (header.magic, TAR_MAGIC, sizeof (header.magic));
    strncpy (header.version, TAR_VERSION, sizeof (header.version));

    putOctal (header.mode, sizeof (header.mode), statbuf->st_mode & 0777);
    putOctal (header.uid, sizeof (header.uid), statbuf->st_uid);
    putOctal (header.gid, sizeof (header.gid), statbuf->st_gid);
    putOctal (header.size, sizeof (header.size), statbuf->st_size);
    putOctal (header.mtime, sizeof (header.mtime), statbuf->st_mtime);

    header.typeFlag = TAR_TYPE_REGULAR;

    /* 
     * Calculate and store the checksum.
     * This is the sum of all of the bytes of the header,
     * with the checksum field itself treated as blanks.
     */
    memset (header.checkSum, ' ', sizeof (header.checkSum));

    cp = (const unsigned char *) &header;
    len = sizeof (header);
    checkSum = 0;

    while (len-- > 0)
	checkSum += *cp++;

    putOctal (header.checkSum, sizeof (header.checkSum), checkSum);

    /* 
     * Write the tar header.
     */
    writeTarBlock ((const char *) &header, sizeof (header));
}


/*
 * Write data to one or more blocks of the tar file.
 * The data is always padded out to a multiple of TAR_BLOCK_SIZE.
 * The errorFlag static variable is set on an error.
 */
static void writeTarBlock (const char *buf, int len)
{
    int partialLength;
    int completeLength;
    char fullBlock[TAR_BLOCK_SIZE];

    /* 
     * If we had a write error before, then do nothing more.
     */
    if (errorFlag==TRUE)
	return;

    /* 
     * Get the amount of complete and partial blocks.
     */
    partialLength = len % TAR_BLOCK_SIZE;
    completeLength = len - partialLength;

    /* 
     * Write all of the complete blocks.
     */
    if ((completeLength > 0) && !fullWrite (tarFd, buf, completeLength)) {
	perror (tarName);

	errorFlag = TRUE;

	return;
    }

    /* 
     * If there are no partial blocks left, we are done.
     */
    if (partialLength == 0)
	return;

    /* 
     * Copy the partial data into a complete block, and pad the rest
     * of it with zeroes.
     */
    memcpy (fullBlock, buf + completeLength, partialLength);
    memset (fullBlock + partialLength, 0, TAR_BLOCK_SIZE - partialLength);

    /* 
     * Write the last complete block.
     */
    if (!fullWrite (tarFd, fullBlock, TAR_BLOCK_SIZE)) {
	perror (tarName);

	errorFlag = TRUE;
    }
}


/*
 * Read an octal value in a field of the specified width, with optional
 * spaces on both sides of the number and with an optional null character
 * at the end.  Returns -1 on an illegal format.
 */
static long getOctal (const char *cp, int len)
{
    long val;

    while ((len > 0) && (*cp == ' ')) {
	cp++;
	len--;
    }

    if ((len == 0) || !isOctal (*cp))
	return -1;

    val = 0;

    while ((len > 0) && isOctal (*cp)) {
	val = val * 8 + *cp++ - '0';
	len--;
    }

    while ((len > 0) && (*cp == ' ')) {
	cp++;
	len--;
    }

    if ((len > 0) && *cp)
	return -1;

    return val;
}


/*
 * 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 *tempString;
    char tempBuffer[32];

    /* 
     * Create a string of the specified length with an initial space,
     * leading zeroes and the octal number, and a trailing null.
     */
    tempString = tempBuffer;

    sprintf (tempString, " %0*lo", len - 2, value);

    tempLength = strlen (tempString) + 1;

    /* 
     * If the string is too large, suppress the leading space.
     */
    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;
}


/*
 * See if the specified file name belongs to one of the specified list
 * of path prefixes.  An empty list implies that all files are wanted.
 * Returns TRUE if the file is selected.
 */
static int
wantFileName (const char *fileName, int fileCount, char **fileTable)
{
    const char *pathName;
    int fileLength;
    int pathLength;

    /* 
     * If there are no files in the list, then the file is wanted.
     */
    if (fileCount == 0)
	return TRUE;

    fileLength = strlen (fileName);

    /* 
     * Check each of the test paths.
     */
    while (fileCount-- > 0) {
	pathName = *fileTable++;

	pathLength = strlen (pathName);

	if (fileLength < pathLength)
	    continue;

	if (memcmp (fileName, pathName, pathLength) != 0)
	    continue;

	if ((fileLength == pathLength) || (fileName[pathLength] == '/')) {
	    return TRUE;
	}
    }

    return FALSE;
}



/* END CODE */
