[net.sources] shar request

sscalsk@NSWC-WO.ARPA (03/06/86)

would someone please mail or post to the net a copy of the 'shar' creation
program. direct mailings to sscalsk@nswc-wo.    - thanx - 

jay@isis.UUCP (Jay) (03/09/86)

In article <1600@brl-smoke.ARPA> sscalsk@NSWC-WO.ARPA writes:
>would someone please mail or post to the net a copy of the 'shar' creation
>program. direct mailings to sscalsk@nswc-wo.    - thanx - 

Ditto.  POST them - don't mail them.  There are more of us out there that
want it.  Thanks in advance.

Jay Batson.
{hao,nbires}!isis!jay

jbs@mit-eddie.MIT.EDU (Jeff Siegal) (03/10/86)

In article <371@isis.UUCP> jay@isis.UUCP (Jay) writes:
>In article <1600@brl-smoke.ARPA> sscalsk@NSWC-WO.ARPA writes:
>>[...] please [...] post [...] a copy of the 'shar' creation
>>program.
>
>Ditto.  POST them [...].

Agreed.

Jeff Siegal - MIT EECS

jpn@teddy.UUCP (03/11/86)

>>would someone please mail or post to the net a copy of the 'shar' creation
>>program.
>
>Ditto.  POST them - don't mail them.  There are more of us out there that
>want it.  Thanks in advance.

Please DON'T post them.  There are two very good implementations of shar
in the mod.sources archives, both in volume1 (one implemented as an sh
script called "newshar", and one implemented in C called "cshar").  Please
consult the last mod.sources Index (posted to both net.sources and
mod.sources) for archive access methods.  There is absolutely no reason
to keep re-posting the same sources over and over.


John P. Nelson, Moderator, mod.sources
(decvax!genrad!panda!jpn  seismo!harvard!wjh12!panda!jpn)
Send source code to panda!sources, requests to panda!sources-request

jay@isis.UUCP (Jay) (03/12/86)

In article <1242@mit-eddie.MIT.EDU> jbs@mit-eddie.UUCP (Jeff Siegal) writes:
>In article <371@isis.UUCP> jay@isis.UUCP (Jay) writes:
>>In article <1600@brl-smoke.ARPA> sscalsk@NSWC-WO.ARPA writes:
>>>[...] please [...] post [...] a copy of the 'shar' creation
>>>program.
>>
>>Ditto.  POST them [...].
>
>Agreed.
>
>Jeff Siegal - MIT EECS
I got this 'mail' from: Vincent P. Broman <gould9!noscvax!broman@pyramid.UUCP>
on shar creation.  Due to the requests for posting, here is 'broman''s reply:

>simple.
>
>: Create a shell script that can be run to extract a bunch of files.
>echo ": This is a shar archive.  Extract with sh, not csh."
>echo ": The rest of this file will extract:"
>echo ":" "$*"
>for file
>do
>    echo "echo x $file"
>    echo "sed 's/^X//' > $file << 'xEOF'"
>    sed 's/^/X/' < $file
>    echo "xEOF"
>done
>
>vincent broman, code 632, naval ocean systems center, san diego, ca 92152, usa
>phone: +1 619 225 2365    starship: 32d 42m 22s n/ 117d 14m 13s w
>arpa: broman@nosc.mil     uucp: {sdcsvax,gould9,bonnie,hp-sdd}!noscvax!broman
>

Jay Batson
{hao,nbires}!isis!jay

Disclaimer:  I disclaim all disclaimers.

avolio@decuac.UUCP (Frederick M. Avolio) (03/12/86)

>>>>>> [...] please [...] post [...] a copy of the 'shar' creation
>>>>>> program.
>>>>> Ditto.  POST them [...].
>>>> Agreed.
>>> Me too
>> Oh yes do!
>Can I have it too?

Oh for crying out loud, enough already. (uhhh...  I added a few
'enclosures' for ... affect?) Look, every month or so a list of archived
sources from mod.sources is posted to mod.sources (and net.sources, I
believe).  Check it out, and see how to get the big, fancy shar (it is
very nice).  For now, use this:

--------------------------------------------------------
for i
do
	echo "echo x - $i"
	echo "sed 's/^X//' >$i <<'*-*-END-of-$i-*-*'"
	sed 's/^/X/' $i
	echo "*-*-END-of-$i-*-*"
