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

  1. From: wht@n4hgf.uucp (Warren Tucker)
  2. Newsgroups: alt.sources
  3. Subject: shar311/patch03
  4. Message-ID: <670@n4hgf.uucp>
  5. Date: 18 Apr 90 07:12:17 GMT
  6. X-Checksum-Snefru: 98ba155e 2e6309a3 e069ce0b 2bd5ece7
  7.  
  8. Submitted by: wht%n4hgf@gatech.edu
  9. Archive-name: shar311/patch03
  10.  
  11. rhg@CPS.COM (Richard H. Gumpertz) added a GREAT set of new features to
  12. shar 3.11.  This posting replaces the previous README and shar.c files.
  13. The revision number is now 3.20.
  14.  
  15. The files are supplied since the diffs to shar.c were 40k and the whole
  16. file is only 28k.
  17.  
  18. If you missed the previous postings, I'll be glad to mail you a complete
  19. mailing.  Please forgive me if the snefru header fails; it's my first
  20. try and it might get out of here wrong.
  21.  
  22. Changes since 3.11: 
  23.  
  24. 1.  The -l switch still specifies a maximum size for the generated
  25.     shar files, but now it prevents files from spanning shar parts.
  26.     Shars generated using this method may be unpacked in any order.
  27.  
  28. 2.  The old -l switch functionality is precisely emulated by using the
  29.     the -L switch.  That is, archived files may be split across parts.
  30.     Shars generated using this method must still be unpacked in order.
  31.  
  32. 3.  The -C switch causes files to be compressed, then uuencoded.
  33.     Unpacking reverses the process.
  34.  
  35. 4.  The -P causes the shar to use temp files instead of pipes in
  36.     the unshar process.
  37.  
  38. 5.  The -f causes files to be restored by name only (i.e., strip
  39.     directory portion of input filenames before placing the name
  40.     into the shar.
  41.  
  42. #!/bin/sh
  43. # This is shar311/patch03, a shell archive (shar 3.20)
  44. # made 04/18/1990 06:54 UTC by wht%n4hgf@gatech.edu
  45. # Source directory /u1/src/shar
  46. #
  47. # existing files WILL be overwritten
  48. #
  49. # This shar contains:
  50. # length  mode       name
  51. # ------ ---------- ------------------------------------------
  52. #   3445 -rw-r--r-- README
  53. #  28686 -rw-r--r-- shar.c
  54. #
  55. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  56.  then TOUCH=touch
  57.  else TOUCH=true
  58. fi
  59. # ============= README ==============
  60. echo "x - extracting README (Text)"
  61. sed 's/^X//' << 'SHAR_EOF' > README &&
  62. XSubmitted by: wht%n4hgf@gatech.edu
  63. XArchive-name: shar320/part01
  64. X
  65. XHere is shar 3.20, an updated version of shar 3.11, derived from 'shar2'
  66. XThis offering is the work of many people. rhg@CPS.COM (Richard H.
  67. XGumpertz) made significant changes to 3.11. They are outlined at
  68. Xthe bottom of this file.
  69. X
  70. XThis version
  71. X1) generates shell code which attempts to create missing directories
  72. X2) handle deviants sun, vax, pyramid, sequent, and SCO XENIX/UNIX
  73. X   automatically; for system V systems I did not catch, add -DSYS5
  74. X   to CFLAGS; for other BSD-like systems, add -DBSD42
  75. X3) if unsharing system's touch is Sys V compatible (allows touch -m),
  76. X   the unshar process restores file dates
  77. X4) An archive name may be specified for includion in the header
  78. X   of the shar files( -n switch)
  79. X5) allows automatic generation of "Submitted-by: who@where" &
  80. X   "Archive-name: <name>/part##" headers
  81. X6) uses getopt; no good system library should be without a copy
  82. X   but it is readily available
  83. X7) other chrome-plated junque
  84. X
  85. X------------------------ usage -----------------------------------
  86. X
  87. Xshar 3.20
  88. Xusage: shar [ options ] file [ file1 ... ] ]
  89. X-v  verbose messages OFF while executing
  90. X-w  don't check with 'wc -c' after unpack
  91. X-n  Name of archive (documentation)
  92. X-a  Generate Submitted-by: & Archive-name: headers
  93. X-s  override automatically determined submitter name
  94. X-x  don't overwrite existing files
  95. X-X  interactively overwrite existing files (NOT FOR NET SHARS)
  96. X-b  treat all files as binary, use uuencode
  97. X-t  treat all files as text (default)
  98. X-C  compress and uuencode all files
  99. X-p  allow positional parameter options. The options "-b" and "-t"
  100. X    and "-C" may be embedded, and files to the right of the
  101. X    option will be processed in the specified mode
  102. X-M  mixed mode. Determine if the files are text or
  103. X    binary and archive correctly.
  104. X-P  use temp files instead of pipes in the shar file
  105. X-c  start the shar with a cut line
  106. X-f  restore by filename only, rather than path
  107. X-dXXX   use XXX to delimit the files in the shar
  108. X-oXXX   (or -o XXX) output to file XXX.01 thru XXX.nn
  109. X-lXX    limit output file size to XXk bytes (but don't split files)
  110. X-LXX    limit output file size to XXk bytes (may split files)
  111. X
  112. XThe 'o' option is required if the 'l' or 'L' option is used
  113. XThe 'n' option is required if the 'a' option is used
  114. XThe 'x' and 'L' options are incompatible
  115. X
  116. X-a generates sharname/part## headers. If you are producing patches
  117. Xyou'll need to edit -a headers (or please improve shar :-))
  118. XThe automatic submitter name is trivial: essentially `whoami`@`uname`
  119. X
  120. X--------------------- history -----------------------------------------
  121. XChanges since 3.11: kudos to rhg@CPS.COM (Richard H. Gumpertz)
  122. X
  123. X1.  The -l switch still specifies a maximum size for the generated
  124. X    shar files, but now it prevents files from spanning shar parts.
  125. X    Shars generated using this method may be unpacked in any order.
  126. X
  127. X2.  The old -l switch functionality is precisely emulated by using the
  128. X    the -L switch.  That is, archived files may be split across parts.
  129. X    Shars generated using this method must still be unpacked in order.
  130. X
  131. X3.  The -C switch causes files to be compressed, then uuencoded.
  132. X    Unpacking reverses the process.
  133. X
  134. X4.  The -P causes the shar to use temp files instead of pipes in
  135. X    the unshar process.
  136. X
  137. X5.  The -f causes files to be restored by name only (i.e., strip
  138. X    directory portion of input filenames before placing the name
  139. X    into the shar.
  140. X
  141. X
  142. SHAR_EOF
  143. $TOUCH -am 0418025190 README &&
  144. chmod 0644 README ||
  145. echo "restore of README failed"
  146. set `wc -c README`;Wc_c=$1
  147. if test "$Wc_c" != "3445"; then
  148.     echo original size 3445, current size $Wc_c
  149. fi
  150. # ============= shar.c ==============
  151. echo "x - extracting shar.c (Text)"
  152. sed 's/^X//' << 'SHAR_EOF' > shar.c &&
  153. X/* CHK=0xE0B7 */
  154. Xchar *revision = "3.20";
  155. X/*
  156. X** shar.c
  157. X
  158. X  Defined functions:
  159. X    Rname(file)
  160. X    exit_incompat()
  161. X    gen_mkdir(path)
  162. X    gen_mkdir_script(path)
  163. X    setTOUCH()
  164. X    header(argc,argv)
  165. X    helpuser()
  166. X    main(argc,argv)
  167. X    mode_map(mode,mode_str)
  168. X    shar(file)
  169. X
  170. X*/
  171. X/*+:EDITS:*/
  172. X/*:04-18-1990-02:01-wht@n4hgf-3.20 rhg@cps.com did all the NICE work */
  173. X/*:04-17-1990-14:30-rhg@cps.com-pretty up if-then-else-fi in shar file */
  174. X/*:04-17-1990-12:13-rhg@cps.com-add Split and renamed old -l to -L */
  175. X/*:04-17-1990-12:13-rhg@cps.com-add -c option to shar file execution */
  176. X/*:04-17-1990-11:20-rhg@cps.com-simplify TOUCH logic in shar file */
  177. X/*:04-17-1990-10:27-rhg@cps.com-create setTOUCH to avoid duplicate code */
  178. X/*:04-17-1990-04:43-rhg@cps.com-add missing && to commands in shar file(s) */
  179. X/*:04-17-1990-02:03-rhg@cps.com-add Compress */
  180. X/*:04-16-1990-17:08-rhg@cps.com-add AvoidPipes as well as code to use pipes */
  181. X/*:04-03-1990-20:09-wht@n4hgf-3.11 */
  182. X/*:04-01-1990-13:20-pat@rwing-correct case on M option in getopt() call */
  183. X/*:04-01-1990-13:50-pat@rwing-change defaults on -v, -w to be on */
  184. X/*:03-29-1990-18:23-wht@n4hgf-add automatic sequent support */
  185. X/*:03-28-1990-15:56-wht@n4hgf-add mode and length net.bandwidth chrome */
  186. X/*:03-28-1990-14:23-wht@n4hgf-correct some runtime diagnostics */
  187. X/*:11-14-1989-02:21-wht-SHAR_EOF was botched if last file char not newline */
  188. X/*:11-02-1989-14:11-wht-add touch -am */
  189. X
  190. X/*
  191. X Shar puts readable text files together in a package
  192. X from which they are easy to extract.
  193. X earlier attribution wht@n4hgf has:    decvax!microsof!uw-beave!jim
  194. X                                    (James Gosling at CMU)
  195. X*/
  196. X/*
  197. X *    I have made several mods to this program:
  198. X *
  199. X *    1) the -----Cut Here-----... now preceds the script.
  200. X *    2) the cat has been changed to a sed which removes a prefix
  201. X *    character from the beginning of each line of the extracted
  202. X *    file, this prefix character is added to each line of the archived
  203. X *    files and is not the same as the first character of the
  204. X *    file delimeter.
  205. X *    3) added several options:
  206. X *        -c    - add the -----Cut Here-----... line.
  207. X *        -d'del' - change the file delimeter to del.
  208. X *        -s    - cause the resulting script to print the wc of
  209. X *              the orignal file and the wc of the extracted
  210. X *              file.
  211. X *
  212. X *                Michael A. Thompson
  213. X *                Dalhousie University
  214. X *                Halifax, N.S., Canada.
  215. X */
  216. X
  217. X/*
  218. X *    I, too, have been hacking this code. This is the version on sixhub
  219. X *        bill davidsen (davidsen@sixhub.uucp)
  220. X *
  221. X *    - added support for binary files
  222. X *    - automatic creation of limited size multiple file archives,
  223. X *      each of which may be unpacked separately, and with sequence
  224. X *      checking.
  225. X *    - support for mixed text and binary files
  226. X *    - preserve file permissions
  227. X *    - restore to filename rather than pathname
  228. X *
  229. X */
  230. X/*
  231. X *  One good hack deserves another ... this version generates shell
  232. X *  code which attempts to create missing directories
  233. X *  handle deviants sun, vax, pyr (pyramid), SCO XENIX/UNIX automatically
  234. X *  for sequent, add -DBSD42
  235. X *  force Verbose on
  236. X *  if unsharing system's touch Sys V compatible (allows touch -m),
  237. X *  restore file dates
  238. X *  -n switch puts an alpha "name" in header
  239. X *  -a (if also -n) puts "Submitted-by:" & "Archive-name: <name>/part##
  240. X *  use getopt
  241. X *  as well as some other chrome-plated junque
  242. X *  ...!gatech!emory!tridom!wht (wht%n4hgf@gatech.edu) Warren Tucker
  243. X *
  244. X *  3.11 - Fri Apr  6 14:21:51 EDT 1990
  245. X *  With due deference to davidsen@sixhub, more changes..... copies
  246. X *  of this, like 3.10,  were mailed to him:
  247. X *  From wht  Fri Apr  6 15:14:30 1990 remote from n4hgf
  248. X *  Received: by n4hgf.UUCP (smail2.5-UNIX/386 5.3.2)
  249. X *      id AA01781; 6 Apr 90 15:14:30 EDT (Fri)
  250. X *  Date: Fri, 6 Apr 90 15:14:30 EDT
  251. X *  X-Mailer: Mail User's Shell (6.5 4/17/89)
  252. X *  From: wht@n4hgf (Warren Tucker)
  253. X *  To: davidsen@sixhub
  254. X *  Subject: shar 3.11
  255. X *  X-Bang-Reply-to: gatech!n4hgf!wht -or- emory!tridom!n4hgf!wht
  256. X *  Reply-to: wht%n4hgf@gatech.edu
  257. X *  Message-Id: <9004061514.AA01781@n4hgf.UUCP>
  258. X *
  259. X *  1. changes suggested by pat@rwing (Pat Myrto) and silvert@cs.dal.ca
  260. X *  (Bill Silvert)
  261. X *  2. fixes to who_am_i code in who@where.c
  262. X *
  263. X *  3.20 - Wed Apr 18 01:58:32 EDT 1990
  264. X *  changes were made per edit notes by
  265. XFrom: gatech!mailrus!uunet!cpsolv.CPS.COM!rhg (Richard H. Gumpertz)
  266. X *  ...!gatech!n4hgf!wht (wht%n4hgf@gatech.edu) Warren Tucker
  267. X *
  268. X */
  269. X
  270. X#include <stdio.h>
  271. X#include <sys/types.h>
  272. X#include <time.h>
  273. X#include <sys/stat.h>
  274. X
  275. X/* assume system v unless otherwise fixed */
  276. X#if (defined(pyr) || defined(vax) || defined(sequent)) && !defined(BSD42)
  277. X#define BSD42
  278. X#endif
  279. X#if defined(sun)    /* this miscreant doesn't exactly fit BSD or SYSV */
  280. X#undef BSD42
  281. X#undef SYS5
  282. X#endif
  283. X#if !defined(BSD42) && !defined(sun)
  284. X#define SYS5
  285. X#endif
  286. X
  287. X#if defined(sun) || defined(BSD42)
  288. X#define strchr    index
  289. X#define strrchr    rindex
  290. X#endif
  291. X
  292. Xchar *strchr();
  293. Xchar *strrchr();
  294. X#ifdef __STDC__ /* my concession to ANSI-pansiness */
  295. Xvoid *malloc();
  296. X#else
  297. Xchar *malloc();
  298. X#endif
  299. XFILE *fdopen();
  300. XFILE *popen();
  301. X
  302. X#define    DELIM        "SHAR_EOF"/* put after each file */
  303. X#define PREFIX1        'X'    /* goes in front of each line */
  304. X#define PREFIX2        'Y'    /* goes in front of each line if Delim
  305. X                         * starts with PREFIX1 */
  306. X#define PREFIX        (Delim[0] == PREFIX1 ? PREFIX2 : PREFIX1)
  307. X#define WC            "wc -c"
  308. X
  309. Xint Archive_name = 0;    /* option to generate "Archive-name:" headers */
  310. Xint Verbose = 1;        /* option to provide append/extract feedback */
  311. Xint Wc_c = 1;            /* option to provide wc checking */
  312. Xchar *Delim = DELIM;    /* pointer to delimiter string */
  313. Xint Cut = 0;            /* option to provide cut mark */
  314. Xint Binary = 0;            /* flag for binary files */
  315. Xint AvoidPipes = 0;        /* use temp file instead of pipe to feed uudecode, etc.
  316. X                           (better error detection at expense of disk space) */
  317. Xint Compress = 0;        /* run input files through compress (requires Binary) */
  318. Xint Mixed = 0;            /* mixed text and binary files */
  319. Xint eXists = 0;            /* check if file exists */
  320. Xint InterOW = 0;        /* interactive overwrite */
  321. Xint PosParam = 0;        /* allow positional parameters */
  322. Xint FileStrip;            /* strip directories from filenames */
  323. X#ifdef    DEBUG
  324. Xint de_bug = 0;            /* switch for debugging on */
  325. X#define DeBug(f,v) if (de_bug) printf(f, v)
  326. X#else    /* normal compile */
  327. X#define DeBug(f,v)        /* do nothing */
  328. X#endif
  329. X
  330. XFILE *fpout = stdout;
  331. Xchar *Rname();            /* file restore name */
  332. Xunsigned limit = 0;
  333. Xint Split = 0;            /* Split files in the middle */
  334. Xlong ftell();
  335. Xlong TypePos;            /* position for archive type message */
  336. Xlong EndHeadPos;        /* position for first file in the shar file */
  337. Xchar outname[50];        /* base for output filename */
  338. Xchar filename[50];        /* actual output filename */
  339. Xchar *sharname = (char *)0;
  340. Xchar *submitter = (char *)0;
  341. Xint filenum = 0;        /* output file # */
  342. Xstruct stat fst;        /* check file type, access */
  343. X
  344. Xmain(argc,argv)
  345. Xchar **argv;
  346. X{
  347. Xint status = 0;
  348. Xchar *oname;
  349. Xint c;
  350. Xextern int optind;
  351. Xextern char *optarg;
  352. X
  353. X    while((c = getopt(argc,argv,"vwd:btCxXcfMpPas:n:l:L:o:h")) != -1)
  354. X    {
  355. X        switch(c)
  356. X        {
  357. X        case 'v':
  358. X            Verbose = 0;
  359. X            break;
  360. X        case 'w':
  361. X            Wc_c = 0;
  362. X            break;
  363. X        case 'd':
  364. X            Delim = optarg;
  365. X            break;
  366. X        case 'b': /* binary files */
  367. X            Binary = 1;
  368. X            Compress = 0;
  369. X            break;
  370. X        case 't': /* text mode */
  371. X            Binary = 0;
  372. X            Compress = 0;
  373. X            break;
  374. X        case 'C': /* Compress */
  375. X            Binary = 1;
  376. X            Compress = 1;
  377. X            break;
  378. X        case 'x': /* does the file exist */
  379. X            eXists = 1;
  380. X            if(InterOW || Split)
  381. X                exit_incompat();
  382. X            break;
  383. X        case 'X': /* does the file exist */
  384. X            InterOW = 1;
  385. X            if(eXists || Split)
  386. X                exit_incompat();
  387. X            eXists = 1;
  388. X            break;
  389. X        case 'c':
  390. X            Cut = 1;
  391. X            break;
  392. X        case 'f': /* filenames only */
  393. X            FileStrip = 1;
  394. X            break;
  395. X        case 'M': /* mixed text and binary */
  396. X            Mixed = 1;
  397. X            break;
  398. X        case 'p': /* allow positional parameters */
  399. X            PosParam = 1;
  400. X            break;
  401. X        case 'P': /* use temp files instead of pipes in the shar file */
  402. X            AvoidPipes = 1;
  403. X            break;
  404. X        case 'l': /* soft size limit in k */
  405. X            if((limit = atoi(optarg)) > 1)
  406. X                --limit;
  407. X            Split = 0;
  408. X            DeBug("Soft limit %dk\n",limit);
  409. X            break;
  410. X        case 'L': /* hard size limit in k */
  411. X            if(eXists)
  412. X                exit_incompat();
  413. X            if((limit = atoi(optarg)) > 1)
  414. X                --limit;
  415. X            Split = (limit != 0);
  416. X            AvoidPipes = 1;
  417. X            DeBug("Hard limit %dk\n",limit);
  418. X            break;
  419. X        case 'n': /* name of archive */
  420. X            sharname = optarg;
  421. X            break;
  422. X        case 's': /* submitter */
  423. X            submitter = optarg;
  424. X            break;
  425. X        case 'a': /* generate Archive-name: headers */
  426. X            Archive_name = 1;
  427. X            break;
  428. X        case 'o': /* specify output file */
  429. X            oname = optarg;
  430. X            strcpy(outname,oname);
  431. X            strcat(outname,".");
  432. X            filenum = 1;
  433. X            strcpy(filename,outname);
  434. X            strcat(filename,"01");
  435. X            fpout = fopen(filename,"w");
  436. X            if(!fpout)
  437. X            { /* creation error */
  438. X                perror("can't create output file");
  439. X                exit(1);
  440. X            }
  441. X            break;
  442. X#ifdef    DEBUG
  443. X        case '$': /* totally undocumented $ option, debug on */
  444. X            de_bug = 1;
  445. X            break;
  446. X#endif
  447. X        default: /* invalid option */
  448. X        case 'h': /* help */
  449. X            helpuser();
  450. X            break;
  451. X        }
  452. X    }
  453. X
  454. X    if(optind >= argc)
  455. X    {
  456. X        fprintf(stderr,"shar: No input files\n");
  457. X        helpuser();
  458. X        exit(1);
  459. X    }
  460. X
  461. X    if(Archive_name && !sharname)
  462. X    {
  463. X        fprintf(stderr,"shar: -n must accompany -a\n");
  464. X        helpuser();
  465. X        exit(1);
  466. X    }
  467. X
  468. X    if(!submitter)
  469. X    {
  470. X        submitter = malloc(128);
  471. X        who_where(submitter);
  472. X    }
  473. X
  474. X    if(header(argc-optind,&argv[optind]))
  475. X        exit(2);
  476. X
  477. X    if(InterOW)
  478. X    {
  479. X        Verbose = 1;
  480. X        fprintf(fpout,"wish=\n");
  481. X        if(Archive_name)
  482. X        {
  483. X            printf("PLEASE do not submit -X shars to the usenet or other\n");
  484. X            printf("public networks.  They will cause problems.\n");
  485. X        }
  486. X    }
  487. X
  488. X    EndHeadPos = ftell(fpout);
  489. X
  490. X    while(optind < argc)
  491. X    { /* process positional parameters and files */
  492. X        if(PosParam)
  493. X        {        /* allow -b and -t and -C inline */
  494. X            if(strcmp(argv[optind],"-b") == 0)
  495. X            { /* set binary */
  496. X                Binary = 1;
  497. X                Compress = 0;
  498. X                optind++;
  499. X                continue;
  500. X            }
  501. X            if(strcmp(argv[optind],"-t") == 0)
  502. X            { /* set mode text */
  503. X                Binary = 0;
  504. X                Compress = 0;
  505. X                optind++;
  506. X                continue;
  507. X            }
  508. X            if(strcmp(argv[optind],"-C") == 0)
  509. X            { /* set compress */
  510. X                Binary = 1;
  511. X                Compress = 1;
  512. X                optind++;
  513. X                continue;
  514. X            }
  515. X        }
  516. X        status += shar(argv[optind++]);
  517. X    }
  518. X
  519. X    /* delete the sequence file, if any */
  520. X    if(Split && filenum > 1)
  521. X    {
  522. X        fputs("rm -f @shar_seq_.tmp\n",fpout);
  523. X        fputs("echo \"You have unpacked the last part\"\n",fpout);
  524. X        if(!Verbose)
  525. X            fprintf(stderr,"Created %d files\n",filenum);
  526. X    }
  527. X    fputs("exit 0\n",fpout);
  528. X    exit(status);
  529. X}
  530. X
  531. X/*+-----------------------------------------------------------------------
  532. X    mode_map(mode,mode_str)    build drwxrwxrwx string
  533. X------------------------------------------------------------------------*/
  534. Xchar *
  535. Xmode_map(mode,mode_str)
  536. Xunsigned short mode;
  537. Xchar *mode_str;
  538. X{
  539. Xregister unsigned ftype = mode & S_IFMT;
  540. Xregister char *rtn;
  541. Xstatic char result[12];
  542. X
  543. X    rtn = (mode_str == (char *)0) ? result : mode_str;
  544. X
  545. X    /*          drwxrwxrwx */
  546. X    /*          0123456789 */
  547. X    strcpy(rtn,"----------");
  548. X
  549. X#ifdef THIS_IS_NOT_NEEDED_FOR_SHAR
  550. X    switch(ftype)
  551. X    {
  552. X        case S_IFIFO:    *rtn = 'p'; break; /* FIFO (named pipe) */
  553. X        case S_IFDIR:    *rtn = 'd'; break; /* directory */
  554. X        case S_IFCHR:    *rtn = 'c'; break; /* character special */
  555. X        case S_IFBLK:    *rtn = 'b'; break; /* block special */
  556. X        case S_IFREG:    *rtn = '-'; break; /* regular */
  557. X
  558. X#if defined(sun) | defined(BSD42)
  559. X        case S_IFLNK:    *rtn = 'l'; break; /* symbolic link */
  560. X        case S_IFSOCK:    *rtn = 's'; break; /* socket */
  561. X#endif
  562. X
  563. X#if defined (SYS5)
  564. X        case S_IFNAM:                        /* name space entry */
  565. X            if(mode & S_INSEM)                /* semaphore */
  566. X            {
  567. X                *rtn = 's';
  568. X                break;
  569. X            }
  570. X            if(mode & S_INSHD)                /* shared memory */
  571. X            {
  572. X                *rtn = 'm';
  573. X                break;
  574. X            }
  575. X#endif
  576. X
  577. X        default:        *rtn = '?'; break;    /* ??? */
  578. X    }
  579. X#endif /* THIS_IS_NOT_NEEDED_FOR_SHAR */
  580. X
  581. X    if(mode & 000400) *(rtn + 1) = 'r';
  582. X    if(mode & 000200) *(rtn + 2) = 'w';
  583. X    if(mode & 000100) *(rtn + 3) = 'x';
  584. X    if(mode & 004000) *(rtn + 3) = 's';
  585. X    if(mode & 000040) *(rtn + 4) = 'r';
  586. X    if(mode & 000020) *(rtn + 5) = 'w';
  587. X    if(mode & 000010) *(rtn + 6) = 'x';
  588. X    if(mode & 002000) *(rtn + 6) = 's';
  589. X    if(mode & 000004) *(rtn + 7) = 'r';
  590. X    if(mode & 000002) *(rtn + 8) = 'w';
  591. X    if(mode & 000001) *(rtn + 9) = 'x';
  592. X    if(mode & 001000) *(rtn + 9) = 't';
  593. X
  594. X    return(rtn);
  595. X
  596. X}    /* end of mode_map */
  597. X
  598. Xvoid
  599. XsetTOUCH()
  600. X{
  601. X    fputs("if touch 2>&1 | fgrep '[-amc]' > /dev/null\n",fpout);
  602. X    fputs(" then TOUCH=touch\n",fpout);
  603. X    fputs(" else TOUCH=true\n",fpout);
  604. X    fputs("fi\n",fpout);
  605. X} /* end of setTOUCH */
  606. X
  607. Xheader(argc,argv)
  608. Xchar **argv;
  609. X{
  610. Xint i;
  611. Xint status;
  612. XFILE *fpsource;    /* pipe temp */
  613. Xchar s128[128];
  614. Xlong now;
  615. Xstruct tm *utc;
  616. Xstruct tm *gmtime();
  617. X
  618. X    /* see if any conflicting options */
  619. X    if(limit && !filenum)
  620. X    { /* can't rename what you don't have */
  621. X        fprintf(stderr,"Can't use -l or -L option without -o\n");
  622. X        helpuser();
  623. X    }
  624. X
  625. X    for(i = 0; i < argc; i++)
  626. X    { /* skip positional parameters */
  627. X        if(PosParam &&
  628. X            (strcmp(argv[i],"-b") == 0 ||
  629. X             strcmp(argv[i],"-t") == 0 ||
  630. X             strcmp(argv[i],"-C") == 0))
  631. X            continue;
  632. X
  633. X        /* see if access and correct type */
  634. X        if(access(argv[i],4))
  635. X        {
  636. X            fprintf(stderr,"shar: Can't access %s\n",argv[i]);
  637. X            return(1);
  638. X        }
  639. X
  640. X        /* get file type */
  641. X        stat(argv[i],&fst);
  642. X        status = fst.st_mode & S_IFMT;
  643. X
  644. X        /* at this point I check to see that this is a regular file */
  645. X        if(status != S_IFREG)
  646. X        { /* this is not a regular file */
  647. X            fprintf(stderr,"shar: %s is not a regular file\n",argv[i]);
  648. X            return(1);
  649. X        }
  650. X    }
  651. X
  652. X    if(Archive_name)
  653. X    {
  654. X        fprintf(fpout,"Submitted by: %s\n",submitter);
  655. X        fprintf(fpout,"Archive-name: %s/part%02d\n\n",
  656. X            sharname,(filenum) ? filenum : 1);
  657. X    }
  658. X
  659. X    if(Cut)
  660. X        fputs("---- Cut Here and unpack ----\n",fpout);
  661. X    fputs("#!/bin/sh\n",fpout);
  662. X    if(sharname)
  663. X        fprintf(fpout,"# This is %s, a shell archive (shar %s)\n",
  664. X            sharname,revision);
  665. X    else
  666. X        fprintf(fpout,"# This is a shell archive (shar %s)\n",revision);
  667. X
  668. X    time(&now);
  669. X    utc = gmtime(&now);
  670. X    fprintf(fpout,"# made %02d/%02d/%04d %02d:%02d UTC ",
  671. X        utc->tm_mon + 1,utc->tm_mday,utc->tm_year + 1900,
  672. X        utc->tm_hour,utc->tm_min);
  673. X
  674. X    fputs("by ",fpout);
  675. X    fputs(submitter,fpout);
  676. X    fputs("\n",fpout);
  677. X
  678. X#if defined(SYS5)
  679. X    if(!(fpsource = popen("/bin/pwd","r")))
  680. X        return(-1);
  681. X    fgets(s128,sizeof(s128),fpsource);
  682. X    s128[strlen(s128) - 1] = 0;
  683. X    fclose(fpsource);
  684. X#else
  685. X#if defined(BSD42) || defined(sun)
  686. X    getwd(s128);
  687. X#else
  688. X#include "Need_conditional_compile_fix"
  689. X#endif
  690. X#endif
  691. X    fprintf(fpout,"# Source directory %s\n",s128);
  692. X
  693. X    fprintf(fpout,"#\n# existing files %s be overwritten\n",
  694. X        (eXists) ? "will NOT"
  695. X                 : ((InterOW) ? "MAY" : "WILL"));
  696. X    if(InterOW)
  697. X        fprintf(fpout,"# The unsharer will be INTERACTIVELY queried.\n");
  698. X
  699. X    if(Split)
  700. X    { /* may be split, explain */
  701. X        fputs("#\n",fpout);
  702. X        TypePos = ftell(fpout);
  703. X        fprintf(fpout,"%-75s\n%-75s\n","#","#");
  704. X    }
  705. X
  706. X    fputs("#\n# This shar contains:\n",fpout);
  707. X    fputs("# length  mode       name\n",fpout);
  708. X    fputs("# ------ ---------- ------------------------------------------\n",
  709. X        fpout);
  710. X    for(i = 0; i < argc; i++)
  711. X    { /* output names of files but not parameters */
  712. X        if(PosParam &&
  713. X            (strcmp(argv[i],"-b") == 0 ||
  714. X             strcmp(argv[i],"-t") == 0 ||
  715. X             strcmp(argv[i],"-C") == 0))
  716. X            continue;
  717. X        stat(argv[i],&fst);
  718. X        fst.st_mode &= ~(07000); /* turn off setuid, setgid and sticky bits */
  719. X        fprintf(fpout,"# %6ld %s %s\n",fst.st_size,
  720. X            mode_map(fst.st_mode,(char *)0),Rname(argv[i]));
  721. X    }
  722. X    fputs("#\n",fpout);
  723. X
  724. X    setTOUCH();
  725. X
  726. X    if(Split)
  727. X    { /* now check the sequence */
  728. X        fputs("if test -r @shar_seq_.tmp; then\n",fpout);
  729. X        fputs("\techo \"Must unpack archives in sequence!\"\n",fpout);
  730. X        fputs("\tnext=`cat @shar_seq_.tmp`; ",fpout);
  731. X        fputs("echo \"Please unpack part $next next\"\n\texit 1\nfi\n",fpout);
  732. X    }
  733. X    return(0);
  734. X}
  735. X
  736. X#define MAX_MKDIR_ALREADY    128    /* ridiculously enough */
  737. Xchar *mkdir_already[MAX_MKDIR_ALREADY];
  738. Xint mkdir_already_count = 0;
  739. X
  740. Xvoid
  741. Xgen_mkdir(path)
  742. Xchar *path;
  743. X{
  744. Xregister int ialready;
  745. Xchar *cptr;
  746. X
  747. X/* if already generated code for this dir creation, dont do again */
  748. X    for(ialready = 0; ialready < mkdir_already_count; ialready++)
  749. X    {
  750. X        if(!strcmp(path,mkdir_already[ialready]))
  751. X            return;
  752. X    }
  753. X
  754. X/* haven't done this one */
  755. X    if(mkdir_already_count == MAX_MKDIR_ALREADY)
  756. X    {
  757. X        fprintf(stderr,"too many directories for mkdir generation\n");
  758. X        exit(255);
  759. X    }
  760. X    if(!(cptr = mkdir_already[mkdir_already_count++] = malloc(strlen(path)+1)))
  761. X    {
  762. X        fprintf(stderr,"out of memory for mkdir generation\n");
  763. X        exit(255);
  764. X    }
  765. X    strcpy(cptr,path);
  766. X
  767. X/* generate the text */
  768. X    fprintf(fpout,"if test ! -d '%s'; then\n",path);
  769. X    if(Verbose)
  770. X        fprintf(fpout,"    echo \"x - creating directory %s\"\n",path);
  771. X    fprintf(fpout,"    mkdir '%s'\n",path);
  772. X    fprintf(fpout,"fi\n");
  773. X
  774. X}    /* end of gen_mkdir */
  775. X
  776. Xvoid
  777. Xgen_mkdir_script(path)
  778. Xregister char *path;
  779. X{
  780. Xregister char *cptr;
  781. X
  782. X    for(cptr = strchr(path,'/'); cptr; cptr = strchr(cptr + 1,'/'))
  783. X    {
  784. X        /* avoid empty string if leading or double '/' */
  785. X        if(cptr == path || *(cptr - 1) == '/')
  786. X            continue;
  787. X        /* omit '.' */
  788. X        if((*(cptr - 1) == '.') && ((cptr == path + 1) || (*(cptr - 2) == '/')))
  789. X            continue;
  790. X        *cptr = 0;                /* temporarily terminate string */
  791. X        gen_mkdir(path);
  792. X        *cptr = '/';
  793. X    }
  794. X}    /* end of gen_mkdir_script */
  795. X
  796. Xshar(file)
  797. Xchar *file;
  798. X{
  799. Xchar line[BUFSIZ];
  800. XFILE *fpsource;
  801. Xlong cursize,remaining,ftell();
  802. Xint split = 0;        /* file split flag */
  803. Xchar *filetype;        /* text or binary */
  804. Xchar *RstrName;        /* name for restore */
  805. Xstruct tm *lt;
  806. Xchar *filename_base;
  807. X
  808. X    /* get file size, dates, and mode for later */
  809. X    stat(file,&fst);
  810. X
  811. X    /* if limit set, get the current output length */
  812. X    if(limit)
  813. X    {
  814. X        cursize = ftell(fpout);
  815. X        remaining = (limit * 1024L) - cursize;
  816. X        DeBug("In shar: remaining size %ld\n",remaining);
  817. X        
  818. X        if(!Split && cursize > EndHeadPos &&
  819. X            (Binary ? fst.st_size + fst.st_size/3 : fst.st_size) > remaining)
  820. X        { /* change to another file */
  821. X            DeBug("Newfile, remaining %ld, ",remaining);
  822. X            DeBug("limit still %d\n",limit);
  823. X
  824. X            fprintf(fpout,
  825. X                "echo \"End of part %d, continue with part %d\"\n",
  826. X                filenum,filenum + 1);
  827. X            fprintf(fpout,"exit 0\n");
  828. X
  829. X            fclose(fpout);
  830. X
  831. X            /* form the next filename */
  832. X            sprintf(filename,"%s%02d",outname,++filenum);
  833. X            fpout = fopen(filename,"w");
  834. X
  835. X            if(Archive_name)
  836. X            {
  837. X                fprintf(fpout,"Submitted by: %s\n",submitter);
  838. X                fprintf(fpout,"Archive-name: %s/part%2d\n\n",
  839. X                    sharname,(filenum) ? filenum : 1);
  840. X            }
  841. X
  842. X            if(Cut)
  843. X                fputs("---- Cut Here and unpack ----\n",fpout);
  844. X            if(!(filename_base = strrchr(filename,'/')))
  845. X                filename_base = filename;
  846. X            else
  847. X                filename_base++;
  848. X
  849. X            fprintf(fpout,"#!/bin/sh\n");
  850. X            fprintf(fpout,
  851. X                "# this is %s (part %d of %s)\n",
  852. X                filename_base,
  853. X                filenum,
  854. X                (sharname) ? sharname : "a multipart archive");
  855. X
  856. X            setTOUCH();
  857. X
  858. X            EndHeadPos = ftell(fpout);
  859. X        }
  860. X    }
  861. X
  862. X    /* determine the name to use for restore */
  863. X    RstrName = Rname(file);
  864. X
  865. X    fputs("# ============= ",fpout);
  866. X    fputs(RstrName,fpout);
  867. X    fputs(" ==============\n",fpout);
  868. X
  869. X    gen_mkdir_script(RstrName);
  870. X
  871. X    /* if mixed, determine the file type */
  872. X    if(Mixed)
  873. X    {
  874. X        int count;
  875. X        sprintf(line,"file %s | egrep -c \"text|shell\"",file);
  876. X        fpsource = popen(line,"r");
  877. X        fscanf(fpsource,"%d",&count);
  878. X        pclose(fpsource);
  879. X        Binary = (count != 1);
  880. X    }
  881. X
  882. X    if(Binary)
  883. X    { /* fork a uuencode process */
  884. X        static int pid,pipex[2];
  885. X
  886. X        pipe(pipex);
  887. X        fflush(fpout);
  888. X
  889. X        if(pid = fork())
  890. X        { /* parent, create a file to read */
  891. X            close(pipex[1]);
  892. X            fpsource = fdopen(pipex[0],"r");
  893. X            filetype = (Compress ? "Compressed" : "Binary");
  894. X        }
  895. X        else
  896. X        { /* start writing the pipe with encodes */
  897. X            FILE *outptr;
  898. X
  899. X            if(Compress)
  900. X            {
  901. X                sprintf(line, "compress < %s", file);
  902. X                fpsource = popen(line, "r");
  903. X            }
  904. X            else
  905. X                fpsource = fopen(file, "rb");
  906. X            outptr = fdopen(pipex[1],"w");
  907. X            fprintf(outptr,"begin 600 %s\n",
  908. X                (Compress ? "@shar_cmp_.tmp" : RstrName));
  909. X            encode(fpsource,outptr);
  910. X            fprintf(outptr,"end\n");
  911. X            if(Compress)
  912. X                pclose(fpsource);
  913. X            else
  914. X                fclose(fpsource);
  915. X            exit(0);
  916. X        }
  917. X    }
  918. X    else
  919. X    {
  920. X        fpsource = fopen(file,"r");
  921. X        filetype = "Text";
  922. X    }
  923. X
  924. X    if(fpsource)
  925. X    {
  926. X        /* protect existing files */
  927. X        if(eXists)
  928. X        {
  929. X            fprintf(fpout,"if test X\"$1\" != X\"-c\" -a -f '%s'; then\n",
  930. X                RstrName);
  931. X            if(InterOW)
  932. X            {
  933. X                fprintf(fpout,"\tcase $wish in\n");
  934. X                fprintf(fpout,"\tA*|a*) echo x - overwriting '%s';;\n",
  935. X                    RstrName);
  936. X                fprintf(fpout,
  937. X        "\t*) echo \"? - overwrite '%s' -- [No], [Y]es, [A]ll, [Q]uit? \"\n",
  938. X                    RstrName);
  939. X                fprintf(fpout,"\t\tread wish;;\n");
  940. X                fprintf(fpout,"\tesac\n");
  941. X                fprintf(fpout,"\tcase $wish in\n");
  942. X                fprintf(fpout,"\tQ*|q*) echo aborted; exit 86;;\n");
  943. X                fprintf(fpout,"\tA*|a*|Y*|y*) x=Y;;\n");
  944. X                fprintf(fpout,"\t*) x=N;;\n");
  945. X                fprintf(fpout,"\tesac\n");
  946. X                fprintf(fpout,"else\n");
  947. X                fprintf(fpout,"\tx=Y\n");
  948. X                fprintf(fpout,"fi\n");
  949. X                fprintf(fpout,"if test $x != Y; then\n");
  950. X                fprintf(fpout,"\techo x - skipping '%s'\n",RstrName);
  951. X            }
  952. X            else
  953. X                fprintf(fpout,"\techo \"File already exists: skipping '%s'\"\n",
  954. X                    RstrName);
  955. X            fprintf(fpout,"else\n");
  956. X        }
  957. X
  958. X        fprintf(stderr,"shar: saving %s (%s)\n",file,filetype);
  959. X        if(Verbose)
  960. X        { /* info on archive and unpack */
  961. X            fprintf(fpout,"echo \"x - extracting %s (%s)\"\n",
  962. X                RstrName,filetype);
  963. X        }
  964. X        if(Binary)
  965. X        { /* run sed through uudecode (via temp file if might get split) */
  966. X            fprintf(fpout, "sed 's/^%c//' << '%s' %s &&\n",
  967. X                   PREFIX,Delim,
  968. X                (AvoidPipes ? "> @shar_tmp_.tmp" : "| uudecode"));
  969. X        }
  970. X        else
  971. X        { /* just run it into the file */
  972. X            fprintf(fpout,"sed 's/^%c//' << '%s' > %s &&\n",
  973. X                PREFIX,Delim,RstrName);
  974. X        }
  975. X        while(fgets(line,BUFSIZ,fpsource))
  976. X        { /* output a line and test the length */
  977. X            fprintf(fpout,"%c%s",PREFIX,line);
  978. X            if(Split && (remaining -= strlen(line) + 2) < 0)
  979. X            { /* change to another file */
  980. X                DeBug("Newfile, remaining %ld, ",remaining);
  981. X                DeBug("limit still %d\n",limit);
  982. X
  983. X                if(line[strlen(line) - 1] != '\n')
  984. X                    fputc('\n',fpout);
  985. X
  986. X                fprintf(fpout,"%s\n",Delim);
  987. X                if(Verbose)
  988. X                { /* output some reassurance */
  989. X                    fprintf(fpout,
  990. X                        "echo \"End of %s part %d\"\n",
  991. X                            (sharname) ? sharname : "",filenum);
  992. X                    fprintf(fpout,
  993. X                        "echo \"File %s is continued in part %d\"\n",
  994. X                        RstrName,filenum + 1);
  995. X                }
  996. X                else
  997. X                    fprintf(fpout,
  998. X                        "echo \"End of part %d, continue with part %d\"\n",
  999. X                        filenum,filenum + 1);
  1000. X                fprintf(fpout,"echo \"%d\" > @shar_seq_.tmp\n",filenum + 1);
  1001. X                fprintf(fpout,"exit 0\n");
  1002. X
  1003. X                if(filenum == 1)
  1004. X                { /* rewrite the info lines on the firstheader */
  1005. X                    fseek(fpout,TypePos,0);
  1006. X                    fprintf(fpout,"%-75s\n%-75s\n",
  1007. X                        "# This is part 1 of a multipart archive",
  1008. X                        "# do not concatenate these parts, unpack them in order with /bin/sh");
  1009. X                }
  1010. X                fclose(fpout);
  1011. X
  1012. X                /* form the next filename */
  1013. X                sprintf(filename,"%s%02d",outname,++filenum);
  1014. X                fpout = fopen(filename,"w");
  1015. X
  1016. X                if(Archive_name)
  1017. X                {
  1018. X                    fprintf(fpout,"Submitted by: %s\n",submitter);
  1019. X                    fprintf(fpout,"Archive-name: %s/part%2d\n\n",
  1020. X                        sharname,(filenum) ? filenum : 1);
  1021. X                }
  1022. X
  1023. X                if(Cut)
  1024. X                    fputs("---- Cut Here and unpack ----\n",fpout);
  1025. X                if(!(filename_base = strrchr(filename,'/')))
  1026. X                    filename_base = filename;
  1027. X                else
  1028. X                    filename_base++;
  1029. X
  1030. X                fprintf(fpout,"#!/bin/sh\n");
  1031. X                fprintf(fpout,
  1032. X                    "# this is %s (part %d of %s)\n",
  1033. X                    filename_base,
  1034. X                    filenum,
  1035. X                    (sharname) ? sharname : "a multipart archive");
  1036. X                fputs("# do not concatenate these parts, ",fpout);
  1037. X                fputs("unpack them in order with /bin/sh\n",fpout);
  1038. X                fprintf(fpout,"# file %s continued\n#\n",RstrName);
  1039. X
  1040. X                setTOUCH();
  1041. X                
  1042. X                fputs("if test ! -r @shar_seq_.tmp; then\n",fpout);
  1043. X                fputs("\techo \"Please unpack part 1 first!\"\n",fpout);
  1044. X                fputs("\texit 1\nfi\n",fpout);
  1045. X                fputs("(read Scheck\n",fpout);
  1046. X                fprintf(fpout,
  1047. X                      " if test \"$Scheck\" != %d; then\n",filenum);
  1048. X                fputs("\techo \"Please unpack part $Scheck next!\"\n",
  1049. X                    fpout);
  1050. X                fputs("\texit 1\n",fpout);
  1051. X                fputs(" else\n\texit 0\n fi\n",fpout);
  1052. X                fputs(") < @shar_seq_.tmp || exit 1\n",fpout);
  1053. X
  1054. X                if(Verbose)
  1055. X                { /* keep everybody informed */
  1056. X                    fprintf(stderr,"Starting file %s\n",filename);
  1057. X                    fprintf(fpout,
  1058. X                        "echo \"x - Continuing file %s\"\n",RstrName);
  1059. X                }
  1060. X                fprintf(fpout,
  1061. X                    "sed 's/^%c//' << '%s' >> %s &&\n",
  1062. X                    PREFIX,Delim,
  1063. X                    (Binary ? "@shar_tmp_.tmp" : RstrName));
  1064. X                remaining = limit * 1024L;
  1065. X                split = 1;
  1066. X            }
  1067. X        }
  1068. X
  1069. X        (void) fclose(fpsource);
  1070. X
  1071. X        if(line[strlen(line) - 1] != '\n')
  1072. X            fputc('\n',fpout);
  1073. X
  1074. X        fprintf(fpout,"%s\n",Delim);
  1075. X        if(split && Verbose)
  1076. X            fprintf(fpout,
  1077. X                "echo \"File %s is complete\" &&\n",RstrName);
  1078. X
  1079. X        /* if this file was uuencoded w/Split, decode it and drop the temp */
  1080. X        if(Binary && AvoidPipes)
  1081. X        {
  1082. X            if(Verbose)
  1083. X                fprintf(fpout,"echo \"uudecoding file %s\" &&\n",RstrName);
  1084. X            fprintf(fpout,
  1085. X                "uudecode < @shar_tmp_.tmp && rm -f @shar_tmp_.tmp &&\n");
  1086. X        }
  1087. X
  1088. X        /* if this file was compressed, uncompress it and drop the temp */
  1089. X        if(Compress)
  1090. X        {
  1091. X            if(Verbose)
  1092. X                fprintf(fpout,"echo \"uncompressing file %s\" &&\n",RstrName);
  1093. X            fprintf(fpout,
  1094. X                "compress -d < @shar_cmp_.tmp > %s && rm -f @shar_cmp_.tmp &&\n",
  1095. X                RstrName);
  1096. X        }
  1097. X
  1098. X        /* set the dates as they were */
  1099. X        lt = localtime(&fst.st_mtime);
  1100. X        fprintf(fpout,"$TOUCH -am %02d%02d%02d%02d%02d %s &&\n",
  1101. X            lt->tm_mon + 1,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_year,
  1102. X            RstrName);
  1103. X
  1104. X        /* set the permissions as they were */
  1105. X        fprintf(fpout,"chmod %04o %s ||\n",
  1106. X            fst.st_mode & 00777,RstrName);
  1107. X
  1108. X        /* report an error if any of the above failed */
  1109. X        fprintf(fpout,"echo \"restore of %s failed\"\n",RstrName);
  1110. X
  1111. X        if(Wc_c)
  1112. X        { /* validate the transferred file */
  1113. X            FILE *pfp;
  1114. X            char command[BUFSIZ];
  1115. X
  1116. X            sprintf(command,"%s %s",WC,file);
  1117. X            if((pfp = popen(command,"r")))
  1118. X            {
  1119. X                char wc[BUFSIZ];
  1120. X
  1121. X                fscanf(pfp,"%s",wc);
  1122. X                fprintf(fpout,"set `%s %s`;Wc_c=$1\n",
  1123. X                    WC,RstrName);
  1124. X                fprintf(fpout,
  1125. X                    "if test \"$Wc_c\" != \"%s\"; then\n",wc);
  1126. X                fprintf(fpout,
  1127. X                    "\techo original size %s, current size $Wc_c\nfi\n",
  1128. X                    wc);
  1129. X                pclose(pfp);
  1130. X            }
  1131. X        }
  1132. X
  1133. X        /* if the exists option is in place close the if */
  1134. X        if(eXists)
  1135. X            fprintf(fpout,"fi\n");
  1136. X
  1137. X        return(0);
  1138. X    }
  1139. X    else
  1140. X    {
  1141. X        fprintf(stderr,"shar: Can't open %s (%s): ",file,filetype);
  1142. X        perror("");
  1143. X        return(1);
  1144. X    }
  1145. X}
  1146. X
  1147. Xchar *
  1148. XRname(file)
  1149. Xregister char *file;
  1150. X{
  1151. X    register char *RstrName;
  1152. X
  1153. X    if(FileStrip)
  1154. X    { /* use just the filename */
  1155. X        RstrName = file+strlen(file);
  1156. X        while(RstrName > file && *RstrName != '/')
  1157. X            RstrName--;
  1158. X        if(*RstrName == '/') RstrName++;
  1159. X    }
  1160. X    else
  1161. X        RstrName = file;
  1162. X    if(!strncmp(RstrName,"./",2))
  1163. X        RstrName += 2;
  1164. X    return(RstrName);
  1165. X}
  1166. X
  1167. X/*****************************************************************
  1168. X |  exit_incompat - incompatible options
  1169. X ****************************************************************/
  1170. X
  1171. Xexit_incompat()
  1172. X{
  1173. X       fputs("You may only specify one of -L, -X or -x\n",stderr);
  1174. X    exit(1);
  1175. X}
  1176. X
  1177. Xhelpuser()
  1178. X{                /* output a command format message */
  1179. X    register char **ptr;
  1180. X    static char *helpinfo[] =
  1181. X    {
  1182. X        "-v  verbose messages OFF while executing",
  1183. X        "-w  don't check with 'wc -c' after unpack",
  1184. X        "-n  Name of archive (documentation)",
  1185. X        "-a  Generate Submitted-by: & Archive-name: headers",
  1186. X        "-s  override automatically determined submitter name",
  1187. X        "-x  don't overwrite existing files",
  1188. X        "-X  interactively overwrite existing files (NOT FOR NET SHARS)",
  1189. X        "-b  treat all files as binary, use uuencode",
  1190. X        "-t  treat all files as text (default)",
  1191. X        "-C  compress and uuencode all files",
  1192. X        "-p  allow positional parameter options. The options \"-b\" and \"-t\"",
  1193. X        "    and \"-C\" may be embedded, and files to the right of the",
  1194. X        "    option will be processed in the specified mode",
  1195. X        "-M  mixed mode. Determine if the files are text or",
  1196. X        "    binary and archive correctly.",
  1197. X        "-P  use temp files instead of pipes in the shar file",
  1198. X#ifdef THIS_APPEARS_TO_BE_OBSOLETE
  1199. X        "-D  output date, user, and directory comments to the archive",
  1200. X#endif /* THIS_APPEARS_TO_BE_OBSOLETE */
  1201. X        "-c  start the shar with a cut line",
  1202. X        "-f  restore by filename only, rather than path",
  1203. X        "-dXXX   use XXX to delimit the files in the shar",
  1204. X        "-oXXX   (or -o XXX) output to file XXX.01 thru XXX.nn",
  1205. X        "-lXX    limit output file size to XXk bytes (but don't split files)",
  1206. X        "-LXX    limit output file size to XXk bytes (may split files)",
  1207. X        "\nThe 'o' option is required if the 'l' or 'L' option is used",
  1208. X        "The 'n' option is required if the 'a' option is used",
  1209. X        "The 'x' and 'L' options are incompatible",
  1210. X        "\n-a generates sharname/part## headers. If you are producing patches",
  1211. X        "you'll need to edit -a headers (or please improve shar :-))",
  1212. X        "The automatic submitter name is trivial: essentially `whoami`@`uname`",
  1213. X        (char *)0
  1214. X    };
  1215. X    fprintf(stderr,
  1216. X        "shar %s\nusage: shar [ options ] file [ file1 ... ] ]\n",revision);
  1217. X    for(ptr = helpinfo; *ptr; ptr++)
  1218. X        fprintf(stderr,"%s\n",*ptr);
  1219. X
  1220. X    exit(1);
  1221. X}
  1222. X/* vi: set tabstop=4 shiftwidth=4: */
  1223. SHAR_EOF
  1224. $TOUCH -am 0418021390 shar.c &&
  1225. chmod 0644 shar.c ||
  1226. echo "restore of shar.c failed"
  1227. set `wc -c shar.c`;Wc_c=$1
  1228. if test "$Wc_c" != "28686"; then
  1229.     echo original size 28686, current size $Wc_c
  1230. fi
  1231. exit 0
  1232.  
  1233. ------------------------------------------------------------------
  1234. Warren Tucker, TuckerWare gatech!n4hgf!wht or wht%n4hgf@gatech.edu
  1235. McCarthyism did to cinema what ANSI did to C,  cast a great number
  1236. of characters into the void.
  1237.