/*
 * Copyright (c) 1999 by David I. Bell
 * Permission is granted to use, distribute, or modify this source,
 * provided that this copyright notice remains intact.
 *
 * The "tar" command, taken from sash.
 * This allows creation, extraction, and listing of tar files.
 *
 * Permission to distribute this code under the GPL has been granted.
 * Modified for busybox by Erik Andersen <andersee@debian.org>
 */


#include "internal.h"
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>


static const char tar_usage[] =
    "Create, extract, or list files from a TAR file\n\n"
    "usage: tar -[cxtvOf] [tarFileName] [FILE] ...\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;
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) {
	fprintf (stderr, "%s", tar_usage);
	exit (FALSE);
    }


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

    /* 
     * Parse the options.
     */
    options = *argv++;
    argc--;

    if (**argv == '-') {
	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 '-':
		break;

	    default:
		fprintf (stderr, "Unknown tar flag '%c'\n", *options);

		exit (FALSE);
	    }
	}
    }

    /* 
     * Validate the options.
     */
    if (extractFlag + listFlag + createFlag != 1) {
	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)
	writeTarFile (argc, argv);
    else
	readTarFile (argc, argv);
    if (errorFlag)
	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 = 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) {
	/* 
	 * 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) {
	    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;
    long size;
    time_t mtime;
    const char *name;
    int cc;
    int hardLink;
    int softLink;

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

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

	badHeader = TRUE;

	return;
    }

    badHeader = FALSE;
    skipFileFlag = 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 or a regular file.
     */
    if (name[strlen (name) - 1] == '/')
	mode |= S_IFDIR;
    else if ((mode & S_IFMT) == 0)
	mode |= S_IFREG;

    /* 
     * 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) {
	    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)) {
	if (!hardLink && !softLink && S_ISREG (mode)) {
	    inHeader = (size == 0);
	    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) {
	if (verboseFlag) {
	    printf ("%s %3d/%-d %9ld %s %s", modeString (mode),
		    uid, gid, size, timeString (mtime), name);
	} else
	    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)) {
	    inHeader = (size == 0);
	    dataCc = size;
	}

	printf ("\n");

	return;
    }

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

    if (hardLink) {
	if (link (hp->linkName, name) < 0)
	    perror (name);

	return;
    }

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

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

	return;
    }

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

    inHeader = (size == 0);
    dataCc = size;

    /* 
     * Start the output file.
     */
    if (tostdoutFlag == TRUE)
	outFd = STDOUT;
    else
	outFd = open (name, O_WRONLY | O_CREAT | O_TRUNC, mode);

    if (outFd < 0) {
	perror (name);
	skipFileFlag = TRUE;
	return;
    }

    /* 
     * If the file is empty, then that's all we need to do.
     */
    if (size == 0 && tostdoutFlag == 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 || skipFileFlag)
	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 = 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 && (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)
	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)
	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;
    }

    /* 
     * 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) {
	    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 && ((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)
	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 */
