/*
 * 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> <andersen@lineo.com>
 */


#include "internal.h"

#ifdef BB_TAR

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



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

/*
 * 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	void	createPath(const char * name, int mode);
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);
		return 1;
	}


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

						return 1;
					}

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

					return 1;
			}
		}
	}

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

		return 1;
	}

	/*
	 * 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");
	return( 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[PATH_LEN];

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


/*
 * Attempt to create the directories along the specified path, except for
 * the final component.  The mode is given for the final directory only,
 * while all previous ones get default protections.  Errors are not reported
 * here, as failures to restore files can be reported later.
 */
static void
createPath(const char * name, int mode)
{
	char *	cp;
	char *	cpOld;
	char	buf[TAR_NAME_SIZE];

	strcpy(buf, name);

	cp = strchr(buf, '/');

	while (cp)
	{
		cpOld = cp;
		cp = strchr(cp + 1, '/');

		*cpOld = '\0';

		if (mkdir(buf, cp ? 0777 : mode) == 0)
			printf("Directory \"%s\" created\n", buf);

		*cpOld = '/';
	}
}


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



#endif
/* END CODE */


