/* ark.c
 *
 * The transmission of tar, cpio, or ar archives via cu
 * is completely problematic.  This is a no frills archiver expressly
 * designed for xmission of archives that are the contents of some
 * directory.
 * 
 *	Usage: ark c[F][v] file ... file > file.ark
 *	       ark x[F][v]f filename  file.ark
 *	       ark x[F][v] file.ark ... file.ark
 *	       ark t[F][v]f filename  file.ark
 *	       ark t[F][v] file.ark ... file.ark
 *	       ark d[v]f filename  file.ark
 *
 * c = create arkfile on stdout from named files
 * x = extract or unload named arkfiles
 * xf = extract filename if it is listed in file.ark
 * df = delete filename if it is contained in file.ark
 * tf = print filename to stdout if it is listed in file.ark
 * v = print names of files actually operated on to stderr.
 * F = use the filter in extraction to eliminate all nul
 *     and extended ascii chars.
 *
 * With no "files" given, ark takes its list of files from stdin.
 * Thus
 *	ark c < listfile > arkfile
 *
 * ark always directs its output to stdout, thus the stand alone usage
 * would be
 *
 *	ark c * > pathname
 *	ark x arkfile
 *
 * to archive all the files in the current directory to the file given
 * by pathname, and
 *
 *	ark x arkfile
 *
 * to extract the contents of arkfile into the current directory.
 *
 * The verbose option t is also available with c or x: ark cv or ark xv
 *
 * The archive file for the c option example should not be
 * in the current directory.
 *
 * CAVEAT: Relative pathnames given on ark c are restored literally as
 *	   relative pathnames with ark x.  It is best not to be very fancy
 *	   in creating ark files.
 *
 *  -----------------------------------------------------------------------
 *			cc -o ark ark.c -s -O
 *  -----------------------------------------------------------------------
 *
 *   Extended-ascii chars and null chars can get into the stream when
 *   xmission from a remote system.  Ark is used to deal with archives
 *   of text files.
 *   The 'F' option invokes the filter to eliminate any extended ascii
 *   and nul chars in unloading and ark file.
 *
 * NB - the optional filtering in extract mode to eliminate non-ascii chars
 *   and nulls should not be used if the ark file contains packed or
 *   encrypted files.
 *
 * NB   arking an empty file really fucks up the resulting ark file.  It's
 *	all there, but two separator strings in a row makes the arkfile
 *	unreadable.  This can occur and did if a metachar reference for
 *	the list of files to be arked includes the the arkfile.
 *
 * IMPROVEMENTS over old 'ark':
 *
 *	1) Defense against arking directories, encypted files, packed files.
 *	2) x option for extraction of multiple arkfiles.
 *		ark x file1.ark file2.ark ... filen.ark
 *	3) New f|n option for extraction of a single file from an arkfile
 *		ark xf filename file.ark
 * ---------------------------------------------------------------------------
 * ADDED: delete 'd' option that physically removes
 *        a named file from the named arkfile.
 *
 *          Adding a file is easy: ark c file >> arkfile
 *
 * 
 * REVISION: September 11, 1996:
 * Standard extraction is fucking up the extracted files.
 * It seems to involve either long lines and/or tabs, or how LF is treated.
 *
 * Lengthened MAXLINE from 514 -> 1026
 * Cleaned up usg(), added error messages with perror().
 * Checked that 'Filter' switch was not inadvertantly set.
 * Report added at end of creation.
 *
 * Bug fixed - not taken into account in search for separator lines
 * that sscanf() will skip leading white space.
 *
 * Init of xfile[0]: Linux doesn't do it 12/12/97
 * Added other file extensions (.gz .zip .arc .o) in names as excluded in
 * an arkfile 12/12/97
 * Extension of file name size array to 128
 *
 * ADD? an interactive extraction option based on tellfile()
 *
 *-----------------------------------------------------------------------------
 * Functions:
 * int putfile( fn )
 * int isdir( fn )
 * int ispacked( fn )
 * int islinked( fn )
 * int funark( fn, an )
 * int unark( an )
 * int tellfiles( an, xf )
 * int fdelark( fn, an )
 * void usg()
 *-----------------------------------------------------------------------------
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SEPARATOR "XYZZY"	/* The magic string appearing at beginning of
				 * line that separates files.
				 * Structure of separating line is:
				 * SEPARATOR-STRING SPACE FILENAME.
				 * SPACE is safer than tab since remote
				 * xmission can convert tab -> 8 spaces.
				 */