done
echo exit
--------------------------------------------------------
-- 
Fred @ DEC Ultrix Applications Center
UUCP: {decvax,seismo,cbosgd}!decuac!avolio       INET: avolio@decuac.DEC.COM

barad@brand.UUCP (Herb Barad) (03/17/86)

In article <371@isis.UUCP> jay@isis.UUCP (Jay) writes:
>In article <1600@brl-smoke.ARPA> sscalsk@NSWC-WO.ARPA writes:
>>would someone please mail or post to the net a copy of the 'shar' creation
>>program. direct mailings to sscalsk@nswc-wo.    - thanx - 
>
>Ditto.  POST them - don't mail them.  There are more of us out there that
>want it.  Thanks in advance.
>
>Jay Batson.
>{hao,nbires}!isis!jay

ok, here it is.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	getopt.3
#	getopt.c
#	shar.1
#	shar.c
#	traverse.3
#	traverse.c
# This archive created: Fri Jul 26 11:50:30 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(625 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'Makefile'
	X# make this getopt.o if on a BSD or other non system V
	XGETOPT= getopt.o
	X
	XCFLAGS=-O
	X
	Xall:	traverse shar
	X
	Xshar:	shar.o traverse.o $(GETOPT)
	X	$(CC) -O -s -o shar shar.o traverse.o $(GETOPT)
	X
	Xtraverse:
	X	$(CC) $(CFLAGS) -s -o traverse -DSTANDALONE traverse.c
	X
	Xinstall:	all
	X	/etc/install -f /usr/bin shar
	X	/etc/install -f /usr/bin traverse
	X	strip /usr/bin/shar /usr/bin/traverse
	X	cp shar.1 /usr/man/u_man/man1/shar.1
	X	cp traverse.3 /usr/man/p_man/man3/traverse.3
	X
	Xclean:
	X	rm -f shar traverse *.o
	X
	Xshar.shar: Makefile shar.c traverse.c shar.1 traverse.3
	X	shar -a -d EOF_SHAR Makefile shar.c traverse.c shar.1 traverse.3 > shar.shar
SHAR_EOF
if test 625 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 625 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getopt.3'" '(2749 characters)'
if test -f 'getopt.3'
then
	echo shar: will not over-write existing file "'getopt.3'"
else
sed 's/^	X//' << \SHAR_EOF > 'getopt.3'
	X.TH GETOPT 3
	X.DA 25 March 1982
	X.SH NAME
	Xgetopt \- get option letter from argv
	X.SH SYNOPSIS
	X.ft B
	Xint getopt(argc, argv, optstring)
	X.br
	Xint argc;
	X.br
	Xchar **argv;
	X.br
	Xchar *optstring;
	X.sp
	Xextern char *optarg;
	X.br
	Xextern int optind;
	X.ft
	X.SH DESCRIPTION
	X.I Getopt
	Xreturns the next option letter in
	X.I argv
	Xthat matches a letter in
	X.IR optstring .
	X.I Optstring
	Xis a string of recognized option letters;
	Xif a letter is followed by a colon, the option is expected to have
	Xan argument that may or may not be separated from it by white space.
	X.I Optarg
	Xis set to point to the start of the option argument on return from
	X.IR getopt .
	X.PP
	X.I Getopt
	Xplaces in
	X.I optind
	Xthe
	X.I argv
	Xindex of the next argument to be processed.
	XBecause
	X.I optind
	Xis external, it is normally initialized to zero automatically
	Xbefore the first call to 
	X.IR getopt .
	X.PP
	XWhen all options have been processed (i.e., up to the first
	Xnon-option argument),
	X.I getopt
	Xreturns
	X.BR EOF .
	XThe special option
	X.B \-\-
	Xmay be used to delimit the end of the options;
	X.B EOF
	Xwill be returned, and
	X.B \-\-
	Xwill be skipped.
	X.SH SEE ALSO
	Xgetopt(1)
	X.SH DIAGNOSTICS
	X.I Getopt
	Xprints an error message on
	X.I stderr
	Xand returns a question mark
	X.RB ( ? )
	Xwhen it encounters an option letter not included in
	X.IR optstring .
	X.SH EXAMPLE
	XThe following code fragment shows how one might process the arguments
	Xfor a command that can take the mutually exclusive options
	X.B a
	Xand
	X.BR b ,
	Xand the options
	X.B f
	Xand
	X.BR o ,
	Xboth of which require arguments:
	X.PP
	X.RS
	X.nf
	Xmain(argc, argv)
	Xint argc;
	Xchar **argv;
	X{
	X	int c;
	X	extern int optind;
	X	extern char *optarg;
	X	\&.
	X	\&.
	X	\&.
	X	while ((c = getopt(argc, argv, "abf:o:")) != EOF)
	X		switch (c) {
	X		case 'a':
	X			if (bflg)
	X				errflg++;
	X			else
	X				aflg++;
	X			break;
	X		case 'b':
	X			if (aflg)
	X				errflg++;
	X			else
	X				bproc();
	X			break;
	X		case 'f':
	X			ifile = optarg;
	X			break;
	X		case 'o':
	X			ofile = optarg;
	X			break;
	X		case '?':
	X		default:
	X			errflg++;
	X			break;
	X		}
	X	if (errflg) {
	X		fprintf(stderr, "Usage: ...");
	X		exit(2);
	X	}
	X	for (; optind < argc; optind++) {
	X		\&.
	X		\&.
	X		\&.
	X	}
	X	\&.
	X	\&.
	X	\&.
	X}
	X.RE
	X.PP
	XA template similar to this can be found in
	X.IR /usr/pub/template.c .
	X.SH HISTORY
	XWritten by Henry Spencer, working from a Bell Labs manual page.
	XBehavior believed identical to the Bell version.
	X.SH BUGS
	XIt is not obvious how
	X`\-'
	Xstanding alone should be treated;  this version treats it as
	Xa non-option argument, which is not always right.
	X.PP
	XOption arguments are allowed to begin with `\-';
	Xthis is reasonable but reduces the amount of error checking possible.
	X.PP
	X.I Getopt
	Xis quite flexible but the obvious price must be paid:  there is much
	Xit could do that it doesn't, like
	Xchecking mutually exclusive options, checking type of
	Xoption arguments, etc.
