[alt.sources] shar 3.43 part 1 of 2

rhg@cpsolv.CPS.COM (Richard H. Gumpertz) (09/09/90)

Submitted-by: rhg@cpsolv.cps.com
Archive-name: shar3.43/part01

Enclosed is shar 3.43 which has several bug fixes and improvements over shar
3.32.  Due to huge volumes of hate mail, Warren Tucker has given up posting
shar.  Nevertheless, I think it is important that this get out to the network,
especially because it responds to several of the criticisms raised.

PLEASE DO NOT SEND FLAMES ABOUT WHAT THIS PROGRAM DOES!  Constructive comments,
preferably in the form of SOURCE CODE, will be accepted.  This is a community
effort to produce code that many people find useful; if you don't want it then
don't use it.  The defaults are now such that few systems should choke on the
shar archives produced.

Changes since 3.32:

1.  Several bug fixes.

2.  Inverted the meaning of '-x'; the new default is to NOT overwrite.

3.  Added '-c' checking when unpacking so the recipient can force overwrites.

4.  Made '-L' work even with files not being overwritten.

5.  Added '-m' and changed the default behavior to not generate TOUCH commands.

6.  Added '-F'; the default is to suppress the extra 'X' at the beginning of
    each line unless it is needed (i.e., the first character of the line is
    already 'X' or is a non-graphic).

7.  Renamed '-b' and '-t' to '-B' and '-T', respectively.

8.  Added '-b<n>' for use with compression (calls compress with -b<n>).

9.  Renamed the temporary files used in unpacking from shar3_???_.tmp to
    _shar_???_.tmp.

10. Directories may now be passed to shar; a recursive directory walk is
    performed.  This feature may be disabled by compiling with -DNO_WALKTREE.

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is shar3.43, a shell archive (shar 3.43)
# made 09/08/1990 15:54 UTC by rhg@cpsolv
# Source directory /u/rhg/src/shar
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#  10777 -rw-r--r-- README
#   3090 -rw-r--r-- Makefile
#   7946 -rw-r--r-- shar.1
#   1515 -rw-r--r-- unshar.1
#   1365 -rw-r--r-- uushar.c
#   2882 -rw-r--r-- who@where.c
#  11348 -rw-r--r-- unshar.c
#  36835 -rw-r--r-- shar.c
#
# ============= README ==============
if test -f 'README' -a X"$1" != X"-c"; then
	echo 'x - skipping README (File already exists)'
