home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume1 / newshar < prev    next >
Internet Message Format  |  1986-11-30  |  11KB

  1. From: decvax!ucbvax!hpda!hpdsb!bd (Bob Desinger)
  2. Subject: The Connoisseur's Shar, version 2 
  3. Status: RO
  4.  
  5. Here is the shell archiver often referred to as "The Connoisseur's Shar."
  6. Actually, it's an upgrade to the Conn. Shar originally posted to net.sources
  7. a few months ago.  It runs on Berkeley and Bell Unixes.
  8.  
  9. Bob Desinger
  10. ucbvax!hpda!bd        hpda!bd@BERKELEY    ihnp4!hpfcla!hpda!bd
  11. Hewlett-Packard Co.    11000 Wolfe Road    Cupertino, CA  95014
  12.  
  13.  
  14. # This is a shell archive.  Remove anything before this line,
  15. # then unpack it by saving it in a file and typing "sh file".
  16. #
  17. # Wrapped by hpdsb!bd on Tue Dec 18 14:08:21 PST 1984
  18. # Contents:  shar.announcement shar.l shar
  19.  
  20. echo x - shar.announcement
  21. sed 's/^@//' > "shar.announcement" <<'@//E*O*F shar.announcement//'
  22. Here's the latest "Connoisseur's shar" and documentation.  It has a few
  23. advantages over the previously-posted version:
  24.  
  25. 1.  You can archive a whole directory subtree via:  shar `find dir -print`
  26. 2.  The original file's permissions/modes are duplicated upon unpacking.
  27. 3.  The EOF marker is guaranteed to be unique from what's in the archive files.
  28. 4.  A timestamp and personstamp is recorded in the archive.
  29. 5.  Lines beginning with characters that mailers don't like (tildes, dots,
  30.     ampersands) are no longer dangerous.
  31. 6.  The table-of-contents line no longer overflows your mailer's maximum line.
  32.  
  33. These features also make this a candidate for being dubbed "The Glutton's Shar"
  34. since it takes longer to start up.  The way to fix that would be to rewrite it
  35. in C, but that seems to take away some of its novelty.  Still, a C version may
  36. be forthcoming (especially if someone volunteers!)....
  37.  
  38. Kudos to Dan Hoey <hoey@NRL-AIC.ARPA>, who contributed immensely to shar's
  39. current feature set, especially the directory-recursing code.  A tip of the
  40. Hatlo hat also to Alan Silverstein, who set shar's clear coding style and fixed
  41. bugs in earlier versions.
  42.  
  43. Bob Desinger
  44. ucbvax!hpda!bd        hpda!bd@BERKELEY    ihnp4!hpfcla!hpda!bd
  45. Hewlett-Packard Co.    11000 Wolfe Road    Cupertino, CA  95014
  46. @//E*O*F shar.announcement//
  47. chmod u=rw,g=rw,o=r shar.announcement
  48.  
  49. echo x - shar.l
  50. sed 's/^@//' > "shar.l" <<'@//E*O*F shar.l//'
  51. @.TH SHAR LOCAL HEWLETT-PACKARD
  52. @.ad b
  53. @.SH NAME
  54. shar \- make a shell archive package
  55. @.SH SYNOPSIS
  56. \fBshar\fR [\fB-b\fR] [\fB-c\fR] [\fB-t\fR] [\fB-v\fR] file ...
  57. @.SH DESCRIPTION
  58. @.I Shar
  59. bundles the named
  60. @.IR file ( s )
  61. into a single distribution package suitable for mailing or carrying around.
  62. The files should be mailable (not object code, for instance).
  63. @.IR Shar 's
  64. resulting package, written to standard output, is an editable file.
  65. It is actually a shell script using
  66. @.IR sh (1)
  67. "here" documents to extract its contents into the appropriate places.
  68. @.PP
  69. The package is unwrapped by running
  70. @.IR sh
  71. with the package name as an argument.
  72. Its files are written to the pathnames recorded in the archive,
  73. then permissions are set via
  74. @.IR chmod (1)
  75. to match the original files.
  76. @.PP
  77. Except with the
  78. @.B \-b
  79. option, a directory tree
  80. @.I dir
  81. can be archived using the command "shar `find
  82. @.I dir
  83. -print`".
  84. @.PP
  85. Available options are:
  86. @.TP
  87. @.B \-b
  88. Archive files under their basenames, regardless of the original pathnames
  89. specified.
  90. The contents are thus unpacked into the current directory instead of to the
  91. originally-specified pathnames.
  92. This allows you to archive files from many directories but unpack them into a
  93. single directory.
  94. It also allows you to unpack, say,
  95. @.I /etc/termcap
  96. into
  97. @.I ./termcap
  98. instead of overwriting the original one in
  99. @.IR /etc .
  100. @.TP
  101. @.B \-c
  102. Append to the package a simple data-integrity check using
  103. @.IR wc (1)
  104. to insure that the contents were not damaged in transit.
  105. This check will be performed automatically after unpacking.
  106. @.TP
  107. @.B \-t
  108. Write diagnostics and messages directly to your terminal,
  109. instead of to the standard error.  This is useful when invoking
  110. @.I shar
  111. from programs such as
  112. @.IR vi (1)
  113. which normally combine standard error with standard output.
  114. Specifying
  115. @.B \-t
  116. also turns on the
  117. @.B \-v
  118. (verbose) option.
  119. @.TP
  120. @.B \-v
  121. Announce archived file names as they are packed.
  122. The
  123. @.B \-t
  124. option determines the destination for these announcements.
  125. @.br
  126. @.ne 5
  127. @.SH FILES
  128. /dev/tty                   if specified with \fB-t\fR
  129. @.br
  130. /tmp/shar*, /tmp/.shar*    when inspecting for damage
  131. @.br
  132. cat, echo, sed, chmod      as subprocesses
  133. @.br
  134. basename, wc, mkdir        as optional subprocesses
  135. @.SH DIAGNOSTICS
  136. @.I Shar
  137. refuses to archive nonexistent files.
  138. When the
  139. @.B \-b
  140. option is used, it refuses to archive directories.
  141. @.I Shar
  142. terminates and does no archiving if it encounters either problem.
  143. @.PP
  144. Exit status 1 is returned upon interrupt or trouble with arguments.
  145. @.SH "SEE ALSO"
  146. ar(1),
  147. cpio(1),
  148. find(1),
  149. tar(1).
  150. @.SH BUGS
  151. Archived directories must appear before the files in them.  Failure to adhere
  152. to this ordering is not detected, but the result will fail to unpack.
  153. @.PP
  154. Ownerships for archived files are not retained.
  155. @.PP
  156. The integrity check is very simple-minded.
  157. In particular, it notices only if the number of characters, words, or lines
  158. is altered; it fails to catch bits flipped during transmission.
  159. @.PP
  160. @.I Shar
  161. should complain about binary files.
  162. It should also complain about filenames with embedded spaces and
  163. question marks, which
  164. @.IR shar 's
  165. subprocesses don't handle.
  166. @.PP
  167. There should be a standard way
  168. to record the system on which the archive was created.
  169. Berkeley hosts return this information via
  170. @.IR "who am i" ,
  171. but Bell-derived hosts often use wildly differing methods.
  172. @//E*O*F shar.l//
  173. chmod u=rw,g=rw,o=r shar.l
  174.  
  175. echo x - shar
  176. sed 's/^@//' > "shar" <<'@//E*O*F shar//'
  177.  
  178. # UNISRC_ID: @(#)shar.sh    27.1    84/12/17  
  179. : Make a shell archive package
  180.  
  181. # Usage: $0 [-b] [-c] [-t] [-v] files... > package
  182. # See the manual entry for details.
  183.  
  184.  
  185. # Initialize:
  186.  
  187. diagnostic='eval echo >&2'    # diagnostics to stderr by default.
  188. trap '$diagnostic "$0: quitting early"; exit 1' 1 2 3 15
  189. base_option=FALSE        # use pathnames, not basenames.
  190. check_option=FALSE        # don't generate integrity check.
  191. USAGE='Usage: $0 \[-b] \[-c] \[-t] \[-v] files... \> package'
  192.  
  193.  
  194. # Extract and digest options, if any:
  195. #
  196. # Un-comment the "-)" line below to treat single dashes as a no-op.
  197. # Commented means single dashes elicit a usage diagnostic.
  198.  
  199. while [ -n "$1" ]    # while there are more arguments,
  200. do            # digest them; stop when you find a non-option.
  201.     case "$1" in
  202.     -b)    base_option=TRUE;    shift;;
  203.     -c)    check_option=TRUE;    shift;;
  204.     -v)    verbose=TRUE;        shift;;
  205.     -t)    verbose=TRUE; diagnostic='eval echo >/dev/tty'; shift;;
  206. ###    -)    shift;;        # if uncommented, eat single dashes.
  207.     -*)    $diagnostic $USAGE; exit 1;;     # die at illegal options.
  208.     *)    break;;        # non-option found.
  209.     esac
  210. done
  211.  
  212.  
  213. # Check remaining arguments, which should be just a list of files:
  214.  
  215. if [ $# = 0 ]
  216. then    # no arguments left!
  217.     $diagnostic $USAGE
  218.     exit 1
  219. fi
  220.  
  221.  
  222. # Check the cupboard to see if the ingredients are all there:
  223.  
  224. contents=''    # no files so far.
  225. contdirs=''    # no directories so far.
  226.  
  227. for arg        # for all files specified,
  228. do        # establish the archive name.
  229.     if [ -f "$arg" ]
  230.     then    # file exists and is not a directory.
  231.         case $base_option in
  232.         TRUE)    unpack_name=`basename "$arg"` ;;
  233.         FALSE)    unpack_name="$arg" ;;
  234.         esac
  235.  
  236.         contents="$contents $unpack_name"
  237.  
  238.     elif [ -d "$arg" ]
  239.     then    # file exists and is a directory.
  240.         case $base_option in
  241.         TRUE)   $diagnostic '$0: cannot archive directory "$arg" with -b option.'
  242.             exit 1 ;;
  243.         FALSE)  contdirs="$contdirs $arg/ " ;;
  244.         esac
  245.  
  246.     else    # not a plain file and not a directory.
  247.         $diagnostic '$0: cannot archive "$arg"'
  248.         exit 1
  249.     fi
  250. done
  251.  
  252.  
  253. # Emit the prologue:
  254. # (The leading newline is for those who type csh instead of sh.)
  255.  
  256. cat <<!!!
  257.  
  258. # This is a shell archive.  Remove anything before this line,
  259. # then unpack it by saving it in a file and typing "sh file".
  260. #
  261. # Wrapped by `who am i | sed 's/[     ].*//'` on `date`
  262. !!!
  263.  
  264.  
  265. # Emit the list of ingredients:
  266.  
  267. # Simple version (breaks if you shar lots of files at once):
  268. #    echo "# Contents: $contdirs$contents"
  269. #
  270. # Complex and cosmetic version to pack contents list onto lines that fit on
  271. # one terminal line ("expr string : .*" prints the length of the string):
  272.  
  273. MAX=80
  274. line='# Contents: '
  275. for item in $contdirs $contents
  276. do
  277.     if [ `expr "$line" : '.*' + 1 + "$item" : '.*'` -lt $MAX ]
  278.     then    # length of old line + new item is short enough,
  279.         line="$line $item"    # so just append it.
  280.  
  281.     else    # new element makes line too long,
  282.         echo "$line"        # so put it on a new line.
  283.         line="#    $item"        # start a new line.
  284.         MAX=74            # compensate for tab width.
  285.     fi
  286. done
  287.  
  288. echo "$line"
  289. echo " "
  290.  
  291.  
  292. # Emit the files and their separators:
  293.  
  294. for arg
  295. do
  296.     # Decide which name to archive under.
  297.     case $base_option in
  298.     TRUE)   unpack_name=`basename "$arg"`
  299.         test $verbose && $diagnostic "a - $unpack_name [from $arg]" ;;
  300.     FALSE)  unpack_name="$arg"
  301.         test $verbose && $diagnostic "a - $arg" ;;
  302.     esac
  303.  
  304.     # Emit either a mkdir or a cat/sed to extract the file.
  305.     if [ -d "$arg" ]
  306.     then
  307.         echo "echo mkdir - $arg"
  308.         echo "mkdir $arg"
  309.     else
  310.         echo "echo x - $unpack_name"
  311.         separator="@//E*O*F $unpack_name//"
  312.         echo "sed 's/^@//' > \"$unpack_name\" <<'$separator'"
  313.         sed  -e 's/^[.~@]/@&/'  -e 's/^From/@&/'  "$arg"
  314.         echo $separator
  315.     fi
  316.  
  317.     # Emit chmod to set permissions on the extracted file;
  318.     # this keels over if the filename contains "?".
  319.     ls -ld $arg | sed \
  320.         -e 's/^.\(...\)\(...\)\(...\).*/u=\1,g=\2,o=\3/' \
  321.         -e 's/-//g' \
  322.         -e 's?.*?chmod & '"$unpack_name?"
  323.     echo " "
  324. done
  325.  
  326.  
  327. # If the -c option was given, emit the checking epilogue:
  328. # (The sed script converts files to basenames so it works regardless of -b.)
  329.  
  330. if [ $check_option = TRUE ]
  331. then
  332.     echo 'echo Inspecting for damage in transit...'
  333.     echo 'temp=/tmp/shar$$; dtemp=/tmp/.shar$$'
  334.     echo 'trap "rm -f $temp $dtemp; exit" 0 1 2 3 15'
  335.     echo 'cat > $temp <<\!!!'
  336.     case $base_option in
  337.     TRUE)   wc $@ | sed 's=[^ ]*/=='    ;;
  338.     FALSE)  wc $contents | sed 's=[^ ]*/=='    ;;
  339.     esac
  340.     echo '!!!'
  341.     echo "wc $contents | sed 's=[^ ]*/==' | "'diff -b $temp - >$dtemp'
  342.     echo 'if [ -s $dtemp ]'
  343.     echo 'then echo "Ouch [diff of wc output]:" ; cat $dtemp'
  344.     echo 'else echo "No problems found."'
  345.     echo 'fi'
  346. fi
  347.  
  348.  
  349. # Finish up:
  350.  
  351. echo 'exit 0'    # sharchives unpack even if junk follows.
  352. exit 0
  353. @//E*O*F shar//
  354. chmod u=rwx,g=rx,o=rx shar
  355.  
  356. echo Inspecting for damage in transit...
  357. temp=/tmp/shar$$; dtemp=/tmp/.shar$$
  358. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  359. cat > $temp <<\!!!
  360.       24     195    1278 shar.announcement
  361.      121     539    3292 shar.l
  362.      176     771    4548 shar
  363.      321    1505    9118 total
  364. !!!
  365. wc  shar.announcement shar.l shar | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  366. if [ -s $dtemp ]
  367. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  368. else echo "No problems found."
  369. fi
  370. exit 0
  371.  
  372.