SHAR_EOF
if test 2749 -ne "`wc -c < 'getopt.3'`"
then
	echo shar: error transmitting "'getopt.3'" '(should have been 2749 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'getopt.c'" '(1437 characters)'
if test -f 'getopt.c'
then
	echo shar: will not over-write existing file "'getopt.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'getopt.c'
	X/* got this off net.sources */
	X#include <stdio.h>
	X
	X/*
	X * get option letter from argument vector
	X */
	Xint	opterr = 1,		/* useless, never set or used */
	X	optind = 1,		/* index into parent argv vector */
	X	optopt;			/* character checked for validity */
	Xchar	*optarg;		/* argument associated with option */
	X
	X#define BADCH	(int)'?'
	X#define EMSG	""
	X#define tell(s)	fputs(*nargv,stderr);fputs(s,stderr); \
	X		fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
	X
	Xgetopt(nargc,nargv,ostr)
	Xint	nargc;
	Xchar	**nargv,
	X	*ostr;
	X{
	X	static char	*place = EMSG;	/* option letter processing */
	X	register char	*oli;		/* option letter list index */
	X	char	*index();
	X
	X	if(!*place) {			/* update scanning pointer */
	X		if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place) return(EOF);
	X		if (*place == '-') {	/* found "--" */
	X			++optind;
	X			return(EOF);
	X		}
	X	}				/* option letter okay? */
	X	if ((optopt = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
	X		if(!*place) ++optind;
	X		tell(": illegal option -- ");
	X	}
	X	if (*++oli != ':') {		/* don't need argument */
	X		optarg = NULL;
	X		if (!*place) ++optind;
	X	}
	X	else {				/* need an argument */
	X		if (*place) optarg = place;	/* no white space */
	X		else if (nargc <= ++optind) {	/* no arg */
	X			place = EMSG;
	X			tell(": option requires an argument -- ");
	X		}
	X	 	else optarg = nargv[optind];	/* white space */
	X		place = EMSG;
	X		++optind;
	X	}
	X	return(optopt);			/* dump back option letter */
	X}
SHAR_EOF
if test 1437 -ne "`wc -c < 'getopt.c'`"
then
	echo shar: error transmitting "'getopt.c'" '(should have been 1437 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'shar.1'" '(2637 characters)'
if test -f 'shar.1'
then
	echo shar: will not over-write existing file "'shar.1'"