else
echo 'x - extracting README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'README' &&
XThis file last revised Sat Aug 4 17:15:01 CDT 1990
X
XHere is shar 3.43, an updated version of shar 3.32, derived from 'shar2'.
XThis offering is the work of many people.  Thanks to wht@n4hgf.Mt-Park.GA.US
X(Warren Tucker), rhg@CPS.COM (Richard H. Gumpertz), colas@avahi.inria.fr
X(Colas Nahaboo), bill@netagw.com (Bill Aten), marks@rex.cs.tulane.edu, and
Xmaaaany others.
X
XThis version's shar:
X1) generates shell code which attempts to create missing directories
X2) generates shell code which will force overwriting of files when passed
X   the '-c' option.
X3) allows entire directories to be archived
X4) handle deviants sun, vax, pyramid, sequent, and SCO XENIX/UNIX
X   automatically; for system V systems I did not catch, add -DSYS5
X   to CFLAGS; for other BSD-like systems, add -DBSD42
X5) if unsharing system's touch is Sys V compatible (allows touch -m),
X   the unshar process restores file dates (-m switch)
X6) An archive name may be specified for inclusion in the header
X   of the shar files (-n switch)
X7) allows automatic generation of "Submitted-by: who@where" &
X   "Archive-name: <name>/part##" headers
X8) uses getopt; no good system library should be without a copy
X   but it is readily available (like look in unshar.c)
X9) includes other chrome-plated bells, whistles, and junque
X
XThis version's unshar:
X1) can change directory before unsharing
X2) can unshar from standard in, from a COLLECTION of shars,
X   from a file containing multiple concatenated shars,
X   or a mixture of shar files and concatenated-shar files.
X3) can pass the '-c' option on to the script being extracted.
X4) does not have a Social Security number.
X
X------------------------ shar  usage -----------------------------------
Xshar 3.43
Xusage: shar [ options ] file ...
X       shar -S [ options ]
X-V  produce "vanilla" shars demanding little of the unshar environment
X-v  verbose messages OFF while executing
X-m  restore file modification dates & times with "touch" commands
X-w  don't check with 'wc -c' after unpack
X-a  generate Submitted-by: & Archive-name: headers
X-nXXX   use XXX as the name of the archive (documentation)
X-s  override automatically determined submitter name
X-x  overwrite existing files without checking if they already exist
X-X  interactively overwrite existing files (NOT FOR NET SHARS)
X-B  treat all files as binary, use uuencode
X-T  treat all files as text (default)
X-C  compress and uuencode all files
X-bXX    pass -bXX (default 12) to compress when compressing (implies -C)
X-p  allow positional parameter options. The options "-B" and "-B"
X    and "-C" may be embedded, and files to the right of the
X    option will be processed in the specified mode
X-M  mixed mode. Determine if the files are text or
X    binary and archive correctly.
X-P  use temp files instead of pipes in the shar file
X-F  force the prefix character on every line (even if not required)
X-c  start the shar with a cut line
X-f  restore by filename only, rather than path
X-dXXX   use XXX to delimit the files in the shar
X-oXXX   (or -o XXX) output to file XXX.01 thru XXX.nn
X-lXX    limit output file size to XXk bytes (but don't split files)
X-LXX    limit output file size to XXk bytes (may split files)
X-S      read files to wrap from stdin, ignoring argument line
X
XThe -S option reads filenames one per line from stdin; input
Xformat must be similar to 'find' output, except that if -p
Xis specified, -B, -T or -C may be used (on lines by themselves)
Xe.g., find . -type f -print | sort | shar -C -l50 -o /tmp/big
X
XThe 'o' option is required if the 'l' or 'L' option is used
XThe 'n' option is required if the 'a' option is used
X
X-a generates sharname/part## headers. If the -a argument contains
Xa '/', then /part is not appended
XThe automatic submitter name is trivial: essentially `whoami`@`uname`
X
X------------------------ unshar usage -----------------------------------
XUnshar has no usage built in.  It has default actions when invoked
Xwith no arguments (read from stdin).
X
XUsage:     unshar [ -d directory ] [ -c ] [ -e | -E exit_line ] [ files ... ]
X
X      The -c flag is passed through to the shell as a parameter to the script
X      It can unshar shar files concatenated in one file, with the
X      the "-e" command, which separates files by recognizing the
X      "exit 0" string at the beginning of a line
X
X      (The -E string option allows you to specify this string, thus
X      -e is equivalent to -E "exit 0")
X
X      The -d flag tells unshar to change directory before unsharing
X
X
X--------------------- history -----------------------------------------
XChanges since 3.11: kudos to rhg@CPS.COM (Richard H. Gumpertz)
X
X1.  The -l switch still specifies a maximum size for the generated
X    shar files, but now it prevents files from spanning shar parts.
X    Shars generated using this method may be unpacked in any order.
X
X2.  The old -l switch functionality is precisely emulated by using the
X    the -L switch.  That is, archived files may be split across parts.
X    Shars generated using this method must still be unpacked in order.
X
X3.  The -C switch causes files to be compressed, then uuencoded.
X    Unpacking reverses the process.
X
X4.  The -P causes the shar to use temp files instead of pipes in
X    the unshar process.
X
X5.  The -f causes files to be resotred by name only (i.e., strip
X    directory portion of input filenames before placing the name
X    into the shar.
X
X
XChanges since 3.20: kudos to colas@avahi.inria.fr (Colas Nahaboo)
X
X1.  The Archived-name: header no longer uses "/part" if there is
X    a "/" in the -n name.  Thus
X        -n xyzzy                     procduces:
X                                     xyzzy/part01
X                                     xyzzy/part02
X
X        -n xyzzy/patch               procduces:
X                                     xyzzy/patch01
X                                     xyzzy/patch02
X
X        -n xyzzy/patch01.            procduces:
X                                     xyzzy/patch01.01
X                                     xyzzy/patch01.02
X2.  The Archive-name part number other than part01 had no leading zero
X    in the number.
X
X3.  The "Submitted-by:" header was missing the hyphen (minus for olde
X    UNIX hackres).
X
X4.  The unshar program may now unshar a whole mailbox or concatenation
X    of shar files.
X
X    -C "string" looks for "string" at the beginning of the line to
X       break the file into individual shar files
X    -c is equivalent to -C "exit 0"
X
X    This of course will only work if there is something in the shar
X    file recognizable to terminate the shar.  Some shars dont have
X    "exit 0" at the end.  However, a clue: most/many .signatures have
X    "--" on a line right before them.
X
X5.  Unshar -d (change directory) no longer makes argv files unreachable.
X    I had never used the feature until the other day.  I guess the
X    author has used in only for unsharing from stdin.
X
XChanges since 3.21: thanks to Adri Verhoef, <a3@rivm.UUCP>
X
X1.  Some vaxen do not run BSD.  I guess I knew this, but -er-
X    here is Adri's note:
X> Hi Warren,
X> 
X>   I encountered a problem trying to get 'shar3.21' to compile on System V
X> on a vax.  Yes, can you believe it?  We run System V Release 3.0 on VAXen!
X> The shar3.21 code assumes that you are BSD if you're on a vax.  This is not
X> always true!  What I did to get the code compiled on System V, was:
X> (+) edit the Makefile and add -DSYS5 to CFLAGS.
X> (+) edit all the C-source files to circumcise compiler warnings
X>     ("SYS5 redefined").
X> 
X
XHe made a suggestion about having a localize.sh edit a distribution
XMakefile, but for now, I'll just suggest you add -DSYS5 to CFLAGS 
Xmanually.
X
X2.  jhd@irfu.se (Jan Dj{rv, sorry about the screwed up character
X    translation, Jan) wrote man pages.  Thanks!
X
XChanges since 3.22: thanks to Dennis Boylan <dennis@nanovx>
X
X1.  The new -S option allows the list of files to be packed
X    to be read from the standard input rather than from the
X    command line.
X
X2.  A few purist checks were made to ensure fork() or malloc()
X    doesn't fail and excite the "if 20 hours of your time is
X    free then why isn't 200?" crowd (who probably will never see
X    this revision anyway :-))
X
XChanges since 3.23:
X
X1.  The -V mode was added.
X
X2.  Altos doesn't like the '@' in filenames.  The filename format
X    was changed.  Thanks to rhg@cps.com.
X
XChanges since 3.24:
X
X1.  Man pages were revised by gam@netcom (Gordon Moffet). Thanks.
X
X2.  When -L was specified, the "Starting ..." message was not
Xproduced on standard error (with or without -v).
X
X3.  When using -X, the 'not for net' warning was printed on standard
Xoutput rather thsn standard error.
X
X4.  marks@rex.cs.tulane.edu reccommends adding -F 5000 to the load
X    line of unshar when using on XENIX 286 to avoid stack overflow
X    core dumps.  I added this information to an excellkent remake
X    of the Makefile by bill@netagw.com.
X
XChanges since 3.25:
X
X1.  Fixed one minor bug with -a/-n.  The period supplied when a
X    slash appears in the -n name was omitted.  This is a hatefully
X    small bug to fix and reissue a whole release, but
X    a) several new names are on the sharlist now and they have
X       only 3.24 to work with,
X    b) this will surely sync us all up, and
X    c) I think it will put shar to bed for a while ("no known bugs
X       at this ti ... bus error core dumped").
X
XChanges since 3.27:
X
X1.  The unshar-time test for a touch -m facility now greps for
X    'mmdd', not '[-amc]', making it more universally successful.
X
X2.  NOTE:  there is still a problem with -n arguments using
X    a 'x/y' construct, but I don't know how to properly generalize
X    it so you'll have to edit shars made with some uses of -a
X    with -n x/y.
X
X3.  This is surely my last work on this.  It does everything
X    I needed and more.  Thanks for all the help and suggestions.
X    It seems as though we didn't precipitate 'death of the shar'
X    after all :-) :-) :-).
X
XChanges since 3.32:
X
X1.  Several bug fixes.
X
X2.  Inverted the meaning of '-x'; the new default is to NOT overwrite.
X
X3.  Added '-c' checking when unpacking so the recipient can force overwrites.
X
X4.  Made '-L' work even with files not being overwritten.
X
X5.  Added '-m' and changed the default behavior to not generate TOUCH commands.
X
X6.  Added '-F'; the default is to suppress the extra 'X' at the beginning of
X    each line unless it is needed (i.e., the first character of the line is
X    already 'X' or is a non-graphic).
X
X7.  Renamed '-b' and '-t' to '-B' and '-T', respectively.
X
X8.  Added '-b<n>' for use with compression (calls compress with -b<n>).
X
X9.  Renamed the temporary files used in unpacking from shar3_???_.tmp to
X    _shar_???_.tmp.
X
X10. Directories may now be passed to shar; a recursive directory walk is
X    performed.  This feature may be disabled by compiling with -DNO_WALKTREE.
SHAR_EOF
chmod 0644 README ||
echo 'restore of README failed'
Wc_c="`wc -c < 'README'`"
test 10777 -eq "$Wc_c" ||
	echo 'README: original size 10777, current size' "$Wc_c"