#define SEPSZ 8			/* Size of array sepr for test SEPARATOR
				 * string
				 */

#define READ 0
#define WRITE 1

#define FALSE 0
#define TRUE 1

#define MAXLINE 1026
#define FNAMESZ 128

/* Forbidden file types */
#define F_OBJECT	1
#define F_COMPRESS	2
#define F_ARC		3
#define F_ZIP		4
#define F_GZIP		5
#define F_PACK		6

int verbose = FALSE;
int createark = FALSE;
int xtractark = FALSE;
int tellark = FALSE;
int delfark = FALSE;
int f_option = FALSE;
int Filter = FALSE;
int Narked = 0;
int Nnotarked = 0;

static char _sccsid[] = { " ark.c 1.6 1/16/98 " };

int main( argc, argv )
int argc;
char *argv[];
{
	void usg();
	int putfile(), funark(), unark(), tellfiles(), fdelark();

	FILE *rptr;
	char xfile[ FNAMESZ ];
	char c_opt;
	int i;


	/* If no command line arguments */
	if( argc == 1 )    {
		usg();
		exit( 1 );
	}

	/* Set to start processing files from argv[i] on */
	*xfile = NUL;
	i = 2;

	/* All options MUST be contained in argv[1] and we must have options */
	while( ( c_opt =  *argv[1]++ ) != NUL )    {
		switch( c_opt )    {
			case 'F':
				/* Option F set to filter null
				 * and nonascii chars
				 */
				Filter = TRUE;
				break;
			case 'c':
				/* Option c set to create archive */
				createark = TRUE;
				break;
			case 'f':
				/* Option f (extract a single file from archive)
				 * Next argument is the name of the file
				 */
				f_option = TRUE;
				strcpy( xfile, argv[2] );

				/* Start other file options skipping
				 * the argument to f
				 */
				++i;
				break;
			case 'd':
				/* Option d set to delete file from archive */
				delfark = TRUE;
				break;
			case 'x':
				/* Option x set to unload archive */
				xtractark = TRUE;
				break;
			case 't':
				/* Option t just read contents of archive
				 * by file name.  Send output to stdout.
				 */
				tellark = TRUE;
				break;
			case 'v':
				/* Option v = be verbose
				 * Print name of file being currently processed
				 * to stderr.
				 */
				verbose = TRUE;
				break;
			default:
				printf( "%s: Bad Option %c\n", c_opt );
				usg();
				exit( 1 );
		}
	}
	/* Of c, x, t, and d, only one of them can be true */
	if( createark + tellark + xtractark + delfark > 1 )    {
		fprintf( stderr, "%s: One and only one of the arguments c, x, d and t can be used.\n", argv[0] );
		usg();
		exit( 1 );
	}
	/* and one of them must be true */
	if( createark + tellark + xtractark + delfark != 1 )    {
		fprintf( stderr, "%s: One and only one of the arguments c, x, and t must be used.\n", argv[0] );
		usg();
		exit( 1 );
	}

	if( delfark )    {
		if( ! f_option )    {
			fprintf( stderr, "%s: option d requires option f.\n", argv[0] );
			usg();
			exit( 1 );
		}
	}
	if( createark )    {
		if( *xfile != NUL )    {
			fprintf( stderr, "%s: option f is not compatible with option c.\n", argv[0] );
			usg();
			exit( 1 );
		}
		/* Check files sequentially
		 * Not a directory ok, not packed or compressed ok
		 * warn on links
		 * ?other checks - whatif binary?
		 * Send separator and filename to stdout
		 * Send file to stdout
		 * Next file
		 */
		if( strcmp( argv[ 2 ], "-" ) == 0 )    {
			++i;
			/* We read the list of files to be arked from stdin. */
			while( gets( xfile ) )     {
				if( putfile( xfile ) )    {
					++Narked;
				}
				else    {
					++Nnotarked;
				}
			}
		}
		while( i < argc )    {
			if( putfile( argv[i++] ) )    {
				++Narked;
			}
			else    {
				++Nnotarked;
			}
		}
	}
	else if( xtractark )    {
		if( *xfile != NUL )    {
			/* we are extracting a single file xfile=argv[2] from
			 * the named archive which must then be argv[3].
			 */
			funark( xfile, argv[3] );
		}
		else    {
			/* We are unloading all files from the
			 * archives argv[2] ... argv[argc-1]
			 */
			while( i < argc )
				unark( argv[i++] );
		}
	}
	else if( delfark )    {
		/* Physically delete the named file from the archive file */
		fdelark( xfile, argv[3] );
	}
	else    {
		/* Only option t is left */
		if( *xfile != NUL )    {
			/* We list the single xfile by name if it exists in
			 * the named archive which must then be argv[3].
			 */
			tellfiles( argv[3], xfile );
		}
		else    {
			/* Otherwise we read off file names in all
			 * the named ark files
			 */
			while( i < argc )
				tellfiles( argv[i++], NULL );
		}
	}
	if( createark )    {
		fprintf( stderr, "%d files arked; %d files not arked.\n", Narked, Nnotarked );
	}

	exit( 0 );
	return( 0 );

} /* End main() */