else
sed 's/^	X//' << \SHAR_EOF > 'shar.1'
	X.TH SHAR 1
	X.SH NAME
	Xshar \- create file storage archive for extraction by /bin/sh
	X.SH SYNOPSIS
	X.B shar
	X[-abcsv] [-d delim] [-p prefix] files
	X.SH DESCRIPTION
	X.I shar
	Xprints its input files with special command lines around them
	Xto be used by the shell,
	X.I /bin/sh ,
	Xto extract them later.
	XThe output can be filtered through the shell to
	Xrecreate copies of the original files.
	X.PP
	X.I shar
	Xallows directories to be named, and
	X.I shar
	Xprints the necessary commands
	X.ul
	X(mkdir & cd)
	Xto create new directories and fill them.
	X.I shar
	Xwill emit commands to make executable plain files executable.
	X.I shar will not allow existing files to be
	X.I over-written;
	Xsuch files must be removed by the file extractor.
	X.SH OPTIONS
	X.de OP
	X.TP
	X.B -\\$1
	X..
	X.OP a
	XAll the options.
	XThe options:
	X.B "-v -c -b -p <tab>X"
	Xare implied.
	X.OP s
	XSilent running.
	XAll checking and extra output is inhibited.
	X.OP v
	XPrint verbose feedback messages about what
	X.I shar
	Xis doing to be printed during extraction.
	XSizes of plain files are echoed to allow a simple validity check.
	X.OP c
	XCheck file size on extraction by counting characters.
	XAn error message is reported to the person doing the
	Xextraction if the sizes don't match.
	XOne reason why the sizes may not match is that
	X.I shar
	Xwill append a newline to complete incomplete last lines;
	X.I shar
	Xprints a message that mentions added newlines.
	XAnother reason why the sizes may not match is that some
	Xnetwork mail programs remove non-whitespace control characters.
	X.I shar
	Xprints a message that mentions control characters to the extractor.
	X.OP b
	XExtract files into basenames so that files with absolute path names
	Xare put into the current directory.
	XThis option has strange effects when directories are archived.
	X.OP d delim
	XUse this as the ``end of file'' delimiter instead of the default.
	XThe only reason to change it is if you suspect a file
	Xcontains the default delimiter:
	X.B SHAR_EOF.
	X.OP p prefix
	XUse this as the prefix to each line of the archived files.
	XThis is to make sure that special characters at the start of lines are not
	Xeaten up by programs like mailers.
	XIf this option is used,
	Xthe files will be extracted with the stream editor
	X.B sed
	Xrather than
	X.B cat
	Xso it is more efficient and portable to avoid setting the prefix,
	Xthough perhaps less safe if you don't know what is in the files.
	X.SH "SEE ALSO
	Xtar(1), cpio(1), tp(1), sh(1)
	X.SH AUTHOR
	XGary Perlman
	X(based on a shell version by James Gosling,
	Xwith additions motivated by
	XDerek Zahn,
	XMichael Thompson,
	XH. Morrow Long,
	XFred Avolio,
	XGran Uddeborg,
	X&
	XChuck Wegrzyn)
	X.SH LIMITATIONS
	X.I shar
	Xdoes not know anything about
	Xlinks between files
	Xor binary files.
SHAR_EOF
if test 2637 -ne "`wc -c < 'shar.1'`"
then
	echo shar: error transmitting "'shar.1'" '(should have been 2637 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'shar.c'" '(8881 characters)'