fi
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
	echo 'x - skipping Makefile (File already exists)'
else
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
X#  makefile for shar
X#
X# $Header: /u/rhg/src/shar/Makefile,v 3.43 90/08/13 08:10:03 rhg Exp $
X#
X#+:EDITS:
X#:08-07-1990-21:25-rhg@cps.com-compress man pages if MANEXT ends with .Z
X#:08-05-1990-23:50-rhg@cps.com-add post and compressed.
X#:08-05-1990-12:19-rhg@cps.com-add LIBS and -ldirent
X#:08-04-1990-18:51-rhg@cps.com-add CC, LD; move strip; reorder chgrp/chown.
X#:05-14-1990-17:33-wht@n4hgf-add -F 5000 for XENIX 286
X#:05-14-1990-17:32-bill@netagw.com-expanded Makefile
X#:03-28-1990-14:54-wht@n4hgf-for 3.10, add who@where.c
X
XBINDIR	= /usr/local/bin
XOWNER	= bin
XGROUP	= bin
XBINMODE	= 0755
XMANDIR	= /usr/man/man1
XMANEXT	= 1
XMANOWN	= bin
XMANGRP	= bin
XMANMODE	= 0644
X
XCC	= cc
XLD	= ${CC}
X
X# If you don't have Doug Gwyn's dirent routines or equivalent, then remove
X# -ldirent from LIBS and add -DNO_WALKTREE to CFLAGS.  All you will give up
X# is the ability to shar directorys without using "find ... -type f | shar -S".
X# Note that many systems have the equivalent of the dirent library built into
X# the standard C library.  For such systems, just remove -ldirent from LIBS.
X# (note by RHG@CPS.COM: I don't know which systems listed below are like that.)
X
X# For VAX, PYRAMID, SEQUENT, AT&T 3B1/7300
XCFLAGS	= -O 
XLDFLAGS	=
XLIBS	= -ldirent
X
X# For SUN and SCO XENIX/UNIX 386
X#CFLAGS	= -O 
X#LDFLAGS	=
X#LIBS	=
X
X# For SCO XENIX 286
X#CFLAGS	= -O 
X#LDFLAGS	= -F 5000
X#LIBS	= -ldirent
X
X# For other System V systems I did not catch
X#CFLAGS	= -O -DSYS5
X#LDFLAGS	=
X#LIBS	= -ldirent
X
X# For other BSD-like systems
X#CFLAGS	= -O -DBSD42
X#LDFLAGS	=
X#LIBS	=
X
XSOURCES	= README Makefile shar.1 unshar.1 uushar.c who@where.c unshar.c shar.c
X
XSHAR	= shar.o uushar.o who@where.o
XUNSHAR	= unshar.o
X
Xall: shar unshar
X
Xshar: ${SHAR}
X	${LD} ${LDFLAGS} ${SHAR} ${LIBS} -o shar
X
Xunshar : ${UNSHAR}
X	${LD} ${LDFLAGS} ${UNSHAR} ${LIBS} -o unshar
X
Xshar.o : shar.c
X	${CC} ${CFLAGS} -c shar.c
X
Xunshar.o : unshar.c
X	${CC} ${CFLAGS} -c unshar.c
X
Xuushar.o : uushar.c
X	${CC} ${CFLAGS} -c uushar.c
X
Xwho@where.o : who@where.c
X	${CC} ${CFLAGS} -c who@where.c
X
Xinstall : shar unshar
X	strip shar unshar
X	cp shar unshar ${BINDIR}
X	chmod ${BINMODE} ${BINDIR}/shar ${BINDIR}/unshar
X	chgrp ${GROUP} ${BINDIR}/shar ${BINDIR}/unshar
X	chown ${OWNER} ${BINDIR}/shar ${BINDIR}/unshar
X	if expr "${MANEXT}" : ".*\.Z$$" >/dev/null; then \
X		compress -b14 < shar.1   > ${MANDIR}/shar.${MANEXT}; \
X		compress -b14 < unshar.1 > ${MANDIR}/unshar.${MANEXT}; \
X	else \
X		cp shar.1   ${MANDIR}/shar.${MANEXT}; \
X		cp unshar.1 ${MANDIR}/unshar.${MANEXT}; \
X	fi
X	chmod ${MANMODE} ${MANDIR}/shar.${MANEXT} ${MANDIR}/unshar.${MANEXT}
X	chgrp ${MANGRP}  ${MANDIR}/shar.${MANEXT} ${MANDIR}/unshar.${MANEXT}
X	chown ${MANOWN}  ${MANDIR}/shar.${MANEXT} ${MANDIR}/unshar.${MANEXT}
X
Xclean :
X	rm -f shar unshar *.o core
X
XSETV =	X="`head -1 shar.c`"; \
X	V=`expr "$$X" : 'char \*revision = "\([1-9][0-9]*\.[0-9.a-zA-Z]*\)";$$'`;
X
Xpost : ${SOURCES}
X	${SETV} test -n "$$V" && ( \
X	rm -f shar$$V.[0-9][0-9]; \
X	shar -l50 -acF -n "shar$$V" -o "shar$$V" ${SOURCES} )
X
Xcompressed : ${SOURCES}
X	${SETV} test -n "$$V" && \
X	shar -acFm -b16 -n "shar$$V" > "shar$$V" ${SOURCES}
X
SHAR_EOF
chmod 0644 Makefile ||
echo 'restore of Makefile failed'
Wc_c="`wc -c < 'Makefile'`"
test 3090 -eq "$Wc_c" ||
	echo 'Makefile: original size 3090, current size' "$Wc_c"
fi
# ============= shar.1 ==============
if test -f 'shar.1' -a X"$1" != X"-c"; then
	echo 'x - skipping shar.1 (File already exists)'