/* Returns TRUE is file has been put to arkfile succesufully
 * and returns FALSE if it has not.
 */
int putfile( fn )
char *fn;
{
	int isdir(), ispacked(), islinked();

	FILE *rptr;
	int c;

	/* Check here for file being a directory or packed */
	if( isdir( fn ) )    {
		fprintf( stderr, "%s is directory\n", fn );
		return( FALSE );
	}
	switch( ispacked( fn ) )    {
		case F_OBJECT:
			fprintf( stderr, "%s is object file\n", fn );
			return( FALSE );
		case F_COMPRESS:
			fprintf( stderr, "%s is compressed\n", fn );
			return( FALSE );
		case F_ARC:
			fprintf( stderr, "%s is arc file\n", fn );
			return( FALSE );
		case F_ZIP:
			fprintf( stderr, "%s is zipped\n", fn );
			return( FALSE );
		case F_GZIP:
			fprintf( stderr, "%s is gzipped\n", fn );
			return( FALSE );
		case F_PACK:
			fprintf( stderr, "%s is packed\n", fn );
			return( FALSE );
		default:
			break;
	}
	if( islinked( fn ) )    {
		fprintf( stderr, "warning: %s has links\n", fn );
		/* Do not return */
	}
	
	if( verbose )
		fprintf( stderr, "%s\n", fn );
	if( ( rptr = fopen( fn, "r" ) ) == NULL )   {
		fprintf( stderr, "Ark: can't read %s\n", fn );
		return( FALSE );
	}

	/* Write file to ark file */
	printf( "%s %s\n", SEPARATOR, fn );
	while( ( c = getc( rptr ) ) != EOF )
		putchar( (char)c );
	fclose( rptr );

	return( TRUE );
}

int isdir( fn )
char *fn;
{
	extern int stat();

	struct stat st_buf;

	if( stat( fn, &st_buf ) < 0 )    {
		perror( "ark" );
		errno = 0;
		return( TRUE );
	}
	if( st_buf.st_mode == S_IFDIR )    {
		return( TRUE );
	}
	return( FALSE );
}

int ispacked( fn )
char *fn;
{
	unsigned int len;

	len = strlen( fn );
	if( strcmp( &fn[ len - 2 ], ".z" ) == 0 )    {
		return( F_PACK );
	}
	else if( strcmp( &fn[ len - 3 ], ".gz" ) == 0 )    {
		return( F_GZIP );
	}
	else if( strcmp( &fn[ len - 4 ], ".zip" ) == 0 )    {
		return( F_ZIP );
	}
	else if( strcmp( &fn[ len - 4 ], ".arc" ) == 0 )    {
		return( F_ARC );
	}
	else if( strcmp( &fn[ len - 2 ], ".Z" ) == 0 )    {
		return( F_COMPRESS );
	}
	else if( strcmp( &fn[ len - 2 ], ".o" ) == 0 )    {
		return( F_OBJECT );
	}
	else    {
		return( FALSE );
	}
}