if test -f 'shar.c'
then
	echo shar: will not over-write existing file "'shar.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'shar.c'
	X#include <stdio.h>
	X#include <sys/types.h>
	X#include <sys/stat.h>
	X#include <ctype.h>
	X
	X/*{
	XShar puts readable text files together in a package
	Xfrom which they are easy to extract.  The original version
	Xwas a shell script posted to the net, shown below:
	X	#Date: Mon Oct 18 11:08:34 1982
	X	#From: decvax!microsof!uw-beave!jim (James Gosling at CMU)
	X	AR=$1
	X	shift
	X	for i do
	X		echo a - $i
	X		echo "echo x - $i" >>$AR
	X		echo "cat >$i <<'!Funky!Stuff!'" >>$AR
	X		cat $i >>$AR
	X		echo "!Funky!Stuff!" >>$AR
	X	done
	XI rewrote this version in C to provide better diagnostics
	Xand to run faster.  The major difference is that my version
	Xdoes not affect any files because it prints to the standard
	Xoutput.  Mine also has several options.
	X
	XGary Perlman/Wang Institute/Tyngsboro, MA/01879/(617) 649-9731
	X
	XMany enhancements motivated by Michael Thompson.
	X
	XDirectory archiving motivated by Derek Zahn @ wisconsin
	X	His version had some problems, so I wrote a general
	X	routine for traversing a directory hierarchy.  It
	X	allows marching through a directory on old and new
	X	UNIX systems.
	X}*/
	X
	X/* COMMANDS */
	X#define	EXTRACT "#! /bin/sh"     /* magic exec string at shar file start */
	X#define	PATH    "/bin:$PATH"     /* search path for programs */
	X#define	CAT     "cat";           /* /bin/cat */
	X#define	SED     "sed 's/^%s//'"  /* /bin/sed removes Prefix from lines */
	X#define	MKDIR   "mkdir"          /* make a new dirctory */
	X#define	CHMOD   "chmod +x"       /* change file protection (for executables) */
	X#define	CHDIR   "cd"             /* change current directory */
	X#define	TEST    "test"           /* /bin/test files */
	X#define	WC_C    "wc -c <"        /* counts chars in file */
	X#define	ECHO    "echo shar"      /* echo a message to extractor */
	X
	Xmain (argc, argv) char **argv;	
	X	{
	X	int 	shar ();
	X	int 	optind;
	X	if ((optind = initial (argc, argv)) < 0)
	X		exit (1);
	X	if (header (argc, argv, optind))
	X		exit (2);
	X	while (optind < argc)
	X		traverse (argv[optind++], shar);
	X	footer ();
	X	exit (0);
	X	}
	X
	X/*			OPTIONS			*/
	Xtypedef	int	lgl;
	X#define	true	((lgl) 1)
	X#define	false	((lgl) 0)
	Xint 	Lastchar;   /* the last character printed */
	Xint 	Ctrlcount;  /* how many bad control characters are in file */
	X
	X#define	USAGE "[-abcsv] [-p prefix] [-d delim] files > archive"
	X#define	OPTSTRING "abcsvp:d:"
	X
	Xlgl 	Verbose = false;       /* provide append/extract feedback */
	Xlgl 	Basename = false;      /* extract into basenames */
	Xlgl 	Count = false;         /* count characters to check transfer */
	Xlgl 	Silent = false;        /* turn off all verbosity */
	Xchar	*Delim = "SHAR_EOF";   /* put after each file */
	Xchar	Filter[100] = CAT;     /* used to extract archived files */
	Xchar	*Prefix = NULL;        /* line prefix to avoid funny chars */
	X
	Xint /* returns the index of the first operand file */
	Xinitial (argc, argv) char **argv;
	X	{
	X	int 	errflg = 0;
	X	extern	int 	optind;
	X	extern	char	*optarg;
	X	int 	C;
	X	while ((C = getopt (argc, argv, OPTSTRING)) != EOF)
	X		switch (C)
	X			{
	X			case 'v': Verbose = true; break;
	X			case 'c': Count = true; break;
	X			case 'b': Basename = true; break;
	X			case 'd': Delim = optarg; break;
	X			case 's': /* silent running */
	X				Silent = true;
	X				Verbose = false;
	X				Count = false;
	X				Prefix = NULL;
	X				break;
	X			case 'a': /* all the options */
	X				Verbose = true;
	X				Count = true;
	X				Basename = true;
	X				/* fall through to set prefix */
	X				optarg = "	X";
	X			case 'p': (void) sprintf (Filter, SED, Prefix = optarg); break;
	X			default: errflg++;
	X			}
	X	if (errflg || optind == argc)
	X		{
	X		if (optind == argc)
	X			fprintf (stderr, "shar: No input files\n");
	X		fprintf (stderr, "USAGE: shar %s\n", USAGE);
	X		return (-1);
	X		}
	X	return (optind);
	X	}
	X
	Xheader (argc, argv, optind)
	Xchar	**argv;
	X	{
	X	int 	i;
	X	lgl 	problems = false;
	X	long	clock;
	X	char	*ctime ();
	X	char	*getenv ();
	X	char	*NAME = getenv ("NAME");
	X	char	*ORG = getenv ("ORGANIZATION");
	X	for (i = optind; i < argc; i++)
	X		if (access (argv[i], 4)) /* check read permission */
	X			{
	X			fprintf (stderr, "shar: Can't read '%s'\n", argv[i]);
	X			problems++;
	X			}
	X	if (problems) return (problems);
	X	/*	I have given up on putting a cut line in the archive.
	X		Too many people complained about having to remove it.
	X		puts ("-----cut here-----cut here-----cut here-----cut here-----");
	X	*/
	X	puts (EXTRACT);
	X	puts ("# This is a shell archive, meaning:");
	X	printf ("# 1. Remove everything above the %s line.\n", EXTRACT);
	X	puts ("# 2. Save the resulting text in a file.");
	X	puts ("# 3. Execute the file with /bin/sh (not csh) to create the files:");
	X	for (i = optind; i < argc; i++)
	X		printf ("#\t%s\n", argv[i]);
	X	(void) time (&clock);
	X	printf ("# This archive created: %s", ctime (&clock));
	X	if (NAME)
	X		printf ("# By:\t%s (%s)\n", NAME, ORG ? ORG : "");
	X	printf ("export PATH; PATH=%s\n", PATH);
	X	return (0);
	X	}
	X
	Xfooter ()
	X	{
	X	puts ("#\tEnd of shell archive");
	X	puts ("exit 0");
	X	}
	X
	Xarchive (input, output)
	Xchar	*input, *output;
	X	{
	X	char	buf[BUFSIZ];
	X	FILE	*ioptr;
	X	if (ioptr = fopen (input, "r"))
	X		{
	X		if (Count == true)
	X			{
	X			Ctrlcount = 0;    /* no bad control characters so far */
	X			Lastchar = '\n';  /* simulate line start */
	X			}
	X		printf ("%s << \\%s > '%s'\n", Filter, Delim, output);
	X		if (Prefix)
	X			{
	X			while (fgets (buf, BUFSIZ, ioptr))
	X				{
	X				if (Prefix) outline (Prefix);
	X				outline (buf);
	X				}
	X			}
	X		else copyout (ioptr);
	X		/* thanks to H. Morrow Long (ittvax!long) for the next fix */
	X		if (Lastchar != '\n') /* incomplete last line */
	X			putchar ('\n');   /* Delim MUST begin new line! */
	X		puts (Delim);
	X		if (Count == true && Lastchar != '\n')
	X			printf ("%s: a missing newline was added to \"'%s'\"\n", ECHO, input);
	X		if (Count == true && Ctrlcount)
	X			printf ("%s: %d control character%s may be missing from \"'%s'\"\n",
	X				ECHO, Ctrlcount, Ctrlcount > 1 ? "s" : "", input);
	X		(void) fclose (ioptr);
	X		return (0);
	X		}
	X	else
	X		{
	X		fprintf (stderr, "shar: Can't open '%s'\n", input);
	X		return (1);
	X		}
	X	}
	X
	X/*
	X	Copyout copies its ioptr almost as fast as possible
	X	except that it has to keep track of the last character
	X	printed.  If the last character is not a newline, then
	X	shar has to add one so that the end of file delimiter
	X	is recognized by the shell.  This checking costs about
	X	a 10% difference in user time.  Otherwise, it is about
	X	as fast as cat.  It also might count control characters.
	X*/
	X#define	badctrl(c) (iscntrl (c) && !isspace (c))
	Xcopyout (ioptr)
	Xregister	FILE	*ioptr;
	X	{
	X	register	int 	C;
	X	register	int 	L;
	X	register	count;
	X	count = Count;
	X	while ((C = getc (ioptr)) != EOF)
	X		{
	X		if (count == true && badctrl (C)) Ctrlcount++;
	X		L = putchar (C);
	X		}
	X	Lastchar = L;
	X	}
	X
	Xoutline (s)
	Xregister	char	*s;
	X	{
	X	if (*s)
	X		{
	X		while (*s)
	X			{
	X			if (Count == true && badctrl (*s)) Ctrlcount++;
	X			putchar (*s++);
	X			}
	X		Lastchar = *(s-1);
	X		}
	X	}
	X
	X#define	FSIZE     statbuf.st_size
	Xshar (file, type, pos)
	Xchar	*file;     /* file or directory to be processed */
	Xint 	type;      /* either 'f' for file or 'd' for directory */
	Xint 	pos;       /* 0 going in to a file or dir, 1 going out */
	X	{
	X	struct	stat	statbuf;
	X	char	*basefile = file;
	X	if (!strcmp (file, ".")) return;
	X	if (stat (file, &statbuf)) FSIZE = 0;
	X	if (Basename == true)
	X		{
	X		while (*basefile) basefile++; /* go to end of name */
	X		while (basefile > file && *(basefile-1) != '/') basefile--;
	X		}
	X	if (pos == 0) /* before the file starts */
	X		{
	X		if (type == 'd')
	X			{
	X			printf ("if %s ! -d '%s'\n", TEST, basefile);
	X			printf ("then\n");
	X			if (Verbose == true)
	X				printf ("	%s: creating directory \"'%s'\"\n", ECHO, basefile);
	X			printf ("	%s '%s'\n", MKDIR, basefile);
	X			printf ("fi\n");
	X			if (Verbose == true)
	X				printf ("%s: entering directory \"'%s'\"\n", ECHO, basefile);
	X			printf ("%s '%s'\n", CHDIR, basefile);
	X			}
	X		else /* type == 'f' */
	X			{
	X			if (Verbose == true)
	X				printf ("%s: extracting \"'%s'\" '(%d character%s)'\n",
	X					ECHO, basefile, FSIZE, FSIZE > 1 ? "s" : "");
	X			if (Silent == false) /* this solution by G|ran Uddeborg */
	X				{
	X				printf ("if %s -f '%s'\n", TEST, basefile);
	X				puts ("then");
	X				printf ("	%s: will not over-write existing file \"'%s'\"\n",
	X					ECHO, basefile);
	X				puts ("else");
	X				}
	X			if (archive (file, basefile)) exit (-1);
	X			}
	X		}
	X	else /* pos == 1, after the file is archived */
	X		{
	X		if (type == 'd')
	X			{
	X			if (Verbose == true)
	X				printf ("%s: done with directory \"'%s'\"\n", ECHO, basefile);
	X			printf ("%s ..\n", CHDIR);
	X			}
	X		else /* type == 'f' (plain file) */
	X			{
	X			if (Count == true)
	X				{
	X				printf ("if %s %d -ne \"`%s '%s'`\"\n",
	X					TEST, FSIZE, WC_C, basefile);
	X				puts ("then");
	X				printf ("	%s: error transmitting \"'%s'\" ", ECHO, basefile);
	X				printf ("'(should have been %d character%s)'\n",
	X					FSIZE, FSIZE > 1 ? "s" : "");
	X				puts ("fi");
	X				}
	X			if (access (file, 1) == 0) /* executable -> chmod +x */
	X				printf ("%s '%s'\n", CHMOD, basefile);
	X			if (Silent == false)
	X				{
	X				puts ("fi # end of overwriting check");
	X				}
	X			}
	X		}
	X	}