else
echo 'x - extracting shar.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'shar.1' &&
X.TH SHAR 1 "August 12, 1990"
X.SH NAME
Xshar \- create shell archives
X.SH SYNOPSIS
X.nf
Xshar [ options ] file ...
Xshar \-S [ options ]
X.fi
X.SH DESCRIPTION
XShar
Xcreates "shell archives" (or shar files) which are in text format
Xand can be mailed. These files may be unpacked later by executing them
Xwith /bin/sh. The resulting archive is sent to standard out unless the
X\f2\-o\f1 option is given.  A wide range of features provide extensive
Xflexibility in manufacturing shars and in specifying shar "smartness."
XArchives may be "vanilla" or comprehensive.
XThis manual page reflects shar version 3.43.
X.SS OPTIONS
X.PP
XOptions can be given in any order. Some options depend on each other:
X.nf
X	The \f2\-o\f1 option is required if the \f2\-l\f1 or \f2\-L\f1 option is used.
X	The \f2\-n\f1 option is required if the \f2\-a\f1 option is used.
X	See \f2\-V\f1 below.
X.fi
X.IP "\f2\-V\f1"
XProduce "vanilla" shars which rely only upon the existence of sed and
Xecho in the unsharing environment.  In addition, "if test" must also be
Xsupported if the \f2\-X\f1 option is used.  The \f2\-V\f1 silently
Xdisables options offensive to the "network cop" (or "brown shirt"), but
Xdoes warn you if it is specified with \f2\-B\f1, \f2\-C\f1, \f2\-p\f1
Xor \f2\-M\f1 (any of which does or might require uudecode or compress in
Xthe unsharing environment).
X.IP "\f2\-v\f1"
XVerbose OFF. Disables the inclusion of comments to be output when the archive
Xis unpacked.
X.IP "\f2\-w\f1"
XDo NOT check with 'wc \-c' after unpack. The default is to check.
X.IP "\f2\-n\f1 name"
XName of archive to be included in the header of the shar files.
XSee the \f2\-a\f1 switch.
X.IP "\f2\-a\f1"
XAllows automatic generation of headers:
X.nf
X	Submitted-by: who@where
X	Archive-name: <name>/part##
X.fi
XThe <name> must be given with the \f2\-n\f1 switch.
XIf name includes a '/' "/part" isn't used. Thus:
X.RS 10m
X.nf
X.ta 30m
X\-n xyzzy	produces:
X	xyzzy/part01
X	xyzzy/part02
X
X\-n xyzzy/patch	produces:
X	xyzzy/patch01
X	xyzzy/patch02
X
X\-n xyzzy/patch01.	produces:
X	xyzzy/patch01.01
X	xyzzy/patch01.02
X.RE
X.fi
X.IP ""
XThe who@where can be
Xexplicitly stated with the \f2\-s\f1 switch if the default isn't apropriate.
XWho@where is essentially built as `whoami`@`uname`.
X.IP "\f2\-s\f1 who@where"
XOverride automatically determined submitter name.
X.IP "\f2\-x\f1"
XOverwrite existing files without checking.
XIf neither \f2\-x\f1 nor \f2\-X\f1 is specified, the unpack will
Xcheck for and
Xnot overwrite existing files when unpacking the archive
X(unless '\-c' is passed as a parameter to the script when unpacking).
X.IP "\f2\-X\f1"
XInteractively overwrite existing files
X(DO NOT USE FOR SHARS SUBMITTED TO THE NET).
X.IP "\f2\-B\f1"
XTreat all files as binary, use uuencode prior to packing. This increases the
Xsize of the archive. The recipient must have uudecode in order to unpack.
X(USE OF UUENCODE IS NOT APPRECIATED BY MANY ON THE NET).
X.IP "\f2\-T\f1"
XTreat all files as text (default).
X.IP "\f2\-C\f1"
XCompress and uuencode all files prior to packing. The recipient must have
Xuudecode and uncompress in order to unpack
X(USE OF UUENCODE AND COMPRESS IS NOT APPRECIATED BY MANY ON THE NET).
X.IP "\f2\-m\f1"
XGenerate 'touch' commands to restore the file modification dates when
Xunpacking files from the archive.
X.IP "\f2\-p\f1"
XAllow positional parameter options. The options "\f2\-B\f1" and "\f2\-T\f1"
Xand "\f2\-C\f1" may be embedded, and files to the right of the
Xoption will be processed in the specified mode.
X.IP "\f2\-b\f1 X"
XWhen doing compression, use '\-bX' as a parameter to compress.
XThe \f2\-B\f1 options turns on the \f2\-C\f1 option by default.
X.IP "\f2\-M\f1"
XMixed mode. Determine if the files are text or binary and archive correctly.
XFiles found to be binary are uudecoded prior to packing
X(USE OF UUENCODE IS NOT APPRECIATED BY MANY ON THE NET).
X.IP "\f2\-P\f1"
XUse temporary files instead of pipes in the shar file.
X.IP "\f2\-c\f1"
XStart the shar with a cut line. A line saying 'Cut here' is placed at the
Xstart of each output file.
X.IP "\f2\-f\f1"
XRestore by filename only, rather than path. This option causes only file
Xnames to be used, which is useful when building a shar from several
Xdirectories, or another directory.  Note that if a directory name is passed
Xto shar, the substructure of that directory will be restored whether \f2\-f\f1
Xis specified or not.
X.IP "\f2\-d\f1 XXX"
XUse XXX to delimit the files in the shar instead of SHAR_EOF.
XThis is for those who want to personalize their shar files.
X.IP "\f2\-F\f1"
XForces the prefix character (normally 'X' unless the parameter to the \f2\-d\f1
Xoption starts with 'X') to be prepended to every line even if
Xnot required.  This option may slightly increase the size of the archive,
Xespecially if \f2\-B\f1 or \f2\-C\f1 is used.
X.IP "\f2\-o\f1 XXX"
XSave the archive to files XXX.01 thru XXX.nn instead of standard out.
XMust be used when the \f2\-l\f1 or the \f2\-L\f1 switches are used
X.IP "\f2\-l\f1 XX"
XLimit the output file size to XXk bytes but don't split input files.
X.IP "\f2\-L\f1 XX"
XLimit output file size to XXk bytes and split files if necessary. The archives
Xcreated with this option must be unpacked in correct order.
X.IP "\f2\-S\f1"
XRead list of files to be packed from the standard input rather than
Xfrom the command line.  Input must be in a form similar to
Xthat generated by the find command, one filename per line.  This
Xswitch is especially useful when the command line will not hold
Xthe list of files to be packed. For example:
X.nf
X
Xfind . \-type f \-print | sort | shar \-S \-C \-L50 \-o /tmp/big
X
X.fi
XIf \f2\-p\f1 is specified on the command line, then the 
Xoptions "\f2\-B\f1" and "\f2\-T\f1" and "\f2\-C\f1" may be included
Xin the standard input (on a line separate from filenames).
XThe maximum number of lines of standard input, file names
Xand options, may not exceed 1024.
X.SH EXAMPLES
X.nf
X.ta 37m
Xshar *.c > cprog.shar	# all C prog sources
Xshar \-v *.[ch] > cprog.shar	# non-verbose, .c and .h files
Xshar \-B \-l28 \-oarc.sh *.arc	# all binary .arc files, into
X	# files arc.sh.01 thru arc.sh.NN
Xshar \-f /lcl/src/u*.c > u.sh	# use only the filenames
X.ta
X.fi
X.SH WARNINGS
X.PP
XNo chmod or touch is ever generated for directories created when unpacking.
XThus, if a directory is given to shar, the protection and
Xmodification dates of corresponding unpacked directory
Xmay not match those of the original.
X.PP
XIf a directory is passed to shar, it may be scanned more than once.  Therefore,
Xone should be careful not change the directory while shar is running.
X.PP
XBe careful that the output file(s) are not included in the inputs or shar
Xmay loop until the disk fills up.  Be particularly careful when a directory
Xis passed to shar that the output files are not in that directory
X(or a subdirectory of that directory).
X.PP
XUse of the \f2\-B\f1, \f2\-M\f1 or \f2\-C\f1 may slow the archive process
Xconsiderably, depending on the number of files.
X.PP
XUse of \f2\-X\f1 produces shars which \f2WILL\f1 cause problems
Xwith many unshar procedures.  Use this feature only for archives
Xto be passed among agreeable parties.  Certainly, \f2\-X\f1 is NOT
Xfor shell archives which are to be submitted to Usenet.
XUsage of \f2\-B\f1 or \f2\-C\f1 in net shars will cause you to
Xbe flamed off the earth.
XUsing \f2\-m\f1 or not using \f2\-F\f1 may also get you occasional complaints.
X.SH SEE ALSO
X.PP 
Xunshar(1)
X.SH DIAGNOSTICS
X.PP
XError messages for illegal or incompatible options,
Xfor non-regular, missing or inaccessible files or for (unlikely)
Xmemory allocation failure.
X.SH AUTHORS
X.nf
Xshar3 is a derived work based on the efforts of:
Xdecvax!microsof!uw-beave!jim (James Gosling at CMU)
XMichael A. Thompson, Dalhousie University, Halifax, N.S., Canada
Xdavidsen@sixhub (Bill Davidsen)
Xrhg@CPS.COM (Richard H. Gumpertz)
Xcolas@avahi.inria.fr (Colas Nahaboo)
Xbill@netagw.com (Bill Aten)
Xdennis%nanovx@gatech.edu (Dennis Boylan)
Xwht%n4hgf@gatech.edu (Warren Tucker)
X(other anonymous persons)
X
Xman pages:
Xjhd@irfu.se (Jan Dj{rv)
X.fi
SHAR_EOF
chmod 0644 shar.1 ||
echo 'restore of shar.1 failed'
Wc_c="`wc -c < 'shar.1'`"
test 7946 -eq "$Wc_c" ||
	echo 'shar.1: original size 7946, current size' "$Wc_c"
fi
# ============= unshar.1 ==============
if test -f 'unshar.1' -a X"$1" != X"-c"; then
	echo 'x - skipping unshar.1 (File already exists)'
else
echo 'x - extracting unshar.1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'unshar.1' &&
X.TH UNSHAR 1 "August 12, 1990"
X.SH NAME
Xunshar \- unpack a shar file
X.SH SYNOPSIS
Xunshar [ \f2\-d\f1 directory ] [ \f2\-c\f1 ] [ \f2\-e\f1 | \f2\-E\f1 exit_line ] [ file ... ]
X.SH DESCRIPTION
X.PP
XUnshar scans mail messages looking for the start of a shell archive. It
Xthen passes the archive through a copy of the shell to unpack it. It
Xwill accept multiple files. If no files are given, standard input is used.
X.PP
XThe \f2\-d\f1 option tells unshar to change directory before unpacking
Xany files.
X.PP
XThe \f2\-c\f1 option is passed through to 'sh' as a parameter to the unpacked
Xscript.  Many archive shar scripts (including those produced by
Xshar 3.40 and newer)
Xuse this to indicate that existing files should be overwritten.
X.PP
XUnshar can unpack shar files that are concatenated in one file with the
X\f2\-e\f1 option, which separates files by recognizing the "exit 0" string
Xat the beginning of a line. 
XThe \f2\-E\f1 option allows you to specify the string that separates archives
Xif "exit 0" isn't appropriate. (Hint: most .signatures have a "\-\-" on a line
Xright before them). \f2\-e\f1 is equivalent to \f2\-E "exit 0"\f1.
X.SH SEE ALSO
Xshar(1)
X.SH DIAGNOSTICS
XAny message from the shell may be displayed.
X.SH AUTHORS
X.nf
XMichael Mauldin at Carnegie-Mellon University
Xguido@mcvax (Guido van Rossum at CWI, Amsterdam)
Xdavidsen@sixhub.uuxp (Bill Davidsen)
Xwht%n4hgf@gatech.edu (Warren Tucker)
Xrhg@CPS.COM (Richard H. Gumpertz)
Xcolas@avahi.inria.fr (Colas Nahaboo)
X
Xman pages:
Xjhd@irfu.se (Jan Dj{rv)
X.fi
X.PP
SHAR_EOF
chmod 0644 unshar.1 ||
echo 'restore of unshar.1 failed'
Wc_c="`wc -c < 'unshar.1'`"
test 1515 -eq "$Wc_c" ||
	echo 'unshar.1: original size 1515, current size' "$Wc_c"
fi
# ============= uushar.c ==============
if test -f 'uushar.c' -a X"$1" != X"-c"; then
	echo 'x - skipping uushar.c (File already exists)'
else
echo 'x - extracting uushar.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'uushar.c' &&
X/* $Header: /u/rhg/src/shar/uushar.c,v 3.43 90/08/13 07:50:57 rhg Exp $ */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X/* ENC is the basic 1 character encoding function to make a char printing */
X#if 1 /* Richard H. Gumpertz (RHG@CPS.COM), 24 April 1990 */
X#define ENC(c) ((((c) + 077) & 077) + 041)
X#else /* RHG */
X#define ENC(c) ((((c) & 077) + ' ') | ((c & 077) == 0 ? 0100 : 0))
X#endif /* RHG */
X
Xencode (in, out)
X    FILE *in;
X    FILE *out;
X{
X    char  buf[80];
X    int  i, n;
X
X    for (;;)
X    {
X    /* 1 (up to) 45 character line */
X	n = fr (in, buf, 45);
X	putc (ENC (n), out);
X
X	for (i = 0; i < n; i += 3)
X	    outdec (&buf[i], out);
X
X	putc ('\n', out);
X	if (n <= 0)
X	    break;
X    }
X}
X
X/*
X * output one group of 3 bytes, pointed at by p, on file f.
X */
Xoutdec (p, f)
X    char *p;
X    FILE *f;
X{
X    int  c1, c2, c3, c4;
X
X    c1 = *p >> 2;
X    c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
X    c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
X    c4 = p[2] & 077;
X    putc (ENC (c1), f);
X    putc (ENC (c2), f);
X    putc (ENC (c3), f);
X    putc (ENC (c4), f);
X}
X
X/* fr: like read but stdio */
Xint
X     fr (fp, buf, cnt)
X    FILE *fp;
X    char *buf;
X    int  cnt;
X{
X    int  c, i;
X
X    for (i = 0; i < cnt; i++)
X    {
X	c = getc (fp);
X	if (c == EOF)
X	    return (i);
X	buf[i] = c;
X    }
X    return (cnt);
X}
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 uushar.c ||
echo 'restore of uushar.c failed'
Wc_c="`wc -c < 'uushar.c'`"
test 1365 -eq "$Wc_c" ||
	echo 'uushar.c: original size 1365, current size' "$Wc_c"
fi
# ============= who@where.c ==============
if test -f 'who@where.c' -a X"$1" != X"-c"; then
	echo 'x - skipping who@where.c (File already exists)'
else
echo 'x - extracting who@where.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'who@where.c' &&
X/* $Header: /u/rhg/src/shar/who@where.c,v 3.43 90/08/13 07:51:00 rhg Exp $ */
X
X/*+-------------------------------------------------------------------------
X	who@where.c - find out who i am & where i am
X	...!gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu)
X--------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:04-03-1990-19:55-wht@n4hgf-get rid of complicated who_am_i */
X/*:04-01-1990-13:30-pat@rwing-use utsname.nodename instead of sysname */
X/*:04-02-1990-12:12-wht@n4hgf-sigh... some pwd.h dont declare functions */
X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
X/*:03-28-1990-15:24-wht@n4hgf-creation */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <pwd.h>
X
X/* assume system v unless otherwise fixed */
X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42) && !defined(SYS5)
X#define BSD42
X#endif
X#if defined(sun)	/* this miscreant doesn't exactly fit BSD or SYSV */
X#undef BSD42
X#undef SYS5
X#endif
X#if !defined(BSD42) && !defined(sun) && !defined(SYS5)
X#define SYS5
X#endif
X
X#if defined(sun) || defined(BSD42)
X#define strchr	index
X#define strrchr	rindex
X#endif
X
X#if !defined(SYS5) || defined(sun)
X#include <sys/time.h>
Xextern int errno;
X#else
X#include <sys/utsname.h>
X#include <time.h>
X#endif	/* system dependencies */
X
X/*+-------------------------------------------------------------------------
X	who_am_i() - get user name
X--------------------------------------------------------------------------*/
Xchar *
Xwho_am_i()
X{
X	struct passwd *getpwuid();
X	struct passwd *passwd;
X	passwd = getpwuid(getuid());
X	(void)endpwent();
X	if(passwd == (struct passwd *)0)
X		return("???");
X	return(passwd->pw_name);
X
X}	/* end of who_am_i */
X
X/*+-------------------------------------------------------------------------
X	where_am_i() - do uname, gethostname, or read file (/etc/systemid)
X--------------------------------------------------------------------------*/
Xchar *
Xwhere_am_i()
X{
X#if defined(M_SYS5)	/* SCO UNIX or XENIX */
XFILE *fpsid = fopen("/etc/systemid","r");
Xstatic char s20[20];
X	if(!fpsid)
X		return("???");
X	fgets(s20,sizeof(s20),fpsid);
X	fclose(fpsid);
X	s20[strlen(s20) - 1] = 0;
X	return(s20);
X#else /* M_SYS5 */
X#if defined(SYS5)
Xstatic struct utsname where_i_am;
X	uname(&where_i_am);
X	return(where_i_am.nodename);
X#else /* SYS5 */
Xstatic char where_i_am[64];
X	gethostname(where_i_am,sizeof(where_i_am));
X	return(where_i_am);
X#endif /* SYS5 */
X#endif /* M_SYS5 */
X}	/* end of where_am_i */
X
X/*+-------------------------------------------------------------------------
X	who_where(buf)
X--------------------------------------------------------------------------*/
Xchar *
Xwho_where(buf)
Xchar *buf;
X{
Xstatic char ww[64];
X
X	if(!buf)
X		buf = ww;
X	strcpy(buf,who_am_i());
X	strcat(buf,"@");
X	strcat(buf,where_am_i());
X}	/* end of who_where */
X
X/* vi: set tabstop=4 shiftwidth=4: */
X/* end of who@where.c */
SHAR_EOF
chmod 0644 who@where.c ||
echo 'restore of who@where.c failed'
Wc_c="`wc -c < 'who@where.c'`"
test 2882 -eq "$Wc_c" ||
	echo 'who@where.c: original size 2882, current size' "$Wc_c"