int islinked( fn )
char *fn;
{
	extern int stat();

	struct stat st_buf;

	if( stat( fn, &st_buf ) < 0 )    {
		perror( "ark" );
		errno = 0;
		return( TRUE );
	}
	if( st_buf.st_nlink != 1 )    {
		return( TRUE );
	}
	return( FALSE );
}

/* Find separator line for "fn" in ark file "an" and create file named
 * file in the current directory from the arkfile contents.
 */
int funark( fn, an )
char *fn, *an;
{
	FILE *fptr[2];
	char line[ MAXLINE ];
	char fname[ FNAMESZ ];
	char sepr[ SEPSZ ];
	unsigned int seplen;
	int first = TRUE;
	int found = FALSE;
	int i;

	if( ( fptr[ READ ] = fopen( an, "r" ) ) == NULL )    {
			fprintf( stderr, "Ark: can't read %s\n", an );
			return( FALSE );
	}

	/* Set length of separator for strncmp() */
	seplen = strlen( SEPARATOR );

	if( fgets( line, MAXLINE, fptr[ READ ] ) == NULL )    {
		fprintf( stderr, "Ark: empty ark file %s.\n", an );
		exit( 1 );
	}
	if( strncmp( line, SEPARATOR, 5 ) )    {
		fprintf( stderr, "Ark: %s not in ark file format.\n", an );
		exit( 1 );
	}
	rewind( fptr[ READ ] );

	/* Start, at the top, looking for the named file */
	while( fgets( line, MAXLINE, fptr[ READ ] ) != NULL )    {
		if( !strncmp( line, SEPARATOR, seplen ) )    {
			sscanf( line, "%*s %s", fname );
			/* Beginning of a file segment */
			if( strncmp( fn, fname, strlen( fn ) ) == 0 )    {
				/* Found looked for file segment;
				 * begin extraction
				 */
				if( verbose )
					fprintf( stderr, "%s\n", fname );
					if( ( fptr[ WRITE ] = fopen( fname, "w" ) ) == NULL )    {
					perror( "ark" );
					fprintf( stderr, "Cannot write %s in this directory\n", fname );
					exit( 1 );
				}
				found = TRUE;
				--first;
			}
			else    {
				found = FALSE;
				if( first != 1 )    {
					fflush( fptr[ WRITE ] );
					fclose( fptr[ WRITE ] );
				}
			}
		} 
		else    {
			/* We have file text */
			if( found == TRUE )    {
				/* We are in the middle of the text of the
				 * file that is to be extracted.
				 */
				if( Filter )    {
					/* Alteration to filter
					 * undesirable chars.
					 */
					for( i = 0; i < MAXLINE; i++ )    {
						if( isascii( line[i] ) )    {
							if( line[i] != '\0' )
								putc( line[i], fptr[ WRITE ] );
						}
					}
				}
				else    {
					fprintf( fptr[ WRITE ], "%s", line );
				}
				fflush( fptr[ WRITE ] );
			}

		}
		/* This is essential in view of the above possible filtering
		 */
		for( i = 0; i < MAXLINE; i++ )    {
			line[i] = '\0';
		}
		for( i = 0; i < SEPSZ; i++ )    {
			sepr[i] = '\0';
		}
		for( i = 0; i < FNAMESZ; i++ )    {
			fname[i] = '\0';
		}

	} /* End reading arkfile */

	return( TRUE );
}