SHAR_EOF
if test 8881 -ne "`wc -c < 'shar.c'`"
then
	echo shar: error transmitting "'shar.c'" '(should have been 8881 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'traverse.3'" '(1147 characters)'
if test -f 'traverse.3'
then
	echo shar: will not over-write existing file "'traverse.3'"
else
sed 's/^	X//' << \SHAR_EOF > 'traverse.3'
	X.TH TRAVERSE 3
	X.SH NAME
	Xtraverse \- recursively traverse a directory
	X.SH SYNOPSIS
	X.nf
	Xtraverse (path, func)
	Xchar	*path;
	Xint 	(*func) ();
	X
	Xfunc (path, filetype, position)
	Xchar	*path;
	X.fi
	X.SH DESCRIPTION
	Xtraverse
	Xapplies its argument function func to its argument file pathname path.
	XIf path is a directory,
	Xthen traverse applies func to all its entries.
	XThis traversal is in depth first order
	Xso that files are processed in the order
	Xthat they are stored in the directory.
	X.PP
	XThe argument func should take three parameters:
	Xa file name,
	Xa file type,
	Xand a position.
	XThe call looks like this for directories:
	X.ce
	X(*func) (path, 'd', position);
	Xand like this for other files:
	X.ce
	X(*func) (path, 'f', position);
	XThe position
	Xis 0 when path is first encountered
	Xand 1 when traverse is done.
	XThis is used to allow processing before and after
	Xa directory is processed.
	X.SH EXAMPLE
	X.nf
	Xlist (name, type, pos)
	Xchar	*name;
	X	{
	X	if (type == 'd')
	X		printf ("%s %s\en", pos ? "Leaving" : "Entering", name);
	X	else /* type == 'f' */
	X		printf ("	%s\en", name);
	X	}
	X.fi
	X.SH AUTHOR
	XGary Perlman
	X.SH BUGS
	XThere are no diagnostics when directories cannot be searched.
