Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: notesfiles Path: utzoo!linus!decvax!ittvax!dcdwest!sdcsvax!sdcrdcf!hplabs!hp-pcd!hpfcla!ajs From: ajs@hpfcla.UUCP (ajs) Newsgroups: net.sources Subject: Improved Connoisseur's Shar Message-ID: <43600012@hpfcla.UUCP> Date: Thu, 27-Dec-84 16:32:00 EST Article-I.D.: hpfcla.43600012 Posted: Thu Dec 27 16:32:00 1984 Date-Received: Tue, 1-Jan-85 06:01:01 EST Organization: Hewlett-Packard - Fort Collins, CO Lines: 280 Nf-ID: #N:hpfcla:43600012:000:8017 Nf-From: hpfcla!ajs Dec 27 13:32:00 1984 [Posted for someone else, by request, because mod.sources is not yet reaching many sites. Please respond to address below, not to ajs.] Here's the latest "Connoisseur's shar" and documentation. Actually, it's an upgrade to the Conn. Shar originally posted to net.sources a few months ago. It runs on both Berkeley and Bell Unixes. It has a few advantages over the previously-posted version: 1. You can archive a whole directory subtree via: shar `find dir -print` 2. The original file's permissions/modes are duplicated upon unpacking. 3. The EOF marker is guaranteed to be unique from what's in the archive files. 4. A timestamp and personstamp is recorded in the archive. 5. Lines beginning with characters that mailers don't like (tildes, dots, ampersands) are no longer dangerous. 6. The table-of-contents line no longer overflows your mailer's maximum line. These features also make this a candidate for being dubbed "The Glutton's Shar" since it takes longer to start up. The way to fix that would be to rewrite it in C, but that seems to take away some of its novelty. Still, a C version may be forthcoming (especially if someone volunteers!).... Kudos to Dan Hoey, who contributed immensely to shar's current feature set, especially the directory-recursing code. A tip of the Hatlo hat also to Alan Silverstein, who set shar's clear coding style and fixed bugs in earlier versions, and who posted this for me since I don't have write- access to the Usenet. Bob Desinger ucbvax!hpda!bd hpda!bd@BERKELEY ihnp4!hpfcla!hpda!bd Hewlett-Packard Co. 11000 Wolfe Road Cupertino, CA 95014 ---------- # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # shar shar.1 echo x - shar cat > "shar" << '//E*O*F shar//' # UNISRC_ID: @(#)shar.sh 26.2 84/09/06 : Make a shell archive package # Usage: $0 [-b] [-c] [-t] [-v] files... > package # See the manual entry for details. # Initialize: diagnostic='eval echo >&2' # diagnostics to stderr by default. trap '$diagnostic "$0: quitting early"; exit 1' 1 2 3 15 base_option=FALSE # use pathnames, not basenames. check_option=FALSE # don't generate integrity check. usage='Usage: $0 \[-b] \[-c] \[-t] \[-v] files... \> package' # Extract and digest options, if any: # # Un-comment the "-)" line below to treat single dashes as a no-op. # Commented means single dashes elicit a usage diagnostic. while [ -n "$1" ] # while there are more arguments, do # digest them; stop when you find a non-option. case "$1" in -[bB]) base_option=TRUE; shift ;; -[cC]) check_option=TRUE; shift ;; -[tT]) verbose=TRUE; diagnostic='eval echo >/dev/tty'; shift ;; -[vV]) verbose=TRUE; shift ;; ## -) shift ;; # eat single dashes. -*) $diagnostic $usage; exit 1 ;; # die at illegal options. *) break ;; esac done # Check remaining arguments, which should be just a list of files: if [ $# = 0 ] then # no arguments left! $diagnostic $usage exit 1 fi # Emit the prologue, then check and list ingredients: # (The leading newline is for those who type csh instead of sh.) cat <<\!!! # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: !!! contents='' # no files so far. for arg # for all files specified, do # establish archive name. if [ -f "$arg" ] # non-directory and exists. then case $base_option in TRUE) unpack_name=`basename "$arg"` ;; FALSE) unpack_name="$arg" ;; esac contents="$contents $unpack_name" else $diagnostic "$0: cannot archive $arg" exit 1 fi done echo "#$contents" echo # Emit the files and their separators: for arg # for all arguments left (file names). do case $base_option in TRUE) unpack_name=`basename "$arg"` test $verbose \ && $diagnostic "a - $unpack_name [from $arg]" ;; FALSE) unpack_name="$arg" test $verbose && $diagnostic "a - $arg" ;; esac separator="//E*O*F $unpack_name//" echo "echo x - $unpack_name" echo "cat > \"$unpack_name\" << '$separator'" cat "$arg" echo $separator echo done # If the -c option was given, emit the checking epilogue: # (The sed script converts files to basenames so it works regardless of -b.) if [ $check_option = TRUE ] then echo "echo Possible errors detected by \'wc\' [hopefully none]:" echo 'temp=/tmp/shar$$' echo 'trap "rm -f $temp; exit" 0 1 2 3 15' # will clean up. echo 'cat > $temp <<\!!!' wc $@ | sed 's=[^ ]*/==' echo '!!!' echo "wc $contents | sed 's=[^ ]*/==' | "'diff -b $temp -' fi # Finish up: echo 'exit 0' # sharchives unpack even if junk follows. exit 0 //E*O*F shar// echo x - shar.1 cat > "shar.1" << '//E*O*F shar.1//' .TH SHAR 1 HEWLETT-PACKARD .ad b .SH NAME shar \- make a shell archive package .SH SYNOPSIS \fBshar\fR [\fB-b\fR] [\fB-c\fR] [\fB-t\fR] [\fB-v\fR] \fIfiles...\fR .SH DESCRIPTION .I Shar bundles the named .IR file ( s ) into a single distribution package suitable for mailing or carrying around. The files should be themselves mailable, e.g. not object code. .IR Shar 's resulting package, written to standard output, is an editable ASCII file. It is actually a shell script which uses \fIsh\fR\^(1) "here" documents to extract its contents into appropriate places. .PP The package is unwrapped by running \fIsh\fR\^(1) with the package name as an argument. Its files are written to the pathnames recorded in the archive. .PP Available options are: .TP .B \-b Archive files under their basenames, regardless of the original pathnames specified. The contents are thus unpacked into the current directory instead of to the originally-specified pathnames. This allows you to archive files from many directories but unpack them into a single directory. It also allows you to unpack, say, .I /etc/termcap into .I ./termcap instead of overwriting the original one in .IR /etc . .TP .B \-c Cause .I shar to append to the package a simple data-integrity check using .I wc to insure that the contents were not damaged in transit. This check is performed automatically after unpacking. .TP .B \-t Write diagnostics and messages directly to .IR /dev/tty , your terminal, instead of to standard error. This is useful when invoking .I shar from programs such as .I vi which normally combine standard error with standard output. Specifying .B \-t also turns on the .B \-v (verbose) option. .TP .B \-v Announce archived file names as they are packed. The .B \-t option affects where these announcements go. .SH FILES /dev/tty if specified by the \fB-t\fR option .br /tmp/shar* used for the insurance check after unpacking .br cat, echo as subprocesses .br basename, wc as optional subprocesses .SH DIAGNOSTICS .I Shar refuses to archive nonexistent files and directories. It terminates and does no archiving if it encounters them. .PP Exit status 1 is returned upon interrupt or trouble with arguments. .SH "SEE ALSO" ar(1), basename(1), cat(1), cpio(1), echo(1), sh(1), tar(1), wc(1). .SH BUGS Ownerships and permissions for archived files are not retained. .PP The integrity check is very simple-minded. In particular, it only notices if the number of characters, words, or lines is altered. It fails to catch bits flipped during transmission. .PP There should be a way to archive directories by name instead of using arguments such as .IR dir/* . //E*O*F shar.1// echo Possible errors detected by \'wc\' [hopefully none]: temp=/tmp/$0$$ trap "rm -f $temp; exit" 0 1 2 3 15 cat > $temp <<\!!! 123 480 3083 shar 99 425 2644 shar.1 222 905 5727 total !!! wc shar shar.1 | sed 's=[^ ]*/==' | diff -b $temp - exit 0