/* Unark (unload all files from) the named arkfile */
int unark( an )
char *an;
{
	FILE *fptr[2];
	char line[MAXLINE];
	char fname[FNAMESZ];
	char sepr[SEPSZ];
	unsigned int seplen;
	int first = TRUE;
	int i;

	if( ( fptr[ READ ] = fopen( an, "r" ) ) == NULL )    {
			fprintf( stderr, "Ark: can't read %s\n", an );
			return( FALSE );
	}

	/* Set length of separator for strncmp() */
	seplen = strlen( SEPARATOR );

	/* Open file, get first line and check format */
	if( fgets( line, MAXLINE, fptr[ READ ] ) == NULL )    {
		fprintf( stderr, "Ark: empty ark file %s.\n", an );
		exit( 1 );
	}
	if( strncmp( line, SEPARATOR, 5 ) )    {
		fprintf( stderr, "Ark: %s not in ark file format.\n", an );
		exit( 1 );
	}

	/* If here format is right - start at the top */
	rewind( fptr[ READ ] );
	while( fgets( line, MAXLINE, fptr[ READ ] ) != NULL )    {
		/* separator must start at beginning of line */
		if( !strncmp( line, SEPARATOR, 5 ) )    {
			/* Beginning of a file segment */
			sscanf( line, "%*s %s", fname );
			if( first != 1 )    {
				/* Not first file stored in arkfile */
				fflush( fptr[ WRITE ] );
				fclose( fptr[ WRITE ] );
			}
			else    {
				/* The first file stored in arkfile;
				 * just set switch, we are open and ready
				 * to go.
				 */
				--first;
			}
			if( verbose )    {
				fprintf( stderr, "%s\n", fname );
			}
			if( ( fptr[ WRITE ] = fopen( fname, "w" ) ) == NULL )    {
				perror( "ark" );
				fprintf( stderr, "Cannot write %s in this directory\n", fname );
				exit( 1 );
			}
		} 
		else    {
			/* No separator line and we are extracting a file */
			if( Filter )    {
				/* Alteration to filter
				 * undesirable chars.
				 */
				for( i = 0; i < MAXLINE; i++ )    {
					if( isascii( line[i] ) )    {
						if( line[i] != NUL )
							putc( line[i], fptr[ WRITE ] );
					}
				}
			}
			else    {
				/* Write ark line as is to named file */
				fprintf( fptr[ WRITE ], "%s", line );
			}
			fflush( fptr[ WRITE ] );
		}

		/* Clean all lines for reuse.
		 * This is essential in view of the above possible filtering.
		 */
		for( i = 0; i < MAXLINE; i++ )    {
			line[i] = NUL;
		}
		for( i = 0; i < SEPSZ; i++ )    {
			sepr[i] = NUL;
		}
		for( i = 0; i < FNAMESZ; i++ )    {
			fname[i] = NUL;
		}

	} /* End reading arkfile lines */

	return( TRUE );
}

/* Put to stdout, the names of the files contained in the arkfile */
int tellfiles( an, xf )
char *an, *xf;
{
	FILE *fptr[2];
	char line[MAXLINE];
	char fname[FNAMESZ];
	char sepr[SEPSZ];
	unsigned int seplen;
	int first = TRUE;
	int i;

	if( ( fptr[ READ ] = fopen( an, "r" ) ) == NULL )    {
		perror( "ark" );
		fprintf( stderr, "Ark: can't read %s\n", an );
		exit( 1 );
	}

	/* Set length of separator for strncmp() */
	seplen = strlen( SEPARATOR );

	while( fgets( line, MAXLINE, fptr[ READ ] ) != NULL )    {
		if( !strncmp( line, SEPARATOR, seplen ) )    {
			sscanf( line, "%*s %s", fname );
			if( xf == NULL )    {
				printf( "%s\n", fname );
				if( verbose )
					fprintf( stderr, "%s\n", fname );
			}
			else    {
				/* xf is not null */
				if( strcmp( fname, xf ) == 0 )    {
					printf( "%s\n", fname );
					if( verbose )
						fprintf( stderr, "%s\n", fname );
				}
			}
		}
		for( i = 0; i < MAXLINE; i++ )    {
			line[i] = NUL;
		}
		for( i = 0; i < SEPSZ; i++ )    {
			sepr[i] = NUL;
		}
		for( i = 0; i < FNAMESZ; i++ )    {
			fname[i] = NUL;
		}
	}
	return( TRUE );
}