SHAR_EOF
if test 1147 -ne "`wc -c < 'traverse.3'`"
then
	echo shar: error transmitting "'traverse.3'" '(should have been 1147 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'traverse.c'" '(1769 characters)'
if test -f 'traverse.c'
then
	echo shar: will not over-write existing file "'traverse.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'traverse.c'
	X/*LINTLIBRARY*/
	X#include <stdio.h>
	X#include <sys/types.h>
	X#include <sys/dir.h>
	X
	X#ifdef MAXNAMLEN
	X
	X#define	namedir(entry) (entry->d_name)
	X#define	MAXNAME 256
	X
	X#else
	X
	X#define	DIR	FILE
	X#define	MAXNAME (DIRSIZ+2)
	X#define	opendir(path) fopen (path, "r")
	X#define closedir(dirp) fclose (dirp)
	Xstruct direct *
	Xreaddir (dirp)
	XDIR 	*dirp;
	X	{
	X	static	struct	direct	entry;
	X	if (dirp == NULL) return (NULL);
	X	for (;;)
	X		{
	X		if (fread (&entry, sizeof (struct direct), 1, dirp) == 0) return (NULL);
	X		if (entry.d_ino) return (&entry);
	X		}
	X	}
	Xchar	*strncpy ();
	Xchar *
	Xnamedir (entry)
	Xstruct	direct	*entry;
	X	{
	X	static	char	name[MAXNAME];
	X	return (strncpy (name, entry->d_name, DIRSIZ));
	X	}
	X
	X#endif
	X
	X#include <sys/stat.h>
	X#define	isdir(path) (stat(path, &buf) ? 0 : (buf.st_mode&S_IFMT)==S_IFDIR)
	X
	Xtraverse (path, func)
	Xchar	*path;
	Xint 	(*func) ();
	X	{
	X	DIR 	*dirp;
	X	struct	direct	*entry;
	X	struct	stat	buf;
	X	int 	filetype = isdir (path) ? 'd' : 'f';
	X	(*func) (path, filetype, 0);
	X	if (filetype == 'd')
	X		{
	X		if (chdir (path) == 0)
	X			{
	X			if (dirp = opendir ("."))
	X				{
	X				while (entry = readdir (dirp))
	X					{
	X					char	name[MAXNAME];
	X					(void) strcpy (name, namedir (entry));
	X					if (strcmp(name, ".") && strcmp(name, ".."))
	X						traverse (name, func);
	X					}
	X				(void) closedir(dirp);
	X				}
	X			(void) chdir ("..");
	X			}
	X		}
	X	(*func) (path, filetype, 1);
	X	}
	X
	X#ifdef STANDALONE
	X
	Xstatic	Indent = 0;
	Xtryverse (file, type, pos)
	Xchar	*file;
	X	{
	X	int 	in;
	X	if (pos == 0)
	X		{
	X		for (in = 0; in < Indent; in++) putchar ('\t');
	X		if (type == 'd')
	X			{
	X			printf ("%s/\n", file);
	X			Indent++;
	X			}
	X		else puts (file);
	X		}
	X	else if (type == 'd') Indent--;
	X	}
	X
	Xmain (argc, argv) char **argv;
	X	{
	X	int 	tryverse ();
	X	char	*root = argc > 1 ? argv[1] : ".";
	X	traverse (root, tryverse);
	X	}
	X#endif
SHAR_EOF
if test 1769 -ne "`wc -c < 'traverse.c'`"
then
	echo shar: error transmitting "'traverse.c'" '(should have been 1769 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0


-- 
Herb Barad	[USC - Signal and Image Processing Institute]

USENET:

...!sdcrdcf!usc-oberon!brand!barad			or
...!{lbl-csam|trwrb|trwspp}!trwspf!herb			or
...!{lbl-csam|trwrb|trwspp}!trwspf!brand!barad

ARPANET:	barad%brand@usc-ecl.ARPA