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

  1. From: wht@n4hgf.uucp (Warren Tucker)
  2. Newsgroups: alt.sources
  3. Subject: shar 3.21
  4. Message-ID: <674@n4hgf.uucp>
  5. Date: 19 Apr 90 20:51:37 GMT
  6. X-Checksum-Snefru: cb786230 9313e18f 020da0e0 47abd985
  7.  
  8. Submitted-by: wht%n4hgf@gatech.edu
  9. Archive-name: shar321/part01
  10.  
  11. Here is shar 3.21, an updated version of shar 3.11, derived from 'shar2'.
  12. This offering is the work of many people. Lately, rhg@CPS.COM (Richard H.
  13. Gumpertz) made significant changes to 3.11. colas@avahi.inria.fr (Colas
  14. Nahaboo) and I made enhancements to unshar. The details appear in
  15. the README file.
  16.  
  17. ---- Cut Here and unpack ----
  18. #!/bin/sh
  19. # This is shar321, a shell archive (shar 3.21)
  20. # made 04/19/1990 20:17 UTC by wht%n4hgf@gatech.edu
  21. # Source directory /u1/src/shar
  22. #
  23. # existing files WILL be overwritten
  24. #
  25. # This shar contains:
  26. # length  mode       name
  27. # ------ ---------- ------------------------------------------
  28. #   5941 -rw-r--r-- README
  29. #    333 -rw-r--r-- Makefile
  30. #  28774 -rw-r--r-- shar.c
  31. #  10737 -rw-r--r-- unshar.c
  32. #   1169 -rw-r--r-- uushar.c
  33. #   2784 -rw-r--r-- who@where.c
  34. #
  35. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  36.  then TOUCH=touch
  37.  else TOUCH=true
  38. fi
  39. # ============= README ==============
  40. echo "x - extracting README (Text)"
  41. sed 's/^X//' << 'SHAR_EOF' > README &&
  42. XSubmitted-by: wht%n4hgf@gatech.edu
  43. XArchive-name: shar321/part01
  44. X
  45. XHere is shar 3.21, an updated version of shar 3.11, derived from 'shar2'.
  46. XThis offering is the work of many people. Lately, rhg@CPS.COM (Richard H.
  47. XGumpertz) made significant changes to 3.11. colas@avahi.inria.fr (Colas
  48. XNahaboo) and I made enhancements to unshar. The change history appears
  49. Xat the bottom of this file.
  50. X
  51. XThis version's shar:
  52. X1) generates shell code which attempts to create missing directories
  53. X2) handle deviants sun, vax, pyramid, sequent, and SCO XENIX/UNIX
  54. X   automatically; for system V systems I did not catch, add -DSYS5
  55. X   to CFLAGS; for other BSD-like systems, add -DBSD42
  56. X3) if unsharing system's touch is Sys V compatible (allows touch -m),
  57. X   the unshar process restores file dates
  58. X4) An archive name may be specified for includion in the header
  59. X   of the shar files( -n switch)
  60. X5) allows automatic generation of "Submitted-by: who@where" &
  61. X   "Archive-name: <name>/part##" headers
  62. X6) uses getopt; no good system library should be without a copy
  63. X   but it is readily available (like look in unshar.c)
  64. X7) other chrome-plated junque
  65. X
  66. XThis version's unshar:
  67. X1) can change directory before unsharing
  68. X2) can unshar from standard in, from a collection of shars,
  69. X   from a file containing multiple concatenated shars,
  70. X   or a mixture of shar files and concatenated-shar files.
  71. X3) does not have an Social Security number.
  72. X
  73. X------------------------ shar  usage -----------------------------------
  74. X
  75. Xshar 3.21
  76. Xusage: shar [ options ] file [ file1 ... ] ]
  77. X-v  verbose messages OFF while executing
  78. X-w  don't check with 'wc -c' after unpack
  79. X-n  Name of archive (documentation)
  80. X-a  Generate Submitted-by: & Archive-name: headers
  81. X-s  override automatically determined submitter name
  82. X-x  don't overwrite existing files
  83. X-X  interactively overwrite existing files (NOT FOR NET SHARS)
  84. X-b  treat all files as binary, use uuencode
  85. X-t  treat all files as text (default)
  86. X-C  compress and uuencode all files
  87. X-p  allow positional parameter options. The options "-b" and "-t"
  88. X    and "-C" may be embedded, and files to the right of the
  89. X    option will be processed in the specified mode
  90. X-M  mixed mode. Determine if the files are text or
  91. X    binary and archive correctly.
  92. X-P  use temp files instead of pipes in the shar file
  93. X-c  start the shar with a cut line
  94. X-f  restore by filename only, rather than path
  95. X-dXXX   use XXX to delimit the files in the shar
  96. X-oXXX   (or -o XXX) output to file XXX.01 thru XXX.nn
  97. X-lXX    limit output file size to XXk bytes (but don't split files)
  98. X-LXX    limit output file size to XXk bytes (may split files)
  99. X
  100. XThe 'o' option is required if the 'l' or 'L' option is used
  101. XThe 'n' option is required if the 'a' option is used
  102. XThe 'x' and 'L' options are incompatible
  103. X
  104. X-a generates sharname/part## headers. If you are producing patches
  105. Xyou'll need to edit -a headers (or please improve shar :-))
  106. XThe automatic submitter name is trivial: essentially `whoami`@`uname`
  107. X
  108. X------------------------ unshar usage -----------------------------------
  109. XUnshar has no usage built in.  It has default actions when invoked
  110. Xwith no arguments (read from stdin).
  111. X
  112. XUsage:     unshar [-c] [-C exit_line] [ -d directory ] [ file ] ...
  113. X
  114. X     The -d flag tells unshar to change directory before unsharing
  115. X
  116. X     It can unshar shar files concatenated in one file, with the
  117. X     the "-c" command, which separates files by recognizing the
  118. X     "exit 0" string at the beginning of a line
  119. X
  120. X     (The -C string option allows you to specify this string, thus
  121. X     -c is equivalent to -C "exit 0")
  122. X
  123. X
  124. X--------------------- history -----------------------------------------
  125. XChanges since 3.11: kudos to rhg@CPS.COM (Richard H. Gumpertz)
  126. X
  127. X1.  The -l switch still specifies a maximum size for the generated
  128. X    shar files, but now it prevents files from spanning shar parts.
  129. X    Shars generated using this method may be unpacked in any order.
  130. X
  131. X2.  The old -l switch functionality is precisely emulated by using the
  132. X    the -L switch.  That is, archived files may be split across parts.
  133. X    Shars generated using this method must still be unpacked in order.
  134. X
  135. X3.  The -C switch causes files to be compressed, then uuencoded.
  136. X    Unpacking reverses the process.
  137. X
  138. X4.  The -P causes the shar to use temp files instead of pipes in
  139. X    the unshar process.
  140. X
  141. X5.  The -f causes files to be resotred by name only (i.e., strip
  142. X    directory portion of input filenames before placing the name
  143. X    into the shar.
  144. X
  145. X
  146. XChanges since 3.20: kudos to colas@avahi.inria.fr (Colas Nahaboo)
  147. X
  148. X1.  The Archived-name: header no longer uses "/part" if there is
  149. X    a "/" in the -n name.  Thus
  150. X        -n xyzzy                     procduces:
  151. X                                     xyzzy/part01
  152. X                                     xyzzy/part02
  153. X
  154. X        -n xyzzy/patch               procduces:
  155. X                                     xyzzy/patch01
  156. X                                     xyzzy/patch02
  157. X
  158. X        -n xyzzy/patch01.            procduces:
  159. X                                     xyzzy/patch01.01
  160. X                                     xyzzy/patch01.02
  161. X2.  The Archive-name part number other than part01 had no leading zero
  162. X    in the number.
  163. X
  164. X3.  The "Submitted-by:" header was missing the hyphen (minus for olde
  165. X    UNIX hackres).
  166. X
  167. X4.  The unshar program may now unshar a whole mailbox or concatenation
  168. X    of shar files.
  169. X
  170. X    -C "string" looks for "string" at the beginning of the line to
  171. X       break the file into individual shar files
  172. X    -c is equivalent to -C "exit 0"
  173. X
  174. X    This of course will only work if there is something in the shar
  175. X    file recognizable to terminate the shar.  Some shars dont have
  176. X    "exit 0" at the end.  However, a clue: most/many .signatures have
  177. X    "--" on a line right before them.
  178. X
  179. X5.  Unshar -d (change directory) no longer makes argv files unreachable.
  180. X    I had never used the feature until the other day.  I guess the
  181. X    author has used in only for unsharing from stdin.
  182. X
  183. SHAR_EOF
  184. $TOUCH -am 0419161790 README &&
  185. chmod 0644 README ||
  186. echo "restore of README failed"
  187. set `wc -c README`;Wc_c=$1
  188. if test "$Wc_c" != "5941"; then
  189.     echo original size 5941, current size $Wc_c
  190. fi
  191. # ============= Makefile ==============
  192. echo "x - extracting Makefile (Text)"
  193. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  194. X#  CHK=0xDDF8
  195. X#
  196. X#  makefile for shar
  197. X#
  198. X#+:EDITS:
  199. X#:03-28-1990-14:54-wht@n4hgf-for 3.10, add who@where.c
  200. X
  201. XCFLAGS    = -O 
  202. X
  203. XSRC    = shar.c uushar.c unshar.sh
  204. XOBJ    = shar.o uushar.o who@where.o
  205. XDOC    = shar.1 unshar.1 shar.readme
  206. X
  207. Xall: shar unshar
  208. X
  209. Xshar: $(OBJ)
  210. X    cc $(CFLAGS) $(OBJ) -o shar
  211. X
  212. Xunshar : unshar.c
  213. X    cc $(CFLAGS) unshar.c -o unshar;
  214. SHAR_EOF
  215. $TOUCH -am 0328165590 Makefile &&
  216. chmod 0644 Makefile ||
  217. echo "restore of Makefile failed"
  218. set `wc -c Makefile`;Wc_c=$1
  219. if test "$Wc_c" != "333"; then
  220.     echo original size 333, current size $Wc_c
  221. fi
  222. # ============= shar.c ==============
  223. echo "x - extracting shar.c (Text)"
  224. sed 's/^X//' << 'SHAR_EOF' > shar.c &&
  225. X/* CHK=0x688E */
  226. Xchar *revision = "3.21";
  227. X/*
  228. X** shar.c
  229. X
  230. X  Defined functions:
  231. X    Rname(file)
  232. X    exit_incompat()
  233. X    gen_mkdir(path)
  234. X    gen_mkdir_script(path)
  235. X    setTOUCH()
  236. X    header(argc,argv)
  237. X    helpuser()
  238. X    main(argc,argv)
  239. X    mode_map(mode,mode_str)
  240. X    shar(file)
  241. X
  242. X*/
  243. X/*+:EDITS:*/
  244. X/*:04-18-1990-02:01-wht@n4hgf-3.20 rhg@cps.com did all the NICE work */
  245. X/*:04-17-1990-14:30-rhg@cps.com-pretty up if-then-else-fi in shar file */
  246. X/*:04-17-1990-12:13-rhg@cps.com-add Split and renamed old -l to -L */
  247. X/*:04-17-1990-12:13-rhg@cps.com-add -c option to shar file execution */
  248. X/*:04-17-1990-11:20-rhg@cps.com-simplify TOUCH logic in shar file */
  249. X/*:04-17-1990-10:27-rhg@cps.com-create setTOUCH to avoid duplicate code */
  250. X/*:04-17-1990-04:43-rhg@cps.com-add missing && to commands in shar file(s) */
  251. X/*:04-17-1990-02:03-rhg@cps.com-add Compress */
  252. X/*:04-16-1990-17:08-rhg@cps.com-add AvoidPipes as well as code to use pipes */
  253. X/*:04-03-1990-20:09-wht@n4hgf-3.11 */
  254. X/*:04-01-1990-13:20-pat@rwing-correct case on M option in getopt() call */
  255. X/*:04-01-1990-13:50-pat@rwing-change defaults on -v, -w to be on */
  256. X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
  257. X/*:03-28-1990-15:56-wht@n4hgf-add mode and length net.bandwidth chrome */
  258. X/*:03-28-1990-14:23-wht@n4hgf-correct some runtime diagnostics */
  259. X/*:11-14-1989-02:21-wht-SHAR_EOF was botched if last file char not newline */
  260. X/*:11-02-1989-14:11-wht-add touch -am */
  261. X
  262. X/*
  263. X Shar puts readable text files together in a package
  264. X from which they are easy to extract.
  265. X earlier attribution wht@n4hgf has:    decvax!microsof!uw-beave!jim
  266. X                                    (James Gosling at CMU)
  267. X*/
  268. X/*
  269. X *    I have made several mods to this program:
  270. X *
  271. X *    1) the -----Cut Here-----... now preceds the script.
  272. X *    2) the cat has been changed to a sed which removes a prefix
  273. X *    character from the beginning of each line of the extracted
  274. X *    file, this prefix character is added to each line of the archived
  275. X *    files and is not the same as the first character of the
  276. X *    file delimeter.
  277. X *    3) added several options:
  278. X *        -c    - add the -----Cut Here-----... line.
  279. X *        -d'del' - change the file delimeter to del.
  280. X *        -s    - cause the resulting script to print the wc of
  281. X *              the orignal file and the wc of the extracted
  282. X *              file.
  283. X *
  284. X *                Michael A. Thompson
  285. X *                Dalhousie University
  286. X *                Halifax, N.S., Canada.
  287. X */
  288. X
  289. X/*
  290. X *    I, too, have been hacking this code. This is the version on sixhub
  291. X *        bill davidsen (davidsen@sixhub.uucp)
  292. X *
  293. X *    - added support for binary files
  294. X *    - automatic creation of limited size multiple file archives,
  295. X *      each of which may be unpacked separately, and with sequence
  296. X *      checking.
  297. X *    - support for mixed text and binary files
  298. X *    - preserve file permissions
  299. X *    - restore to filename rather than pathname
  300. X *
  301. X */
  302. X/*
  303. X *  One good hack deserves another ... this version generates shell
  304. X *  code which attempts to create missing directories
  305. X *  handle deviants sun, vax, pyr (pyramid), SCO XENIX/UNIX automatically
  306. X *  for sequent, add -DBSD42
  307. X *  force Verbose on
  308. X *  if unsharing system's touch Sys V compatible (allows touch -m),
  309. X *  restore file dates
  310. X *  -n switch puts an alpha "name" in header
  311. X *  -a (if also -n) puts "Submitted-by:" & "Archive-name: <name>/part##
  312. X *  use getopt
  313. X *  as well as some other chrome-plated junque
  314. X *  ...!gatech!emory!tridom!wht (wht%n4hgf@gatech.edu) Warren Tucker
  315. X *
  316. X *  3.11 - Fri Apr  6 14:21:51 EDT 1990
  317. X *  With due deference to davidsen@sixhub, more changes..... copies
  318. X *  of this, like 3.10,  were mailed to him:
  319. X *  From wht  Fri Apr  6 15:14:30 1990 remote from n4hgf
  320. X *  Received: by n4hgf.UUCP (smail2.5-UNIX/386 5.3.2)
  321. X *      id AA01781; 6 Apr 90 15:14:30 EDT (Fri)
  322. X *  Date: Fri, 6 Apr 90 15:14:30 EDT
  323. X *  X-Mailer: Mail User's Shell (6.5 4/17/89)
  324. X *  From: wht@n4hgf (Warren Tucker)
  325. X *  To: davidsen@sixhub
  326. X *  Subject: shar 3.11
  327. X *  X-Bang-Reply-to: gatech!n4hgf!wht -or- emory!tridom!n4hgf!wht
  328. X *  Reply-to: wht%n4hgf@gatech.edu
  329. X *  Message-Id: <9004061514.AA01781@n4hgf.UUCP>
  330. X *
  331. X *  1. changes suggested by pat@rwing (Pat Myrto) and silvert@cs.dal.ca
  332. X *  (Bill Silvert)
  333. X *  2. fixes to who_am_i code in who@where.c
  334. X *
  335. X *  3.20 - Wed Apr 18 01:58:32 EDT 1990
  336. X *  changes were made per edit notes by
  337. XFrom: gatech!mailrus!uunet!cpsolv.CPS.COM!rhg (Richard H. Gumpertz)
  338. X *  ...!gatech!n4hgf!wht (wht%n4hgf@gatech.edu) Warren Tucker
  339. X *
  340. X */
  341. X
  342. X#include <stdio.h>
  343. X#include <sys/types.h>
  344. X#include <time.h>
  345. X#include <sys/stat.h>
  346. X
  347. X/* assume system v unless otherwise fixed */
  348. X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42)
  349. X#define BSD42
  350. X#endif
  351. X#if defined(sun)    /* this miscreant doesn't exactly fit BSD or SYSV */
  352. X#undef BSD42
  353. X#undef SYS5
  354. X#endif
  355. X#if !defined(BSD42) && !defined(sun)
  356. X#define SYS5
  357. X#endif
  358. X
  359. X#if defined(sun) || defined(BSD42)
  360. X#define strchr    index
  361. X#define strrchr    rindex
  362. X#endif
  363. X
  364. Xchar *strchr();
  365. Xchar *strrchr();
  366. X#ifdef __STDC__ /* my concession to ANSI-pansiness */
  367. Xvoid *malloc();
  368. X#else
  369. Xchar *malloc();
  370. X#endif
  371. XFILE *fdopen();
  372. XFILE *popen();
  373. X
  374. X#define    DELIM        "SHAR_EOF"/* put after each file */
  375. X#define PREFIX1        'X'    /* goes in front of each line */
  376. X#define PREFIX2        'Y'    /* goes in front of each line if Delim
  377. X                         * starts with PREFIX1 */
  378. X#define PREFIX        (Delim[0] == PREFIX1 ? PREFIX2 : PREFIX1)
  379. X#define WC            "wc -c"
  380. X
  381. Xint Archive_name = 0;    /* option to generate "Archive-name:" headers */
  382. Xint Verbose = 1;        /* option to provide append/extract feedback */
  383. Xint Wc_c = 1;            /* option to provide wc checking */
  384. Xchar *Delim = DELIM;    /* pointer to delimiter string */
  385. Xint Cut = 0;            /* option to provide cut mark */
  386. Xint Binary = 0;            /* flag for binary files */
  387. Xint AvoidPipes = 0;        /* use temp file instead of pipe to feed uudecode, etc.
  388. X                           (better error detection at expense of disk space) */
  389. Xint Compress = 0;        /* run input files through compress (requires Binary) */
  390. Xint Mixed = 0;            /* mixed text and binary files */
  391. Xint eXists = 0;            /* check if file exists */
  392. Xint InterOW = 0;        /* interactive overwrite */
  393. Xint PosParam = 0;        /* allow positional parameters */
  394. Xint FileStrip;            /* strip directories from filenames */
  395. X#ifdef    DEBUG
  396. Xint de_bug = 0;            /* switch for debugging on */
  397. X#define DeBug(f,v) if (de_bug) printf(f, v)
  398. X#else    /* normal compile */
  399. X#define DeBug(f,v)        /* do nothing */
  400. X#endif
  401. X
  402. XFILE *fpout = stdout;
  403. Xchar *Rname();            /* file restore name */
  404. Xunsigned limit = 0;
  405. Xint Split = 0;            /* Split files in the middle */
  406. Xlong ftell();
  407. Xlong TypePos;            /* position for archive type message */
  408. Xlong EndHeadPos;        /* position for first file in the shar file */
  409. Xchar outname[50];        /* base for output filename */
  410. Xchar filename[50];        /* actual output filename */
  411. Xchar *sharname = (char *)0;
  412. Xchar *submitter = (char *)0;
  413. Xint filenum = 0;        /* output file # */
  414. Xstruct stat fst;        /* check file type, access */
  415. X
  416. Xmain(argc,argv)
  417. Xchar **argv;
  418. X{
  419. Xint status = 0;
  420. Xchar *oname;
  421. Xint c;
  422. Xextern int optind;
  423. Xextern char *optarg;
  424. X
  425. X    while((c = getopt(argc,argv,"vwd:btCxXcfMpPas:n:l:L:o:h")) != -1)
  426. X    {
  427. X        switch(c)
  428. X        {
  429. X        case 'v':
  430. X            Verbose = 0;
  431. X            break;
  432. X        case 'w':
  433. X            Wc_c = 0;
  434. X            break;
  435. X        case 'd':
  436. X            Delim = optarg;
  437. X            break;
  438. X        case 'b': /* binary files */
  439. X            Binary = 1;
  440. X            Compress = 0;
  441. X            break;
  442. X        case 't': /* text mode */
  443. X            Binary = 0;
  444. X            Compress = 0;
  445. X            break;
  446. X        case 'C': /* Compress */
  447. X            Binary = 1;
  448. X            Compress = 1;
  449. X            break;
  450. X        case 'x': /* does the file exist */
  451. X            eXists = 1;
  452. X            if(InterOW || Split)
  453. X                exit_incompat();
  454. X            break;
  455. X        case 'X': /* does the file exist */
  456. X            InterOW = 1;
  457. X            if(eXists || Split)
  458. X                exit_incompat();
  459. X            eXists = 1;
  460. X            break;
  461. X        case 'c':
  462. X            Cut = 1;
  463. X            break;
  464. X        case 'f': /* filenames only */
  465. X            FileStrip = 1;
  466. X            break;
  467. X        case 'M': /* mixed text and binary */
  468. X            Mixed = 1;
  469. X            break;
  470. X        case 'p': /* allow positional parameters */
  471. X            PosParam = 1;
  472. X            break;
  473. X        case 'P': /* use temp files instead of pipes in the shar file */
  474. X            AvoidPipes = 1;
  475. X            break;
  476. X        case 'l': /* soft size limit in k */
  477. X            if((limit = atoi(optarg)) > 1)
  478. X                --limit;
  479. X            Split = 0;
  480. X            DeBug("Soft limit %dk\n",limit);
  481. X            break;
  482. X        case 'L': /* hard size limit in k */
  483. X            if(eXists)
  484. X                exit_incompat();
  485. X            if((limit = atoi(optarg)) > 1)
  486. X                --limit;
  487. X            Split = (limit != 0);
  488. X            AvoidPipes = 1;
  489. X            DeBug("Hard limit %dk\n",limit);
  490. X            break;
  491. X        case 'n': /* name of archive */
  492. X            sharname = optarg;
  493. X            break;
  494. X        case 's': /* submitter */
  495. X            submitter = optarg;
  496. X            break;
  497. X        case 'a': /* generate Archive-name: headers */
  498. X            Archive_name = 1;
  499. X            break;
  500. X        case 'o': /* specify output file */
  501. X            oname = optarg;
  502. X            strcpy(outname,oname);
  503. X            strcat(outname,".");
  504. X            filenum = 1;
  505. X            strcpy(filename,outname);
  506. X            strcat(filename,"01");
  507. X            fpout = fopen(filename,"w");
  508. X            if(!fpout)
  509. X            { /* creation error */
  510. X                perror("can't create output file");
  511. X                exit(1);
  512. X            }
  513. X            break;
  514. X#ifdef    DEBUG
  515. X        case '$': /* totally undocumented $ option, debug on */
  516. X            de_bug = 1;
  517. X            break;
  518. X#endif
  519. X        default: /* invalid option */
  520. X        case 'h': /* help */
  521. X            helpuser();
  522. X            break;
  523. X        }
  524. X    }
  525. X
  526. X    if(optind >= argc)
  527. X    {
  528. X        fprintf(stderr,"shar: No input files\n");
  529. X        helpuser();
  530. X        exit(1);
  531. X    }
  532. X
  533. X    if(Archive_name && !sharname)
  534. X    {
  535. X        fprintf(stderr,"shar: -n must accompany -a\n");
  536. X        helpuser();
  537. X        exit(1);
  538. X    }
  539. X
  540. X    if(!submitter)
  541. X    {
  542. X        submitter = malloc(128);
  543. X        who_where(submitter);
  544. X    }
  545. X
  546. X    if(header(argc-optind,&argv[optind]))
  547. X        exit(2);
  548. X
  549. X    if(InterOW)
  550. X    {
  551. X        Verbose = 1;
  552. X        fprintf(fpout,"wish=\n");
  553. X        if(Archive_name)
  554. X        {
  555. X            printf("PLEASE do not submit -X shars to the usenet or other\n");
  556. X            printf("public networks.  They will cause problems.\n");
  557. X        }
  558. X    }
  559. X
  560. X    EndHeadPos = ftell(fpout);
  561. X
  562. X    while(optind < argc)
  563. X    { /* process positional parameters and files */
  564. X        if(PosParam)
  565. X        {        /* allow -b and -t and -C inline */
  566. X            if(strcmp(argv[optind],"-b") == 0)
  567. X            { /* set binary */
  568. X                Binary = 1;
  569. X                Compress = 0;
  570. X                optind++;
  571. X                continue;
  572. X            }
  573. X            if(strcmp(argv[optind],"-t") == 0)
  574. X            { /* set mode text */
  575. X                Binary = 0;
  576. X                Compress = 0;
  577. X                optind++;
  578. X                continue;
  579. X            }
  580. X            if(strcmp(argv[optind],"-C") == 0)
  581. X            { /* set compress */
  582. X                Binary = 1;
  583. X                Compress = 1;
  584. X                optind++;
  585. X                continue;
  586. X            }
  587. X        }
  588. X        status += shar(argv[optind++]);
  589. X    }
  590. X
  591. X    /* delete the sequence file, if any */
  592. X    if(Split && filenum > 1)
  593. X    {
  594. X        fputs("rm -f @shar_seq_.tmp\n",fpout);
  595. X        fputs("echo \"You have unpacked the last part\"\n",fpout);
  596. X        if(!Verbose)
  597. X            fprintf(stderr,"Created %d files\n",filenum);
  598. X    }
  599. X    fputs("exit 0\n",fpout);
  600. X    exit(status);
  601. X}
  602. X
  603. X/*+-----------------------------------------------------------------------
  604. X    mode_map(mode,mode_str)    build drwxrwxrwx string
  605. X------------------------------------------------------------------------*/
  606. Xchar *
  607. Xmode_map(mode,mode_str)
  608. Xunsigned short mode;
  609. Xchar *mode_str;
  610. X{
  611. Xregister unsigned ftype = mode & S_IFMT;
  612. Xregister char *rtn;
  613. Xstatic char result[12];
  614. X
  615. X    rtn = (mode_str == (char *)0) ? result : mode_str;
  616. X
  617. X    /*          drwxrwxrwx */
  618. X    /*          0123456789 */
  619. X    strcpy(rtn,"----------");
  620. X
  621. X#ifdef THIS_IS_NOT_NEEDED_FOR_SHAR
  622. X    switch(ftype)
  623. X    {
  624. X        case S_IFIFO:    *rtn = 'p'; break; /* FIFO (named pipe) */
  625. X        case S_IFDIR:    *rtn = 'd'; break; /* directory */
  626. X        case S_IFCHR:    *rtn = 'c'; break; /* character special */
  627. X        case S_IFBLK:    *rtn = 'b'; break; /* block special */
  628. X        case S_IFREG:    *rtn = '-'; break; /* regular */
  629. X
  630. X#if defined(sun) | defined(BSD42)
  631. X        case S_IFLNK:    *rtn = 'l'; break; /* symbolic link */
  632. X        case S_IFSOCK:    *rtn = 's'; break; /* socket */
  633. X#endif
  634. X
  635. X#if defined (SYS5)
  636. X        case S_IFNAM:                        /* name space entry */
  637. X            if(mode & S_INSEM)                /* semaphore */
  638. X            {
  639. X                *rtn = 's';
  640. X                break;
  641. X            }
  642. X            if(mode & S_INSHD)                /* shared memory */
  643. X            {
  644. X                *rtn = 'm';
  645. X                break;
  646. X            }
  647. X#endif
  648. X
  649. X        default:        *rtn = '?'; break;    /* ??? */
  650. X    }
  651. X#endif /* THIS_IS_NOT_NEEDED_FOR_SHAR */
  652. X
  653. X    if(mode & 000400) *(rtn + 1) = 'r';
  654. X    if(mode & 000200) *(rtn + 2) = 'w';
  655. X    if(mode & 000100) *(rtn + 3) = 'x';
  656. X    if(mode & 004000) *(rtn + 3) = 's';
  657. X    if(mode & 000040) *(rtn + 4) = 'r';
  658. X    if(mode & 000020) *(rtn + 5) = 'w';
  659. X    if(mode & 000010) *(rtn + 6) = 'x';
  660. X    if(mode & 002000) *(rtn + 6) = 's';
  661. X    if(mode & 000004) *(rtn + 7) = 'r';
  662. X    if(mode & 000002) *(rtn + 8) = 'w';
  663. X    if(mode & 000001) *(rtn + 9) = 'x';
  664. X    if(mode & 001000) *(rtn + 9) = 't';
  665. X
  666. X    return(rtn);
  667. X
  668. X}    /* end of mode_map */
  669. X
  670. Xvoid
  671. XsetTOUCH()
  672. X{
  673. X    fputs("if touch 2>&1 | fgrep '[-amc]' > /dev/null\n",fpout);
  674. X    fputs(" then TOUCH=touch\n",fpout);
  675. X    fputs(" else TOUCH=true\n",fpout);
  676. X    fputs("fi\n",fpout);
  677. X} /* end of setTOUCH */
  678. X
  679. Xheader(argc,argv)
  680. Xchar **argv;
  681. X{
  682. Xint i;
  683. Xint status;
  684. XFILE *fpsource;    /* pipe temp */
  685. Xchar s128[128];
  686. Xlong now;
  687. Xstruct tm *utc;
  688. Xstruct tm *gmtime();
  689. X
  690. X    /* see if any conflicting options */
  691. X    if(limit && !filenum)
  692. X    { /* can't rename what you don't have */
  693. X        fprintf(stderr,"Can't use -l or -L option without -o\n");
  694. X        helpuser();
  695. X    }
  696. X
  697. X    for(i = 0; i < argc; i++)
  698. X    { /* skip positional parameters */
  699. X        if(PosParam &&
  700. X            (strcmp(argv[i],"-b") == 0 ||
  701. X             strcmp(argv[i],"-t") == 0 ||
  702. X             strcmp(argv[i],"-C") == 0))
  703. X            continue;
  704. X
  705. X        /* see if access and correct type */
  706. X        if(access(argv[i],4))
  707. X        {
  708. X            fprintf(stderr,"shar: Can't access %s\n",argv[i]);
  709. X            return(1);
  710. X        }
  711. X
  712. X        /* get file type */
  713. X        stat(argv[i],&fst);
  714. X        status = fst.st_mode & S_IFMT;
  715. X
  716. X        /* at this point I check to see that this is a regular file */
  717. X        if(status != S_IFREG)
  718. X        { /* this is not a regular file */
  719. X            fprintf(stderr,"shar: %s is not a regular file\n",argv[i]);
  720. X            return(1);
  721. X        }
  722. X    }
  723. X
  724. X    if(Archive_name)
  725. X    {
  726. X        fprintf(fpout,"Submitted-by: %s\n",submitter);
  727. X        fprintf(fpout,"Archive-name: %s%s%02d\n\n",
  728. X            sharname,(strchr(sharname,'/')) ? "" : "/part",
  729. X            (filenum) ? filenum : 1);
  730. X    }
  731. X
  732. X    if(Cut)
  733. X        fputs("---- Cut Here and unpack ----\n",fpout);
  734. X    fputs("#!/bin/sh\n",fpout);
  735. X    if(sharname)
  736. X        fprintf(fpout,"# This is %s, a shell archive (shar %s)\n",
  737. X            sharname,revision);
  738. X    else
  739. X        fprintf(fpout,"# This is a shell archive (shar %s)\n",revision);
  740. X
  741. X    time(&now);
  742. X    utc = gmtime(&now);
  743. X    fprintf(fpout,"# made %02d/%02d/%04d %02d:%02d UTC ",
  744. X        utc->tm_mon + 1,utc->tm_mday,utc->tm_year + 1900,
  745. X        utc->tm_hour,utc->tm_min);
  746. X
  747. X    fputs("by ",fpout);
  748. X    fputs(submitter,fpout);
  749. X    fputs("\n",fpout);
  750. X
  751. X#if defined(SYS5)
  752. X    if(!(fpsource = popen("/bin/pwd","r")))
  753. X        return(-1);
  754. X    fgets(s128,sizeof(s128),fpsource);
  755. X    s128[strlen(s128) - 1] = 0;
  756. X    fclose(fpsource);
  757. X#else
  758. X#if defined(BSD42) || defined(sun)
  759. X    getwd(s128);
  760. X#else
  761. X#include "Need_conditional_compile_fix"
  762. X#endif
  763. X#endif
  764. X    fprintf(fpout,"# Source directory %s\n",s128);
  765. X
  766. X    fprintf(fpout,"#\n# existing files %s be overwritten\n",
  767. X        (eXists) ? "will NOT"
  768. X                 : ((InterOW) ? "MAY" : "WILL"));
  769. X    if(InterOW)
  770. X        fprintf(fpout,"# The unsharer will be INTERACTIVELY queried.\n");
  771. X
  772. X    if(Split)
  773. X    { /* may be split, explain */
  774. X        fputs("#\n",fpout);
  775. X        TypePos = ftell(fpout);
  776. X        fprintf(fpout,"%-75s\n%-75s\n","#","#");
  777. X    }
  778. X
  779. X    fputs("#\n# This shar contains:\n",fpout);
  780. X    fputs("# length  mode       name\n",fpout);
  781. X    fputs("# ------ ---------- ------------------------------------------\n",
  782. X        fpout);
  783. X    for(i = 0; i < argc; i++)
  784. X    { /* output names of files but not parameters */
  785. X        if(PosParam &&
  786. X            (strcmp(argv[i],"-b") == 0 ||
  787. X             strcmp(argv[i],"-t") == 0 ||
  788. X             strcmp(argv[i],"-C") == 0))
  789. X            continue;
  790. X        stat(argv[i],&fst);
  791. X        fst.st_mode &= ~(07000); /* turn off setuid, setgid and sticky bits */
  792. X        fprintf(fpout,"# %6ld %s %s\n",fst.st_size,
  793. X            mode_map(fst.st_mode,(char *)0),Rname(argv[i]));
  794. X    }
  795. X    fputs("#\n",fpout);
  796. X
  797. X    setTOUCH();
  798. X
  799. X    if(Split)
  800. X    { /* now check the sequence */
  801. X        fputs("if test -r @shar_seq_.tmp; then\n",fpout);
  802. X        fputs("\techo \"Must unpack archives in sequence!\"\n",fpout);
  803. X        fputs("\tnext=`cat @shar_seq_.tmp`; ",fpout);
  804. X        fputs("echo \"Please unpack part $next next\"\n\texit 1\nfi\n",fpout);
  805. X    }
  806. X    return(0);
  807. X}
  808. X
  809. X#define MAX_MKDIR_ALREADY    128    /* ridiculously enough */
  810. Xchar *mkdir_already[MAX_MKDIR_ALREADY];
  811. Xint mkdir_already_count = 0;
  812. X
  813. Xvoid
  814. Xgen_mkdir(path)
  815. Xchar *path;
  816. X{
  817. Xregister int ialready;
  818. Xchar *cptr;
  819. X
  820. X/* if already generated code for this dir creation, dont do again */
  821. X    for(ialready = 0; ialready < mkdir_already_count; ialready++)
  822. X    {
  823. X        if(!strcmp(path,mkdir_already[ialready]))
  824. X            return;
  825. X    }
  826. X
  827. X/* haven't done this one */
  828. X    if(mkdir_already_count == MAX_MKDIR_ALREADY)
  829. X    {
  830. X        fprintf(stderr,"too many directories for mkdir generation\n");
  831. X        exit(255);
  832. X    }
  833. X    if(!(cptr = mkdir_already[mkdir_already_count++] = malloc(strlen(path)+1)))
  834. X    {
  835. X        fprintf(stderr,"out of memory for mkdir generation\n");
  836. X        exit(255);
  837. X    }
  838. X    strcpy(cptr,path);
  839. X
  840. X/* generate the text */
  841. X    fprintf(fpout,"if test ! -d '%s'; then\n",path);
  842. X    if(Verbose)
  843. X        fprintf(fpout,"    echo \"x - creating directory %s\"\n",path);
  844. X    fprintf(fpout,"    mkdir '%s'\n",path);
  845. X    fprintf(fpout,"fi\n");
  846. X
  847. X}    /* end of gen_mkdir */
  848. X
  849. Xvoid
  850. Xgen_mkdir_script(path)
  851. Xregister char *path;
  852. X{
  853. Xregister char *cptr;
  854. X
  855. X    for(cptr = strchr(path,'/'); cptr; cptr = strchr(cptr + 1,'/'))
  856. X    {
  857. X        /* avoid empty string if leading or double '/' */
  858. X        if(cptr == path || *(cptr - 1) == '/')
  859. X            continue;
  860. X        /* omit '.' */
  861. X        if((*(cptr - 1) == '.') && ((cptr == path + 1) || (*(cptr - 2) == '/')))
  862. X            continue;
  863. X        *cptr = 0;                /* temporarily terminate string */
  864. X        gen_mkdir(path);
  865. X        *cptr = '/';
  866. X    }
  867. X}    /* end of gen_mkdir_script */
  868. X
  869. Xshar(file)
  870. Xchar *file;
  871. X{
  872. Xchar line[BUFSIZ];
  873. XFILE *fpsource;
  874. Xlong cursize,remaining,ftell();
  875. Xint split = 0;        /* file split flag */
  876. Xchar *filetype;        /* text or binary */
  877. Xchar *RstrName;        /* name for restore */
  878. Xstruct tm *lt;
  879. Xchar *filename_base;
  880. X
  881. X    /* get file size, dates, and mode for later */
  882. X    stat(file,&fst);
  883. X
  884. X    /* if limit set, get the current output length */
  885. X    if(limit)
  886. X    {
  887. X        cursize = ftell(fpout);
  888. X        remaining = (limit * 1024L) - cursize;
  889. X        DeBug("In shar: remaining size %ld\n",remaining);
  890. X        
  891. X        if(!Split && cursize > EndHeadPos &&
  892. X            (Binary ? fst.st_size + fst.st_size/3 : fst.st_size) > remaining)
  893. X        { /* change to another file */
  894. X            DeBug("Newfile, remaining %ld, ",remaining);
  895. X            DeBug("limit still %d\n",limit);
  896. X
  897. X            fprintf(fpout,
  898. X                "echo \"End of part %d, continue with part %d\"\n",
  899. X                filenum,filenum + 1);
  900. X            fprintf(fpout,"exit 0\n");
  901. X
  902. X            fclose(fpout);
  903. X
  904. X            /* form the next filename */
  905. X            sprintf(filename,"%s%02d",outname,++filenum);
  906. X            fpout = fopen(filename,"w");
  907. X
  908. X            if(Archive_name)
  909. X            {
  910. X                fprintf(fpout,"Submitted-by: %s\n",submitter);
  911. X                fprintf(fpout,"Archive-name: %s%s%02d\n\n",
  912. X                    sharname,(strchr(sharname,'/')) ? "." : "/part",
  913. X                    (filenum) ? filenum : 1);
  914. X            }
  915. X
  916. X            if(Cut)
  917. X                fputs("---- Cut Here and unpack ----\n",fpout);
  918. X            if(!(filename_base = strrchr(filename,'/')))
  919. X                filename_base = filename;
  920. X            else
  921. X                filename_base++;
  922. X
  923. X            fprintf(fpout,"#!/bin/sh\n");
  924. X            fprintf(fpout,"# This is part %02d of %s\n",
  925. X                filenum,(sharname) ? sharname : "a multipart archive");
  926. X
  927. X            setTOUCH();
  928. X
  929. X            EndHeadPos = ftell(fpout);
  930. X        }
  931. X    }
  932. X
  933. X    /* determine the name to use for restore */
  934. X    RstrName = Rname(file);
  935. X
  936. X    fputs("# ============= ",fpout);
  937. X    fputs(RstrName,fpout);
  938. X    fputs(" ==============\n",fpout);
  939. X
  940. X    gen_mkdir_script(RstrName);
  941. X
  942. X    /* if mixed, determine the file type */
  943. X    if(Mixed)
  944. X    {
  945. X        int count;
  946. X        sprintf(line,"file %s | egrep -c \"text|shell\"",file);
  947. X        fpsource = popen(line,"r");
  948. X        fscanf(fpsource,"%d",&count);
  949. X        pclose(fpsource);
  950. X        Binary = (count != 1);
  951. X    }
  952. X
  953. X    if(Binary)
  954. X    { /* fork a uuencode process */
  955. X        static int pid,pipex[2];
  956. X
  957. X        pipe(pipex);
  958. X        fflush(fpout);
  959. X
  960. X        if(pid = fork())
  961. X        { /* parent, create a file to read */
  962. X            close(pipex[1]);
  963. X            fpsource = fdopen(pipex[0],"r");
  964. X            filetype = (Compress ? "Compressed" : "Binary");
  965. X        }
  966. X        else
  967. X        { /* start writing the pipe with encodes */
  968. X            FILE *outptr;
  969. X
  970. X            if(Compress)
  971. X            {
  972. X                sprintf(line, "compress < %s", file);
  973. X                fpsource = popen(line, "r");
  974. X            }
  975. X            else
  976. X                fpsource = fopen(file, "rb");
  977. X            outptr = fdopen(pipex[1],"w");
  978. X            fprintf(outptr,"begin 600 %s\n",
  979. X                (Compress ? "@shar_cmp_.tmp" : RstrName));
  980. X            encode(fpsource,outptr);
  981. X            fprintf(outptr,"end\n");
  982. X            if(Compress)
  983. X                pclose(fpsource);
  984. X            else
  985. X                fclose(fpsource);
  986. X            exit(0);
  987. X        }
  988. X    }
  989. X    else
  990. X    {
  991. X        fpsource = fopen(file,"r");
  992. X        filetype = "Text";
  993. X    }
  994. X
  995. X    if(fpsource)
  996. X    {
  997. X        /* protect existing files */
  998. X        if(eXists)
  999. X        {
  1000. X            fprintf(fpout,"if test X\"$1\" != X\"-c\" -a -f '%s'; then\n",
  1001. X                RstrName);
  1002. X            if(InterOW)
  1003. X            {
  1004. X                fprintf(fpout,"\tcase $wish in\n");
  1005. X                fprintf(fpout,"\tA*|a*) echo x - overwriting '%s';;\n",
  1006. X                    RstrName);
  1007. X                fprintf(fpout,
  1008. X        "\t*) echo \"? - overwrite '%s' -- [No], [Y]es, [A]ll, [Q]uit? \"\n",
  1009. X                    RstrName);
  1010. X                fprintf(fpout,"\t\tread wish;;\n");
  1011. X                fprintf(fpout,"\tesac\n");
  1012. X                fprintf(fpout,"\tcase $wish in\n");
  1013. X                fprintf(fpout,"\tQ*|q*) echo aborted; exit 86;;\n");
  1014. X                fprintf(fpout,"\tA*|a*|Y*|y*) x=Y;;\n");
  1015. X                fprintf(fpout,"\t*) x=N;;\n");
  1016. X                fprintf(fpout,"\tesac\n");
  1017. X                fprintf(fpout,"else\n");
  1018. X                fprintf(fpout,"\tx=Y\n");
  1019. X                fprintf(fpout,"fi\n");
  1020. X                fprintf(fpout,"if test $x != Y; then\n");
  1021. X                fprintf(fpout,"\techo x - skipping '%s'\n",RstrName);
  1022. X            }
  1023. X            else
  1024. X                fprintf(fpout,"\techo \"File already exists: skipping '%s'\"\n",
  1025. X                    RstrName);
  1026. X            fprintf(fpout,"else\n");
  1027. X        }
  1028. X
  1029. X        fprintf(stderr,"shar: saving %s (%s)\n",file,filetype);
  1030. X        if(Verbose)
  1031. X        { /* info on archive and unpack */
  1032. X            fprintf(fpout,"echo \"x - extracting %s (%s)\"\n",
  1033. X                RstrName,filetype);
  1034. X        }
  1035. X        if(Binary)
  1036. X        { /* run sed through uudecode (via temp file if might get split) */
  1037. X            fprintf(fpout, "sed 's/^%c//' << '%s' %s &&\n",
  1038. X                   PREFIX,Delim,
  1039. X                (AvoidPipes ? "> @shar_tmp_.tmp" : "| uudecode"));
  1040. X        }
  1041. X        else
  1042. X        { /* just run it into the file */
  1043. X            fprintf(fpout,"sed 's/^%c//' << '%s' > %s &&\n",
  1044. X                PREFIX,Delim,RstrName);
  1045. X        }
  1046. X        while(fgets(line,BUFSIZ,fpsource))
  1047. X        { /* output a line and test the length */
  1048. X            fprintf(fpout,"%c%s",PREFIX,line);
  1049. X            if(Split && (remaining -= strlen(line) + 2) < 0)
  1050. X            { /* change to another file */
  1051. X                DeBug("Newfile, remaining %ld, ",remaining);
  1052. X                DeBug("limit still %d\n",limit);
  1053. X
  1054. X                if(line[strlen(line) - 1] != '\n')
  1055. X                    fputc('\n',fpout);
  1056. X
  1057. X                fprintf(fpout,"%s\n",Delim);
  1058. X                if(Verbose)
  1059. X                { /* output some reassurance */
  1060. X                    fprintf(fpout,
  1061. X                        "echo \"End of %s part %d\"\n",
  1062. X                            (sharname) ? sharname : "",filenum);
  1063. X                    fprintf(fpout,
  1064. X                        "echo \"File %s is continued in part %d\"\n",
  1065. X                        RstrName,filenum + 1);
  1066. X                }
  1067. X                else
  1068. X                    fprintf(fpout,
  1069. X                        "echo \"End of part %d, continue with part %d\"\n",
  1070. X                        filenum,filenum + 1);
  1071. X                fprintf(fpout,"echo \"%d\" > @shar_seq_.tmp\n",filenum + 1);
  1072. X                fprintf(fpout,"exit 0\n");
  1073. X
  1074. X                if(filenum == 1)
  1075. X                { /* rewrite the info lines on the firstheader */
  1076. X                    fseek(fpout,TypePos,0);
  1077. X                    fprintf(fpout,"%-75s\n%-75s\n",
  1078. X                        "# This is part 1 of a multipart archive",
  1079. X                        "# do not concatenate these parts, unpack them in order with /bin/sh");
  1080. X                }
  1081. X                fclose(fpout);
  1082. X
  1083. X                /* form the next filename */
  1084. X                sprintf(filename,"%s%02d",outname,++filenum);
  1085. X                fpout = fopen(filename,"w");
  1086. X
  1087. X                if(Archive_name)
  1088. X                {
  1089. X                    fprintf(fpout,"Submitted-by: %s\n",submitter);
  1090. X                    fprintf(fpout,"Archive-name: %s%s%02d\n\n",
  1091. X                        sharname,(strchr(sharname,'/')) ? "." : "/part",
  1092. X                        (filenum) ? filenum : 1);
  1093. X                }
  1094. X
  1095. X                if(Cut)
  1096. X                    fputs("---- Cut Here and unpack ----\n",fpout);
  1097. X                if(!(filename_base = strrchr(filename,'/')))
  1098. X                    filename_base = filename;
  1099. X                else
  1100. X                    filename_base++;
  1101. X
  1102. X                fprintf(fpout,"#!/bin/sh\n");
  1103. X                fprintf(fpout,
  1104. X                    "# this is %s (part %d of %s)\n",
  1105. X                    filename_base,
  1106. X                    filenum,
  1107. X                    (sharname) ? sharname : "a multipart archive");
  1108. X                fputs("# do not concatenate these parts, ",fpout);
  1109. X                fputs("unpack them in order with /bin/sh\n",fpout);
  1110. X                fprintf(fpout,"# file %s continued\n#\n",RstrName);
  1111. X
  1112. X                setTOUCH();
  1113. X                
  1114. X                fputs("if test ! -r @shar_seq_.tmp; then\n",fpout);
  1115. X                fputs("\techo \"Please unpack part 1 first!\"\n",fpout);
  1116. X                fputs("\texit 1\nfi\n",fpout);
  1117. X                fputs("(read Scheck\n",fpout);
  1118. X                fprintf(fpout,
  1119. X                      " if test \"$Scheck\" != %d; then\n",filenum);
  1120. X                fputs("\techo \"Please unpack part $Scheck next!\"\n",
  1121. X                    fpout);
  1122. X                fputs("\texit 1\n",fpout);
  1123. X                fputs(" else\n\texit 0\n fi\n",fpout);
  1124. X                fputs(") < @shar_seq_.tmp || exit 1\n",fpout);
  1125. X
  1126. X                if(Verbose)
  1127. X                { /* keep everybody informed */
  1128. X                    fprintf(stderr,"Starting file %s\n",filename);
  1129. X                    fprintf(fpout,
  1130. X                        "echo \"x - Continuing file %s\"\n",RstrName);
  1131. X                }
  1132. X                fprintf(fpout,
  1133. X                    "sed 's/^%c//' << '%s' >> %s &&\n",
  1134. X                    PREFIX,Delim,
  1135. X                    (Binary ? "@shar_tmp_.tmp" : RstrName));
  1136. X                remaining = limit * 1024L;
  1137. X                split = 1;
  1138. X            }
  1139. X        }
  1140. X
  1141. X        (void) fclose(fpsource);
  1142. X
  1143. X        if(line[strlen(line) - 1] != '\n')
  1144. X            fputc('\n',fpout);
  1145. X
  1146. X        fprintf(fpout,"%s\n",Delim);
  1147. X        if(split && Verbose)
  1148. X            fprintf(fpout,
  1149. X                "echo \"File %s is complete\" &&\n",RstrName);
  1150. X
  1151. X        /* if this file was uuencoded w/Split, decode it and drop the temp */
  1152. X        if(Binary && AvoidPipes)
  1153. X        {
  1154. X            if(Verbose)
  1155. X                fprintf(fpout,"echo \"uudecoding file %s\" &&\n",RstrName);
  1156. X            fprintf(fpout,
  1157. X                "uudecode < @shar_tmp_.tmp && rm -f @shar_tmp_.tmp &&\n");
  1158. X        }
  1159. X
  1160. X        /* if this file was compressed, uncompress it and drop the temp */
  1161. X        if(Compress)
  1162. X        {
  1163. X            if(Verbose)
  1164. X                fprintf(fpout,"echo \"uncompressing file %s\" &&\n",RstrName);
  1165. X            fprintf(fpout,
  1166. X                "compress -d < @shar_cmp_.tmp > %s && rm -f @shar_cmp_.tmp &&\n",
  1167. X                RstrName);
  1168. X        }
  1169. X
  1170. X        /* set the dates as they were */
  1171. X        lt = localtime(&fst.st_mtime);
  1172. X        fprintf(fpout,"$TOUCH -am %02d%02d%02d%02d%02d %s &&\n",
  1173. X            lt->tm_mon + 1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_year,
  1174. X            RstrName);
  1175. X
  1176. X        /* set the permissions as they were */
  1177. X        fprintf(fpout,"chmod %04o %s ||\n",
  1178. X            fst.st_mode & 00777,RstrName);
  1179. X
  1180. X        /* report an error if any of the above failed */
  1181. X        fprintf(fpout,"echo \"restore of %s failed\"\n",RstrName);
  1182. X
  1183. X        if(Wc_c)
  1184. X        { /* validate the transferred file */
  1185. X            FILE *pfp;
  1186. X            char command[BUFSIZ];
  1187. X
  1188. X            sprintf(command,"%s %s",WC,file);
  1189. X            if((pfp = popen(command,"r")))
  1190. X            {
  1191. X                char wc[BUFSIZ];
  1192. X
  1193. X                fscanf(pfp,"%s",wc);
  1194. X                fprintf(fpout,"set `%s %s`;Wc_c=$1\n",
  1195. X                    WC,RstrName);
  1196. X                fprintf(fpout,
  1197. X                    "if test \"$Wc_c\" != \"%s\"; then\n",wc);
  1198. X                fprintf(fpout,
  1199. X                    "\techo original size %s, current size $Wc_c\nfi\n",
  1200. X                    wc);
  1201. X                pclose(pfp);
  1202. X            }
  1203. X        }
  1204. X
  1205. X        /* if the exists option is in place close the if */
  1206. X        if(eXists)
  1207. X            fprintf(fpout,"fi\n");
  1208. X
  1209. X        return(0);
  1210. X    }
  1211. X    else
  1212. X    {
  1213. X        fprintf(stderr,"shar: Can't open %s (%s): ",file,filetype);
  1214. X        perror("");
  1215. X        return(1);
  1216. X    }
  1217. X}
  1218. X
  1219. Xchar *
  1220. XRname(file)
  1221. Xregister char *file;
  1222. X{
  1223. X    register char *RstrName;
  1224. X
  1225. X    if(FileStrip)
  1226. X    { /* use just the filename */
  1227. X        RstrName = file+strlen(file);
  1228. X        while(RstrName > file && *RstrName != '/')
  1229. X            RstrName--;
  1230. X        if(*RstrName == '/') RstrName++;
  1231. X    }
  1232. X    else
  1233. X        RstrName = file;
  1234. X    if(!strncmp(RstrName,"./",2))
  1235. X        RstrName += 2;
  1236. X    return(RstrName);
  1237. X}
  1238. X
  1239. X/*****************************************************************
  1240. X |  exit_incompat - incompatible options
  1241. X ****************************************************************/
  1242. X
  1243. Xexit_incompat()
  1244. X{
  1245. X       fputs("You may only specify one of -L, -X or -x\n",stderr);
  1246. X    exit(1);
  1247. X}
  1248. X
  1249. Xhelpuser()
  1250. X{                /* output a command format message */
  1251. X    register char **ptr;
  1252. X    static char *helpinfo[] =
  1253. X    {
  1254. X        "-v  verbose messages OFF while executing",
  1255. X        "-w  don't check with 'wc -c' after unpack",
  1256. X        "-n  Name of archive (documentation)",
  1257. X        "-a  Generate Submitted-by: & Archive-name: headers",
  1258. X        "-s  override automatically determined submitter name",
  1259. X        "-x  don't overwrite existing files",
  1260. X        "-X  interactively overwrite existing files (NOT FOR NET SHARS)",
  1261. X        "-b  treat all files as binary, use uuencode",
  1262. X        "-t  treat all files as text (default)",
  1263. X        "-C  compress and uuencode all files",
  1264. X        "-p  allow positional parameter options. The options \"-b\" and \"-t\"",
  1265. X        "    and \"-C\" may be embedded, and files to the right of the",
  1266. X        "    option will be processed in the specified mode",
  1267. X        "-M  mixed mode. Determine if the files are text or",
  1268. X        "    binary and archive correctly.",
  1269. X        "-P  use temp files instead of pipes in the shar file",
  1270. X#ifdef THIS_APPEARS_TO_BE_OBSOLETE
  1271. X        "-D  output date, user, and directory comments to the archive",
  1272. X#endif /* THIS_APPEARS_TO_BE_OBSOLETE */
  1273. X        "-c  start the shar with a cut line",
  1274. X        "-f  restore by filename only, rather than path",
  1275. X        "-dXXX   use XXX to delimit the files in the shar",
  1276. X        "-oXXX   (or -o XXX) output to file XXX.01 thru XXX.nn",
  1277. X        "-lXX    limit output file size to XXk bytes (but don't split files)",
  1278. X        "-LXX    limit output file size to XXk bytes (may split files)",
  1279. X        "\nThe 'o' option is required if the 'l' or 'L' option is used",
  1280. X        "The 'n' option is required if the 'a' option is used",
  1281. X        "The 'x' and 'L' options are incompatible",
  1282. X        "\n-a generates sharname/part## headers. If you are producing patches",
  1283. X        "you'll need to edit -a headers (or please improve shar :-))",
  1284. X        "The automatic submitter name is trivial: essentially `whoami`@`uname`",
  1285. X        (char *)0
  1286. X    };
  1287. X    fprintf(stderr,
  1288. X        "shar %s\nusage: shar [ options ] file [ file1 ... ] ]\n",revision);
  1289. X    for(ptr = helpinfo; *ptr; ptr++)
  1290. X        fprintf(stderr,"%s\n",*ptr);
  1291. X
  1292. X    exit(1);
  1293. X}
  1294. X/* vi: set tabstop=4 shiftwidth=4: */
  1295. SHAR_EOF
  1296. $TOUCH -am 0419135590 shar.c &&
  1297. chmod 0644 shar.c ||
  1298. echo "restore of shar.c failed"
  1299. set `wc -c shar.c`;Wc_c=$1
  1300. if test "$Wc_c" != "28774"; then
  1301.     echo original size 28774, current size $Wc_c
  1302. fi
  1303. # ============= unshar.c ==============
  1304. echo "x - extracting unshar.c (Text)"
  1305. sed 's/^X//' << 'SHAR_EOF' > unshar.c &&
  1306. X/* CHK=0x2B39 */
  1307. Xchar *revision = "3.22";
  1308. X/****************************************************************
  1309. X * unshar.c: Unpackage one or more shell archive files
  1310. X *
  1311. X * Usage:     unshar [-c] [-C exit_line] [ -d directory ] [ file ] ...
  1312. X *
  1313. X * Description:    unshar is a filter which removes the front part
  1314. X *        of a file and passes the rest to the 'sh' command.
  1315. X *        It understands phrases like "cut here", and also
  1316. X *        knows about shell comment characters and the Unix
  1317. X *        commands "echo", "cat", and "sed".
  1318. X *
  1319. X *      It can unshar shar files concatenated in one file, with the
  1320. X *      the "-c" command, which separates files by recognizing the
  1321. X *      "exit 0" string at the beginning of a line
  1322. X *
  1323. X *      (The -C string option allows you to specify this string, thus
  1324. X *      -c is equivalent to -C "exit 0")
  1325. X *
  1326. X *      The -d flag tells unshar to change directory before unsharing
  1327. X *
  1328. X * HISTORY
  1329. X * 19-Apr-90  Colas Nahaboo (colas@mirsa.inria.fr)
  1330. X *      added -c and -C flags to read from concatenated archives
  1331. X *  1-Feb-85  Guido van Rossum (guido@mcvax) at CWI, Amsterdam
  1332. X *    Added missing 'quit' routine;
  1333. X *    added -d flag to change to directory first;
  1334. X *    added filter mode (read stdin when no arguments);
  1335. X *    added 'getopt' to get flags (makes it self-contained).
  1336. X * 29-Jan-85  Michael Mauldin (mlm) at Carnegie-Mellon University
  1337. X *    Created.
  1338. X ****************************************************************/
  1339. X/*+:EDITS:*/
  1340. X/*:04-19-1990-15:20-wht@n4hgf-fix so -d doesnt make argv files unreachable */
  1341. X/*:04-19-1990-15:06-wht@n4hgf-colas@mirsa patches had expanded tabs */
  1342. X/*:04-10-1990-22:02-wht@n4hgf-stdin failed sometimes-can not seek on pipe */
  1343. X
  1344. X#include <stdio.h>
  1345. X#define EOL '\n'
  1346. X
  1347. X#if defined(pyr) || defined(sun) || defined(BSD42) || \
  1348. X defined(vax) || defined(sequent)
  1349. X#define strchr    index
  1350. X#undef USE_GETCWD
  1351. Xchar *getwd();
  1352. X#else
  1353. X#define USE_GETCWD
  1354. Xchar *getcwd();
  1355. X#endif
  1356. X
  1357. Xchar *strchr();
  1358. X
  1359. Xextern char *optarg;
  1360. Xextern int optind;
  1361. X
  1362. Xint continue_reading = 0;
  1363. Xchar *exit_string = "exit 0";
  1364. Xint exit_string_length;
  1365. Xchar argvdir[1024];
  1366. X
  1367. Xmain(argc,argv)
  1368. Xint argc;
  1369. Xchar *argv[];
  1370. X{
  1371. X    int i,ch;
  1372. X    FILE *in;
  1373. X    char s1024[1024];
  1374. X
  1375. X    setbuf(stdout,NULL);
  1376. X    setbuf(stderr,NULL);
  1377. X
  1378. X#ifdef USE_GETCWD
  1379. X    if(!getcwd(argvdir,sizeof(argvdir)))
  1380. X    {
  1381. X        perror("cannot get current directory name");
  1382. X        exit(1);
  1383. X    }
  1384. X#else
  1385. X    argvdir[0] = 0;
  1386. X    if(!getwd(argvdir))
  1387. X    {
  1388. X        if(argvdir[0])
  1389. X            fprintf(stderr,"%s\n",argvdir);
  1390. X        else
  1391. X            printf(stderr,"cannot get current directory name\n");
  1392. X        exit(1);
  1393. X    }
  1394. X#endif
  1395. X
  1396. X
  1397. X    /* Process options */
  1398. X
  1399. X    while((ch = getopt(argc,argv,"d:cC:")) != EOF)
  1400. X    {
  1401. X        switch(ch)
  1402. X        {
  1403. X        case 'd':
  1404. X            if(chdir(optarg) == -1)
  1405. X            {
  1406. X                fprintf(stderr,"unshar: cannot chdir to '%s'\n",optarg);
  1407. X                exit(2);
  1408. X            }
  1409. X            break;
  1410. X        case 'C':
  1411. X            exit_string = optarg;
  1412. X        case 'c':
  1413. X            continue_reading = 1;
  1414. X            exit_string_length = strlen(exit_string);
  1415. X            break;
  1416. X        default:
  1417. X            quit(2,"Usage: unshar [-d directory] [file] ...\n");
  1418. X        }
  1419. X    }
  1420. X
  1421. X    if(optind < argc)
  1422. X    {
  1423. X        for(i= optind; i < argc; ++i)
  1424. X        {
  1425. X            strcpy(s1024,argvdir);
  1426. X            strcat(s1024,"/");
  1427. X            strcat(s1024,argv[i]);
  1428. X            if(!(in = fopen(s1024,"r")))
  1429. X            {
  1430. X                perror(s1024);
  1431. X                exit(1);
  1432. X            }
  1433. X            process(s1024,in);
  1434. X            fclose(in);
  1435. X        }
  1436. X    }
  1437. X    else
  1438. X    {
  1439. X        sprintf(s1024,"/tmp/unsh.%05d",getpid());
  1440. X        unlink(s1024);
  1441. X        if(!(in = fopen(s1024,"w+")))
  1442. X        {
  1443. X            fprintf(stderr,"cannot open temp file '%s'\n",s1024);
  1444. X            exit(1);
  1445. X        }
  1446. X        unlink(s1024);    /* don't try this with MSDOS, sports fans */
  1447. X        while(i = fread(s1024,1,sizeof(s1024),stdin))
  1448. X            fwrite(s1024,i,1,in);
  1449. X        rewind(in);
  1450. X        process("standard input",in);
  1451. X        fclose(in);
  1452. X    }
  1453. X
  1454. X    exit(0);
  1455. X}
  1456. X
  1457. X
  1458. Xprocess(name,in)
  1459. Xchar *name;
  1460. XFILE *in;
  1461. X{
  1462. X    char buffer[8196];
  1463. X    char ch;
  1464. X    FILE *shpr,*popen();
  1465. X    long current_position = 0;
  1466. X    char *more_to_read = 0;
  1467. X
  1468. X    while(position(name,in,current_position))
  1469. X    {
  1470. X        printf("%s:\n",name);
  1471. X        if(!(shpr = popen("sh","w")))
  1472. X            quit(1,"unshar: cannot open 'sh' process\n");
  1473. X
  1474. X        if (!continue_reading) {
  1475. X            while((ch = fgetc(in)) != EOF)
  1476. X                fputc(ch,shpr);
  1477. X            pclose(shpr);
  1478. X            break;
  1479. X        } else {
  1480. X            while (more_to_read = fgets(buffer, 8196, in)) {
  1481. X                fputs(buffer, shpr);
  1482. X                if (!strncmp(exit_string, buffer, exit_string_length)) {
  1483. X                    break;
  1484. X                }
  1485. X            }
  1486. X            pclose(shpr);
  1487. X            if (more_to_read)
  1488. X                current_position = ftell(in);
  1489. X            else {
  1490. X                break;
  1491. X            }
  1492. X        }
  1493. X    }
  1494. X}
  1495. X
  1496. X/****************************************************************
  1497. X * position: position 'fil' at the start of the shell command
  1498. X * portion of a shell archive file.
  1499. X ****************************************************************/
  1500. X
  1501. Xposition(fn,fil,start)
  1502. Xchar *fn;
  1503. XFILE *fil;
  1504. Xlong start;                   /* scan file from position */
  1505. X{
  1506. X    char buf[BUFSIZ];
  1507. X    long pos,ftell();
  1508. X
  1509. X    /* Results from star matcher */
  1510. X    static char res1[BUFSIZ],res2[BUFSIZ],res3[BUFSIZ],res4[BUFSIZ];
  1511. X    static char *result[] = 
  1512. X    {
  1513. X        res1,res2,res3,res4         };
  1514. X
  1515. X    fseek(fil, start, 0);
  1516. X
  1517. X    while(1)
  1518. X    { /* Record position of the start of this line */
  1519. X        pos = ftell(fil);
  1520. X
  1521. X        /* Read next line, fail if no more and no previous process */
  1522. X        if(!fgets(buf,BUFSIZ,fil))
  1523. X        {
  1524. X            if(!start)
  1525. X                fprintf(stderr,"unshar: found no shell commands in %s\n",fn);
  1526. X            return(0);
  1527. X        }
  1528. X
  1529. X        /* Bail out if we see C preprocessor commands or C comments */
  1530. X        if(stlmatch(buf,"#include")    || stlmatch(buf,"# include") ||
  1531. X            stlmatch(buf,"#define")    || stlmatch(buf,"# define") ||
  1532. X            stlmatch(buf,"#ifdef")    || stlmatch(buf,"# ifdef") ||
  1533. X            stlmatch(buf,"#ifndef")    || stlmatch(buf,"# ifndef") ||
  1534. X            stlmatch(buf,"/*"))
  1535. X        {
  1536. X            fprintf(stderr,
  1537. X                "unshar: %s looks like raw C code, not a shell archive\n",fn);
  1538. X            return(0);
  1539. X        }
  1540. X
  1541. X        /* Does this line start with a shell command or comment */
  1542. X        if(stlmatch(buf,"#")    || stlmatch(buf,":") ||
  1543. X            stlmatch(buf,"echo ")    || stlmatch(buf,"sed ") ||
  1544. X            stlmatch(buf,"cat ") || stlmatch(buf,"if "))
  1545. X        {
  1546. X            fseek(fil,pos,0);
  1547. X            return(1);
  1548. X        }
  1549. X
  1550. X        /* Does this line say "Cut here" */
  1551. X        if(smatch(buf,"*CUT*HERE*",result) ||
  1552. X            smatch(buf,"*cut*here*",result) ||
  1553. X            smatch(buf,"*TEAR*HERE*",result) ||
  1554. X            smatch(buf,"*tear*here*",result) ||
  1555. X            smatch(buf,"*CUT*CUT*",result) ||
  1556. X            smatch(buf,"*cut*cut*",result))
  1557. X        {
  1558. X            /* Read next line after "cut here", skipping blank lines */
  1559. X            while(1)
  1560. X            {
  1561. X                pos = ftell(fil);
  1562. X
  1563. X                if(!fgets(buf,BUFSIZ,fil))
  1564. X                {
  1565. X                    fprintf(stderr,
  1566. X                        "unshar: found no shell commands after 'cut' in %s\n",fn);
  1567. X                    return(0);
  1568. X                }
  1569. X
  1570. X                if(*buf != '\n') break;
  1571. X            }
  1572. X
  1573. X            /* Win if line starts with a comment character of lower case letter */
  1574. X            if(*buf == '#' || *buf == ':' || (('a' <= *buf) && ('z' >= *buf)))
  1575. X            {
  1576. X                fseek(fil,pos,0);
  1577. X                return(1);
  1578. X            }
  1579. X
  1580. X            /* Cut here message lied to us */
  1581. X            fprintf(stderr,"unshar: %s is probably not a shell archive,\n",fn);
  1582. X            fprintf(stderr,"        the 'cut' line was followed by: %s",buf);
  1583. X            return(0);
  1584. X        }
  1585. X    }
  1586. X}
  1587. X
  1588. X/*****************************************************************
  1589. X * stlmatch  --  match leftmost part of string
  1590. X *
  1591. X * Usage:  i = stlmatch (big,small)
  1592. X *    int i;
  1593. X *    char *small, *big;
  1594. X *
  1595. X * Returns 1 iff initial characters of big match small exactly;
  1596. X * else 0.
  1597. X *
  1598. X * HISTORY
  1599. X * 18-May-82 Michael Mauldin (mlm) at Carnegie-Mellon University
  1600. X *      Ripped out of CMU lib for Rog-O-Matic portability
  1601. X * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  1602. X *    Rewritten for VAX from Ken Greer's routine.
  1603. X *
  1604. X *  Originally from klg (Ken Greer) on IUS/SUS UNIX
  1605. X *****************************************************************/
  1606. X
  1607. Xint stlmatch(big,small)
  1608. Xchar *small,*big;
  1609. X{
  1610. X    register char *s,*b;
  1611. X    s = small;
  1612. X    b = big;
  1613. X    do
  1614. X    {
  1615. X        if(*s == '\0')
  1616. X            return(1);
  1617. X    }  while(*s++ == *b++);
  1618. X    return(0);
  1619. X}
  1620. X
  1621. X/*****************************************************************
  1622. X * smatch: Given a data string and a pattern containing one or
  1623. X * more embedded stars (*) (which match any number of characters)
  1624. X * return true if the match succeeds, and set res[i] to the
  1625. X * characters matched by the 'i'th *.
  1626. X *****************************************************************/
  1627. X
  1628. Xsmatch(dat,pat,res)
  1629. Xregister char *dat,*pat,**res;
  1630. X{
  1631. X    register char *star = 0,*starend,*resp;
  1632. X    int nres = 0;
  1633. X
  1634. X    while(1)
  1635. X    {
  1636. X        if(*pat == '*')
  1637. X        {
  1638. X            star = ++pat;                  /* Pattern after * */
  1639. X            starend = dat;                  /* Data after * match */
  1640. X            resp = res[nres++];              /* Result string */
  1641. X            *resp = '\0';                  /* Initially null */
  1642. X        }
  1643. X        else if(*dat == *pat)              /* Characters match */
  1644. X        {
  1645. X            if(*pat == '\0')              /* Pattern matches */
  1646. X                return(1);
  1647. X            pat++;                      /* Try next position */
  1648. X            dat++;
  1649. X        }
  1650. X        else
  1651. X        {
  1652. X            if(*dat == '\0')              /* Pattern fails - no more */
  1653. X                return(0);                  /* data */
  1654. X            if(star == 0)                  /* Pattern fails - no * to */
  1655. X                return(0);                  /* adjust */
  1656. X            pat = star;                  /* Restart pattern after * */
  1657. X            *resp++ = *starend;              /* Copy character to result */
  1658. X            *resp = '\0';                  /* null terminate */
  1659. X            dat = ++starend;                  /* Rescan after copied char */
  1660. X        }
  1661. X    }
  1662. X}
  1663. X
  1664. X/*****************************************************************
  1665. X * Addendum: quit subroutine (print a message and exit)
  1666. X *****************************************************************/
  1667. X
  1668. Xquit(status,message)
  1669. Xint status;
  1670. Xchar *message;
  1671. X{
  1672. X    fprintf(stderr,message);
  1673. X    exit(status);
  1674. X}
  1675. X
  1676. X/*****************************************************************
  1677. X * Public Domain getopt routine
  1678. X *****************************************************************/
  1679. X
  1680. X/*
  1681. X * get option letter from argument vector
  1682. X */
  1683. Xint opterr = 1;        /* useless, never set or used */
  1684. Xint optind = 1;        /* index into parent argv vector */
  1685. Xint optopt;            /* character checked for validity */
  1686. Xchar *optarg;        /* argument associated with option */
  1687. X
  1688. X#define BADCH    (int)'?'
  1689. X#define EMSG    ""
  1690. X#define tell(s)    fputs(*nargv,stderr);fputs(s,stderr); \
  1691. X        fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
  1692. X
  1693. Xgetopt(nargc,nargv,ostr)
  1694. Xint nargc;
  1695. Xchar **nargv,*ostr;
  1696. X{
  1697. X    static char *place = EMSG;    /* option letter processing */
  1698. X    register char *oli;        /* option letter list index */
  1699. X    char *strchr();
  1700. X
  1701. X    if(!*place)
  1702. X    {            /* update scanning pointer */
  1703. X        if(optind >= nargc || *(place = nargv[optind]) != '-' || !*++place)
  1704. X            return(EOF);
  1705. X        if(*place == '-')
  1706. X        {    /* found "--" */
  1707. X            ++optind;
  1708. X            return(EOF);
  1709. X        }
  1710. X    }                /* option letter okay? */
  1711. X    if((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt)))
  1712. X    {
  1713. X        if(!*place) ++optind;
  1714. X        tell(": illegal option -- ");
  1715. X    }
  1716. X    if(*++oli != ':')
  1717. X    {        /* don't need argument */
  1718. X        optarg = (char *)0;
  1719. X        if(!*place) ++optind;
  1720. X    }
  1721. X    else 
  1722. X    {                /* need an argument */
  1723. X        if(*place) optarg = place;    /* no white space */
  1724. X        else if(nargc <= ++optind)
  1725. X        {    /* no arg */
  1726. X            place = EMSG;
  1727. X            tell(": option requires an argument -- ");
  1728. X        }
  1729. X        else optarg = nargv[optind];    /* white space */
  1730. X        place = EMSG;
  1731. X        ++optind;
  1732. X    }
  1733. X    return(optopt);            /* dump back option letter */
  1734. X}
  1735. X/* vi: set tabstop=4 shiftwidth=4: */
  1736. SHAR_EOF
  1737. $TOUCH -am 0419161290 unshar.c &&
  1738. chmod 0644 unshar.c ||
  1739. echo "restore of unshar.c failed"
  1740. set `wc -c unshar.c`;Wc_c=$1
  1741. if test "$Wc_c" != "10737"; then
  1742.     echo original size 10737, current size $Wc_c
  1743. fi
  1744. # ============= uushar.c ==============
  1745. echo "x - extracting uushar.c (Text)"
  1746. sed 's/^X//' << 'SHAR_EOF' > uushar.c &&
  1747. X/* CHK=0x46B4 */
  1748. X#include <stdio.h>
  1749. X#include <sys/types.h>
  1750. X#include <sys/stat.h>
  1751. X
  1752. X/* ENC is the basic 1 character encoding function to make a char printing */
  1753. X#define ENC(c) ((((c) & 077) + ' ') | ((c & 077) == 0 ? 0100 : 0))
  1754. X
  1755. Xencode (in, out)
  1756. X    FILE *in;
  1757. X    FILE *out;
  1758. X{
  1759. X    char  buf[80];
  1760. X    int  i, n;
  1761. X
  1762. X    for (;;)
  1763. X    {
  1764. X    /* 1 (up to) 45 character line */
  1765. X    n = fr (in, buf, 45);
  1766. X    putc (ENC (n), out);
  1767. X
  1768. X    for (i = 0; i < n; i += 3)
  1769. X        outdec (&buf[i], out);
  1770. X
  1771. X    putc ('\n', out);
  1772. X    if (n <= 0)
  1773. X        break;
  1774. X    }
  1775. X}
  1776. X
  1777. X/*
  1778. X * output one group of 3 bytes, pointed at by p, on file f.
  1779. X */
  1780. Xoutdec (p, f)
  1781. X    char *p;
  1782. X    FILE *f;
  1783. X{
  1784. X    int  c1, c2, c3, c4;
  1785. X
  1786. X    c1 = *p >> 2;
  1787. X    c2 = (*p << 4) & 060 | (p[1] >> 4) & 017;
  1788. X    c3 = (p[1] << 2) & 074 | (p[2] >> 6) & 03;
  1789. X    c4 = p[2] & 077;
  1790. X    putc (ENC (c1), f);
  1791. X    putc (ENC (c2), f);
  1792. X    putc (ENC (c3), f);
  1793. X    putc (ENC (c4), f);
  1794. X}
  1795. X
  1796. X/* fr: like read but stdio */
  1797. Xint
  1798. X     fr (fp, buf, cnt)
  1799. X    FILE *fp;
  1800. X    char *buf;
  1801. X    int  cnt;
  1802. X{
  1803. X    int  c, i;
  1804. X
  1805. X    for (i = 0; i < cnt; i++)
  1806. X    {
  1807. X    c = getc (fp);
  1808. X    if (c == EOF)
  1809. X        return (i);
  1810. X    buf[i] = c;
  1811. X    }
  1812. X    return (cnt);
  1813. X}
  1814. X/* vi: set tabstop=4 shiftwidth=4: */
  1815. SHAR_EOF
  1816. $TOUCH -am 0330002690 uushar.c &&
  1817. chmod 0644 uushar.c ||
  1818. echo "restore of uushar.c failed"
  1819. set `wc -c uushar.c`;Wc_c=$1
  1820. if test "$Wc_c" != "1169"; then
  1821.     echo original size 1169, current size $Wc_c
  1822. fi
  1823. # ============= who@where.c ==============
  1824. echo "x - extracting who@where.c (Text)"
  1825. sed 's/^X//' << 'SHAR_EOF' > who@where.c &&
  1826. X/* CHK=0xCB66 */
  1827. X/*+-------------------------------------------------------------------------
  1828. X    who@where.c - find out who i am & where i am
  1829. X    ...!gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu)
  1830. X--------------------------------------------------------------------------*/
  1831. X/*+:EDITS:*/
  1832. X/*:04-03-1990-19:55-wht@n4hgf-get rid of complicated who_am_i */
  1833. X/*:04-01-1990-13:30-pat@rwing-use utsname.nodename instead of sysname */
  1834. X/*:04-02-1990-12:12-wht@n4hgf-sigh... some pwd.h dont declare functions */
  1835. X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
  1836. X/*:03-28-1990-15:24-wht@n4hgf-creation */
  1837. X
  1838. X#include <stdio.h>
  1839. X#include <sys/types.h>
  1840. X#include <pwd.h>
  1841. X
  1842. X/* assume system v unless otherwise fixed */
  1843. X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42)
  1844. X#define BSD42
  1845. X#endif
  1846. X#if defined(sun)    /* this miscreant doesn't exactly fit BSD or SYSV */
  1847. X#undef BSD42
  1848. X#undef SYS5
  1849. X#endif
  1850. X#if !defined(BSD42) && !defined(sun)
  1851. X#define SYS5
  1852. X#endif
  1853. X
  1854. X#if defined(sun) || defined(BSD42)
  1855. X#define strchr    index
  1856. X#define strrchr    rindex
  1857. X#endif
  1858. X
  1859. X#if !defined(SYS5) || defined(sun)
  1860. X#include <sys/time.h>
  1861. Xextern int errno;
  1862. X#else
  1863. X#include <sys/utsname.h>
  1864. X#include <time.h>
  1865. X#endif    /* system dependencies */
  1866. X
  1867. X/*+-------------------------------------------------------------------------
  1868. X    who_am_i() - get user name
  1869. X--------------------------------------------------------------------------*/
  1870. Xchar *
  1871. Xwho_am_i()
  1872. X{
  1873. X    struct passwd *getpwuid();
  1874. X    struct passwd *passwd;
  1875. X    passwd = getpwuid(getuid());
  1876. X    (void)endpwent();
  1877. X    if(passwd == (struct passwd *)0)
  1878. X        return("???");
  1879. X    return(passwd->pw_name);
  1880. X
  1881. X}    /* end of who_am_i */
  1882. X
  1883. X/*+-------------------------------------------------------------------------
  1884. X    where_am_i() - do uname, gethostname, or read file (/etc/systemid)
  1885. X--------------------------------------------------------------------------*/
  1886. Xchar *
  1887. Xwhere_am_i()
  1888. X{
  1889. X#if defined(M_SYS5)    /* SCO UNIX or XENIX */
  1890. XFILE *fpsid = fopen("/etc/systemid","r");
  1891. Xstatic char s20[20];
  1892. X    if(!fpsid)
  1893. X        return("???");
  1894. X    fgets(s20,sizeof(s20),fpsid);
  1895. X    fclose(fpsid);
  1896. X    s20[strlen(s20) - 1] = 0;
  1897. X    return(s20);
  1898. X#else /* M_SYS5 */
  1899. X#if defined(SYS5)
  1900. Xstatic struct utsname where_i_am;
  1901. X    uname(&where_i_am);
  1902. X    return(where_i_am.nodename);
  1903. X#else /* SYS5 */
  1904. Xstatic char where_i_am[64];
  1905. X    gethostname(where_i_am,sizeof(where_i_am));
  1906. X    return(where_i_am);
  1907. X#endif /* SYS5 */
  1908. X#endif /* M_SYS5 */
  1909. X}    /* end of where_am_i */
  1910. X
  1911. X/*+-------------------------------------------------------------------------
  1912. X    who_where(buf)
  1913. X--------------------------------------------------------------------------*/
  1914. Xchar *
  1915. Xwho_where(buf)
  1916. Xchar *buf;
  1917. X{
  1918. Xstatic char ww[64];
  1919. X
  1920. X    if(!buf)
  1921. X        buf = ww;
  1922. X    strcpy(buf,who_am_i());
  1923. X    strcat(buf,"@");
  1924. X    strcat(buf,where_am_i());
  1925. X}    /* end of who_where */
  1926. X
  1927. X/* vi: set tabstop=4 shiftwidth=4: */
  1928. X/* end of who@where.c */
  1929. SHAR_EOF
  1930. $TOUCH -am 0419135590 who@where.c &&
  1931. chmod 0644 who@where.c ||
  1932. echo "restore of who@where.c failed"
  1933. set `wc -c who@where.c`;Wc_c=$1
  1934. if test "$Wc_c" != "2784"; then
  1935.     echo original size 2784, current size $Wc_c
  1936. fi
  1937. exit 0
  1938.  
  1939. ------------------------------------------------------------------
  1940. Warren Tucker, TuckerWare gatech!n4hgf!wht or wht%n4hgf@gatech.edu
  1941. McCarthyism did to cinema what ANSI did to C,  cast a great number
  1942. of characters into the void.
  1943.