int fdelark( fn, an )
char *fn, *an;
{
	FILE *fptr[2];
	char line[MAXLINE];
	char cmd[MAXLINE];
	char fname[FNAMESZ];
	char tfname[FNAMESZ];
	char sepr[SEPSZ];
	unsigned int seplen;
	int first = TRUE;
	int start;
	int i;

	if( ( fptr[ READ ] = fopen( an, "r" ) ) == NULL )    {
		fprintf( stderr, "Ark: can't read %s\n", an );
		exit( 1 );
	}
	sprintf( tfname, "/tmp/%d", getpid() );
	if( ( fptr[ WRITE ] = fopen( tfname, "w" ) ) == NULL )    {
		fprintf( stderr, "Ark: can't write %s\n", tfname );
		exit( 1 );
	}

	/* Set length of separator for strncmp() */
	seplen = strlen( SEPARATOR );

	start = 0;
	while( fgets( line, MAXLINE, fptr[ READ ] ) != NULL )    {
		if( !strncmp( line, SEPARATOR, seplen ) )    {
			sscanf( line, "%*s %s", fname );
			if( start )    {
				start = 0;
			}
			if( strcmp( fname, fn ) == 0 )    {
				start = 1;
				if( verbose )
					fprintf( stderr, "%s\n", fname );
			}
		}
		/* Write all lines but those to be deleted to the tmp file */

		if( start == 0 )
			fprintf( fptr[ WRITE ], "%s", line );

		/* ---------------- Clean Arrays ------------------------- */
		for( i = 0; i < MAXLINE; i++ )    {
			line[i] = NUL;
		}
		for( i = 0; i < SEPSZ; i++ )    {
			sepr[i] = NUL;
		}
		for( i = 0; i < FNAMESZ; i++ )    {
			fname[i] = NUL;
		}
	}
	fclose( fptr[ READ ] );
	fclose( fptr[ WRITE ] );

	/* Move the tmp file back to the archive file */
	sprintf( cmd, "mv %s %s", tfname, an );
	system( cmd );

	return( TRUE );
}

void usg()
{
	fprintf( stderr, "Usage: ark c[F][v] file ... file > file.ark\n" );
	fprintf( stderr, "       ark c[F][v] - < listfile > file.ark\n" );
	fprintf( stderr, "       ... | ark c[F][v] - > file.ark\n" );
	fprintf( stderr, "       ark x[F][v]f filename  file.ark\n" );
	fprintf( stderr, "       ark x[F][v] file.ark ... file.ark\n" );
	fprintf( stderr, "       ark t[F][v]f filename  file.ark\n" );
	fprintf( stderr, "       ark t[F][v] file.ark ... file.ark\n" );
	fprintf( stderr, "       ark d[v]f filename  file.ark\n" );
}
------------------------- FORMATED MANUAL -------------------------------



     ARK(LOCAL)		    XENIX System V (LM)		    ARK(LOCAL)



     NAME
	  ark -	create,	unload and edit	archive	file

     SYNOPSIS
	  ark c[v] file	[file ... file]	> 
	  ark c[v] - <  > 
	  | ark	c[v] - > 
	  ark x[F][v] 
	  ark x[F][v]f  
	  ark t[v] 
	  ark t[v]f  
	  ark d[v]f  

     DESCRIPTION
	  Ark creates archive files of ascii text files	 suitable  for
	  storage  files  that	can  be	 packed	 or compressed and for
	  transmission via cu or uucp, neither of which	deal correctly
	  with	files  produced	 by  tar, ar or	cpio.  Transmission of
	  binary files still remains problematic unless	 uuencode  and
	  uudecode is used.

	  The c	key causes ark to create  the  arkfile	of  the	 named
	  files	 on  the  standard  out	stream.	 If '-'	is used	as the
	  second argument to ark, the list of files  to	 be  arked  is
	  taken	 from standard in.  The	 is then a file with
	  one file name	per line.  The	list  of  files	 can  also  be
	  supplied through a pipeline.

	  The x	key is used to extract all the file elements by	 their
	  archived  name  from	a  named  arkfile,  while  the	f  key
	  modifier, which takes	an argument that is the	name of	a file
	  in the archive file extracts that file only.

	  The t	key prints the all the	names  of  the	files  in  the
	  archive  file	 unless	 the  f	 key  modifier	is  used.  The
	  argument to f	is presumably the name of  some	 file  in  the
	  archive.   If	 the file is found in the archive, its name is
	  printed, if it is not	found nothing is printed.

	  The d	key must have the f modifier.  The file	whose name  is
	  the  argument	 to  f is physically deleted from the archive.
	  If the file is not found nothing is done.

	  One and only one of the keys c, x t, d must be used.	The  d
	  key  must  also take the f key.  It is an error to use the f
	  with the c key.

	  In all cases,	the use	of the optional	v causes the names  of
	  the found files to be	written	on the standard	error stream.

	  The 'F' option is used in the	 extract  modes	 only;	it  is
	  otherwise  ignored.	When  invoked  the extracted file will



     Page 1					    (printed 12/13/97)






     ARK(LOCAL)		    XENIX System V (LM)		    ARK(LOCAL)



	  have any nul characters and any  extended  ascii  characters
	  stripped  from the file image	in the archive file before the
	  file is written out to the disk.

     COMMENTS
	  ark ignores directories, compressed  files  with  extensions
	  (.z .Z .arc .zip .gz)	and object files with .o extensions.

	  While	the delete option is provided for an ark archive,  and
	  add option is	not necessary.	To add files to	an archive,

	       ark c[v]	file1 ... filen	>> archive

	  will append the file entry to	the archive.  Care to use  the
	  append   stream   diversion  '>>'  rather  that  the	create
	  diversion '>'	is necessary, since this  will	overwrite  the
	  archive (unless "noclobber" is set for your login csh).

     FILES
	  /usr/bin/ark	      the program

     SEE ALSO
	  pack(C), compress(C) tar(C)
































     Page 2					    (printed 12/13/97)



