home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1815 < prev    next >
Internet Message Format  |  1990-12-28  |  46KB

  1. From: rhg@cpsolv.CPS.COM (Richard H. Gumpertz)
  2. Newsgroups: alt.sources
  3. Subject: shar 3.49 (part 1 of 2)
  4. Message-ID: <541@cpsolv.CPS.COM>
  5. Date: 12 Sep 90 20:22:30 GMT
  6.  
  7. Submitted-by: rhg@cpsolv
  8. Archive-name: shar3.49/part01
  9.  
  10. Patch 3 to shar 3.43 was relative to the wrong version of Makefile.  Rather
  11. than try to patch a patch and all that, here is the whole thing.
  12.  
  13. ---- Cut Here and feed the following to sh ----
  14. #!/bin/sh
  15. # This is shar3.49, a shell archive (produced by shar 3.49)
  16. # To extract the files from this archive, save it to a file, remove
  17. # everything above the "!/bin/sh" line above, and type "sh file_name".
  18. #
  19. # made 09/12/1990 20:16 UTC by rhg@cpsolv
  20. # Source directory /u/rhg/src/shar
  21. #
  22. # existing files will NOT be overwritten unless -c is specified
  23. #
  24. # This shar contains:
  25. # length  mode       name
  26. # ------ ---------- ------------------------------------------
  27. #  10942 -rw-r--r-- README
  28. #   3696 -rw-r--r-- Makefile
  29. #   7946 -rw-r--r-- shar.1
  30. #   1515 -rw-r--r-- unshar.1
  31. #   1365 -rw-r--r-- uushar.c
  32. #   3077 -rw-r--r-- who@where.c
  33. #  11602 -rw-r--r-- unshar.c
  34. #  38151 -rw-r--r-- shar.c
  35. #
  36. # ============= README ==============
  37. if test -f 'README' -a X"$1" != X"-c"; then
  38.     echo 'x - skipping README (File already exists)'
  39. else
  40. echo 'x - extracting README (Text)'
  41. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  42. XThis file last revised Sat Aug 4 17:15:01 CDT 1990
  43. X
  44. XHere is shar 3.49, an updated version of shar 3.43, derived from 'shar2'.
  45. XThis offering is the work of many people.  Thanks to wht@n4hgf.Mt-Park.GA.US
  46. X(Warren Tucker), rhg@CPS.COM (Richard H. Gumpertz), colas@avahi.inria.fr
  47. X(Colas Nahaboo), bill@netagw.com (Bill Aten), marks@rex.cs.tulane.edu, and
  48. Xmaaaany others.
  49. X
  50. XThis version's shar:
  51. X1) generates shell code which attempts to create missing directories
  52. X2) generates shell code which will force overwriting of files when passed
  53. X   the '-c' option.
  54. X3) allows entire directories to be archived
  55. X4) handle deviants sun, vax, pyramid, sequent, and SCO XENIX/UNIX
  56. X   automatically; for system V systems I did not catch, add -DSYS5
  57. X   to CFLAGS; for other BSD-like systems, add -DBSD42
  58. X5) if unsharing system's touch is Sys V compatible (allows touch -m),
  59. X   the unshar process restores file dates (-m switch)
  60. X6) An archive name may be specified for inclusion in the header
  61. X   of the shar files (-n switch)
  62. X7) allows automatic generation of "Submitted-by: who@where" &
  63. X   "Archive-name: <name>/part##" headers
  64. X8) uses getopt; no good system library should be without a copy
  65. X   but it is readily available (like look in unshar.c)
  66. X9) includes other chrome-plated bells, whistles, and junque
  67. X
  68. XThis version's unshar:
  69. X1) can change directory before unsharing
  70. X2) can unshar from standard in, from a COLLECTION of shars,
  71. X   from a file containing multiple concatenated shars,
  72. X   or a mixture of shar files and concatenated-shar files.
  73. X3) can pass the '-c' option on to the script being extracted.
  74. X4) does not have a Social Security number.
  75. X
  76. X------------------------ shar  usage -----------------------------------
  77. Xshar 3.49
  78. Xusage: shar [ options ] file ...
  79. X       shar -S [ options ]
  80. X-V  produce "vanilla" shars demanding little of the unshar environment
  81. X-v  verbose messages OFF while executing
  82. X-m  restore file modification dates & times with "touch" commands
  83. X-w  don't check with 'wc -c' after unpack
  84. X-a  generate Submitted-by: & Archive-name: headers
  85. X-nXXX   use XXX as the name of the archive (documentation)
  86. X-s  override automatically determined submitter name
  87. X-x  overwrite existing files without checking if they already exist
  88. X-X  interactively overwrite existing files (NOT FOR NET SHARS)
  89. X-B  treat all files as binary, use uuencode
  90. X-T  treat all files as text (default)
  91. X-C  compress and uuencode all files
  92. X-bXX    pass -bXX (default 12) to compress when compressing (implies -C)
  93. X-p  allow positional parameter options. The options "-B" and "-B"
  94. X    and "-C" may be embedded, and files to the right of the
  95. X    option will be processed in the specified mode
  96. X-M  mixed mode. Determine if the files are text or
  97. X    binary and archive correctly.
  98. X-P  use temp files instead of pipes in the shar file
  99. X-F  force the prefix character on every line (even if not required)
  100. X-c  start the shar with a cut line
  101. X-f  restore by filename only, rather than path
  102. X-dXXX   use XXX to delimit the files in the shar
  103. X-oXXX   (or -o XXX) output to file XXX.01 thru XXX.nn
  104. X-lXX    limit output file size to XXk bytes (but don't split files)
  105. X-LXX    limit output file size to XXk bytes (may split files)
  106. X-S      read files to wrap from stdin, ignoring argument line
  107. X
  108. XThe -S option reads filenames one per line from stdin; input
  109. Xformat must be similar to 'find' output, except that if -p
  110. Xis specified, -B, -T or -C may be used (on lines by themselves)
  111. Xe.g., find . -type f -print | sort | shar -C -l50 -o /tmp/big
  112. X
  113. XThe 'o' option is required if the 'l' or 'L' option is used
  114. XThe 'n' option is required if the 'a' option is used
  115. X
  116. X-a generates sharname/part## headers. If the -a argument contains
  117. Xa '/', then /part is not appended
  118. XThe automatic submitter name is trivial: essentially `whoami`@`uname`
  119. X
  120. X------------------------ unshar usage -----------------------------------
  121. XUnshar has no usage built in.  It has default actions when invoked
  122. Xwith no arguments (read from stdin).
  123. X
  124. XUsage:     unshar [ -d directory ] [ -c ] [ -e | -E exit_line ] [ files ... ]
  125. X
  126. X      The -c flag is passed through to the shell as a parameter to the script
  127. X      It can unshar shar files concatenated in one file, with the
  128. X      the "-e" command, which separates files by recognizing the
  129. X      "exit 0" string at the beginning of a line
  130. X
  131. X      (The -E string option allows you to specify this string, thus
  132. X      -e is equivalent to -E "exit 0")
  133. X
  134. X      The -d flag tells unshar to change directory before unsharing
  135. X
  136. X
  137. X--------------------- history -----------------------------------------
  138. XChanges since 3.11: kudos to rhg@CPS.COM (Richard H. Gumpertz)
  139. X
  140. X1.  The -l switch still specifies a maximum size for the generated
  141. X    shar files, but now it prevents files from spanning shar parts.
  142. X    Shars generated using this method may be unpacked in any order.
  143. X
  144. X2.  The old -l switch functionality is precisely emulated by using the
  145. X    the -L switch.  That is, archived files may be split across parts.
  146. X    Shars generated using this method must still be unpacked in order.
  147. X
  148. X3.  The -C switch causes files to be compressed, then uuencoded.
  149. X    Unpacking reverses the process.
  150. X
  151. X4.  The -P causes the shar to use temp files instead of pipes in
  152. X    the unshar process.
  153. X
  154. X5.  The -f causes files to be resotred by name only (i.e., strip
  155. X    directory portion of input filenames before placing the name
  156. X    into the shar.
  157. X
  158. X
  159. XChanges since 3.20: kudos to colas@avahi.inria.fr (Colas Nahaboo)
  160. X
  161. X1.  The Archived-name: header no longer uses "/part" if there is
  162. X    a "/" in the -n name.  Thus
  163. X        -n xyzzy                     procduces:
  164. X                                     xyzzy/part01
  165. X                                     xyzzy/part02
  166. X
  167. X        -n xyzzy/patch               procduces:
  168. X                                     xyzzy/patch01
  169. X                                     xyzzy/patch02
  170. X
  171. X        -n xyzzy/patch01.            procduces:
  172. X                                     xyzzy/patch01.01
  173. X                                     xyzzy/patch01.02
  174. X2.  The Archive-name part number other than part01 had no leading zero
  175. X    in the number.
  176. X
  177. X3.  The "Submitted-by:" header was missing the hyphen (minus for olde
  178. X    UNIX hackres).
  179. X
  180. X4.  The unshar program may now unshar a whole mailbox or concatenation
  181. X    of shar files.
  182. X
  183. X    -C "string" looks for "string" at the beginning of the line to
  184. X       break the file into individual shar files
  185. X    -c is equivalent to -C "exit 0"
  186. X
  187. X    This of course will only work if there is something in the shar
  188. X    file recognizable to terminate the shar.  Some shars dont have
  189. X    "exit 0" at the end.  However, a clue: most/many .signatures have
  190. X    "--" on a line right before them.
  191. X
  192. X5.  Unshar -d (change directory) no longer makes argv files unreachable.
  193. X    I had never used the feature until the other day.  I guess the
  194. X    author has used in only for unsharing from stdin.
  195. X
  196. XChanges since 3.21: thanks to Adri Verhoef, <a3@rivm.UUCP>
  197. X
  198. X1.  Some vaxen do not run BSD.  I guess I knew this, but -er-
  199. X    here is Adri's note:
  200. X> Hi Warren,
  201. X> 
  202. X>   I encountered a problem trying to get 'shar3.21' to compile on System V
  203. X> on a vax.  Yes, can you believe it?  We run System V Release 3.0 on VAXen!
  204. X> The shar3.21 code assumes that you are BSD if you're on a vax.  This is not
  205. X> always true!  What I did to get the code compiled on System V, was:
  206. X> (+) edit the Makefile and add -DSYS5 to CFLAGS.
  207. X> (+) edit all the C-source files to circumcise compiler warnings
  208. X>     ("SYS5 redefined").
  209. X> 
  210. X
  211. XHe made a suggestion about having a localize.sh edit a distribution
  212. XMakefile, but for now, I'll just suggest you add -DSYS5 to CFLAGS 
  213. Xmanually.
  214. X
  215. X2.  jhd@irfu.se (Jan Dj{rv, sorry about the screwed up character
  216. X    translation, Jan) wrote man pages.  Thanks!
  217. X
  218. XChanges since 3.22: thanks to Dennis Boylan <dennis@nanovx>
  219. X
  220. X1.  The new -S option allows the list of files to be packed
  221. X    to be read from the standard input rather than from the
  222. X    command line.
  223. X
  224. X2.  A few purist checks were made to ensure fork() or malloc()
  225. X    doesn't fail and excite the "if 20 hours of your time is
  226. X    free then why isn't 200?" crowd (who probably will never see
  227. X    this revision anyway :-))
  228. X
  229. XChanges since 3.23:
  230. X
  231. X1.  The -V mode was added.
  232. X
  233. X2.  Altos doesn't like the '@' in filenames.  The filename format
  234. X    was changed.  Thanks to rhg@cps.com.
  235. X
  236. XChanges since 3.24:
  237. X
  238. X1.  Man pages were revised by gam@netcom (Gordon Moffet). Thanks.
  239. X
  240. X2.  When -L was specified, the "Starting ..." message was not
  241. Xproduced on standard error (with or without -v).
  242. X
  243. X3.  When using -X, the 'not for net' warning was printed on standard
  244. Xoutput rather thsn standard error.
  245. X
  246. X4.  marks@rex.cs.tulane.edu reccommends adding -F 5000 to the load
  247. X    line of unshar when using on XENIX 286 to avoid stack overflow
  248. X    core dumps.  I added this information to an excellkent remake
  249. X    of the Makefile by bill@netagw.com.
  250. X
  251. XChanges since 3.25:
  252. X
  253. X1.  Fixed one minor bug with -a/-n.  The period supplied when a
  254. X    slash appears in the -n name was omitted.  This is a hatefully
  255. X    small bug to fix and reissue a whole release, but
  256. X    a) several new names are on the sharlist now and they have
  257. X       only 3.24 to work with,
  258. X    b) this will surely sync us all up, and
  259. X    c) I think it will put shar to bed for a while ("no known bugs
  260. X       at this ti ... bus error core dumped").
  261. X
  262. XChanges since 3.27:
  263. X
  264. X1.  The unshar-time test for a touch -m facility now greps for
  265. X    'mmdd', not '[-amc]', making it more universally successful.
  266. X
  267. X2.  NOTE:  there is still a problem with -n arguments using
  268. X    a 'x/y' construct, but I don't know how to properly generalize
  269. X    it so you'll have to edit shars made with some uses of -a
  270. X    with -n x/y.
  271. X
  272. X3.  This is surely my last work on this.  It does everything
  273. X    I needed and more.  Thanks for all the help and suggestions.
  274. X    It seems as though we didn't precipitate 'death of the shar'
  275. X    after all :-) :-) :-).
  276. X
  277. XChanges since 3.32:
  278. X
  279. X1.  Several bug fixes.
  280. X
  281. X2.  Inverted the meaning of '-x'; the new default is to NOT overwrite.
  282. X
  283. X3.  Added '-c' checking when unpacking so the recipient can force overwrites.
  284. X
  285. X4.  Made '-L' work even with files not being overwritten.
  286. X
  287. X5.  Added '-m' and changed the default behavior to not generate TOUCH commands.
  288. X
  289. X6.  Added '-F'; the default is to suppress the extra 'X' at the beginning of
  290. X    each line unless it is needed (i.e., the first character of the line is
  291. X    already 'X' or is a non-graphic).
  292. X
  293. X7.  Renamed '-b' and '-t' to '-B' and '-T', respectively.
  294. X
  295. X8.  Added '-bn' for use with compression (calls compress with -bn).
  296. X
  297. X9.  Renamed the temporary files used in unpacking from shar3_???_.tmp to
  298. X    _shar_???_.tmp.
  299. X
  300. X10. Directories may now be passed to shar; a recursive directory walk is
  301. X    performed.  This feature may be disabled by compiling with -DNO_WALKTREE.
  302. X
  303. XChanges since 3.43:
  304. X
  305. X1.  Several more minor bug fixes.
  306. X
  307. X2.  Added support for BSD-style <sys/dir.h> and -ldir.
  308. X
  309. X3.  Added more usage directions to the shar header.
  310. SHAR_EOF
  311. chmod 0644 README ||
  312. echo 'restore of README failed'
  313. Wc_c="`wc -c < 'README'`"
  314. test 10942 -eq "$Wc_c" ||
  315.     echo 'README: original size 10942, current size' "$Wc_c"
  316. fi
  317. # ============= Makefile ==============
  318. if test -f 'Makefile' -a X"$1" != X"-c"; then
  319.     echo 'x - skipping Makefile (File already exists)'
  320. else
  321. echo 'x - extracting Makefile (Text)'
  322. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  323. X#  makefile for shar
  324. X#
  325. X# $Header: /u/rhg/src/shar/Makefile,v 3.49 90/09/12 15:14:18 rhg Exp $
  326. X#
  327. X#+:EDITS:
  328. X#:09-09-1990-20:12-rhg@cps.com-added CLOSEDIR_VOID
  329. X#:09-09-1990-11:31-bill@netagw.com-add SHELL variable/-ldir for XENIX/UNIX 386
  330. X#:08-07-1990-21:25-rhg@cps.com-compress man pages if MANEXT ends with .Z
  331. X#:08-05-1990-23:50-rhg@cps.com-add post and compressed.
  332. X#:08-05-1990-12:19-rhg@cps.com-add LIBS and -ldirent
  333. X#:08-04-1990-18:51-rhg@cps.com-add CC, LD; move strip; reorder chgrp/chown.
  334. X#:05-14-1990-17:33-wht@n4hgf-add -F 5000 for XENIX 286
  335. X#:05-14-1990-17:32-bill@netagw.com-expanded Makefile
  336. X#:03-28-1990-14:54-wht@n4hgf-for 3.10, add who@where.c
  337. X
  338. XSHELL=/bin/sh
  339. X
  340. XBINDIR    = /usr/local/bin
  341. XOWNER    = bin
  342. XGROUP    = bin
  343. XBINMODE    = 0755
  344. XMANDIR    = /usr/man/man1
  345. XMANEXT    = 1
  346. XMANOWN    = bin
  347. XMANGRP    = bin
  348. XMANMODE    = 0644
  349. X
  350. XCC    = cc
  351. XLD    = ${CC}
  352. X
  353. X# If you don't have Doug Gwyn's dirent routines or equivalent, then remove
  354. X# -ldirent from LIBS and add -DNO_WALKTREE to CFLAGS.  All you will give up
  355. X# is the ability to shar directorys without using "find ... -type f | shar -S".
  356. X# Note that many systems have the equivalent of the dirent library built into
  357. X# the standard C library.  For such systems, just remove -ldirent from LIBS.
  358. X# (note by RHG@CPS.COM: I don't know which systems listed below are like that.)
  359. X# Some systems, such as SCO XENIX/UNIX 386 use -ldir instead.
  360. X# Some systems, such as SunOS 3, use <sys/dir.h> instead of <dirent.h>.  For
  361. X# these systems, add -DNO_DIRENT to CFLAGS.  Many of these same systems, such
  362. X# as BSD, have a closedir that has no return value.  For these systems, add
  363. X# both -DNO_DIRENT and -DCLOSEDIR_VOID to CFLAGS.
  364. X
  365. X# For VAX, PYRAMID, SEQUENT, AT&T 3B1/7300
  366. XCFLAGS    = -O 
  367. XLDFLAGS    =
  368. XLIBS    = -ldirent
  369. X
  370. X# For SUN
  371. X#CFLAGS    = -O -DNO_DIRENT -DCLOSEDIR_VOID
  372. X#LDFLAGS    =
  373. X#LIBS    =
  374. X
  375. X# For SCO XENIX/UNIX 386
  376. X#CFLAGS    = -O -DNO_DIRENT -DCLOSEDIR_VOID
  377. X#LDFLAGS    =
  378. X#LIBS    = -ldir
  379. X
  380. X# For SCO XENIX 286
  381. X#CFLAGS    = -O 
  382. X#LDFLAGS    = -F 5000
  383. X#LIBS    = -ldirent
  384. X
  385. X# For other System V systems I did not catch
  386. X#CFLAGS    = -O -DSYS5
  387. X#LDFLAGS    =
  388. X#LIBS    = -ldirent
  389. X
  390. X# For BSD-like systems
  391. X#CFLAGS    = -O -DBSD42 -DNO_DIRENT -DCLOSEDIR_VOID
  392. X#LDFLAGS    =
  393. X#LIBS    =
  394. X
  395. XSOURCES    = README Makefile shar.1 unshar.1 uushar.c who@where.c unshar.c shar.c
  396. X
  397. XSHAR    = shar.o uushar.o who@where.o
  398. XUNSHAR    = unshar.o
  399. X
  400. Xall: shar unshar
  401. X
  402. Xshar: ${SHAR}
  403. X    ${LD} ${LDFLAGS} ${SHAR} ${LIBS} -o shar
  404. X
  405. Xunshar : ${UNSHAR}
  406. X    ${LD} ${LDFLAGS} ${UNSHAR} ${LIBS} -o unshar
  407. X
  408. Xshar.o : shar.c
  409. X    ${CC} ${CFLAGS} -c shar.c
  410. X
  411. Xunshar.o : unshar.c
  412. X    ${CC} ${CFLAGS} -c unshar.c
  413. X
  414. Xuushar.o : uushar.c
  415. X    ${CC} ${CFLAGS} -c uushar.c
  416. X
  417. Xwho@where.o : who@where.c
  418. X    ${CC} ${CFLAGS} -c who@where.c
  419. X
  420. Xinstall : shar unshar
  421. X    strip shar unshar
  422. X    cp shar unshar ${BINDIR}
  423. X    chmod ${BINMODE} ${BINDIR}/shar ${BINDIR}/unshar
  424. X    chgrp ${GROUP} ${BINDIR}/shar ${BINDIR}/unshar
  425. X    chown ${OWNER} ${BINDIR}/shar ${BINDIR}/unshar
  426. X    if expr "${MANEXT}" : ".*\.Z$$" >/dev/null; then \
  427. X        compress -b14 < shar.1   > ${MANDIR}/shar.${MANEXT}; \
  428. X        compress -b14 < unshar.1 > ${MANDIR}/unshar.${MANEXT}; \
  429. X    else \
  430. X        cp shar.1   ${MANDIR}/shar.${MANEXT}; \
  431. X        cp unshar.1 ${MANDIR}/unshar.${MANEXT}; \
  432. X    fi
  433. X    chmod ${MANMODE} ${MANDIR}/shar.${MANEXT} ${MANDIR}/unshar.${MANEXT}
  434. X    chgrp ${MANGRP}  ${MANDIR}/shar.${MANEXT} ${MANDIR}/unshar.${MANEXT}
  435. X    chown ${MANOWN}  ${MANDIR}/shar.${MANEXT} ${MANDIR}/unshar.${MANEXT}
  436. X
  437. Xclean :
  438. X    rm -f shar unshar *.o core
  439. X
  440. XSETV =    X="`head -1 shar.c`"; \
  441. X    V=`expr "$$X" : 'char \*revision = "\([1-9][0-9]*\.[0-9.a-zA-Z]*\)";$$'`;
  442. X
  443. Xpost : ${SOURCES}
  444. X    ${SETV} test -n "$$V" && ( \
  445. X    rm -f shar$$V.[0-9][0-9]; \
  446. X    shar -l50 -acF -n "shar$$V" -o "shar$$V" ${SOURCES} )
  447. X
  448. Xcompressed : ${SOURCES}
  449. X    ${SETV} test -n "$$V" && \
  450. X    shar -acFm -b16 -n "shar$$V" > "shar$$V" ${SOURCES}
  451. X
  452. SHAR_EOF
  453. chmod 0644 Makefile ||
  454. echo 'restore of Makefile failed'
  455. Wc_c="`wc -c < 'Makefile'`"
  456. test 3696 -eq "$Wc_c" ||
  457.     echo 'Makefile: original size 3696, current size' "$Wc_c"
  458. fi
  459. # ============= shar.1 ==============
  460. if test -f 'shar.1' -a X"$1" != X"-c"; then
  461.     echo 'x - skipping shar.1 (File already exists)'
  462. else
  463. echo 'x - extracting shar.1 (Text)'
  464. sed 's/^X//' << 'SHAR_EOF' > 'shar.1' &&
  465. X.TH SHAR 1 "August 12, 1990"
  466. X.SH NAME
  467. Xshar \- create shell archives
  468. X.SH SYNOPSIS
  469. X.nf
  470. Xshar [ options ] file ...
  471. Xshar \-S [ options ]
  472. X.fi
  473. X.SH DESCRIPTION
  474. XShar
  475. Xcreates "shell archives" (or shar files) which are in text format
  476. Xand can be mailed. These files may be unpacked later by executing them
  477. Xwith /bin/sh. The resulting archive is sent to standard out unless the
  478. X\f2\-o\f1 option is given.  A wide range of features provide extensive
  479. Xflexibility in manufacturing shars and in specifying shar "smartness."
  480. XArchives may be "vanilla" or comprehensive.
  481. XThis manual page reflects shar version 3.49.
  482. X.SS OPTIONS
  483. X.PP
  484. XOptions can be given in any order. Some options depend on each other:
  485. X.nf
  486. X    The \f2\-o\f1 option is required if the \f2\-l\f1 or \f2\-L\f1 option is used.
  487. X    The \f2\-n\f1 option is required if the \f2\-a\f1 option is used.
  488. X    See \f2\-V\f1 below.
  489. X.fi
  490. X.IP "\f2\-V\f1"
  491. XProduce "vanilla" shars which rely only upon the existence of sed and
  492. Xecho in the unsharing environment.  In addition, "if test" must also be
  493. Xsupported if the \f2\-X\f1 option is used.  The \f2\-V\f1 silently
  494. Xdisables options offensive to the "network cop" (or "brown shirt"), but
  495. Xdoes warn you if it is specified with \f2\-B\f1, \f2\-C\f1, \f2\-p\f1
  496. Xor \f2\-M\f1 (any of which does or might require uudecode or compress in
  497. Xthe unsharing environment).
  498. X.IP "\f2\-v\f1"
  499. XVerbose OFF. Disables the inclusion of comments to be output when the archive
  500. Xis unpacked.
  501. X.IP "\f2\-w\f1"
  502. XDo NOT check with 'wc \-c' after unpack. The default is to check.
  503. X.IP "\f2\-n\f1 name"
  504. XName of archive to be included in the header of the shar files.
  505. XSee the \f2\-a\f1 switch.
  506. X.IP "\f2\-a\f1"
  507. XAllows automatic generation of headers:
  508. X.nf
  509. X    Submitted-by: who@where
  510. X    Archive-name: <name>/part##
  511. X.fi
  512. XThe <name> must be given with the \f2\-n\f1 switch.
  513. XIf name includes a '/' "/part" isn't used. Thus:
  514. X.RS 10m
  515. X.nf
  516. X.ta 30m
  517. X\-n xyzzy    produces:
  518. X    xyzzy/part01
  519. X    xyzzy/part02
  520. X
  521. X\-n xyzzy/patch    produces:
  522. X    xyzzy/patch01
  523. X    xyzzy/patch02
  524. X
  525. X\-n xyzzy/patch01.    produces:
  526. X    xyzzy/patch01.01
  527. X    xyzzy/patch01.02
  528. X.RE
  529. X.fi
  530. X.IP ""
  531. XThe who@where can be
  532. Xexplicitly stated with the \f2\-s\f1 switch if the default isn't apropriate.
  533. XWho@where is essentially built as `whoami`@`uname`.
  534. X.IP "\f2\-s\f1 who@where"
  535. XOverride automatically determined submitter name.
  536. X.IP "\f2\-x\f1"
  537. XOverwrite existing files without checking.
  538. XIf neither \f2\-x\f1 nor \f2\-X\f1 is specified, the unpack will
  539. Xcheck for and
  540. Xnot overwrite existing files when unpacking the archive
  541. X(unless '\-c' is passed as a parameter to the script when unpacking).
  542. X.IP "\f2\-X\f1"
  543. XInteractively overwrite existing files
  544. X(DO NOT USE FOR SHARS SUBMITTED TO THE NET).
  545. X.IP "\f2\-B\f1"
  546. XTreat all files as binary, use uuencode prior to packing. This increases the
  547. Xsize of the archive. The recipient must have uudecode in order to unpack.
  548. X(USE OF UUENCODE IS NOT APPRECIATED BY MANY ON THE NET).
  549. X.IP "\f2\-T\f1"
  550. XTreat all files as text (default).
  551. X.IP "\f2\-C\f1"
  552. XCompress and uuencode all files prior to packing. The recipient must have
  553. Xuudecode and uncompress in order to unpack
  554. X(USE OF UUENCODE AND COMPRESS IS NOT APPRECIATED BY MANY ON THE NET).
  555. X.IP "\f2\-m\f1"
  556. XGenerate 'touch' commands to restore the file modification dates when
  557. Xunpacking files from the archive.
  558. X.IP "\f2\-p\f1"
  559. XAllow positional parameter options. The options "\f2\-B\f1" and "\f2\-T\f1"
  560. Xand "\f2\-C\f1" may be embedded, and files to the right of the
  561. Xoption will be processed in the specified mode.
  562. X.IP "\f2\-b\f1 X"
  563. XWhen doing compression, use '\-bX' as a parameter to compress.
  564. XThe \f2\-B\f1 options turns on the \f2\-C\f1 option by default.
  565. X.IP "\f2\-M\f1"
  566. XMixed mode. Determine if the files are text or binary and archive correctly.
  567. XFiles found to be binary are uudecoded prior to packing
  568. X(USE OF UUENCODE IS NOT APPRECIATED BY MANY ON THE NET).
  569. X.IP "\f2\-P\f1"
  570. XUse temporary files instead of pipes in the shar file.
  571. X.IP "\f2\-c\f1"
  572. XStart the shar with a cut line. A line saying 'Cut here' is placed at the
  573. Xstart of each output file.
  574. X.IP "\f2\-f\f1"
  575. XRestore by filename only, rather than path. This option causes only file
  576. Xnames to be used, which is useful when building a shar from several
  577. Xdirectories, or another directory.  Note that if a directory name is passed
  578. Xto shar, the substructure of that directory will be restored whether \f2\-f\f1
  579. Xis specified or not.
  580. X.IP "\f2\-d\f1 XXX"
  581. XUse XXX to delimit the files in the shar instead of SHAR_EOF.
  582. XThis is for those who want to personalize their shar files.
  583. X.IP "\f2\-F\f1"
  584. XForces the prefix character (normally 'X' unless the parameter to the \f2\-d\f1
  585. Xoption starts with 'X') to be prepended to every line even if
  586. Xnot required.  This option may slightly increase the size of the archive,
  587. Xespecially if \f2\-B\f1 or \f2\-C\f1 is used.
  588. X.IP "\f2\-o\f1 XXX"
  589. XSave the archive to files XXX.01 thru XXX.nn instead of standard out.
  590. XMust be used when the \f2\-l\f1 or the \f2\-L\f1 switches are used
  591. X.IP "\f2\-l\f1 XX"
  592. XLimit the output file size to XXk bytes but don't split input files.
  593. X.IP "\f2\-L\f1 XX"
  594. XLimit output file size to XXk bytes and split files if necessary. The archives
  595. Xcreated with this option must be unpacked in correct order.
  596. X.IP "\f2\-S\f1"
  597. XRead list of files to be packed from the standard input rather than
  598. Xfrom the command line.  Input must be in a form similar to
  599. Xthat generated by the find command, one filename per line.  This
  600. Xswitch is especially useful when the command line will not hold
  601. Xthe list of files to be packed. For example:
  602. X.nf
  603. X
  604. Xfind . \-type f \-print | sort | shar \-S \-C \-L50 \-o /tmp/big
  605. X
  606. X.fi
  607. XIf \f2\-p\f1 is specified on the command line, then the 
  608. Xoptions "\f2\-B\f1" and "\f2\-T\f1" and "\f2\-C\f1" may be included
  609. Xin the standard input (on a line separate from filenames).
  610. XThe maximum number of lines of standard input, file names
  611. Xand options, may not exceed 1024.
  612. X.SH EXAMPLES
  613. X.nf
  614. X.ta 37m
  615. Xshar *.c > cprog.shar    # all C prog sources
  616. Xshar \-v *.[ch] > cprog.shar    # non-verbose, .c and .h files
  617. Xshar \-B \-l28 \-oarc.sh *.arc    # all binary .arc files, into
  618. X    # files arc.sh.01 thru arc.sh.NN
  619. Xshar \-f /lcl/src/u*.c > u.sh    # use only the filenames
  620. X.ta
  621. X.fi
  622. X.SH WARNINGS
  623. X.PP
  624. XNo chmod or touch is ever generated for directories created when unpacking.
  625. XThus, if a directory is given to shar, the protection and
  626. Xmodification dates of corresponding unpacked directory
  627. Xmay not match those of the original.
  628. X.PP
  629. XIf a directory is passed to shar, it may be scanned more than once.  Therefore,
  630. Xone should be careful not change the directory while shar is running.
  631. X.PP
  632. XBe careful that the output file(s) are not included in the inputs or shar
  633. Xmay loop until the disk fills up.  Be particularly careful when a directory
  634. Xis passed to shar that the output files are not in that directory
  635. X(or a subdirectory of that directory).
  636. X.PP
  637. XUse of the \f2\-B\f1, \f2\-M\f1 or \f2\-C\f1 may slow the archive process
  638. Xconsiderably, depending on the number of files.
  639. X.PP
  640. XUse of \f2\-X\f1 produces shars which \f2WILL\f1 cause problems
  641. Xwith many unshar procedures.  Use this feature only for archives
  642. Xto be passed among agreeable parties.  Certainly, \f2\-X\f1 is NOT
  643. Xfor shell archives which are to be submitted to Usenet.
  644. XUsage of \f2\-B\f1 or \f2\-C\f1 in net shars will cause you to
  645. Xbe flamed off the earth.
  646. XUsing \f2\-m\f1 or not using \f2\-F\f1 may also get you occasional complaints.
  647. X.SH SEE ALSO
  648. X.PP 
  649. Xunshar(1)
  650. X.SH DIAGNOSTICS
  651. X.PP
  652. XError messages for illegal or incompatible options,
  653. Xfor non-regular, missing or inaccessible files or for (unlikely)
  654. Xmemory allocation failure.
  655. X.SH AUTHORS
  656. X.nf
  657. Xshar3 is a derived work based on the efforts of:
  658. Xdecvax!microsof!uw-beave!jim (James Gosling at CMU)
  659. XMichael A. Thompson, Dalhousie University, Halifax, N.S., Canada
  660. Xdavidsen@sixhub (Bill Davidsen)
  661. Xrhg@CPS.COM (Richard H. Gumpertz)
  662. Xcolas@avahi.inria.fr (Colas Nahaboo)
  663. Xbill@netagw.com (Bill Aten)
  664. Xdennis%nanovx@gatech.edu (Dennis Boylan)
  665. Xwht%n4hgf@gatech.edu (Warren Tucker)
  666. X(other anonymous persons)
  667. X
  668. Xman pages:
  669. Xjhd@irfu.se (Jan Dj{rv)
  670. X.fi
  671. SHAR_EOF
  672. chmod 0644 shar.1 ||
  673. echo 'restore of shar.1 failed'
  674. Wc_c="`wc -c < 'shar.1'`"
  675. test 7946 -eq "$Wc_c" ||
  676.     echo 'shar.1: original size 7946, current size' "$Wc_c"
  677. fi
  678. # ============= unshar.1 ==============
  679. if test -f 'unshar.1' -a X"$1" != X"-c"; then
  680.     echo 'x - skipping unshar.1 (File already exists)'
  681. else
  682. echo 'x - extracting unshar.1 (Text)'
  683. sed 's/^X//' << 'SHAR_EOF' > 'unshar.1' &&
  684. X.TH UNSHAR 1 "August 12, 1990"
  685. X.SH NAME
  686. Xunshar \- unpack a shar file
  687. X.SH SYNOPSIS
  688. Xunshar [ \f2\-d\f1 directory ] [ \f2\-c\f1 ] [ \f2\-e\f1 | \f2\-E\f1 exit_line ] [ file ... ]
  689. X.SH DESCRIPTION
  690. X.PP
  691. XUnshar scans mail messages looking for the start of a shell archive. It
  692. Xthen passes the archive through a copy of the shell to unpack it. It
  693. Xwill accept multiple files. If no files are given, standard input is used.
  694. X.PP
  695. XThe \f2\-d\f1 option tells unshar to change directory before unpacking
  696. Xany files.
  697. X.PP
  698. XThe \f2\-c\f1 option is passed through to 'sh' as a parameter to the unpacked
  699. Xscript.  Many archive shar scripts (including those produced by
  700. Xshar 3.40 and newer)
  701. Xuse this to indicate that existing files should be overwritten.
  702. X.PP
  703. XUnshar can unpack shar files that are concatenated in one file with the
  704. X\f2\-e\f1 option, which separates files by recognizing the "exit 0" string
  705. Xat the beginning of a line. 
  706. XThe \f2\-E\f1 option allows you to specify the string that separates archives
  707. Xif "exit 0" isn't appropriate. (Hint: most .signatures have a "\-\-" on a line
  708. Xright before them). \f2\-e\f1 is equivalent to \f2\-E "exit 0"\f1.
  709. X.SH SEE ALSO
  710. Xshar(1)
  711. X.SH DIAGNOSTICS
  712. XAny message from the shell may be displayed.
  713. X.SH AUTHORS
  714. X.nf
  715. XMichael Mauldin at Carnegie-Mellon University
  716. Xguido@mcvax (Guido van Rossum at CWI, Amsterdam)
  717. Xdavidsen@sixhub.uuxp (Bill Davidsen)
  718. Xwht%n4hgf@gatech.edu (Warren Tucker)
  719. Xrhg@CPS.COM (Richard H. Gumpertz)
  720. Xcolas@avahi.inria.fr (Colas Nahaboo)
  721. X
  722. Xman pages:
  723. Xjhd@irfu.se (Jan Dj{rv)
  724. X.fi
  725. X.PP
  726. SHAR_EOF
  727. chmod 0644 unshar.1 ||
  728. echo 'restore of unshar.1 failed'
  729. Wc_c="`wc -c < 'unshar.1'`"
  730. test 1515 -eq "$Wc_c" ||
  731.     echo 'unshar.1: original size 1515, current size' "$Wc_c"
  732. fi
  733. # ============= uushar.c ==============
  734. if test -f 'uushar.c' -a X"$1" != X"-c"; then
  735.     echo 'x - skipping uushar.c (File already exists)'
  736. else
  737. echo 'x - extracting uushar.c (Text)'
  738. sed 's/^X//' << 'SHAR_EOF' > 'uushar.c' &&
  739. X/* $Header: /u/rhg/src/shar/uushar.c,v 3.49 90/09/12 15:15:26 rhg Exp $ */
  740. X
  741. X#include <stdio.h>
  742. X#include <sys/types.h>
  743. X#include <sys/stat.h>
  744. X
  745. X/* ENC is the basic 1 character encoding function to make a char printing */
  746. X#if 1 /* Richard H. Gumpertz (RHG@CPS.COM), 24 April 1990 */
  747. X#define ENC(c) ((((c) + 077) & 077) + 041)
  748. X#else /* RHG */
  749. X#define ENC(c) ((((c) & 077) + ' ') | ((c & 077) == 0 ? 0100 : 0))
  750. X#endif /* RHG */
  751. X
  752. Xencode (in, out)
  753. X    FILE *in;
  754. X    FILE *out;
  755. X{
  756. X    char  buf[80];
  757. X    int  i, n;
  758. X
  759. X    for (;;)
  760. X    {
  761. X    /* 1 (up to) 45 character line */
  762. X    n = fr (in, buf, 45);
  763. X    putc (ENC (n), out);
  764. X
  765. X    for (i = 0; i < n; i += 3)
  766. X        outdec (&buf[i], out);
  767. X
  768. X    putc ('\n', out);
  769. X    if (n <= 0)
  770. X        break;
  771. X    }
  772. X}
  773. X
  774. X/*
  775. X * output one group of 3 bytes, pointed at by p, on file f.
  776. X */
  777. Xoutdec (p, f)
  778. X    char *p;
  779. X    FILE *f;
  780. X{
  781. X    int  c1, c2, c3, c4;
  782. X
  783. X    c1 = *p >> 2;
  784. X    c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  785. X    c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  786. X    c4 = p[2] & 077;
  787. X    putc (ENC (c1), f);
  788. X    putc (ENC (c2), f);
  789. X    putc (ENC (c3), f);
  790. X    putc (ENC (c4), f);
  791. X}
  792. X
  793. X/* fr: like read but stdio */
  794. Xint
  795. X     fr (fp, buf, cnt)
  796. X    FILE *fp;
  797. X    char *buf;
  798. X    int  cnt;
  799. X{
  800. X    int  c, i;
  801. X
  802. X    for (i = 0; i < cnt; i++)
  803. X    {
  804. X    c = getc (fp);
  805. X    if (c == EOF)
  806. X        return (i);
  807. X    buf[i] = c;
  808. X    }
  809. X    return (cnt);
  810. X}
  811. X/* vi: set tabstop=4 shiftwidth=4: */
  812. SHAR_EOF
  813. chmod 0644 uushar.c ||
  814. echo 'restore of uushar.c failed'
  815. Wc_c="`wc -c < 'uushar.c'`"
  816. test 1365 -eq "$Wc_c" ||
  817.     echo 'uushar.c: original size 1365, current size' "$Wc_c"
  818. fi
  819. # ============= who@where.c ==============
  820. if test -f 'who@where.c' -a X"$1" != X"-c"; then
  821.     echo 'x - skipping who@where.c (File already exists)'
  822. else
  823. echo 'x - extracting who@where.c (Text)'
  824. sed 's/^X//' << 'SHAR_EOF' > 'who@where.c' &&
  825. X/* $Header: /u/rhg/src/shar/who@where.c,v 3.49 90/09/12 15:15:33 rhg Exp $ */
  826. X
  827. X/*+-------------------------------------------------------------------------
  828. X    who@where.c - find out who i am & where i am
  829. X    ...!gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu)
  830. X--------------------------------------------------------------------------*/
  831. X/*+:EDITS:*/
  832. X/*:09-12-1990-01:04-rhg@cps.com-added declarations of strcpy and strcat */
  833. X/*:09-09-1990-19:49-rhg@cps.com-added explicit return statement to who_where */
  834. X/*:04-03-1990-19:55-wht@n4hgf-get rid of complicated who_am_i */
  835. X/*:04-01-1990-13:30-pat@rwing-use utsname.nodename instead of sysname */
  836. X/*:04-02-1990-12:12-wht@n4hgf-sigh... some pwd.h dont declare functions */
  837. X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
  838. X/*:03-28-1990-15:24-wht@n4hgf-creation */
  839. X
  840. X#include <stdio.h>
  841. X#include <sys/types.h>
  842. X#include <pwd.h>
  843. X
  844. X/* assume system v unless otherwise fixed */
  845. X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42) && !defined(SYS5)
  846. X#define BSD42
  847. X#endif
  848. X#if defined(sun)    /* this miscreant doesn't exactly fit BSD or SYSV */
  849. X#undef BSD42
  850. X#undef SYS5
  851. X#endif
  852. X#if !defined(BSD42) && !defined(sun) && !defined(SYS5)
  853. X#define SYS5
  854. X#endif
  855. X
  856. X#if defined(sun) || defined(BSD42)
  857. X#define strchr    index
  858. X#define strrchr    rindex
  859. X#endif
  860. X
  861. X#if !defined(SYS5) || defined(sun)
  862. X#include <sys/time.h>
  863. Xextern int errno;
  864. X#else
  865. X#include <sys/utsname.h>
  866. X#include <time.h>
  867. X#endif    /* system dependencies */
  868. X
  869. Xchar *strcpy();
  870. Xchar *strcat();
  871. Xstruct passwd *getpwuid();
  872. X
  873. X/*+-------------------------------------------------------------------------
  874. X    who_am_i() - get user name
  875. X--------------------------------------------------------------------------*/
  876. Xchar *
  877. Xwho_am_i()
  878. X{
  879. X    struct passwd *passwd;
  880. X    passwd = getpwuid(getuid());
  881. X    (void)endpwent();
  882. X    if(passwd == (struct passwd *)0)
  883. X        return("???");
  884. X    return(passwd->pw_name);
  885. X
  886. X}    /* end of who_am_i */
  887. X
  888. X/*+-------------------------------------------------------------------------
  889. X    where_am_i() - do uname, gethostname, or read file (/etc/systemid)
  890. X--------------------------------------------------------------------------*/
  891. Xchar *
  892. Xwhere_am_i()
  893. X{
  894. X#if defined(M_SYS5)    /* SCO UNIX or XENIX */
  895. XFILE *fpsid = fopen("/etc/systemid","r");
  896. Xstatic char s20[20];
  897. X    if(!fpsid)
  898. X        return("???");
  899. X    fgets(s20,sizeof(s20),fpsid);
  900. X    fclose(fpsid);
  901. X    s20[strlen(s20) - 1] = 0;
  902. X    return(s20);
  903. X#else /* M_SYS5 */
  904. X#if defined(SYS5)
  905. Xstatic struct utsname where_i_am;
  906. X    uname(&where_i_am);
  907. X    return(where_i_am.nodename);
  908. X#else /* SYS5 */
  909. Xstatic char where_i_am[64];
  910. X    gethostname(where_i_am,sizeof(where_i_am));
  911. X    return(where_i_am);
  912. X#endif /* SYS5 */
  913. X#endif /* M_SYS5 */
  914. X}    /* end of where_am_i */
  915. X
  916. X/*+-------------------------------------------------------------------------
  917. X    who_where(buf)
  918. X--------------------------------------------------------------------------*/
  919. Xchar *
  920. Xwho_where(buf)
  921. Xchar *buf;
  922. X{
  923. Xstatic char ww[64];
  924. X
  925. X    if(!buf)
  926. X        buf = ww;
  927. X    strcpy(buf,who_am_i());
  928. X    strcat(buf,"@");
  929. X    return(strcat(buf,where_am_i()));
  930. X}    /* end of who_where */
  931. X
  932. X/* vi: set tabstop=4 shiftwidth=4: */
  933. X/* end of who@where.c */
  934. SHAR_EOF
  935. chmod 0644 who@where.c ||
  936. echo 'restore of who@where.c failed'
  937. Wc_c="`wc -c < 'who@where.c'`"
  938. test 3077 -eq "$Wc_c" ||
  939.     echo 'who@where.c: original size 3077, current size' "$Wc_c"
  940. fi
  941. # ============= unshar.c ==============
  942. if test -f 'unshar.c' -a X"$1" != X"-c"; then
  943.     echo 'x - skipping unshar.c (File already exists)'
  944. else
  945. echo 'x - extracting unshar.c (Text)'
  946. sed 's/^X//' << 'SHAR_EOF' > 'unshar.c' &&
  947. Xchar *revision = "3.49";
  948. Xchar RCS_ID[] = "$Header: /u/rhg/src/shar/unshar.c,v 3.49 90/09/12 15:15:17 rhg Exp $";
  949. X/****************************************************************
  950. X * unshar.c: Unpackage one or more shell archive files
  951. X *
  952. X * Usage:     unshar [ -c ] [ -e | -E exit_line ] [ -d directory ] [ file ... ]
  953. X *
  954. X * Description:    unshar is a filter which removes the front part
  955. X *        of  a file and passes the rest to the 'sh' command.
  956. X *        It understands phrases like "cut here", and also
  957. X *        knows about shell comment characters and the Unix
  958. X *        commands "echo", "cat", and "sed".
  959. X *
  960. X *        The -c flag is passed through to the shell as a parameter to the script
  961. X *
  962. X *        It can unshar shar files concatenated in one file, with the
  963. X *        the "-e" command, which separates files by recognizing the
  964. X *        "exit 0" string at the beginning of a line
  965. X *
  966. X *        (The -E string option allows you to specify this string, thus
  967. X *        -e is equivalent to -E "exit 0")
  968. X *
  969. X *        The -d flag tells unshar to change directory before unsharing
  970. X *
  971. X * HISTORY
  972. X * 12-Sep-90  Richard H. Gumpertz (rhg@cps.com)
  973. X *        use fprintf instead of printf when printing error return from getwd.
  974. X *        deleted unused initialization of more_to_read in process.
  975. X *        changed ch from char to int in process so the EOF check would work.
  976. X *  4-Aug-90  Richard H. Gumpertz (rhg@cps.com)
  977. X *        renamed -c and -C to -e and -E and added -c flag (passed through to sh)
  978. X * 19-Apr-90  Colas Nahaboo (colas@mirsa.inria.fr)
  979. X *        added -c and -C flags to read from concatenated archives
  980. X *  1-Feb-85  Guido van Rossum (guido@mcvax) at CWI, Amsterdam
  981. X *        Added missing 'quit' routine;
  982. X *        added -d flag to change to directory first;
  983. X *        added filter mode (read stdin when no arguments);
  984. X *        added 'getopt' to get flags (makes it self-contained).
  985. X * 29-Jan-85  Michael Mauldin (mlm) at Carnegie-Mellon University
  986. X *        Created.
  987. X ****************************************************************/
  988. X/*+:EDITS:*/
  989. X/*:08-04-1990-15:54-rhg@cps.com-changes listed above (-c/-C => -e/-E, new -c) */
  990. X/*:05-05-1990-01:37-relay.EU.net!rivm!a3-dont assume vax is running BSD */
  991. X/*:04-19-1990-15:20-wht@n4hgf-fix so -d doesnt make argv files unreachable */
  992. X/*:04-19-1990-15:06-wht@n4hgf-colas@mirsa patches had expanded tabs */
  993. X/*:04-10-1990-22:02-wht@n4hgf-stdin failed sometimes-can not seek on pipe */
  994. X
  995. X#include <stdio.h>
  996. X#define EOL '\n'
  997. X
  998. X#if (defined(pyr) || defined(sun) || defined(BSD42) || \
  999. X defined(vax) || defined(sequent)) && !defined(SYS5)
  1000. X#define strchr    index
  1001. X#undef USE_GETCWD
  1002. Xchar *getwd();
  1003. X#else
  1004. X#define USE_GETCWD
  1005. Xchar *getcwd();
  1006. X#endif
  1007. X
  1008. Xchar *strchr();
  1009. X
  1010. Xextern char *optarg;
  1011. Xextern int optind;
  1012. X
  1013. Xint c_flag = 0;
  1014. Xint continue_reading = 0;
  1015. Xchar *exit_string = "exit 0";
  1016. Xint exit_string_length;
  1017. Xchar argvdir[1024];
  1018. X
  1019. Xmain(argc,argv)
  1020. Xint argc;
  1021. Xchar *argv[];
  1022. X{
  1023. X    int i,ch;
  1024. X    FILE *in;
  1025. X    char s1024[1024];
  1026. X
  1027. X    setbuf(stdout,NULL);
  1028. X    setbuf(stderr,NULL);
  1029. X
  1030. X#ifdef USE_GETCWD
  1031. X    if(!getcwd(argvdir,sizeof(argvdir)))
  1032. X    {
  1033. X        perror("cannot get current directory name");
  1034. X        exit(1);
  1035. X    }
  1036. X#else
  1037. X    argvdir[0] = 0;
  1038. X    if(!getwd(argvdir))
  1039. X    {
  1040. X        if(argvdir[0])
  1041. X            fprintf(stderr,"%s\n",argvdir);
  1042. X        else
  1043. X            fprintf(stderr,"cannot get current directory name\n");
  1044. X        exit(1);
  1045. X    }
  1046. X#endif
  1047. X
  1048. X
  1049. X    /* Process options */
  1050. X
  1051. X    while((ch = getopt(argc,argv,"cd:eE:")) != EOF)
  1052. X    {
  1053. X        switch(ch)
  1054. X        {
  1055. X        case 'c':
  1056. X            c_flag = 1;
  1057. X            break;
  1058. X        case 'd':
  1059. X            if(chdir(optarg) == -1)
  1060. X            {
  1061. X                fprintf(stderr,"unshar: cannot chdir to '%s'\n",optarg);
  1062. X                exit(2);
  1063. X            }
  1064. X            break;
  1065. X        case 'E':
  1066. X            exit_string = optarg;
  1067. X        case 'e':
  1068. X            continue_reading = 1;
  1069. X            exit_string_length = strlen(exit_string);
  1070. X            break;
  1071. X        default:
  1072. X            quit(2,"Usage: unshar [-c] [-e | -E exit_line] [-d directory] [file ...]\n");
  1073. X        }
  1074. X    }
  1075. X
  1076. X    if(optind < argc)
  1077. X    {
  1078. X        for(i= optind; i < argc; ++i)
  1079. X        {
  1080. X            if(argv[i][0] == '/') {
  1081. X                strcpy(s1024,argv[i]);
  1082. X            } else {
  1083. X                strcpy(s1024,argvdir);
  1084. X                strcat(s1024,"/");
  1085. X                strcat(s1024,argv[i]);
  1086. X            }
  1087. X            if(!(in = fopen(s1024,"r")))
  1088. X            {
  1089. X                perror(s1024);
  1090. X                exit(1);
  1091. X            }
  1092. X            process(s1024,in);
  1093. X            fclose(in);
  1094. X        }
  1095. X    }
  1096. X    else
  1097. X    {
  1098. X        sprintf(s1024,"/tmp/unsh.%05d",getpid());
  1099. X        unlink(s1024);
  1100. X        if(!(in = fopen(s1024,"w+")))
  1101. X        {
  1102. X            fprintf(stderr,"cannot open temp file '%s'\n",s1024);
  1103. X            exit(1);
  1104. X        }
  1105. X        unlink(s1024);    /* don't try this with MSDOS, sports fans */
  1106. X        while(i = fread(s1024,1,sizeof(s1024),stdin))
  1107. X            fwrite(s1024,i,1,in);
  1108. X        rewind(in);
  1109. X        process("standard input",in);
  1110. X        fclose(in);
  1111. X    }
  1112. X
  1113. X    exit(0);
  1114. X}
  1115. X
  1116. X
  1117. Xprocess(name,in)
  1118. Xchar *name;
  1119. XFILE *in;
  1120. X{
  1121. X    char buffer[8196];
  1122. X    int ch;
  1123. X    FILE *shpr,*popen();
  1124. X    long current_position = 0;
  1125. X    char *more_to_read;
  1126. X
  1127. X    while(position(name,in,current_position))
  1128. X    {
  1129. X        printf("%s:\n",name);
  1130. X        if(!(shpr = popen((c_flag ? "sh -s -c" : "sh"),"w")))
  1131. X            quit(1,"unshar: cannot open 'sh' process\n");
  1132. X
  1133. X        if (!continue_reading) {
  1134. X            while((ch = fgetc(in)) != EOF)
  1135. X                fputc(ch,shpr);
  1136. X            pclose(shpr);
  1137. X            break;
  1138. X        } else {
  1139. X            while (more_to_read = fgets(buffer, 8196, in)) {
  1140. X                fputs(buffer, shpr);
  1141. X                if (!strncmp(exit_string, buffer, exit_string_length)) {
  1142. X                    break;
  1143. X                }
  1144. X            }
  1145. X            pclose(shpr);
  1146. X            if (more_to_read)
  1147. X                current_position = ftell(in);
  1148. X            else {
  1149. X                break;
  1150. X            }
  1151. X        }
  1152. X    }
  1153. X}
  1154. X
  1155. X/****************************************************************
  1156. X * position: position 'fil' at the start of the shell command
  1157. X * portion of a shell archive file.
  1158. X ****************************************************************/
  1159. X
  1160. Xposition(fn,fil,start)
  1161. Xchar *fn;
  1162. XFILE *fil;
  1163. Xlong start;                   /* scan file from position */
  1164. X{
  1165. X    char buf[BUFSIZ];
  1166. X    long pos,ftell();
  1167. X
  1168. X    /* Results from star matcher */
  1169. X    static char res1[BUFSIZ],res2[BUFSIZ],res3[BUFSIZ],res4[BUFSIZ];
  1170. X    static char *result[] = 
  1171. X    {
  1172. X        res1,res2,res3,res4         };
  1173. X
  1174. X    fseek(fil, start, 0);
  1175. X
  1176. X    while(1)
  1177. X    { /* Record position of the start of this line */
  1178. X        pos = ftell(fil);
  1179. X
  1180. X        /* Read next line, fail if no more and no previous process */
  1181. X        if(!fgets(buf,BUFSIZ,fil))
  1182. X        {
  1183. X            if(!start)
  1184. X                fprintf(stderr,"unshar: found no shell commands in %s\n",fn);
  1185. X            return(0);
  1186. X        }
  1187. X
  1188. X        /* Bail out if we see C preprocessor commands or C comments */
  1189. X        if(stlmatch(buf,"#include")    || stlmatch(buf,"# include") ||
  1190. X            stlmatch(buf,"#define")    || stlmatch(buf,"# define") ||
  1191. X            stlmatch(buf,"#ifdef")    || stlmatch(buf,"# ifdef") ||
  1192. X            stlmatch(buf,"#ifndef")    || stlmatch(buf,"# ifndef") ||
  1193. X            stlmatch(buf,"/*"))
  1194. X        {
  1195. X            fprintf(stderr,
  1196. X                "unshar: %s looks like raw C code, not a shell archive\n",fn);
  1197. X            return(0);
  1198. X        }
  1199. X
  1200. X        /* Does this line start with a shell command or comment */
  1201. X        if(stlmatch(buf,"#")    || stlmatch(buf,":") ||
  1202. X            stlmatch(buf,"echo ")    || stlmatch(buf,"sed ") ||
  1203. X            stlmatch(buf,"cat ") || stlmatch(buf,"if "))
  1204. X        {
  1205. X            fseek(fil,pos,0);
  1206. X            return(1);
  1207. X        }
  1208. X
  1209. X        /* Does this line say "Cut here" */
  1210. X        if(smatch(buf,"*CUT*HERE*",result) ||
  1211. X            smatch(buf,"*cut*here*",result) ||
  1212. X            smatch(buf,"*TEAR*HERE*",result) ||
  1213. X            smatch(buf,"*tear*here*",result) ||
  1214. X            smatch(buf,"*CUT*CUT*",result) ||
  1215. X            smatch(buf,"*cut*cut*",result))
  1216. X        {
  1217. X            /* Read next line after "cut here", skipping blank lines */
  1218. X            while(1)
  1219. X            {
  1220. X                pos = ftell(fil);
  1221. X
  1222. X                if(!fgets(buf,BUFSIZ,fil))
  1223. X                {
  1224. X                    fprintf(stderr,
  1225. X                        "unshar: found no shell commands after 'cut' in %s\n",fn);
  1226. X                    return(0);
  1227. X                }
  1228. X
  1229. X                if(*buf != '\n') break;
  1230. X            }
  1231. X
  1232. X            /* Win if line starts with a comment character of lower case letter */
  1233. X            if(*buf == '#' || *buf == ':' || (('a' <= *buf) && ('z' >= *buf)))
  1234. X            {
  1235. X                fseek(fil,pos,0);
  1236. X                return(1);
  1237. X            }
  1238. X
  1239. X            /* Cut here message lied to us */
  1240. X            fprintf(stderr,"unshar: %s is probably not a shell archive,\n",fn);
  1241. X            fprintf(stderr,"        the 'cut' line was followed by: %s",buf);
  1242. X            return(0);
  1243. X        }
  1244. X    }
  1245. X}
  1246. X
  1247. X/*****************************************************************
  1248. X * stlmatch  --  match leftmost part of string
  1249. X *
  1250. X * Usage:  i = stlmatch (big,small)
  1251. X *    int i;
  1252. X *    char *small, *big;
  1253. X *
  1254. X * Returns 1 iff initial characters of big match small exactly;
  1255. X * else 0.
  1256. X *
  1257. X * HISTORY
  1258. X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
  1259. X *      Ripped out of CMU lib for Rog-O-Matic portability
  1260. X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  1261. X *    Rewritten for VAX from Ken Greer's routine.
  1262. X *
  1263. X *  Originally from klg (Ken Greer) on IUS/SUS UNIX
  1264. X *****************************************************************/
  1265. X
  1266. Xint stlmatch(big,small)
  1267. Xchar *small,*big;
  1268. X{
  1269. X    register char *s,*b;
  1270. X    s = small;
  1271. X    b = big;
  1272. X    do
  1273. X    {
  1274. X        if(*s == '\0')
  1275. X            return(1);
  1276. X    }  while(*s++ == *b++);
  1277. X    return(0);
  1278. X}
  1279. X
  1280. X/*****************************************************************
  1281. X * smatch: Given a data string and a pattern containing one or
  1282. X * more embedded stars (*) (which match any number of characters)
  1283. X * return true if the match succeeds, and set res[i] to the
  1284. X * characters matched by the 'i'th *.
  1285. X *****************************************************************/
  1286. X
  1287. Xsmatch(dat,pat,res)
  1288. Xregister char *dat,*pat,**res;
  1289. X{
  1290. X    register char *star = 0,*starend,*resp;
  1291. X    int nres = 0;
  1292. X
  1293. X    while(1)
  1294. X    {
  1295. X        if(*pat == '*')
  1296. X        {
  1297. X            star = ++pat;                  /* Pattern after * */
  1298. X            starend = dat;                  /* Data after * match */
  1299. X            resp = res[nres++];              /* Result string */
  1300. X            *resp = '\0';                  /* Initially null */
  1301. X        }
  1302. X        else if(*dat == *pat)              /* Characters match */
  1303. X        {
  1304. X            if(*pat == '\0')              /* Pattern matches */
  1305. X                return(1);
  1306. X            pat++;                      /* Try next position */
  1307. X            dat++;
  1308. X        }
  1309. X        else
  1310. X        {
  1311. X            if(*dat == '\0')              /* Pattern fails - no more */
  1312. X                return(0);                  /* data */
  1313. X            if(star == 0)                  /* Pattern fails - no * to */
  1314. X                return(0);                  /* adjust */
  1315. X            pat = star;                  /* Restart pattern after * */
  1316. X            *resp++ = *starend;              /* Copy character to result */
  1317. X            *resp = '\0';                  /* null terminate */
  1318. X            dat = ++starend;                  /* Rescan after copied char */
  1319. X        }
  1320. X    }
  1321. X}
  1322. X
  1323. X/*****************************************************************
  1324. X * Addendum: quit subroutine (print a message and exit)
  1325. X *****************************************************************/
  1326. X
  1327. Xquit(status,message)
  1328. Xint status;
  1329. Xchar *message;
  1330. X{
  1331. X    fprintf(stderr,message);
  1332. X    exit(status);
  1333. X}
  1334. X
  1335. X/*****************************************************************
  1336. X * Public Domain getopt routine
  1337. X *****************************************************************/
  1338. X
  1339. X/*
  1340. X * get option letter from argument vector
  1341. X */
  1342. Xint opterr = 1;        /* useless, never set or used */
  1343. Xint optind = 1;        /* index into parent argv vector */
  1344. Xint optopt;            /* character checked for validity */
  1345. Xchar *optarg;        /* argument associated with option */
  1346. X
  1347. X#define BADCH    (int)'?'
  1348. X#define EMSG    ""
  1349. X#define tell(s)    fputs(*nargv,stderr);fputs(s,stderr); \
  1350. X        fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
  1351. X
  1352. Xgetopt(nargc,nargv,ostr)
  1353. Xint nargc;
  1354. Xchar **nargv,*ostr;
  1355. X{
  1356. X    static char *place = EMSG;    /* option letter processing */
  1357. X    register char *oli;        /* option letter list index */
  1358. X    char *strchr();
  1359. X
  1360. X    if(!*place)
  1361. X    {            /* update scanning pointer */
  1362. X        if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place)
  1363. X            return(EOF);
  1364. X        if(*place == '-')
  1365. X        {    /* found "--" */
  1366. X            ++optind;
  1367. X            return(EOF);
  1368. X        }
  1369. X    }                /* option letter okay? */
  1370. X    if((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt)))
  1371. X    {
  1372. X        if(!*place) ++optind;
  1373. X        tell(": illegal option -- ");
  1374. X    }
  1375. X    if(*++oli != ':')
  1376. X    {        /* don't need argument */
  1377. X        optarg = (char *)0;
  1378. X        if(!*place) ++optind;
  1379. X    }
  1380. X    else 
  1381. X    {                /* need an argument */
  1382. X        if(*place) optarg = place;    /* no white space */
  1383. X        else if(nargc <= ++optind)
  1384. X        {    /* no arg */
  1385. X            place = EMSG;
  1386. X            tell(": option requires an argument -- ");
  1387. X        }
  1388. X        else optarg = nargv[optind];    /* white space */
  1389. X        place = EMSG;
  1390. X        ++optind;
  1391. X    }
  1392. X    return(optopt);            /* dump back option letter */
  1393. X}
  1394. X/* vi: set tabstop=4 shiftwidth=4: */
  1395. SHAR_EOF
  1396. chmod 0644 unshar.c ||
  1397. echo 'restore of unshar.c failed'
  1398. Wc_c="`wc -c < 'unshar.c'`"
  1399. test 11602 -eq "$Wc_c" ||
  1400.     echo 'unshar.c: original size 11602, current size' "$Wc_c"
  1401. fi
  1402. true || echo 'restore of shar.c failed'
  1403. echo End of part 1, continue with part 2
  1404. exit 0
  1405.  
  1406. -- 
  1407.   ==========================================================================
  1408.   | Richard H. Gumpertz    rhg@CPS.COM    (913) 642-1777 or (816) 891-3561 |
  1409.   | Computer Problem Solving, 8905 Mohawk Lane, Leawood, Kansas 66206-1749 |
  1410.   ==========================================================================
  1411.