home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume23 / zip / part03 < prev    next >
Text File  |  1991-10-21  |  55KB  |  1,709 lines

  1. Newsgroups: comp.sources.misc
  2. From: kirsch@usasoc.soc.mil (David Kirschbaum)
  3. Subject:  v23i090:  zip - Portable zip v1.0, Part03/09
  4. Message-ID: <1991Oct21.042104.7918@sparky.imd.sterling.com>
  5. X-Md4-Signature: 41414f8ff5213b92238d6f33f9e09e28
  6. Date: Mon, 21 Oct 1991 04:21:04 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: kirsch@usasoc.soc.mil (David Kirschbaum)
  10. Posting-number: Volume 23, Issue 90
  11. Archive-name: zip/part03
  12. Environment: UNIX, Minix, MSDOS, OS/2, VMS
  13.  
  14. #! /bin/sh
  15. # into a shell via "sh file" or similar.  To overwrite existing files,
  16. # type "sh file -c".
  17. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  18. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  19. # Contents:  MANIFEST ship.c util.c
  20. # Wrapped by kent@sparky on Sun Oct 20 22:58:52 1991
  21. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 3 (of 9)."'
  24. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  26. else
  27.   echo shar: Extracting \"'MANIFEST'\" \(1447 characters\)
  28.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  29. X   File Name        Archive #    Description
  30. X-----------------------------------------------------------
  31. X Contents                   1    
  32. X History                    7    
  33. X INFOZIP.WHO                2    
  34. X MANIFEST                   1    This shipping list
  35. X README                     1    
  36. X crypt.h                    1    
  37. X dir_os2.c                  2    
  38. X dir_os2.h                  1    
  39. X doturboc.bat               1    
  40. X fileio.c                   9    
  41. X globals.c                  1    
  42. X im_bits.c                  2    
  43. X im_ctree.c                10    
  44. X im_lm.asm                  3    
  45. X im_lmat.c                  6    
  46. X implode.c                  2    
  47. X implode.h                  2    
  48. X makecrc.c                  1    
  49. X makefile                   1    
  50. X makefile.bor               1    
  51. X makefile.msc               1    
  52. X makefile.os2               1    
  53. X makefile.pwc               1    
  54. X makevms.com                1    
  55. X revision.h                 1    
  56. X ship.c                     8    
  57. X ship.def                   1    
  58. X shrink.c                   3    
  59. X tailor.h                   1    
  60. X tempf.c                    1    
  61. X tempf.h                    1    
  62. X util.c                     3    
  63. X zip.1                      5    
  64. X zip.c                      6    
  65. X zip.def                    1    
  66. X zip.doc                    5    
  67. X zip.h                      2    
  68. X zip.prj                    1    
  69. X ziperr.h                   1    
  70. X zipfile.c                  4    
  71. X zipnote.c                  2    
  72. X zipsplit.c                 4    
  73. X zipup.c                    3    
  74. END_OF_FILE
  75.   if test 1447 -ne `wc -c <'MANIFEST'`; then
  76.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  77.   fi
  78.   # end of 'MANIFEST'
  79. fi
  80. if test -f 'ship.c' -a "${1}" != "-c" ; then 
  81.   echo shar: Will not clobber existing file \"'ship.c'\"
  82. else
  83.   echo shar: Extracting \"'ship.c'\" \(38393 characters\)
  84.   sed "s/^X//" >'ship.c' <<'END_OF_FILE'
  85. X/* ship.c -- Not copyrighted 1991 Mark Adler */
  86. X
  87. X#define SHIPVER "ship version 1.0  September 29, 1991  Mark Adler"
  88. X
  89. X/* Command for mailing (-m): the %s's are, in order, the subject prefix,
  90. X   the part number (always of the form "partnnnn"), the subject suffix
  91. X   (empty or " (last)" if the last part), the mailing address, and the
  92. X   name of the temporary file begin mailed.  The command "Mail" is for BSD
  93. X   systems.  You may need to change it to "mailx" for System V Unix, using
  94. X   the compile option "-DMAILX".  Also, on Sperry (Unisys?) SysV.3 systems,
  95. X   you might try the command name "v6mail". */
  96. X
  97. X#ifdef DIRENT           /* If compiled with zip, DIRENT implies System V */
  98. X#  define MAILX
  99. X#endif /* DIRENT */
  100. X
  101. X#ifdef sun              /* Except Sun's use DIRENT, but have Mail */
  102. X#  ifdef MAILX
  103. X#    undef MAILX
  104. X#  endif /* MAILX */
  105. X#endif /* sun */
  106. X
  107. X#ifdef sgi              /* Silicon Graphics that way too */
  108. X#  ifdef MAILX
  109. X#    undef MAILX
  110. X#  endif /* MAILX */
  111. X#endif /* sgi */
  112. X
  113. X#ifdef VMS
  114. X#  define TMPNAME "_SXXXXXX."
  115. X#  define MAILCMD "mail %s /subj=\"%s %s%s\" \"%s\""
  116. X#  define PATHCUT ']'
  117. X#else /* !VMS */
  118. X#  define TMPNAME "_SXXXXXX"
  119. X#  ifdef MAILX
  120. X#    define MAILCMD "mailx -s \"%s %s%s\" \"%s\" < %s"
  121. X#  else /* !MAILX */
  122. X#    define MAILCMD "Mail -s \"%s %s%s\" \"%s\" < %s"
  123. X#  endif /* ?MAILX */
  124. X#  define PATHCUT '/'
  125. X#endif /* ?VMS */
  126. X
  127. X/*
  128. X
  129. XSHIP -
  130. X
  131. X  Ship is a program for sending binary files through email.  It is designed
  132. X  to supplant uuencode and uudecode.  Ship encodes approximately 6.23 bits
  133. X  per character mailed, compared to uuencode's 5.73 bits per character.
  134. X
  135. X  Ship also has these features: a 32-bit CRC check on each file; automatic
  136. X  splitting of the ship output into multiple, smaller files for speedier
  137. X  mailing; automatic mailing of ship's output, with subject lines for
  138. X  multiple parts; and a check on the sequence of parts when unshipping.
  139. X
  140. X  Usage:
  141. X
  142. X       ship [-nnn] [-m address] [-s subject] file ...
  143. X
  144. X  where nnn is the maximum number of K bytes for each output file, address
  145. X  is the address to send mail to, subject is a Subject" line prefix, and
  146. X  file ... is a list of files to ship.  If no options are given, ship
  147. X  outputs to stdout.  The simplest use is:
  148. X
  149. X       ship foo > x
  150. X
  151. X  where foo is converted into the mailable file, x.
  152. X
  153. X  When -nnn is specified, but -m is not, ship writes to the files
  154. X  part0001, part0002, etc., where each file has nnn or less K bytes.  For
  155. X  example:
  156. X
  157. X       ship -25 bigfoo
  158. X
  159. X  will write however many 25K byte or less ship files is needed to contain
  160. X  bigfoo.  If, say, six files are needed, then the files part0001 to part0006
  161. X  will be written.
  162. X
  163. X  When using -m, nothing is written, either to files or to stdout; rather,
  164. X  the output is mailed to the specified address.  If -nnn is also specified,
  165. X  then the parts are mailed separately with the subject lines part0001, etc.
  166. X  If -nnn is not specified, then only one part (the whole thing) is mailed
  167. X  with the subject line "part0001".  For example:
  168. X
  169. X       ship -25 -m fred bigfoo
  170. X
  171. X  will mail the six parts of bigfoo to fred.
  172. X
  173. X  Any number of files can be shipped at once.  They become part of one long
  174. X  ship stream, so if, for example -25 is specified, all but the last part
  175. X  will have about 25K bytes.  For example:
  176. X
  177. X       ship -25 -m fred fee fi fo fum
  178. X
  179. X  will send the files fee, fi, fo, and fum to fred.
  180. X
  181. X  Fred will get several mail messages with the subject lines part0001, etc.
  182. X  He can then save those messages as the files, say, p1, p2, p3, ...
  183. X  Then he can use the command:
  184. X
  185. X       ship -u p?
  186. X
  187. X  to recreate bigfoo, or fee fi fo and fum, depending on what he was sent.
  188. X  If Fred saved the wrong numbers, ship will detect this and report a
  189. X  sequence error.
  190. X
  191. X  Note: there is enough information in the shipped parts to determine the
  192. X  correct sequence.  A future version of ship will prescan the files to
  193. X  determine the sequence, and then process them in the correct order.
  194. X
  195. X  If a file being received already exists, ship -u will report an error
  196. X  and exit.  The -o option avoids this and allows ship to overwrite existing
  197. X  files.  The -o option must follow the -u option:
  198. X
  199. X       ship -u -o p?
  200. X
  201. X  In addition to the -u option, ship will unship if it sees that its name is
  202. X  unship.  On Unix systems, this can be done simply by linking the executable
  203. X  to unship:
  204. X
  205. X       ln ship unship 
  206. X
  207. X  Ship can also be used as a filter.  The special file name "-" means stdin.
  208. X  For example:
  209. X
  210. X       tar covf - foodir | compress | ship -25 -m fred -
  211. X
  212. X  will tar the directory foodir, compress it, and ship it to fred in 25K byte
  213. X  pieces.  Then, after Fred saves the files as p01, etc. at the other, end,
  214. X  he can:
  215. X
  216. X       ship -u p? | zcat | tar xovf -
  217. X
  218. X  which will recreate the directory foobar and its contents.  ship -u knows
  219. X  to write to stdout, since the original ship put the special file name "-"
  220. X  in the first part.
  221. X
  222. X  Ship uses a base 85 coding that needs 32-bit multiplication and division.
  223. X  This can be slow on 16-bit machines, so ship provides a fast encoding
  224. X  method by specifying the -f option.  This method is somewhat faster even
  225. X  on 32-bit machines, and has approximately a 1% penalty in the size of the
  226. X  encoded result (-f gives 6.26 bits per character, on the average).  The -f
  227. X  option need only be used when shipping--unshipping (ship -u) automatically
  228. X  detects the encoding used.  For example:
  229. X
  230. X       ship -f -25 -m fred foo
  231. X
  232. X  will send foo to fred in 25K byte pieces using the fast encoding method.
  233. X  You don't need to tell Fred, since ship -u will figure that out for him.
  234. X
  235. X  The fast encoding method is probabilistic, so it's possible for the size
  236. X  penalty to be worse than 1%, and it's also possible for the fast encoding
  237. X  to produce a smaller result than base 85 encoding would, all depending on
  238. X  the data.
  239. X
  240. X  The -q option can be used with either ship or unship (ship -u) for quiet
  241. X  operation--informational messages are inhibited.
  242. X
  243. X  You can find out the version of ship and get the command usage by using
  244. X  "ship -h" or "ship -?".  The version number and date and help will be
  245. X  printed, and ship will exit (the rest of the command line is ignored).
  246. X
  247. X  Acknowledgements:
  248. X
  249. X  The hard-arithmetic coding algorithm was blatantly stolen from Peter
  250. X  Gutmann's pgencode/pgdecode programs posted on comp.compression, with
  251. X  modifications to use 86 instead of 94 characters, and to make zeros encode
  252. X  better than, rather than worse than other bytes.  (As Stravinsky once said:
  253. X  "Mediocre composers plagiarize.  Great composers steal.")
  254. X
  255. X*/
  256. X
  257. X/* tailor.h -- Not copyrighted 1991 Mark Adler */
  258. X
  259. X/* const's are inconsistently used across ANSI libraries--kill for all
  260. X   header files. */
  261. X#define const
  262. X
  263. X
  264. X/* Use prototypes and ANSI libraries if __STDC__ */
  265. X#ifdef __STDC__
  266. X#  ifndef PROTO
  267. X#    define PROTO
  268. X#  endif /* !PROTO */
  269. X#  define MODERN
  270. X#endif /* __STDC__ */
  271. X
  272. X
  273. X/* Use prototypes and ANSI libraries if Silicon Graphics */
  274. X#ifdef sgi
  275. X#  ifndef PROTO
  276. X#    define PROTO
  277. X#  endif /* !PROTO */
  278. X#  define MODERN
  279. X#endif /* sgi */
  280. X
  281. X
  282. X/* Define MSDOS for Turbo C as well as Microsoft C */
  283. X#ifdef __POWERC                 /* For Power C too */
  284. X#  define __TURBOC__
  285. X#endif /* __POWERC */
  286. X#ifdef __TURBOC__
  287. X#  ifndef MSDOS
  288. X#    define MSDOS
  289. X#  endif /* !MSDOS */
  290. X#endif /* __TURBOC__ */
  291. X
  292. X
  293. X/* Use prototypes and ANSI libraries if Microsoft or Borland C */
  294. X#ifdef MSDOS
  295. X#  ifndef PROTO
  296. X#    define PROTO
  297. X#  endif /* !PROTO */
  298. X#  define MODERN
  299. X#endif /* MSDOS */
  300. X
  301. X
  302. X/* Turn off prototypes if requested */
  303. X#ifdef NOPROTO
  304. X#  ifdef PROTO
  305. X#    undef PROTO
  306. X#  endif /* PROTO */
  307. X#endif /* NOPROT */
  308. X
  309. X
  310. X/* Used to remove arguments in function prototypes for non-ANSI C */
  311. X#ifdef PROTO
  312. X#  define OF(a) a
  313. X#else /* !PROTO */
  314. X#  define OF(a) ()
  315. X#endif /* ?PROTO */
  316. X
  317. X
  318. X/* Allow far and huge allocation for small model (Microsoft C or Turbo C) */
  319. X#ifdef MSDOS
  320. X#  ifdef __TURBOC__
  321. X#    include <alloc.h>
  322. X#  else /* !__TURBOC__ */
  323. X#    include <malloc.h>
  324. X#    define farmalloc _fmalloc
  325. X#    define farfree   _ffree
  326. X#  endif /* ?__TURBOC__ */
  327. X#else /* !MSDOS */
  328. X#  define huge
  329. X#  define far
  330. X#  define near
  331. X#  define farmalloc malloc
  332. X#  define farfree   free
  333. X#endif /* ?MSDOS */
  334. X
  335. X
  336. X/* Define MSVMS if either MSDOS or VMS defined */
  337. X#ifdef MSDOS
  338. X#  define MSVMS
  339. X#else /* !MSDOS */
  340. X#  ifdef VMS
  341. X#    define MSVMS
  342. X#  endif /* VMS */
  343. X#endif /* ?MSDOS */
  344. X
  345. X
  346. X/* Define void, voidp, and extent (size_t) */
  347. X#include <stdio.h>
  348. X#ifdef MODERN
  349. X#  ifndef M_XENIX
  350. X#    include <stddef.h>
  351. X#  endif /* !M_XENIX */
  352. X#  include <stdlib.h>
  353. X   typedef size_t extent;
  354. X   typedef void voidp;
  355. X#else /* !MODERN */
  356. X   typedef unsigned int extent;
  357. X#  define void int
  358. X   typedef char voidp;
  359. X#endif /* ?MODERN */
  360. X
  361. X/* Get types and stat */
  362. X#ifdef VMS
  363. X#  include <types.h>
  364. X#  include <stat.h>
  365. X#else /* !VMS */
  366. X#  include <sys/types.h>
  367. X#  include <sys/stat.h>
  368. X#endif /* ?VMS */
  369. X
  370. X
  371. X/* Cheap fix for unlink on VMS */
  372. X#ifdef VMS
  373. X#  define unlink delete
  374. X#endif /* VMS */
  375. X
  376. X
  377. X/* For Pyramid */
  378. X#ifdef pyr
  379. X#  define strrchr rindex
  380. X#  define ZMEM
  381. X#endif /* pyr */
  382. X
  383. X
  384. X/* File operations--use "b" for binary if allowed */
  385. X#ifdef MODERN
  386. X#  define FOPR "rb"
  387. X#  define FOPM "r+b"
  388. X#  define FOPW "w+b"
  389. X#else /* !MODERN */
  390. X#  define FOPR "r"
  391. X#  define FOPM "r+"
  392. X#  define FOPW "w+"
  393. X#endif /* ?MODERN */
  394. X
  395. X
  396. X/* Fine tuning */
  397. X#ifndef MSDOS
  398. X#   define BSZ 8192   /* Buffer size for files */
  399. X#else /* !MSDOS */
  400. X#   define BSZ 4096   /* Keep precious NEAR space */
  401. X    /* BSZ can't be 8192 even for compact model because of 64K limitation
  402. X     * in im_lmat.c. If you run out of memory when processing a large number
  403. X     * files, use the compact model and reduce BSZ to 2048 here and in
  404. X     * im_lm.asm.
  405. X     */
  406. X#endif /* ?MSDOS */
  407. X
  408. X/* end of tailor.h */
  409. X
  410. X#ifdef MODERN
  411. X#  include <string.h>
  412. X#else /* !MODERN */
  413. X   voidp *malloc();
  414. X   long atol();
  415. X   char *strcpy();
  416. X   char *strrchr();
  417. X#endif /* ?MODERN */
  418. X
  419. X/* Library functions not in (most) header files */
  420. Xchar *mktemp OF((char *));
  421. Xint unlink OF((char *));
  422. X
  423. X#ifdef MSDOS            /* Use binary mode for binary files */
  424. X#  include <io.h>
  425. X#  include <fcntl.h>
  426. X#endif /* MSDOS */
  427. X
  428. X
  429. X#define LNSZ 1025       /* size of line buffer */
  430. X
  431. Xtypedef unsigned long ulg;      /* 32-bit unsigned integer */
  432. X
  433. Xtypedef struct {        /* associates a CRC with a file */
  434. X  FILE *f;              /* pointer to associated file stream */
  435. X  ulg c;                /* CRC register */
  436. X  ulg b;                /* four byte buffer */
  437. X  int n;                /* buffer count */
  438. X} cfile;
  439. X
  440. X
  441. X/* Function prototypes */
  442. X#ifdef MODERN
  443. X   void err(int, char *);
  444. X   cfile *chook(FILE *);
  445. X   char *nopath(char *);
  446. X   void newship(void);
  447. X   void endship(int);
  448. X   void newline(char *);
  449. X   void ship(char *, FILE *);
  450. X   void mkinv(void);
  451. X   void decode(unsigned char *, cfile *);
  452. X   void unship(char **, int, int);
  453. X   void help(void);
  454. X   void main(int, char **);
  455. X#endif /* MODERN */
  456. X
  457. X
  458. X
  459. X/* Globals for ship() */
  460. Xchar sname[9];          /* current ship file name */
  461. XFILE *sfile;            /* current ship file */
  462. Xulg slns;               /* number of lines written to ship file */
  463. Xulg slmax;              /* maximum number of lines per ship file */
  464. Xint fast;               /* true for arithmetic coding, else base 85 */
  465. Xint mail;               /* true if mailing */
  466. Xchar mpspc[9];          /* prealloced space for prefix */
  467. Xchar *mprefix = mpspc;  /* identification for this mailing */
  468. Xchar *mdest;            /* mail destination */
  469. Xchar mname[10];         /* temporary file name if mailing */
  470. Xulg ccnt;               /* count of bytes read or written */
  471. Xint noisy = 1;          /* false to inhibit informational messages */
  472. X
  473. X
  474. X
  475. X/* Errors */
  476. X#define SE_ARG 1
  477. X#define SE_FIND 2
  478. X#define SE_NONE 3
  479. X#define SE_PART 4
  480. X#define SE_FORM 5
  481. X#define SE_CONT 6
  482. X#define SE_CRC 7
  483. X#define SE_MAIL 8
  484. X#define SE_OVER 9
  485. X#define SE_FULL 10
  486. X#define SE_MANY 11
  487. X#define SE_MEM 12
  488. Xchar *errors[] = {
  489. X  /* 1 */ "invalid argument ",
  490. X  /* 2 */ "could not find ",
  491. X  /* 3 */ "no files received",
  492. X  /* 4 */ "unfinished file ",
  493. X  /* 5 */ "invalid ship format in ",
  494. X  /* 6 */ "wrong sequence for ",
  495. X  /* 7 */ "CRC check failed on ",
  496. X  /* 8 */ "mail command failed: ",
  497. X  /* 9 */ "attempted to overwrite ",
  498. X  /* 10 */ "could not write to ",
  499. X  /* 11 */ "too many output files!",
  500. X  /* 12 */ "out of memory"
  501. X};
  502. X
  503. X
  504. X/* Set of 86 characters used for the base 85 digits (last one not used), and
  505. X   the 86 character arithmetic coding.  Selected to be part of both the ASCII
  506. X   printable characters, and the common EBCDIC printable characters whose
  507. X   ASCII translations are universal. */
  508. Xunsigned char safe[] = {
  509. X        '{','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',
  510. X        '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?','@',
  511. X        'A','B','C','D','E','F','G','H','I','J','K','L','M',
  512. X        'N','O','P','Q','R','S','T','U','V','W','X','Y','Z','_',
  513. X        'a','b','c','d','e','f','g','h','i','j','k','l','m',
  514. X        'n','o','p','q','r','s','t','u','v','w','x','y','z','}'};
  515. X
  516. X#define LOWSZ (sizeof(safe)-64)         /* low set size for fast coding */
  517. X
  518. X/* Special replacement pairs--if first of each pair is received, it is
  519. X   treated like the second member of the pair.  You're probably
  520. X   wondering why.  The first pair is for compatibility with an
  521. X   earlier version of ship that used ! for the base 85 zero digit.
  522. X   However, there exist ASCII-EBCDIC translation tables that don't
  523. X   know about exclamation marks.  The second set has mysterious
  524. X   historical origins that are best left unspoken ... */
  525. Xunsigned char aliases[] = {'!','{','|','+',0};
  526. X
  527. X/* Inverse of safe[], filled in by mkinv() */
  528. Xunsigned char invsafe[256];
  529. X
  530. X/* Table of CRC-32's of all single byte values (made by makecrc.c) */
  531. Xulg crctab[] = {
  532. X  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  533. X  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  534. X  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  535. X  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  536. X  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  537. X  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  538. X  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  539. X  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  540. X  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  541. X  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  542. X  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  543. X  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  544. X  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  545. X  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  546. X  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  547. X  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  548. X  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  549. X  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  550. X  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  551. X  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  552. X  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  553. X  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  554. X  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  555. X  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  556. X  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  557. X  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  558. X  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  559. X  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  560. X  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  561. X  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  562. X  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  563. X  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  564. X  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  565. X  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  566. X  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  567. X  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  568. X  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  569. X  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  570. X  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  571. X  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  572. X  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  573. X  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  574. X  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  575. X  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  576. X  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  577. X  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  578. X  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  579. X  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  580. X  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  581. X  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  582. X  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  583. X  0x2d02ef8dL
  584. X};
  585. X
  586. X/* Macro to update the CRC shift register one byte at a time */
  587. X#define CRC(c,b) (crctab[((int)(c)^(int)(b))&0xff]^((c)>>8))
  588. X
  589. X
  590. Xchar *errname = "ship error";
  591. Xchar *warname = "ship warning";
  592. X
  593. Xvoid err(n, m)
  594. Xint n;                  /* error number */
  595. Xchar *m;                /* additional error information */
  596. X{
  597. X  if (n == SE_FIND || n == SE_FULL)
  598. X    perror(errname);
  599. X  fputs(errname, stderr);
  600. X  fputs(": ", stderr);
  601. X  fputs(errors[n - 1], stderr);
  602. X  fputs(m, stderr);
  603. X  putc('\n', stderr);
  604. X  if (*mname)
  605. X    unlink(mname);
  606. X#ifdef VMS
  607. X  exit(0);
  608. X#else /* !VMS */
  609. X  exit(n);
  610. X#endif /* ?VMS */
  611. X}
  612. X
  613. X
  614. Xcfile *chook(f)
  615. XFILE *f;                /* file stream */
  616. X/* Inherit the file stream structure and add a CRC and buffer for appending
  617. X   a CRC on reads and checking the CRC on writes.  Return a pointer to the
  618. X   cfile structure, or NULL if the malloc() failed.  Also, if MSDOS, set the
  619. X   file mode to binary to avoid LF<->CRLF conversions. */
  620. X{
  621. X  cfile *c;             /* allocated cfile structure */
  622. X
  623. X#ifdef MSDOS
  624. X  /* Set file mode to binary for MSDOS systems */
  625. X  setmode(fileno(f), O_BINARY);
  626. X#endif /* MSDOS */
  627. X
  628. X  /* Allocate and fill structure */
  629. X  if ((c = (cfile *)malloc(sizeof(cfile))) != NULL)
  630. X  {
  631. X    c->f = f;                           /* file stream */
  632. X    c->b = 0;                           /* empty fifo (for output) */
  633. X    c->c = 0xffffffffL;                 /* preload CRC register */
  634. X    c->n = 0;                           /* fifo is empty (output) or */
  635. X  }                                     /*  no CRC bytes given (input) */
  636. X  return c;
  637. X}
  638. X
  639. X
  640. X
  641. X/* cgetc(x)--like getc(f), but appends a 32-bit CRC to the end of the stream.
  642. X   Return the byte read (the last four of which will be the CRC) or EOF. */
  643. X#define cgete(x) (x->n==4?EOF:(x->c=x->n++?x->c>>8:~x->c,(int)x->c&0xff))
  644. X#define cgetc(x) (x->n==0&&(b=getc(x->f))!=EOF?(ccnt++,x->c=CRC(x->c,b),b):cgete(c))
  645. X
  646. X
  647. X/* cputc(d,x)--like putc(d,f), but delays four bytes and computes a CRC.
  648. X   x is a cfile *, and d is expected to be an ulg. */
  649. X#define cputf(x) (int)(x->c=CRC(x->c,x->b),putc((int)x->b&0xff,x->f),ccnt++)
  650. X#define cputc(d,x) (x->n!=4?x->n++:cputf(x),x->b=(x->b>>8)+((ulg)(d)<<24))
  651. X
  652. X
  653. Xchar *nopath(p)
  654. Xchar *p;                /* full file name */
  655. X/* Extract just the name of file--remove and subdirectories or devices */
  656. X{
  657. X#ifdef MSDOS
  658. X  char *q = "/\\:";     /* MSDOS delimiters */
  659. X#else /* !MSDOS */
  660. X#ifdef VMS
  661. X  char *q = "]:";       /* VMS delimiters */
  662. X#else /* !VMS */
  663. X  char *q = "/";        /* Unix delimiter */
  664. X#endif /* ?VMS */
  665. X#endif /* ?MSDOS */
  666. X  char *r;              /* result of strrchr() */
  667. X
  668. X  while (*q)
  669. X    if ((r = strrchr(p, *q++)) != NULL)
  670. X      p = r + 1;
  671. X  return p;
  672. X}
  673. X
  674. X
  675. Xvoid newship()
  676. X/* Open up a new ship file to write to */
  677. X{
  678. X  int i;                /* scans down name to increment */
  679. X
  680. X  for (i = 7; i > 3; i--)
  681. X    if (++sname[i] > '9')
  682. X      sname[i] = '0';
  683. X    else
  684. X      break;
  685. X  if (i == 3)
  686. X    err(SE_MANY, "");
  687. X  if ((sfile = fopen(mail ? mktemp(strcpy(mname, TMPNAME)) : sname,
  688. X                     "w")) == NULL)
  689. X    err(SE_FULL, mail ? mname : sname);
  690. X  slns = 0;
  691. X}
  692. X
  693. X
  694. Xvoid endship(e)
  695. Xint e;          /* true if ending the last ship file */
  696. X/* Finish off current ship file */
  697. X{
  698. X  char *s;              /* malloc'd space for mail command */
  699. X
  700. X  if (ferror(sfile) || fclose(sfile))
  701. X    err(SE_FULL, mail ? mname : sname);
  702. X  if (mail)
  703. X  {
  704. X    if ((s = malloc(strlen(MAILCMD)- 5*2 + strlen(mprefix) + strlen(sname) +
  705. X                    (e ? 7 : 0) + strlen(mdest) + strlen(mname) + 1)) == NULL)
  706. X      err(SE_MEM, "");
  707. X#ifdef VMS
  708. X    sprintf(s, MAILCMD, mname, mprefix, sname, e ? " (last)" : "", mdest);
  709. X    if (!system(s))             /* this string fits on one line */
  710. X      err(SE_MAIL, "system() call is not supported on this machine");
  711. X#else /* !VMS */
  712. X    sprintf(s, MAILCMD, mprefix, sname, e ? " (last)" : "", mdest, mname);
  713. X    if (system(s))
  714. X      err(SE_MAIL, s);
  715. X#endif /* ?VMS */
  716. X    free((voidp *)s);
  717. X    unlink(mname);
  718. X    *mname = 0;
  719. X  }
  720. X}
  721. X
  722. X
  723. Xvoid newline(p)
  724. Xchar *p;                /* name of the input file */
  725. X/* Add a new line inside a ship file, possibly cut the file */
  726. X{
  727. X  putc('\n', sfile);
  728. X  slns++;
  729. X  if (slmax && slns >= slmax - 2)
  730. X  {
  731. X    putc('$', sfile);
  732. X    if (fast)
  733. X      fputs(" f", sfile);
  734. X    fputs("\nmore\n", sfile);
  735. X    endship(0);
  736. X    newship();
  737. X    fprintf(sfile, "$%s\ncont %lu %s\n", fast ? " f" : "", ccnt, nopath(p));
  738. X    slns += 2;
  739. X  }
  740. X}
  741. X
  742. X
  743. X/* Macro to avoid leading dots.  It assumes i==0 at the beginning of a line
  744. X   and that b is an available int.  c is only evaluated once. */
  745. X#define sputc(c,f) (i==0?((b=(c))=='.'?putc(' ',f):0,putc(b,f)):putc(c,f))
  746. X
  747. X
  748. Xvoid ship(p, f)
  749. Xchar *p;                /* name of the input file */
  750. XFILE *f;                /* input file */
  751. X/* Encode the binary file f. */
  752. X{
  753. X  int b;                /* character just read */
  754. X  cfile *c;             /* checked file stream */
  755. X  int i;                /* how much is written on line so far */
  756. X  int j;                /* how much is in bit buffer */
  757. X
  758. X  /* Set up output file if needed */
  759. X  if ((mail || slmax) && sfile == stdout)
  760. X  {
  761. X    strcpy(sname, "part0000");
  762. X    newship();
  763. X  }
  764. X
  765. X  /* Write header */
  766. X  if ((c = chook(f)) == NULL)
  767. X    err(SE_MEM, "");
  768. X  ccnt = 0;
  769. X  if (slmax && slns >= slmax - 5) 
  770. X  {
  771. X    endship(0);
  772. X    newship();
  773. X  }
  774. X  fprintf(sfile, "$%s\nship %s\n", fast ? " f" : "", nopath(p));
  775. X  slns += 2;
  776. X
  777. X  /* Encode the file, writing to sfile */
  778. X  if (fast)
  779. X  {
  780. X    int d;              /* accumulates bits (never more than 14) */
  781. X
  782. X    d = j = i = 0;
  783. X    while ((b = cgetc(c)) != EOF)
  784. X    {
  785. X      d |= b << j;
  786. X      j += 8;
  787. X      if ((d & 0x3f) >= LOWSZ)
  788. X      {
  789. X        sputc((int)(safe[(d & 0x3f) + LOWSZ]), sfile);
  790. X        d >>= 6;
  791. X        j -= 6;
  792. X      }
  793. X      else
  794. X      {
  795. X        sputc((int)(safe[(d & 0x3f) + (d & 0x40 ? LOWSZ : 0)]), sfile);
  796. X        d >>= 7;
  797. X        j -= 7;
  798. X      }
  799. X      if (++i == 79)
  800. X      {
  801. X        newline(p);
  802. X        i = 0;
  803. X      }
  804. X      if (j >= 6 && (d & 0x3f) >= LOWSZ)
  805. X      {
  806. X        sputc((int)(safe[(d & 0x3f) + LOWSZ]), sfile);
  807. X        d >>= 6;
  808. X        j -= 6;
  809. X        if (++i == 79)
  810. X        {
  811. X          newline(p);
  812. X          i = 0;
  813. X        }
  814. X      }
  815. X      else if (j >= 7)
  816. X      {
  817. X        sputc((int)(safe[(d & 0x3f) + (d & 0x40 ? LOWSZ : 0)]), sfile);
  818. X        d >>= 7;
  819. X        j -= 7;
  820. X        if (++i == 79)
  821. X        {
  822. X          newline(p);
  823. X          i = 0;
  824. X        }
  825. X      }
  826. X    }
  827. X    free((voidp *)c);
  828. X
  829. X    /* Write leftover bits */
  830. X    if (j)
  831. X    {
  832. X      sputc((int)(safe[d + (d < LOWSZ ? 0 : LOWSZ)]), sfile);
  833. X      putc('\n', sfile);
  834. X      slns++;
  835. X    }
  836. X    else if (i)
  837. X    {
  838. X      putc('\n', sfile);
  839. X      slns++;
  840. X    }
  841. X  }
  842. X  else
  843. X  {
  844. X    ulg d;              /* accumulates bytes */
  845. X
  846. X    d = j = i = 0;
  847. X    while ((b = cgetc(c)) != EOF)
  848. X    {
  849. X      d += ((ulg)b) << j;
  850. X      if ((j += 8) == 32)
  851. X      {
  852. X        sputc((int)(safe[(int)(d % 85)]), sfile);  d /= 85;
  853. X        putc((int)(safe[(int)(d % 85)]), sfile);  d /= 85;
  854. X        putc((int)(safe[(int)(d % 85)]), sfile);  d /= 85;
  855. X        putc((int)(safe[(int)(d % 85)]), sfile);  d /= 85;
  856. X        putc((int)(safe[(int)d]), sfile);
  857. X        if (++i == 15)                  /* each line is <= 75 characters */
  858. X        {
  859. X          newline(p);
  860. X          i = 0;
  861. X        }
  862. X        d = j = 0;
  863. X      }
  864. X    }
  865. X    free((voidp *)c);
  866. X  
  867. X    /* Write leftover data */
  868. X    if (j)
  869. X    {
  870. X      j >>= 3;
  871. X      sputc((int)(safe[(int)(d % 85)]), sfile);
  872. X      while (j--)
  873. X      {
  874. X        d /= 85;
  875. X        putc((int)(safe[(int)(d % 85)]), sfile);
  876. X      }
  877. X      putc('\n', sfile);
  878. X      slns++;
  879. X    }
  880. X    else if (i)
  881. X    {
  882. X      putc('\n', sfile);
  883. X      slns++;
  884. X    }
  885. X  }
  886. X  putc('$', sfile);
  887. X  if (fast)
  888. X    fputs(" f", sfile);
  889. X  fputs("\nend\n", sfile);
  890. X  slns += 2;
  891. X  if (ferror(sfile) || fflush(sfile))
  892. X    err(SE_FULL, mail ? mname : sname);
  893. X  if (noisy)
  894. X    fprintf(stderr, "%s shipped\n", p);
  895. X}
  896. X
  897. X
  898. Xvoid mkinv()
  899. X/* Build invsafe[], the inverse of safe[]. */
  900. X{
  901. X  int i;
  902. X
  903. X  for (i = 0; i < 256; i++)
  904. X    invsafe[i] = 127;
  905. X  for (i = 0; i < sizeof(safe); i++)
  906. X    invsafe[safe[i]] = (char)i;
  907. X  for (i = 0; aliases[i]; i += 2)
  908. X    invsafe[aliases[i]] = invsafe[aliases[i + 1]];
  909. X}
  910. X
  911. X
  912. Xunsigned int decb;      /* bit buffer for decode */
  913. Xunsigned int decn;      /* number of bits in decb */
  914. X
  915. Xvoid decode(s, c)
  916. Xunsigned char *s;       /* data to decode */
  917. Xcfile *c;               /* binary output file */
  918. X/* Decode s, a string of base 85 digits or, if fast is true, a string of safe
  919. X   characters generated arithmetically, into its binary equivalent, writing
  920. X   the result to c, using cputc(). */
  921. X{
  922. X  int b;                /* state of line loop, next character */
  923. X  int k;                /* counts bits or digits read */
  924. X  /* powers of 85 table for decoding */
  925. X  static ulg m[] = {1L,85L,85L*85L,85L*85L*85L,85L*85L*85L*85L};
  926. X
  927. X  if (fast)
  928. X  {
  929. X    unsigned int d;     /* disperses bits */
  930. X
  931. X    d = decb;
  932. X    k = decn;
  933. X    while ((b = *s++) != 0)
  934. X      if ((b = invsafe[b]) < sizeof(safe))
  935. X      {
  936. X        if (b < LOWSZ)
  937. X        {
  938. X          d |= b << k;
  939. X          k += 7;
  940. X        }
  941. X        else if ((b -= LOWSZ) < LOWSZ)
  942. X        {
  943. X          d |= (b + 0x40) << k;
  944. X          k += 7;
  945. X        }
  946. X        else
  947. X        {
  948. X          d |= b << k;
  949. X          k += 6;
  950. X        }
  951. X        if (k >= 8)
  952. X        {
  953. X          cputc(d, c);
  954. X          d >>= 8;
  955. X          k -= 8;
  956. X        }
  957. X      }
  958. X    decb = d;
  959. X    decn = k;
  960. X  }
  961. X  else
  962. X  {
  963. X    ulg d;              /* disperses bytes */
  964. X
  965. X    d = k = 0;
  966. X    while ((b = *s++) != 0)
  967. X      if ((b = invsafe[b]) < 85)
  968. X      {
  969. X        d += m[k] * b;
  970. X        if (++k == 5)
  971. X        {
  972. X          cputc(d, c);  d >>= 8;
  973. X          cputc(d, c);  d >>= 8;
  974. X          cputc(d, c);  d >>= 8;
  975. X          cputc(d, c);
  976. X          d = k = 0;
  977. X        }
  978. X      }
  979. X    if (--k > 0)
  980. X    {
  981. X      while (--k)
  982. X      {
  983. X        cputc(d, c);
  984. X        d >>= 8;
  985. X      }
  986. X      cputc(d, c);
  987. X    }
  988. X  }
  989. X}
  990. X
  991. X
  992. Xvoid unship(v, g, o)
  993. Xchar **v;               /* arguments */
  994. Xint g;                  /* number of arguments */
  995. Xint o;                  /* overwrite flag */
  996. X/* Extract from the files named in the arguments the files that were
  997. X   encoded by ship.  If an argument is "-", then stdin is read. */
  998. X{
  999. X  int b;                /* state of line loop */
  1000. X  cfile *c;             /* output binary file */
  1001. X  FILE *f;              /* output file */
  1002. X  char *h;              /* name of current ship file */
  1003. X  char l[LNSZ];         /* line buffer on input */
  1004. X  int n;                /* next argument to use for input */
  1005. X  char *p;              /* modifies line buffer */
  1006. X  char *q;              /* scans continuation line */
  1007. X  char *r;              /* name of output binary file */
  1008. X  FILE *s;              /* current ship file */
  1009. X  int z;                /* true if zero files received */
  1010. X
  1011. X  /* Build inverse table */
  1012. X  mkinv();
  1013. X
  1014. X  /* No input or output files initially */
  1015. X  s = NULL;
  1016. X  c = NULL;
  1017. X  h = r = NULL;
  1018. X
  1019. X  /* Loop on input files' lines */
  1020. X  z = 1;                                /* none received yet */
  1021. X  n = 0;                                /* start with file zero */
  1022. X  b = 2;                                /* not in body yet */
  1023. X  while (1)                             /* return on end of last file */
  1024. X  {
  1025. X    /* Get next line from list of files */
  1026. X    while (s == NULL || fgets(l, LNSZ, s) == NULL)
  1027. X    {
  1028. X      if (s != NULL)
  1029. X        fclose(s);
  1030. X      if (n >= g)
  1031. X      {
  1032. X        if (c != NULL)
  1033. X          err(SE_PART, r);
  1034. X        else if (z)
  1035. X          err(SE_NONE, "");
  1036. X        return;
  1037. X      }
  1038. X      if (v[n][0] == '-')
  1039. X        if (v[n][1])
  1040. X          err(SE_ARG, v[n]);
  1041. X        else
  1042. X        {
  1043. X          h = "stream stdin";
  1044. X          s = stdin;
  1045. X        }
  1046. X      else
  1047. X      {
  1048. X        h = v[n];
  1049. X        if ((s = fopen(h, "r")) == NULL)
  1050. X          err(SE_FIND, h);
  1051. X      }
  1052. X      n++;
  1053. X      b &= ~1;                          /* not in middle of line */
  1054. X    }
  1055. X
  1056. X    /* Strip control characters and leading blank space, if any */
  1057. X    for (q = l; *q && *q <= ' ' && *q != '\n'; q++)
  1058. X      ;
  1059. X    for (p = l; *q; q++)
  1060. X      if (*q >= ' ' || *q == '\n')
  1061. X        *p++ = *q;
  1062. X    *p = 0;
  1063. X
  1064. X    /* Based on current state, end or start on terminator.  States are:
  1065. X         b == 0:  at start of body or body terminator line
  1066. X         b == 1:  in middle of body line
  1067. X         b == 2:  at start of non-body line
  1068. X         b == 3:  in middle of non-body line
  1069. X         b == 4:  at information line
  1070. X    */
  1071. X    switch (b)
  1072. X    {
  1073. X    case 0:
  1074. X      if ((!fast && strcmp(l, "$\n") == 0) ||
  1075. X          (fast && strcmp(l, "$ f\n") == 0))
  1076. X      {
  1077. X        b = 4;
  1078. X        break;
  1079. X      }
  1080. X      /* fall through to case 1 */
  1081. X    case 1:
  1082. X      decode((unsigned char *)l, c);
  1083. X      b = l[strlen(l) - 1] != '\n';
  1084. X      break;
  1085. X    case 2:
  1086. X      if (strcmp(l, "$\n") == 0 || strcmp(l, "$ f\n") == 0)
  1087. X      {
  1088. X        fast = l[1] == ' ';
  1089. X        b = 4;
  1090. X        break;
  1091. X      }
  1092. X      /* fall through to case 3 */
  1093. X    case 3:
  1094. X      b = l[strlen(l)-1] == '\n' ? 2 : 3;
  1095. X      break;
  1096. X    case 4:
  1097. X      /* Possible information lines are ship, more, cont, and end */
  1098. X      if (l[b = strlen(l) - 1] != '\n')
  1099. X        err(SE_FORM, h);
  1100. X      l[b] = 0;
  1101. X      if (strncmp(l, "ship ", 5) == 0)
  1102. X      {
  1103. X        /* get name, open new output file */
  1104. X        if (c != NULL)
  1105. X          err(SE_FORM, h);
  1106. X        if ((r = malloc(b - 4)) == NULL)
  1107. X          err(SE_MEM, "");
  1108. X        strcpy(r, l + 5);
  1109. X        if (strcmp(r, "-") == 0)
  1110. X          f = stdout;
  1111. X#ifndef VMS     /* shouldn't have explicit version #, so VMS won't overwrite */
  1112. X        else if (!o && (f = fopen(r, "r")) != NULL)
  1113. X        {
  1114. X          fclose(f);
  1115. X          err(SE_OVER, r);
  1116. X        }
  1117. X#endif /* !VMS */
  1118. X        else if ((f = fopen(r, "w")) == NULL)
  1119. X          err(SE_FULL, r);
  1120. X        if ((c = chook(f)) == NULL)
  1121. X          err(SE_MEM, "");
  1122. X        b = decb = decn = 0;
  1123. X        ccnt = 0;
  1124. X      }
  1125. X      else if (strcmp(l, "more") == 0)
  1126. X      {
  1127. X        /* check if currently writing */
  1128. X        if (c == NULL)
  1129. X          err(SE_FORM, h);
  1130. X        b = 2;
  1131. X      }
  1132. X      else if (strncmp(l, "cont ", 5) == 0)
  1133. X      {
  1134. X        /* check name and file offset */
  1135. X        if (c == NULL)
  1136. X          err(SE_FORM, h);
  1137. X        for (q = l + 5; *q && *q != ' '; q++)
  1138. X          ;
  1139. X        if (*q == 0 || atol(l + 5) != ccnt + 4 + (decn != 0) ||
  1140. X            strcmp(q + 1, r))
  1141. X          err(SE_CONT, r);
  1142. X        b = 0;
  1143. X      }
  1144. X      else if (strcmp(l, "end") == 0)
  1145. X      {
  1146. X        /* check crc, close output file */
  1147. X        if (c == NULL)
  1148. X          err(SE_FORM, h);
  1149. X        if (c->n != 4 || c->b != ~c->c)
  1150. X          err(SE_CRC, r);
  1151. X        if (ferror(c->f) || fclose(c->f))
  1152. X          err(SE_FULL, r);
  1153. X        if (noisy)
  1154. X          fprintf(stderr, "%s received\n", r);
  1155. X        z = 0;
  1156. X        free((voidp *)c);
  1157. X        c = NULL;
  1158. X        b = 2;
  1159. X      }
  1160. X      else
  1161. X      {
  1162. X        for (q = l; *q && *q != ' '; q++)
  1163. X          ;
  1164. X        *q = 0;
  1165. X        fprintf(stderr, "%s: unsupported keyword '%s' ignored\n", warname, l);
  1166. X        b = 4;
  1167. X      }
  1168. X      break;
  1169. X    }
  1170. X  }
  1171. X}
  1172. X
  1173. X
  1174. Xvoid help()
  1175. X{
  1176. X  int i;
  1177. X  static char *text[] = {
  1178. X"Usage:",
  1179. X"   ship [-f] [-q] [-nnn] [-m address] [-s subject] files...",
  1180. X"",
  1181. X"   ships the files to stdout.  -m sends the output via the mailer to",
  1182. X"   address.  -nnn splits the output into pieces of nnnK bytes or less.",
  1183. X"   if -nnn is used without -m, the output goes to the files partxxxx,",
  1184. X"   where xxxx is 0001, 0002, etc.  If -0 is specified, the output goes",
  1185. X"   entirely to the file part0001.  -f uses a fast method with slightly",
  1186. X"   less performance.  If no files are given, stdin is used.  The special",
  1187. X"   filename '-' also takes input from stdin.  Files shipped from stdin",
  1188. X"   are unshipped to stdout.  This can be used to document a shipment.",
  1189. X"   When mailing, -s gives a subject line prefix.  -q inhibits messages.",
  1190. X"",
  1191. X"   ship -u [-o] [-q] files...",
  1192. X"   unship  [-o] [-q] files...",
  1193. X"",
  1194. X"   extracts the contents of the mail messages in files...  -o allows",
  1195. X"   existing files to be overwritten.  -u is implied if the name of the",
  1196. X"   executable is unship.  If no files are given, the input is from",
  1197. X"   stdin.  If any of the files were shipped from stdin, then they are",
  1198. X"   extracted to stdout."
  1199. X  };
  1200. X
  1201. X  puts(SHIPVER);
  1202. X  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
  1203. X  {
  1204. X    printf(text[i]);
  1205. X    putchar('\n');
  1206. X  }
  1207. X  exit(0);
  1208. X}
  1209. X
  1210. X
  1211. Xvoid main(argc, argv)
  1212. Xint argc;               /* number of arguments */
  1213. Xchar **argv;            /* table of argument strings */
  1214. X{
  1215. X  FILE *f;              /* input file */
  1216. X  char *p;              /* temporary variable */
  1217. X  int o;                /* overwrite flag */
  1218. X  int r;                /* temporary variable */
  1219. X  int s;                /* true if no names given */
  1220. X
  1221. X  /* No temporary file yet (for err()) */
  1222. X  *mname = 0;
  1223. X
  1224. X  /* No subject prefix yet */
  1225. X  *mprefix = 0;
  1226. X
  1227. X  /* See if help requested */
  1228. X  if (argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "-?") == 0))
  1229. X    help();
  1230. X
  1231. X  /* Unship */
  1232. X  if ((p = strrchr(argv[0], PATHCUT)) == NULL)
  1233. X    p = argv[0];
  1234. X  else
  1235. X    p++;
  1236. X  r = 0;                                /* (make some compilers happier) */
  1237. X  if ((r = strncmp(p, "unship", 6)) == 0 ||
  1238. X      (r = strncmp(p, "UNSHIP", 6)) == 0 ||
  1239. X      (argc > 1 && strcmp(argv[1], "-u") == 0))
  1240. X  {
  1241. X    errname = "unship error";
  1242. X    warname = "unship warning";
  1243. X    r = r ? 2 : 1;                      /* next arg */
  1244. X    o = 0;                              /* disallow overwriting */
  1245. X    if (r < argc && strcmp(argv[r], "-o") == 0)
  1246. X    {
  1247. X      r++;
  1248. X      o = 1;                            /* allow overwriting */
  1249. X    }
  1250. X    if (r < argc && strcmp(argv[r], "-q") == 0)
  1251. X    {
  1252. X      r++;
  1253. X      noisy = 0;                        /* inhibit messages */
  1254. X    }
  1255. X    if (r < argc)
  1256. X      unship(argv + r, argc - r, o);    /* unship files in args */
  1257. X    else
  1258. X    {
  1259. X      char *a[1];       /* short list of names (one) */
  1260. X
  1261. X      a[0] = "-";
  1262. X      unship(a, 1, o);                  /* no args--do stdin */
  1263. X    }
  1264. X  }
  1265. X
  1266. X  /* Ship */
  1267. X  else
  1268. X  {
  1269. X    mail = 0;                           /* not mailing */
  1270. X    fast = 0;                           /* use base 85 encoding */
  1271. X    s = 1;                              /* no names given yet */
  1272. X    strcpy(sname, "-");                 /* output to stdout */
  1273. X    sfile = stdout;
  1274. X    slns = slmax = 0;
  1275. X    for (r = 1; r < argc; r++)          /* go through args */
  1276. X      if (argv[r][0] == '-')            /* option or stdin */
  1277. X        if (argv[r][1])                 /* option */
  1278. X        {
  1279. X          if (argv[r][1] == 'm')        /* mail output */
  1280. X          {
  1281. X            mail = 1;
  1282. X            mdest = NULL;               /* next arg is mail address */
  1283. X          }
  1284. X          else if (argv[r][1] == 's')   /* next arg is subject prefix */
  1285. X            mprefix = NULL;
  1286. X          else if (argv[r][1] == 'f')   /* fast arithmetic encoding */
  1287. X            fast = 1;
  1288. X          else if (argv[r][1] == 'q')   /* quiet operation */
  1289. X            noisy = 0;
  1290. X          else                          /* option is number of lines */
  1291. X          {
  1292. X            /* Check numeric option */
  1293. X            for (p = argv[r] + 1; *p; p++)
  1294. X              if (*p < '0' || *p > '9')
  1295. X                break;
  1296. X            if (*p || slmax)
  1297. X              err(SE_ARG, argv[r]);
  1298. X  
  1299. X            /* Zero means infinity, else convert */
  1300. X            if ((slmax = atol(argv[r] + 1)) == 0)
  1301. X              slmax = -1L;
  1302. X            else
  1303. X            {
  1304. X              long b;
  1305. X
  1306. X              b = slmax * 1000L;
  1307. X              slmax = (int)(b / (fast ? 81 : 77));
  1308. X              /* Note: five of the lines aren't that long, but that
  1309. X                 leaves some slack for mail headers, etc.  Also, note
  1310. X                 that we conservatively assume 1000 bytes/K and two
  1311. X                 bytes per new line. */
  1312. X            }
  1313. X          }
  1314. X        }
  1315. X        else                            /* input file is stdin */
  1316. X        {
  1317. X          if (mail && mdest == NULL)
  1318. X            err(SE_ARG, "- (no mail destination given)");
  1319. X          s = 0;
  1320. X          if (mail && !*mprefix)
  1321. X            strcpy(mprefix, "(stdin)");
  1322. X          ship("-", stdin);
  1323. X        }
  1324. X      else                              /* not option or stdin */
  1325. X        if (mail && mdest == NULL)      /* arg is mail address */
  1326. X          mdest = argv[r];
  1327. X        else if (mprefix == NULL)       /* arg is subject prefix */
  1328. X          mprefix = argv[r];
  1329. X        else                            /* arg is file to ship */
  1330. X        {
  1331. X          s = 0;
  1332. X          if ((f = fopen(argv[r], "r")) == NULL)
  1333. X            err(SE_FIND, argv[r]);
  1334. X          if (mail && !*mprefix)
  1335. X          {
  1336. X            int i;
  1337. X
  1338. X            for (i = 0, p = nopath(argv[r]); i < 8 && *p; p++)
  1339. X              if ((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'Z') ||
  1340. X                  (*p >= 'a' && *p <= 'z') || *p == '.' || *p == '_')
  1341. X                mprefix[i++] = *p;
  1342. X            mprefix[i] = 0;
  1343. X          }
  1344. X          ship(argv[r], f);
  1345. X          fclose(f);
  1346. X        }
  1347. X    if (s)                              /* no names--act as filter */
  1348. X      if (mail && mdest == NULL)
  1349. X        err(SE_ARG, "-m (no mail destination given)");
  1350. X      else if (mprefix == NULL)
  1351. X        err(SE_ARG, "-s (no subject prefix given)");
  1352. X      else
  1353. X      {
  1354. X        if (mail && !*mprefix)
  1355. X          strcpy(mprefix, "(stdin)");
  1356. X        ship("-", stdin);
  1357. X      }
  1358. X    endship(1);                         /* clean up */
  1359. X    if (noisy && (mail || slmax))
  1360. X      fprintf(stderr, "file%s%s %s\n",
  1361. X              strcmp("part0001", sname) ? "s part0001.." : " ", sname,
  1362. X              mail ? "mailed" : "written");
  1363. X  }
  1364. X
  1365. X  /* Done */
  1366. X  exit(0);
  1367. X}
  1368. END_OF_FILE
  1369.   if test 38393 -ne `wc -c <'ship.c'`; then
  1370.     echo shar: \"'ship.c'\" unpacked with wrong size!
  1371.   fi
  1372.   # end of 'ship.c'
  1373. fi
  1374. if test -f 'util.c' -a "${1}" != "-c" ; then 
  1375.   echo shar: Will not clobber existing file \"'util.c'\"
  1376. else
  1377.   echo shar: Extracting \"'util.c'\" \(10800 characters\)
  1378.   sed "s/^X//" >'util.c' <<'END_OF_FILE'
  1379. X/*
  1380. X
  1381. X Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, and Jean-loup Gailly.
  1382. X Permission is granted to any individual or institution to use, copy, or
  1383. X redistribute this software so long as all of the original files are included
  1384. X unmodified, that it is not sold for profit, and that this copyright notice
  1385. X is retained.
  1386. X
  1387. X*/
  1388. X
  1389. X/*
  1390. X *  util.c by Mark Adler.
  1391. X */
  1392. X
  1393. X#include "zip.h"
  1394. X
  1395. X/* Local functions */
  1396. X#ifdef PROTO
  1397. X  local int recmatch(char *, char *);
  1398. X#endif /* PROTO */
  1399. X
  1400. X
  1401. Xchar *isshexp(p)
  1402. Xchar *p;                /* candidate sh expression */
  1403. X/* If p is a sh expression, a pointer to the first special character is
  1404. X   returned.  Otherwise, NULL is returned. */
  1405. X{
  1406. X  int c;
  1407. X
  1408. X  c = -1;
  1409. X  for (; *p; p++)
  1410. X#ifdef VMS
  1411. X    if (c != '\\' && (*p == '%' || *p == '*'))
  1412. X#else /* !VMS */
  1413. X    if (c != '\\' && (*p == '?' || *p == '*' || *p == '['))
  1414. X#endif /* ?VMS */
  1415. X      return p;
  1416. X  return NULL;
  1417. X}
  1418. X
  1419. X
  1420. Xlocal int recmatch(p, s)
  1421. Xchar *p;                /* sh pattern to match */
  1422. Xchar *s;                /* string to match it to */
  1423. X/* Recursively compare the sh pattern p with the string s and return 1 if
  1424. X   they match, and 0 or 2 if they don't or if there is a syntax error in the
  1425. X   pattern.  This routine recurses on itself no deeper than the number of
  1426. X   characters in the pattern. */
  1427. X{
  1428. X  int c;                /* pattern char or start of range in [-] loop */ 
  1429. X
  1430. X  /* Get first character, the pattern for new recmatch calls follows */
  1431. X  c = *p++;
  1432. X
  1433. X  /* If that was the end of the pattern, match if string empty too */
  1434. X  if (c == 0)
  1435. X    return *s == 0;
  1436. X
  1437. X  /* '?' (or '%') matches any character (but not an empty string) */
  1438. X#ifdef VMS
  1439. X  if (c == '%')
  1440. X#else /* !VMS */
  1441. X  if (c == '?')
  1442. X#endif /* ?VMS */
  1443. X    return *s ? recmatch(p, s + 1) : 0;
  1444. X
  1445. X  /* '*' matches any number of characters, including zero */
  1446. X  if (c == '*')
  1447. X  {
  1448. X    if (*p == 0)
  1449. X      return 1;
  1450. X    for (; *s; s++)
  1451. X      if ((c = recmatch(p, s)) != 0)
  1452. X        return c;
  1453. X    return 2;           /* 2 means give up--shmatch will return false */
  1454. X  }
  1455. X
  1456. X#ifndef VMS             /* No bracket matching in VMS */
  1457. X  /* Parse and process the list of characters and ranges in brackets */
  1458. X  if (c == '[')
  1459. X  {
  1460. X    int e;              /* flag true if next char to be taken literally */
  1461. X    char *q;            /* pointer to end of [-] group */
  1462. X    int r;              /* flag true to match anything but the range */
  1463. X
  1464. X    if (*s == 0)                        /* need a character to match */
  1465. X      return 0;
  1466. X    p += (r = *p == '!');               /* see if reverse */
  1467. X    for (q = p, e = 0; *q; q++)         /* find closing bracket */
  1468. X      if (e)
  1469. X        e = 0;
  1470. X      else
  1471. X        if (*q == '\\')
  1472. X          e = 1;
  1473. X        else if (*q == ']')
  1474. X          break;
  1475. X    if (*q != ']')                      /* nothing matches if bad syntax */
  1476. X      return 0;
  1477. X    for (c = 0, e = *p == '-'; p < q; p++)      /* go through the list */
  1478. X    {
  1479. X      if (e == 0 && *p == '\\')         /* set escape flag if \ */
  1480. X        e = 1;
  1481. X      else if (e == 0 && *p == '-')     /* set start of range if - */
  1482. X        c = *(p-1);
  1483. X      else
  1484. X      {
  1485. X        if (*(p+1) != '-')
  1486. X          for (c = c ? c : *p; c <= *p; c++)    /* compare range */
  1487. X#ifdef OS2
  1488. X            if (tolower(c) == tolower(*s))
  1489. X#else /* !OS2 */
  1490. X            if (c == *s)
  1491. X#endif /* ?OS2 */
  1492. X              return r ? 0 : recmatch(q + 1, s + 1);
  1493. X        c = e = 0;                      /* clear range, escape flags */
  1494. X      }
  1495. X    }
  1496. X    return r ? recmatch(q + 1, s + 1) : 0;      /* bracket match failed */
  1497. X  }
  1498. X#endif /* !VMS */
  1499. X
  1500. X  /* If escape ('\'), just compare next character */
  1501. X  if (c == '\\')
  1502. X    if ((c = *p++) == 0)                /* if \ at end, then syntax error */
  1503. X      return 0;
  1504. X
  1505. X  /* Just a character--compare it */
  1506. X#ifdef OS2
  1507. X  return tolower(c) == tolower(*s) ? recmatch(p, ++s) : 0;
  1508. X#else /* !OS2 */
  1509. X  return c == *s++ ? recmatch(p, s) : 0;        /* compare one character */
  1510. X#endif /* ?OS2 */
  1511. X}
  1512. X
  1513. X
  1514. Xint shmatch(p, s)
  1515. Xchar *p;                /* sh pattern to match */
  1516. Xchar *s;                /* string to match it to */
  1517. X/* Compare the sh pattern p with the string s and return true if they match,
  1518. X   false if they don't or if there is a syntax error in the pattern. */
  1519. X{
  1520. X  return recmatch(p, s) == 1;
  1521. X}
  1522. X
  1523. X
  1524. X#ifdef MSDOS
  1525. X
  1526. Xint dosmatch(p, s)
  1527. Xchar *p;                /* dos pattern to match */
  1528. Xchar *s;                /* string to match it to */
  1529. X/* Break the pattern and string into name and extension parts and match
  1530. X   each separately using shmatch(). */
  1531. X{
  1532. X  char *p1, *p2;        /* pattern sections */
  1533. X  char *s1, *s2;        /* string sections */
  1534. X  int r;                /* result */
  1535. X
  1536. X  if ((p1 = malloc(strlen(p) + 1)) == NULL ||
  1537. X      (s1 = malloc(strlen(s) + 1)) == NULL)
  1538. X  {
  1539. X    if (p1 != NULL)
  1540. X      free((voidp *)p1);
  1541. X    return 0;
  1542. X  }
  1543. X  strcpy(p1, p);
  1544. X  strcpy(s1, s);
  1545. X  if ((p2 = strrchr(p1, '.')) != NULL)
  1546. X    *p2++ = 0;
  1547. X  else
  1548. X    p2 = "";
  1549. X  if ((s2 = strrchr(s1, '.')) != NULL)
  1550. X    *s2++ = 0;
  1551. X  else
  1552. X    s2 = "";
  1553. X  r = shmatch(p2, s2) && shmatch(p1, s1);
  1554. X  free((voidp *)p1);
  1555. X  free((voidp *)s1);
  1556. X  return r;
  1557. X}
  1558. X
  1559. X#endif /* MSDOS */
  1560. X
  1561. X
  1562. Xvoidp far **search(b, a, n, cmp)
  1563. Xvoidp *b;               /* pointer to value to search for */
  1564. Xvoidp far **a;          /* table of pointers to values, sorted */
  1565. Xextent n;               /* number of pointers in a[] */
  1566. Xint (*cmp) OF((voidp *, voidp far *));  /* comparison function for search */
  1567. X/* Search for b in the pointer list a[0..n-1] using the compare function
  1568. X   cmp(b, c) where c is an element of a[i] and cmp() returns negative if
  1569. X   *b < *c, zero if *b == *c, or positive if *b > *c.  If *b is found,
  1570. X   search returns a pointer to the entry in a[], else search() returns
  1571. X   NULL.  The nature and size of *b and *c (they can be different) are
  1572. X   left up to the cmp() function.  A binary search is used, and it is
  1573. X   assumed that the list is sorted in ascending order. */
  1574. X{
  1575. X  voidp far **i;        /* pointer to midpoint of current range */
  1576. X  voidp far **l;        /* pointer to lower end of current range */
  1577. X  int r;                /* result of (*cmp)() call */
  1578. X  voidp far **u;        /* pointer to upper end of current range */
  1579. X
  1580. X  l = (voidp far **)a;  u = l + (n-1);
  1581. X  while (u >= l)
  1582. X    if ((r = (*cmp)(b, *(i = l + ((u - l) >> 1)))) < 0)
  1583. X      u = i - 1;
  1584. X    else if (r > 0)
  1585. X      l = i + 1;
  1586. X    else
  1587. X      return (voidp far **)i;
  1588. X  return NULL;          /* If b were in list, it would belong at l */
  1589. X}
  1590. X
  1591. X
  1592. X
  1593. X/* Table of CRC-32's of all single byte values (made by makecrc.c) */
  1594. Xlocal ulg crctab[] = {
  1595. X  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  1596. X  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  1597. X  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  1598. X  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  1599. X  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  1600. X  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  1601. X  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  1602. X  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  1603. X  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  1604. X  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  1605. X  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  1606. X  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  1607. X  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  1608. X  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  1609. X  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  1610. X  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  1611. X  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  1612. X  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  1613. X  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  1614. X  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  1615. X  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  1616. X  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  1617. X  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  1618. X  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  1619. X  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  1620. X  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  1621. X  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  1622. X  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  1623. X  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  1624. X  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  1625. X  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  1626. X  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  1627. X  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  1628. X  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  1629. X  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  1630. X  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  1631. X  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  1632. X  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  1633. X  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  1634. X  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  1635. X  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  1636. X  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  1637. X  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  1638. X  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  1639. X  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  1640. X  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  1641. X  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  1642. X  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  1643. X  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  1644. X  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  1645. X  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  1646. X  0x2d02ef8dL
  1647. X};
  1648. X
  1649. X
  1650. Xulg crc32(c, b)
  1651. Xulg c;                  /* current contents of crc shift register */
  1652. Xint b;                  /* byte (eight bits) to run through */
  1653. X/* Return the CRC-32 c updated with the eight bits in b. */
  1654. X{
  1655. X  return crctab[((int)c ^ b) & 0xff] ^ (c >> 8);
  1656. X}
  1657. X
  1658. X
  1659. Xulg updcrc(s, n)
  1660. Xchar *s;                /* pointer to bytes to pump through */
  1661. Xextent n;               /* number of bytes in s[] */
  1662. X/* Run a set of bytes through the crc shift register.  If s is a NULL
  1663. X   pointer, then initialize the crc shift register contents instead.
  1664. X   Return the current crc in either case. */
  1665. X{
  1666. X  register ulg c;       /* temporary variable */
  1667. X
  1668. X  static ulg crc = 0xffffffffL; /* shift register contents */
  1669. X
  1670. X  if (s == NULL)
  1671. X    c = 0xffffffffL;
  1672. X  else
  1673. X  {
  1674. X    c = crc;
  1675. X    while (n--)
  1676. X      c = crctab[((int)c ^ (*s++)) & 0xff] ^ (c >> 8);
  1677. X  }
  1678. X  crc = c;
  1679. X  return c ^ 0xffffffffL;       /* (instead of ~c for 64-bit machines) */
  1680. X}
  1681. END_OF_FILE
  1682.   if test 10800 -ne `wc -c <'util.c'`; then
  1683.     echo shar: \"'util.c'\" unpacked with wrong size!
  1684.   fi
  1685.   # end of 'util.c'
  1686. fi
  1687. echo shar: End of archive 3 \(of 9\).
  1688. cp /dev/null ark3isdone
  1689. MISSING=""
  1690. for I in 1 2 3 4 5 6 7 8 9 ; do
  1691.     if test ! -f ark${I}isdone ; then
  1692.     MISSING="${MISSING} ${I}"
  1693.     fi
  1694. done
  1695. if test "${MISSING}" = "" ; then
  1696.     echo You have unpacked all 9 archives.
  1697.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1698. else
  1699.     echo You still must unpack the following archives:
  1700.     echo "        " ${MISSING}
  1701. fi
  1702. exit 0
  1703. exit 0 # Just in case...
  1704. -- 
  1705. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1706. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1707. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1708. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1709.