-------------------------- NROFF MANUAL -------------------------------
.TH ARK LOCAL LM
.V 03/26/86 11:28:43
.\"@[$]ark.1        1.2     01/12/95 14:28:43 LAMBDA/MICRO INC
.ad
.fi
.SH NAME
ark \- create, unload and edit archive file
.SH SYNOPSIS
.B ark
c[v] file [file ... file] > 
.br
.B ark
c[v] - <  > 
.br
|
.B ark
c[v] - > 
.br
.B ark
x[F][v] 
.br
.B ark
x[F][v]f  
.br
.B ark
t[v] 
.br
.B ark
t[v]f  
.br
.B ark
d[v]f  
.SH DESCRIPTION
.I Ark
creates archive files of ascii text files
suitable for storage files that can be packed or compressed
and for transmission via cu or uucp,
neither of which deal correctly with files
produced by tar, ar or cpio.
Transmission of binary files still remains
problematic unless uuencode and uudecode is used.
.PP
The c key causes
.I ark
to create the arkfile of the named
files on the standard out stream.
If '-' is used as the second argument to ark, the list of files to be arked
is taken from standard in.
The  is then a file with one file name per line.
The list of files can also be supplied through a pipeline.
.PP
The x key
is used to extract all the file elements by their
archived name from a named arkfile,
while the f key modifier, which takes an argument that is the name of a file
in the archive file extracts that file only.
.PP
The t key prints the all the names of the files in the archive file
unless the f key modifier is used.
The argument to f is presumably the name of some file in the archive.
If the file is found in the archive, its name is printed, if it is not
found nothing is printed.
.PP
The d key must have the f modifier.
The file whose name is the argument to f is physically deleted
from the archive.
If the file is not found nothing is done.
.PP
One and only one of the keys c, x t, d must be used.
The d key must also take the f key.
It is an error to use the f with the c key.
.PP
In all cases, the use of the optional v
causes the names of the found files to be written on
the standard error stream.
.PP
The 'F' option is used in the extract modes only;
it is otherwise ignored.
When invoked the extracted file will have any nul characters and any
extended ascii characters stripped from the file image in the archive file
before the file is written out to the disk.
.SH COMMENTS
.B ark
ignores directories, compressed files with extensions
(.z .Z .arc .zip .gz) and object files with .o extensions.
.PP
While the delete option is provided for an ark archive,
and add option is not necessary.
To add files to an archive,
.sp
.nf
     ark c[v] file1 ... filen >> archive
.fi
.sp
will append the file entry to the archive.
Care to use the append stream diversion '>>' rather
that the create diversion '>' is necessary, since
this will overwrite the archive
(unless "noclobber" is set for your login csh).
.SH FILES
.DT
/usr/bin/ark        the program
.br
.SH "SEE ALSO"
pack(C), compress(C) tar(C)


Return to Home Page
Return to Metayoga Page
Return to C Language Page


The URL for this document is:
http://graham.main.nc.us/~bhammel/graham/CPROGS/ark.html
Created: 1997
Last Updated: May 28, 2000 Email me, Bill Hammel at
bhammel@graham.main.nc.us
READ WARNING BEFORE SENDING E-MAIL