fi
# ============= unshar.c ==============
if test -f 'unshar.c' -a X"$1" != X"-c"; then
	echo 'x - skipping unshar.c (File already exists)'
else
echo 'x - extracting unshar.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'unshar.c' &&
Xchar *revision = "3.43";
Xchar RCS_ID[] = "$Header: /u/rhg/src/shar/unshar.c,v 3.43 90/08/13 07:50:52 rhg Exp $";
X/****************************************************************
X * unshar.c: Unpackage one or more shell archive files
X *
X * Usage:     unshar [ -c ] [ -e | -E exit_line ] [ -d directory ] [ file ... ]
X *
X * Description:	unshar is a filter which removes the front part
X *		of  a file and passes the rest to the 'sh' command.
X *		It understands phrases like "cut here", and also
X *		knows about shell comment characters and the Unix
X *		commands "echo", "cat", and "sed".
X *
X *		The -c flag is passed through to the shell as a parameter to the script
X *
X *		It can unshar shar files concatenated in one file, with the
X *		the "-e" command, which separates files by recognizing the
X *		"exit 0" string at the beginning of a line
X *
X *		(The -E string option allows you to specify this string, thus
X *		-e is equivalent to -E "exit 0")
X *
X *		The -d flag tells unshar to change directory before unsharing
X *
X * HISTORY
X *  4-Aug-90  Richard H. Gumpertz (rhg@cps.com)
X *		renamed -c and -C to -e and -E and added -c flag (passed through to sh)
X * 19-Apr-90  Colas Nahaboo (colas@mirsa.inria.fr)
X *		added -c and -C flags to read from concatenated archives
X *  1-Feb-85  Guido van Rossum (guido@mcvax) at CWI, Amsterdam
X *		Added missing 'quit' routine;
X *		added -d flag to change to directory first;
X *		added filter mode (read stdin when no arguments);
X *		added 'getopt' to get flags (makes it self-contained).
X * 29-Jan-85  Michael Mauldin (mlm) at Carnegie-Mellon University
X *		Created.
X ****************************************************************/
X/*+:EDITS:*/
X/*:08-04-1990-15:54-rhg@cps.com-changes listed above (-c/-C => -e/-E, new -c)
X/*:05-05-1990-01:37-relay.EU.net!rivm!a3-dont assume vax is running BSD */
X/*:04-19-1990-15:20-wht@n4hgf-fix so -d doesnt make argv files unreachable */
X/*:04-19-1990-15:06-wht@n4hgf-colas@mirsa patches had expanded tabs */
X/*:04-10-1990-22:02-wht@n4hgf-stdin failed sometimes-can not seek on pipe */
X
X#include <stdio.h>
X#define EOL '\n'
X
X#if (defined(pyr) || defined(sun) || defined(BSD42) || \
X defined(vax) || defined(sequent)) && !defined(SYS5)
X#define strchr	index
X#undef USE_GETCWD
Xchar *getwd();
X#else
X#define USE_GETCWD
Xchar *getcwd();
X#endif
X
Xchar *strchr();
X
Xextern char *optarg;
Xextern int optind;
X
Xint c_flag = 0;
Xint continue_reading = 0;
Xchar *exit_string = "exit 0";
Xint exit_string_length;
Xchar argvdir[1024];
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int i,ch;
X	FILE *in;
X	char s1024[1024];
X
X	setbuf(stdout,NULL);
X	setbuf(stderr,NULL);
X
X#ifdef USE_GETCWD
X	if(!getcwd(argvdir,sizeof(argvdir)))
X	{
X		perror("cannot get current directory name");
X		exit(1);
X	}
X#else
X	argvdir[0] = 0;
X	if(!getwd(argvdir))
X	{
X		if(argvdir[0])
X			fprintf(stderr,"%s\n",argvdir);
X		else
X			printf(stderr,"cannot get current directory name\n");
X		exit(1);
X	}
X#endif
X
X
X	/* Process options */
X
X	while((ch = getopt(argc,argv,"cd:eE:")) != EOF)
X	{
X		switch(ch)
X		{
X		case 'c':
X			c_flag = 1;
X			break;
X		case 'd':
X			if(chdir(optarg) == -1)
X			{
X				fprintf(stderr,"unshar: cannot chdir to '%s'\n",optarg);
X				exit(2);
X			}
X			break;
X		case 'E':
X			exit_string = optarg;
X		case 'e':
X			continue_reading = 1;
X			exit_string_length = strlen(exit_string);
X			break;
X		default:
X			quit(2,"Usage: unshar [-c] [-e | -E exit_line] [-d directory] [file ...]\n");
X		}
X	}
X
X	if(optind < argc)
X	{
X		for(i= optind; i < argc; ++i)
X		{
X			if(argv[i][0] == '/') {
X				strcpy(s1024,argv[i]);
X			} else {
X				strcpy(s1024,argvdir);
X				strcat(s1024,"/");
X				strcat(s1024,argv[i]);
X			}
X			if(!(in = fopen(s1024,"r")))
X			{
X				perror(s1024);
X				exit(1);
X			}
X			process(s1024,in);
X			fclose(in);
X		}
X	}
X	else
X	{
X		sprintf(s1024,"/tmp/unsh.%05d",getpid());
X		unlink(s1024);
X		if(!(in = fopen(s1024,"w+")))
X		{
X			fprintf(stderr,"cannot open temp file '%s'\n",s1024);
X			exit(1);
X		}
X		unlink(s1024);	/* don't try this with MSDOS, sports fans */
X		while(i = fread(s1024,1,sizeof(s1024),stdin))
X			fwrite(s1024,i,1,in);
X		rewind(in);
X		process("standard input",in);
X		fclose(in);
X	}
X
X	exit(0);
X}
X
X
Xprocess(name,in)
Xchar *name;
XFILE *in;
X{
X	char buffer[8196];
X	char ch;
X	FILE *shpr,*popen();
X	long current_position = 0;
X	char *more_to_read = 0;
X
X	while(position(name,in,current_position))
X	{
X		printf("%s:\n",name);
X		if(!(shpr = popen((c_flag ? "sh -s -c" : "sh"),"w")))
X			quit(1,"unshar: cannot open 'sh' process\n");
X
X		if (!continue_reading) {
X			while((ch = fgetc(in)) != EOF)
X				fputc(ch,shpr);
X			pclose(shpr);
X			break;
X		} else {
X			while (more_to_read = fgets(buffer, 8196, in)) {
X				fputs(buffer, shpr);
X				if (!strncmp(exit_string, buffer, exit_string_length)) {
X					break;
X				}
X			}
X			pclose(shpr);
X			if (more_to_read)
X				current_position = ftell(in);
X			else {
X				break;
X			}
X		}
X	}
X}
X
X/****************************************************************
X * position: position 'fil' at the start of the shell command
X * portion of a shell archive file.
X ****************************************************************/
X
Xposition(fn,fil,start)
Xchar *fn;
XFILE *fil;
Xlong start;                   /* scan file from position */
X{
X	char buf[BUFSIZ];
X	long pos,ftell();
X
X	/* Results from star matcher */
X	static char res1[BUFSIZ],res2[BUFSIZ],res3[BUFSIZ],res4[BUFSIZ];
X	static char *result[] = 
X	{
X		res1,res2,res3,res4 		};
X
X	fseek(fil, start, 0);
X
X	while(1)
X	{ /* Record position of the start of this line */
X		pos = ftell(fil);
X
X		/* Read next line, fail if no more and no previous process */
X		if(!fgets(buf,BUFSIZ,fil))
X		{
X			if(!start)
X				fprintf(stderr,"unshar: found no shell commands in %s\n",fn);
X			return(0);
X		}
X
X		/* Bail out if we see C preprocessor commands or C comments */
X		if(stlmatch(buf,"#include")	|| stlmatch(buf,"# include") ||
X		    stlmatch(buf,"#define")	|| stlmatch(buf,"# define") ||
X		    stlmatch(buf,"#ifdef")	|| stlmatch(buf,"# ifdef") ||
X		    stlmatch(buf,"#ifndef")	|| stlmatch(buf,"# ifndef") ||
X		    stlmatch(buf,"/*"))
X		{
X			fprintf(stderr,
X			    "unshar: %s looks like raw C code, not a shell archive\n",fn);
X			return(0);
X		}
X
X		/* Does this line start with a shell command or comment */
X		if(stlmatch(buf,"#")	|| stlmatch(buf,":") ||
X		    stlmatch(buf,"echo ")	|| stlmatch(buf,"sed ") ||
X		    stlmatch(buf,"cat ") || stlmatch(buf,"if "))
X		{
X			fseek(fil,pos,0);
X			return(1);
X		}
X
X		/* Does this line say "Cut here" */
X		if(smatch(buf,"*CUT*HERE*",result) ||
X		    smatch(buf,"*cut*here*",result) ||
X		    smatch(buf,"*TEAR*HERE*",result) ||
X		    smatch(buf,"*tear*here*",result) ||
X		    smatch(buf,"*CUT*CUT*",result) ||
X		    smatch(buf,"*cut*cut*",result))
X		{
X			/* Read next line after "cut here", skipping blank lines */
X			while(1)
X			{
X				pos = ftell(fil);
X
X				if(!fgets(buf,BUFSIZ,fil))
X				{
X					fprintf(stderr,
X					    "unshar: found no shell commands after 'cut' in %s\n",fn);
X					return(0);
X				}
X
X				if(*buf != '\n') break;
X			}
X
X			/* Win if line starts with a comment character of lower case letter */
X			if(*buf == '#' || *buf == ':' || (('a' <= *buf) && ('z' >= *buf)))
X			{
X				fseek(fil,pos,0);
X				return(1);
X			}
X
X			/* Cut here message lied to us */
X			fprintf(stderr,"unshar: %s is probably not a shell archive,\n",fn);
X			fprintf(stderr,"        the 'cut' line was followed by: %s",buf);
X			return(0);
X		}
X	}
X}
X
X/*****************************************************************
X * stlmatch  --  match leftmost part of string
X *
X * Usage:  i = stlmatch (big,small)
X *	int i;
X *	char *small, *big;
X *
X * Returns 1 iff initial characters of big match small exactly;
X * else 0.
X *
X * HISTORY
X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
X *      Ripped out of CMU lib for Rog-O-Matic portability
X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
X *	Rewritten for VAX from Ken Greer's routine.
X *
X *  Originally from klg (Ken Greer) on IUS/SUS UNIX
X *****************************************************************/
X
Xint stlmatch(big,small)
Xchar *small,*big;
X{
X	register char *s,*b;
X	s = small;
X	b = big;
X	do
X	{
X		if(*s == '\0')
X			return(1);
X	}  while(*s++ == *b++);
X	return(0);
X}
X
X/*****************************************************************
X * smatch: Given a data string and a pattern containing one or
X * more embedded stars (*) (which match any number of characters)
X * return true if the match succeeds, and set res[i] to the
X * characters matched by the 'i'th *.
X *****************************************************************/
X
Xsmatch(dat,pat,res)
Xregister char *dat,*pat,**res;
X{
X	register char *star = 0,*starend,*resp;
X	int nres = 0;
X
X	while(1)
X	{
X		if(*pat == '*')
X		{
X			star = ++pat; 			     /* Pattern after * */
X			starend = dat; 			     /* Data after * match */
X			resp = res[nres++]; 		     /* Result string */
X			*resp = '\0'; 			     /* Initially null */
X		}
X		else if(*dat == *pat) 		     /* Characters match */
X		{
X			if(*pat == '\0') 		     /* Pattern matches */
X				return(1);
X			pat++; 				     /* Try next position */
X			dat++;
X		}
X		else
X		{
X			if(*dat == '\0') 		     /* Pattern fails - no more */
X				return(0); 			     /* data */
X			if(star == 0) 			     /* Pattern fails - no * to */
X				return(0); 			     /* adjust */
X			pat = star; 			     /* Restart pattern after * */
X			*resp++ = *starend; 		     /* Copy character to result */
X			*resp = '\0'; 			     /* null terminate */
X			dat = ++starend; 			     /* Rescan after copied char */
X		}
X	}
X}
X
X/*****************************************************************
X * Addendum: quit subroutine (print a message and exit)
X *****************************************************************/
X
Xquit(status,message)
Xint status;
Xchar *message;
X{
X	fprintf(stderr,message);
X	exit(status);
X}
X
X/*****************************************************************
X * Public Domain getopt routine
X *****************************************************************/
X
X/*
X * get option letter from argument vector
X */
Xint opterr = 1;		/* useless, never set or used */
Xint optind = 1;		/* index into parent argv vector */
Xint 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,*ostr;
X{
X	static char *place = EMSG;	/* option letter processing */
X	register char *oli;		/* option letter list index */
X	char *strchr();
X
X	if(!*place)
X	{			/* update scanning pointer */
X		if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place)
X			return(EOF);
X		if(*place == '-')
X		{	/* found "--" */
X			++optind;
X			return(EOF);
X		}
X	}				/* option letter okay? */
X	if((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt)))
X	{
X		if(!*place) ++optind;
X		tell(": illegal option -- ");
X	}
X	if(*++oli != ':')
X	{		/* don't need argument */
X		optarg = (char *)0;
X		if(!*place) ++optind;
X	}
X	else 
X	{				/* need an argument */
X		if(*place) optarg = place;	/* no white space */
X		else if(nargc <= ++optind)
X		{	/* 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}
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 unshar.c ||
echo 'restore of unshar.c failed'
Wc_c="`wc -c < 'unshar.c'`"
test 11348 -eq "$Wc_c" ||
	echo 'unshar.c: original size 11348, current size' "$Wc_c"
fi
true || echo 'restore of shar.c failed'
echo End of part 1, continue with part 2
exit 0
-- 
  ==========================================================================
  | Richard H. Gumpertz    rhg@CPS.COM    (913) 642-1777 or (816) 891-3561 |
  | Computer Problem Solving, 8905 Mohawk Lane, Leawood, Kansas 66206-1749 |
  ==========================================================================