home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / zip19 / part08 < prev    next >
Encoding:
Text File  |  1992-08-22  |  60.4 KB  |  1,796 lines

  1. Newsgroups: comp.sources.misc
  2. From: zip-bugs@cs.ucla.edu (Info-ZIP group)
  3. Subject:  v31i100:  zip19 - Info-ZIP portable Zip, version 1.9, Part08/11
  4. Message-ID: <1992Aug23.064803.29419@sparky.imd.sterling.com>
  5. X-Md4-Signature: 0d324eadec388c13d7566bdfa95fe008
  6. Date: Sun, 23 Aug 1992 06:48:03 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: zip-bugs@cs.ucla.edu (Info-ZIP group)
  10. Posting-number: Volume 31, Issue 100
  11. Archive-name: zip19/part08
  12. Supersedes: zip: Volume 23, Issue 88-96
  13. Environment: UNIX, VMS, OS/2, MS-DOS, MACINTOSH, WIN-NT, LINUX, MINIX, XOS, !AMIGA, ATARI, symlink, SGI, DEC, Cray, Convex, Amdahl, Sun, PC
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  20. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  21. # Contents:  bits.c makecrc.c os2/makefile.os2.UU vms/VMSmunch.c
  22. #   zipnote.c zipup.c
  23. # Wrapped by kent@sparky on Sun Aug 23 01:00:46 1992
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. echo If this archive is complete, you will see the following message:
  26. echo '          "shar: End of archive 8 (of 11)."'
  27. if test -f 'bits.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'bits.c'\"
  29. else
  30.   echo shar: Extracting \"'bits.c'\" \(11292 characters\)
  31.   sed "s/^X//" >'bits.c' <<'END_OF_FILE'
  32. X/*
  33. X
  34. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  35. X Kai Uwe Rommel and Igor Mandrichenko.
  36. X Permission is granted to any individual or institution to use, copy, or
  37. X redistribute this software so long as all of the original files are included
  38. X unmodified, that it is not sold for profit, and that this copyright notice
  39. X is retained.
  40. X
  41. X*/
  42. X
  43. X/*
  44. X *  bits.c by Jean-loup Gailly and Kai Uwe Rommel.
  45. X *
  46. X *  This is a new version of im_bits.c originally written by Richard B. Wales
  47. X *
  48. X *  PURPOSE
  49. X *
  50. X *      Output variable-length bit strings. Compression can be done
  51. X *      to a file or to memory.
  52. X *
  53. X *  DISCUSSION
  54. X *
  55. X *      The PKZIP "deflate" file format interprets compressed file data
  56. X *      as a sequence of bits.  Multi-bit strings in the file may cross
  57. X *      byte boundaries without restriction.
  58. X *
  59. X *      The first bit of each byte is the low-order bit.
  60. X *
  61. X *      The routines in this file allow a variable-length bit value to
  62. X *      be output right-to-left (useful for literal values). For
  63. X *      left-to-right output (useful for code strings from the tree routines),
  64. X *      the bits must have been reversed first with bi_reverse().
  65. X *
  66. X *      For in-memory compression, the compressed bit stream goes directly
  67. X *      into the requested output buffer. The input data is read in blocks
  68. X *      by the mem_read() function.
  69. X *
  70. X *  INTERFACE
  71. X *
  72. X *      void bi_init (FILE *zipfile)
  73. X *          Initialize the bit string routines.
  74. X *
  75. X *      void send_bits (int value, int length)
  76. X *          Write out a bit string, taking the source bits right to
  77. X *          left.
  78. X *
  79. X *      int bi_reverse (int value, int length)
  80. X *          Reverse the bits of a bit string, taking the source bits left to
  81. X *          right and emitting them right to left.
  82. X *
  83. X *      void bi_windup (void)
  84. X *          Write out any remaining bits in an incomplete byte.
  85. X *
  86. X *      void copy_block(char far *buf, unsigned len, int header)
  87. X *          Copy a stored block to the zip file, storing first the length and
  88. X *          its one's complement if requested.
  89. X *
  90. X *      int seekable(void)
  91. X *          Return true if the zip file can be seeked.
  92. X *
  93. X *      ulg memcompress (char *tgt, ulg tgtsize, char *src, ulg srcsize);
  94. X *          Compress the source buffer src into the target buffer tgt.
  95. X */
  96. X
  97. X#include "zip.h"
  98. X
  99. X/* ===========================================================================
  100. X * Local data used by the "bit string" routines.
  101. X */
  102. X
  103. Xlocal FILE *zfile; /* output zip file */
  104. X
  105. Xlocal unsigned short bi_buf;
  106. X/* Output buffer. bits are inserted starting at the bottom (least significant
  107. X * bits).
  108. X */
  109. X
  110. X#define Buf_size (8 * 2*sizeof(char))
  111. X/* Number of bits used within bi_buf. (bi_buf might be implemented on
  112. X * more than 16 bits on some systems.)
  113. X */
  114. X
  115. Xlocal int bi_valid;
  116. X/* Number of valid bits in bi_buf.  All bits above the last valid bit
  117. X * are always zero.
  118. X */
  119. X
  120. Xchar file_outbuf[1024];
  121. X/* Output buffer for compression to file */
  122. X
  123. Xlocal char *in_buf, *out_buf;
  124. X/* Current input and output buffers. in_buf is used only for in-memory
  125. X * compression.
  126. X */
  127. X
  128. Xlocal ulg in_offset, out_offset;
  129. X/* Current offset in input and output buffers. in_offset is used only for
  130. X * in-memory compression.
  131. X */
  132. X
  133. Xlocal ulg in_size, out_size;
  134. X/* Size of current input and output buffers */
  135. X
  136. Xint (*read_buf) OF((char *buf, unsigned size)) = file_read;
  137. X/* Current input function. Set to mem_read for in-memory compression */
  138. X
  139. X#ifdef DEBUG
  140. Xulg bits_sent;   /* bit length of the compressed data */
  141. X#endif
  142. X
  143. X/* Output a 16 bit value to the bit stream, lower (oldest) byte first */
  144. X#define PUTSHORT(w) \
  145. X{ if (out_offset < out_size-1) { \
  146. X    out_buf[out_offset++] = (char) ((w) & 0xff); \
  147. X    out_buf[out_offset++] = (char) ((ush)(w) >> 8); \
  148. X  } else { \
  149. X    flush_outbuf((w),2); \
  150. X  } \
  151. X}
  152. X
  153. X#define PUTBYTE(b) \
  154. X{ if (out_offset < out_size) { \
  155. X    out_buf[out_offset++] = (char) (b); \
  156. X  } else { \
  157. X    flush_outbuf((b),1); \
  158. X  } \
  159. X}
  160. X
  161. X
  162. X/* ===========================================================================
  163. X *  Prototypes for local functions
  164. X */
  165. Xlocal int  mem_read     OF((char *buf, unsigned size));
  166. Xlocal void flush_outbuf OF((unsigned w, unsigned size));
  167. X
  168. X/* ===========================================================================
  169. X * Initialize the bit string routines.
  170. X */
  171. Xvoid bi_init (zipfile)
  172. X    FILE *zipfile;  /* output zip file, NULL for in-memory compression */
  173. X{
  174. X    zfile  = zipfile;
  175. X    bi_buf = 0;
  176. X    bi_valid = 0;
  177. X#ifdef DEBUG
  178. X    bits_sent = 0L;
  179. X#endif
  180. X
  181. X    /* Set the defaults for file compression. They are set by memcompress
  182. X     * for in-memory compression.
  183. X     */
  184. X    if (zfile != NULL) {
  185. X        out_buf = file_outbuf;
  186. X        out_size = sizeof(file_outbuf);
  187. X        out_offset = 0;
  188. X        read_buf  = file_read;
  189. X    }
  190. X}
  191. X
  192. X/* ===========================================================================
  193. X * Send a value on a given number of bits.
  194. X * IN assertion: length <= 16 and value fits in length bits.
  195. X */
  196. Xvoid send_bits(value, length)
  197. X    int value;  /* value to send */
  198. X    int length; /* number of bits */
  199. X{
  200. X#ifdef DEBUG
  201. X    Tracevv((stderr," l %2d v %4x ", length, value));
  202. X    Assert(length > 0 && length <= 15, "invalid length");
  203. X    bits_sent += (ulg)length;
  204. X#endif
  205. X    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
  206. X     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
  207. X     * unused bits in value.
  208. X     */
  209. X    if (bi_valid > (int)Buf_size - length) {
  210. X        bi_buf |= (value << bi_valid);
  211. X        PUTSHORT(bi_buf);
  212. X        bi_buf = (ush)value >> (Buf_size - bi_valid);
  213. X        bi_valid += length - Buf_size;
  214. X    } else {
  215. X        bi_buf |= value << bi_valid;
  216. X        bi_valid += length;
  217. X    }
  218. X}
  219. X
  220. X/* ===========================================================================
  221. X * Reverse the first len bits of a code, using straightforward code (a faster
  222. X * method would use a table)
  223. X * IN assertion: 1 <= len <= 15
  224. X */
  225. Xunsigned bi_reverse(code, len)
  226. X    unsigned code; /* the value to invert */
  227. X    int len;       /* its bit length */
  228. X{
  229. X    register unsigned res = 0;
  230. X    do {
  231. X        res |= code & 1;
  232. X        code >>= 1, res <<= 1;
  233. X    } while (--len > 0);
  234. X    return res >> 1;
  235. X}
  236. X
  237. X/* ===========================================================================
  238. X * Flush the current output buffer.
  239. X */
  240. Xlocal void flush_outbuf(w, size)
  241. X    unsigned w;    /* value to flush */
  242. X    unsigned size; /* it size in bytes (0, 1 or 2) */
  243. X{
  244. X    if (zfile == NULL) {
  245. X        error("output buffer too small for in-memory compression");
  246. X    }
  247. X    /* Encrypt and write the output buffer: */
  248. X    if (out_offset != 0) {
  249. X        zfwrite(out_buf, 1, (extent)out_offset, zfile);
  250. X        if (ferror(zfile)) error ("write error on zip file");
  251. X    }
  252. X    out_offset = 0;
  253. X    if (size == 2) {
  254. X        PUTSHORT(w);
  255. X    } else if (size == 1) {
  256. X        out_buf[out_offset++] = (char) (w & 0xff);
  257. X    }
  258. X}
  259. X
  260. X/* ===========================================================================
  261. X * Write out any remaining bits in an incomplete byte.
  262. X */
  263. Xvoid bi_windup()
  264. X{
  265. X    if (bi_valid > 8) {
  266. X        PUTSHORT(bi_buf);
  267. X    } else if (bi_valid > 0) {
  268. X        PUTBYTE(bi_buf);
  269. X    }
  270. X    if (zfile != NULL) {
  271. X        flush_outbuf(0, 0);
  272. X    }
  273. X    bi_buf = 0;
  274. X    bi_valid = 0;
  275. X#ifdef DEBUG
  276. X    bits_sent = (bits_sent+7) & ~7;
  277. X#endif
  278. X}
  279. X
  280. X/* ===========================================================================
  281. X * Copy a stored block to the zip file, storing first the length and its
  282. X * one's complement if requested.
  283. X */
  284. Xvoid copy_block(buf, len, header)
  285. X    char far *buf; /* the input data */
  286. X    unsigned len;  /* its length */
  287. X    int header;    /* true if block header must be written */
  288. X{
  289. X    bi_windup();              /* align on byte boundary */
  290. X
  291. X    if (header) {
  292. X        PUTSHORT((ush)len);   
  293. X        PUTSHORT((ush)~len);
  294. X#ifdef DEBUG
  295. X        bits_sent += 2*16;
  296. X#endif
  297. X    }
  298. X    if (zfile) {
  299. X        flush_outbuf(0, 0);
  300. X        zfwrite(buf, 1, len, zfile);
  301. X        if (ferror(zfile)) error ("write error on zip file");
  302. X    } else if (out_offset + (ulg)len > out_size) {
  303. X        error("output buffer too small for in-memory compression");
  304. X    } else {
  305. X        memcpy(out_buf + out_offset, buf, len);
  306. X        out_offset += (ulg)len;
  307. X    }
  308. X#ifdef DEBUG
  309. X    bits_sent += (ulg)len<<3;
  310. X#endif
  311. X}
  312. X
  313. X
  314. X/* ===========================================================================
  315. X * Return true if the zip file can be seeked. This is used to check if
  316. X * the local header can be re-rewritten. This function always returns
  317. X * true for in-memory compression.
  318. X * IN assertion: the local header has already been written (ftell() > 0).
  319. X */
  320. Xint seekable()
  321. X{
  322. X    return (zfile == NULL ||
  323. X            (fseek(zfile, -1L, SEEK_CUR) == 0 &&
  324. X             fseek(zfile,  1L, SEEK_CUR) == 0));
  325. X}    
  326. X
  327. X/* ===========================================================================
  328. X * In-memory compression. This version can be used only if the entire input
  329. X * fits in one memory buffer. The compression is then done in a single
  330. X * call of memcompress(). (An extension to allow repeated calls would be
  331. X * possible but is not needed here.)
  332. X * The first two bytes of the compressed output are set to a short with the
  333. X * method used (DEFLATE or STORE). The following four bytes contain the CRC.
  334. X * The values are stored in little-endian order on all machines.
  335. X * This function returns the byte size of the compressed output, including
  336. X * the first six bytes (method and crc).
  337. X */
  338. X
  339. Xulg memcompress(tgt, tgtsize, src, srcsize)
  340. X    char *tgt, *src;       /* target and source buffers */
  341. X    ulg tgtsize, srcsize;  /* target and source sizes */
  342. X{
  343. X    ush att      = (ush)UNKNOWN;
  344. X    ush flags    = 0;
  345. X    ulg crc      = 0;
  346. X    int method   = DEFLATE;
  347. X
  348. X    if (tgtsize <= 6L) error("target buffer too small");
  349. X
  350. X    crc = updcrc((char *)NULL, 0);
  351. X    crc = updcrc(src, (extent) srcsize);
  352. X
  353. X    read_buf  = mem_read;
  354. X    in_buf    = src;
  355. X    in_size   = srcsize;
  356. X    in_offset = 0;
  357. X
  358. X    out_buf    = tgt;
  359. X    out_size   = tgtsize;
  360. X    out_offset = 2 + 4;
  361. X
  362. X    bi_init(NULL);
  363. X    ct_init(&att, &method);
  364. X    lm_init(level, &flags);
  365. X    deflate();
  366. X
  367. X    /* For portability, force little-endian order on all machines: */
  368. X    tgt[0] = (char)(method & 0xff);
  369. X    tgt[1] = (char)((method >> 8) & 0xff);
  370. X    tgt[2] = (char)(crc & 0xff);
  371. X    tgt[3] = (char)((crc >> 8) & 0xff);
  372. X    tgt[4] = (char)((crc >> 16) & 0xff);
  373. X    tgt[5] = (char)((crc >> 24) & 0xff);
  374. X
  375. X    return out_offset;
  376. X}
  377. X
  378. X/* ===========================================================================
  379. X * In-memory read function. As opposed to file_read(), this function
  380. X * does not perform end-of-line translation, and does not update the
  381. X * crc and input size.
  382. X *    Note that the size of the entire input buffer is an unsigned long,
  383. X * but the size used in mem_read() is only an unsigned int. This makes a
  384. X * difference on 16 bit machines. mem_read() may be called several
  385. X * times for an in-memory compression.
  386. X */
  387. Xlocal int mem_read(buf, size)
  388. X     char *buf;
  389. X     unsigned size; 
  390. X{
  391. X    if (in_offset < in_size) {
  392. X        ulg block_size = in_size - in_offset;
  393. X        if (block_size > (ulg)size) block_size = (ulg)size;
  394. X        memcpy(buf, in_buf + in_offset, (unsigned)block_size);
  395. X        in_offset += block_size;
  396. X        return (int)block_size;
  397. X    } else {
  398. X        return 0; /* end of input */
  399. X    }
  400. X}
  401. END_OF_FILE
  402.   if test 11292 -ne `wc -c <'bits.c'`; then
  403.     echo shar: \"'bits.c'\" unpacked with wrong size!
  404.   fi
  405.   # end of 'bits.c'
  406. fi
  407. if test -f 'makecrc.c' -a "${1}" != "-c" ; then 
  408.   echo shar: Will not clobber existing file \"'makecrc.c'\"
  409. else
  410.   echo shar: Extracting \"'makecrc.c'\" \(2388 characters\)
  411.   sed "s/^X//" >'makecrc.c' <<'END_OF_FILE'
  412. X/* Not copyrighted 1990 Mark Adler */
  413. X
  414. X#include <stdio.h>
  415. X
  416. Xmain()
  417. X/*
  418. X  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
  419. X  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
  420. X
  421. X  Polynomials over GF(2) are represented in binary, one bit per coefficient,
  422. X  with the lowest powers in the most significant bit.  Then adding polynomials
  423. X  is just exclusive-or, and multiplying a polynomial by x is a right shift by
  424. X  one.  If we call the above polynomial p, and represent a byte as the
  425. X  polynomial q, also with the lowest power in the most significant bit (so the
  426. X  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
  427. X  where a mod b means the remainder after dividing a by b.
  428. X
  429. X  This calculation is done using the shift-register method of multiplying and
  430. X  taking the remainder.  The register is initialized to zero, and for each
  431. X  incoming bit, x^32 is added mod p to the register if the bit is a one (where
  432. X  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
  433. X  x (which is shifting right by one and adding x^32 mod p if the bit shifted
  434. X  out is a one).  We start with the highest power (least significant bit) of
  435. X  q and repeat for all eight bits of q.
  436. X
  437. X  The table is simply the CRC of all possible eight bit values.  This is all
  438. X  the information needed to generate CRC's on data a byte at a time for all
  439. X  combinations of CRC register values and incoming bytes.  The table is
  440. X  written to stdout as 256 long hexadecimal values in C language format.
  441. X*/
  442. X{
  443. X  unsigned long c;      /* crc shift register */
  444. X  unsigned long e;      /* polynomial exclusive-or pattern */
  445. X  int i;                /* counter for all possible eight bit values */
  446. X  int k;                /* byte being shifted into crc apparatus */
  447. X
  448. X  /* terms of polynomial defining this crc (except x^32): */
  449. X  static int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
  450. X
  451. X  /* Make exclusive-or pattern from polynomial */
  452. X  e = 0;
  453. X  for (i = 0; i < sizeof(p)/sizeof(int); i++)
  454. X    e |= 1L << (31 - p[i]);
  455. X
  456. X  /* Compute and print table of CRC's, five per line */
  457. X  printf("  0x00000000L");
  458. X  for (i = 1; i < 256; i++)
  459. X  {
  460. X    c = 0;
  461. X    for (k = i | 256; k != 1; k >>= 1)
  462. X    {
  463. X      c = c & 1 ? (c >> 1) ^ e : c >> 1;
  464. X      if (k & 1)
  465. X        c ^= e;
  466. X    }
  467. X    printf(i % 5 ? ", 0x%08lxL" : ",\n  0x%08lxL", c);
  468. X  }
  469. X  putchar('\n');
  470. X  return 0;
  471. X}
  472. END_OF_FILE
  473.   if test 2388 -ne `wc -c <'makecrc.c'`; then
  474.     echo shar: \"'makecrc.c'\" unpacked with wrong size!
  475.   fi
  476.   # end of 'makecrc.c'
  477. fi
  478. if test -f 'os2/makefile.os2.UU' -a "${1}" != "-c" ; then 
  479.   echo shar: Will not clobber existing file \"'os2/makefile.os2.UU'\"
  480. else
  481.   echo shar: Extracting \"'os2/makefile.os2.UU'\" \(8519 characters\)
  482.   sed "s/^X//" >'os2/makefile.os2.UU' <<'END_OF_FILE'
  483. Xbegin 666 os2/makefile.os2
  484. XM(R!-86ME9FEL92!F;W(@6FEP+"!::7!#;&]A:RP@6FEP3F]T92!A;F0@6FEP
  485. XM4W!L:70-"@T*(R!3=7!P;W)T960@36%K92!U=&EL:71I97,Z#0HC("T@36EC
  486. XM<F]S;V9T+TE"32!N;6%K90T*(R M(&1M86ME(#,N." H<&%R86QL96P@;6%K
  487. XM92P@=7-E("U0-"!I9B!Y;W4@:&%V92!T:&4@;65M;W)Y*2P-"B,@("!I;B!T
  488. XM:&4@97AE(&9I;&4@=&%R9V5T<RP@>6]U('=I;&P@:&%V92!T;R!A9&0@<W!A
  489. XM8V5S(&)E9F]R92 D0"!F;W(@9V-C#0HC("T@3D]4('=A=&-O;2!M86ME("AB
  490. XM<F%I;B!D96%D+"!A<'!A<F5N=&QY(&1O97-N)W0@:VYO=R!L:6YE<R!C;VYT
  491. XM)V0@=VET:"!<*0T*(R M($Y/5"!'3E4@;6%K92 H8G5G9WDL(&EN8V]M<&%T
  492. XM:6)L92D-"@T*(R!3=7!P;W)T960@0R!#;VUP:6QE<G,Z#0HC("T@36EC<F]S
  493. XM;V9T($,@-BXP,"!U;F1E<B!/4R\R(#$N>" H,38M8FET*0T*(R M($=.52!G
  494. XM8V,@*&5M>"!K:70I('5N9&5R($]3+S(@,BXP#0HC("T@24)-($,@4V5T+S(@
  495. XM=6YD97(@3U,O,B R+C @(" @(" @("T@9&]E<R!N;W0@>65T('=O<FL@=VET
  496. XM:"!!4TT@8V]D90T*(R M(%=A=&-O;2!#+S,X-B Y+C @=6YD97(@3U,O,B R
  497. XM+C @(" M(&1O97,@;F]T('EE="!W;W)K('=I=&@@05--(&-O9&4-"@T*(R!3
  498. XM=7!P;W)T960@07-S96UB;&5R<SH-"B,@+2!-:6-R;W-O9G0@34%332 V+C P
  499. XM('=I=&@@35,@0RP@24)-($,L(%=A=&-O;2!##0HC("T@36EC<F]S;V9T($U!
  500. XM4TT@-2YX>"!W:71H($U3($,L(&EF('5N8V]M;65N=" B;6%S;2(@;&EN92!N
  501. XM96%R(&QI;F4@,34P#0HC("T@1TY5(&%S('=I=&@@1TY5(&=C8PT*#0HC(%1O
  502. XM('5S92P@96YT97(@(FYM86ME+V1M86ME("UF(&UA:V5F:6QE+F]S,B(@*'1H
  503. XM:7,@;6%K969I;&4@9&5P96YD<R!O;B!I=',-"B,@;F%M92!B96EN9R B;6%K
  504. XM969I;&4N;W,R(BDN#0H-"B,@061D("U$3D]?05--('1O($-&3$%'4R!A;F0@
  505. XM<F5M;W9E(&UA=&-H+F]B:B!F<F]M($]"2D\@:68@>6]U(&1O#0HC(&YO="!H
  506. XM879E(&UA<VT@;W(@;6PN#0HC($%D9" M1$193E]!3$Q/0R!T;R!!4T9,04=3
  507. XM(&EF('EO=2!H879E(&1E9FEN960@:70@:6X@=&%I;&]R+F@@;W(@0T9,04=3
  508. XM#0H-"B,@3F]T97,@;VX@,38M8FET("A-:6-R;W-O9G0@0R V+C P*2!C;VUP
  509. XM:6QA=&EO;CH-"@T*(R @(%1H92!R97-U;'1I;F<@<')O9W)A;7,@8V%N(&)E
  510. XM('5S960@=6YD97(@3U,O,B!P<F]T96-T960@;6]D92!O;FQY+@T*(R @($$@
  511. XM;&%R9V5R('-T86-K(&AA<R!T;R!B92!U<V5D(&9O<B!/4R\R(&)E8V%U<V4@
  512. XM<WES=&5M(&-A;&QS#0HC(" @=7-E(&UO<F4@<W1A8VL@=&AA;B!U;F1E<B!$
  513. XM3U,L(#AK(&ES(')E8V]M;65N9&5D(&)Y($UI8W)O<V]F="X-"B,@("!.;W1E
  514. XM('1H870@7U]35$1#7U\@:&%S('1O(&)E(&1E9FEN960@97AP;&EC:71L>2!W
  515. XM:71H($,@-BXP,"!W:&5N("U:90T*(R @(&ES(&=I=F5N+"!B96-A=7-E($UI
  516. XM8W)O<V]F="!D:7-A8FQE<R!?7U-41$-?7R!W:&5N('1H96ER(&5X=&5N<VEO
  517. XM;G,-"B,@("!A<F4@96YA8FQE9"X@5&AI<R!I<R!D:69F97)E;G0@9G)O;2!T
  518. XM:&4@0R U+C$P(&)E:&%V:6]U<BX-"@T*(R!.;W1E<R!O;B S,BUB:70@*$E"
  519. XM32!#(%-E="\R+"!7871C;VT@0R!O<B!'3E4@9V-C*2!C;VUP:6QA=&EO;CH-
  520. XM"@T*(R @(%1H92!R97-U;'1I;F<@<')O9W)A;7,@8V%N(&)E('5S960@=6YD
  521. XM97(@3U,O,B!P<F]T96-T960-"B,@("!M;V1E(&]F($]3+S(@,BXP(&]N;'DL
  522. XM(&YO="!U;F1E<B Q+G@@86YD(&YO="!U;F1E<B!$3U,N#0HC(" @270@;6%K
  523. XM97,@;F\@9&EF9F5R96YC92!I9B!?7U-41$-?7R!I<R!D969I;F5D(&]R(&YO
  524. XM="X-"B,@("!7871C;VT@0R!A;F0@24)-($,@4V5T+S(@=V]R:R!W:71H($19
  525. XM3E]!3$Q/0R!O;FQY+"!B96-A=7-E(&]F#0HC(" @0V]M<&EL97(@8G5G<RX-
  526. XM"@T*0U)94%1//0T*0TQ/04L]#0I#4D9,04<]#0HC(" J*BH@1F]R(&5N8W)Y
  527. XM<'1I;VX@=F5R<VEO;BP@<F5M;W9E('1H92 C(&%T('1H92!F<F]N="!O9B!N
  528. XM97AT(#,@;&EN97,@*BHJ#0HC0U)94%1//6-R>7!T)"A/0DHI#0HC0TQ/04L]
  529. XM>FEP8VQO86LN97AE#0HC0U)&3$%'/2U$0U)94%0-"@T*9&5F875L=#H-"@E 
  530. XM96-H;R!%;G1E<B B)"A-04M%*2 M9B!M86ME9FEL92YO<S(@;7-C(@T*"4!E
  531. XM8VAO(" @(&]R("(D*$U!2T4I("UF(&UA:V5F:6QE+F]S,B!I8FTB#0H)0&5C
  532. XM:&\@(" @;W(@(B0H34%+12D@+68@;6%K969I;&4N;W,R('=A=&-O;2(-"@E 
  533. XM96-H;R @("!O<B B)"A-04M%*2 M9B!M86ME9FEL92YO<S(@9V-C(@T*#0IM
  534. XM<V-D;W,Z#0H))"A-04M%*2 M9B!M86ME9FEL92YO<S(@>FEP<R!<#0H)0T,]
  535. XM(F-L("UN;VQO9V\@+4%#("U/86EC=" M1W,B(%P-"@E#1DQ!1U,](BU7,R M
  536. XM6F5P("0H0U)&3$%'*2 D*$90*2(@7 T*"4%3/2)M;" M;F]L;V=O(B!<#0H)
  537. XM05-&3$%'4STB+5IM("U#<"(@7 T*"4Q$1DQ!1U,](B0H1E I("U,<B M1B Q
  538. XM,# P("U&92(@7 T*(" @(" @("!,1$9,04=3,CTB+6QI;FL@+VYO92(@7 T*
  539. XM(" @(" @("!/550](BU&;R(@7 T*(" @(" @("!/0DH](BYO8FHB(%P-"@E/
  540. XM0DI!/6UA=&-H+F]B:B!<#0H@(" @(" @($]"2D\](B(-"@T*;7-C.@T*"20H
  541. XM34%+12D@+68@;6%K969I;&4N;W,R('II<',@7 T*"4-#/2)C;" M;F]L;V=O
  542. XM("U!0R M3V-E9VET("U'<R(@7 T*"4-&3$%'4STB+5<Q("U:97 @+4H@+4<R
  543. XM("0H0U)&3$%'*2 M1%]?4U1$0U]?("U$3U,R("0H1E I(B!<#0H)05,](FUL
  544. XM("UN;VQO9V\B(%P-"@E!4T9,04=3/2(M6FT@+4-P(B!<#0H)3$1&3$%'4STB
  545. XM)"A&4"D@+4QP("U&(#(P,# @+49E(B!<#0H@(" @(" @($Q$1DQ!1U,R/2(M
  546. XM;&EN:R O;F]E(B!<#0H@(" @(" @($]55#TB+49O(B!<#0H@(" @(" @($]"
  547. XM2CTB+F]B:B(@7 T*"4]"2D$];6%T8V@N;V)J(%P-"B @(" @(" @1$5&/2)Z
  548. XM:7 N9&5F(@T*#0II8FTZ#0H))"A-04M%*2 M9B!M86ME9FEL92YO<S(@>FEP
  549. XM<R!<#0H)0T,](FEC8R M42 M3R M1W,B(%P-"@E#1DQ!1U,](BU3;2 M4W Q
  550. XM("0H0U)&3$%'*2 M1$]3,B M1$193E]!3$Q/0R M1$Y/7T%332(@7 T*"4Y&
  551. XM3$%'4STB+4\M(B!<#0H)05,](FUL("UN;VQO9V\B(%P-"@E!4T9,04=3/2(M
  552. XM6FT@+4-P(B!<#0H)3$1&3$%'4STB+4(O4U0Z,3,Q,#<R("U&92(@7 T*(" @
  553. XM(" @("!,1$9,04=3,CTB(B!<#0H@(" @(" @($]55#TB+49O(B!<#0H@(" @
  554. XM(" @($]"2CTB+F]B:B(@7 T*"4]"2D$](B(@7 T*(" @(" @("!$148](GII
  555. XM<"YD968B#0H-"G=A=&-O;3H-"@DD*$U!2T4I("UF(&UA:V5F:6QE+F]S,B!Z
  556. XM:7!S(%P-"@E#0STB=V-L,S@V("UZ<2 M3W@@+7,B(%P-"@E#1DQ!1U,](BU:
  557. XM<#$@)"A#4D9,04<I("U$3U,R("U$1%E.7T%,3$]#("U$3D]?05--(B!<#0H)
  558. XM05,](FUL("UN;VQO9V\B(%P-"@E!4T9,04=3/2(M6FT@+4-P(B!<#0H)3$1&
  559. XM3$%'4STB+6LQ,S$P-S(@+7@@+49E/2(@7 T*(" @(" @("!,1$9,04=3,CTB
  560. XM(B!<#0H@(" @(" @($]55#TB+49O(B!<#0H@(" @(" @($]"2CTB+F]B:B(@
  561. XM7 T*"4]"2D$](B(-"@T*9V-C.@T*"20H34%+12D@+68@;6%K969I;&4N;W,R
  562. XM('II<',@7 T*"4-#/2)G8V,@+4\@+7,B(%P-"@E#1DQ!1U,](B0H0U)&3$%'
  563. XM*2 M1$]3,B(@7 T*"4%3/2)G8V,B(%P-"@E!4T9,04=3/2(M575N:7@B(%P-
  564. XM"@E,1$9,04=3/2(M;R B(%P-"B @(" @(" @3$1&3$%'4S(](BUL;W,R(B!<
  565. XM#0H@(" @(" @($]55#TB+6\B(%P-"B @(" @(" @3T)*/2(N;R(@7 T*"4]"
  566. XM2D$](FUA=&-H+F\B#0H-"D]"2D\@/2 @;W,R>FEP#0H-"D]"2EH@/2 @>FEP
  567. XM)"A/0DHI('II<&9I;&4D*$]"2BD@>FEP=7 D*$]"2BD@9FEL96EO)"A/0DHI
  568. XM('5T:6PD*$]"2BD@7 T*(" @(" @("!G;&]B86QS)"A/0DHI(&1E9FQA=&4D
  569. XM*$]"2BD@=')E97,D*$]"2BD@8FET<R0H3T)**2 D*$-265!43RD@7 T*"20H
  570. XM3T)*3RDD*$]"2BD-"@T*3T)*52 ]("!Z:7!F:6QE7R0H3T)**2!Z:7!U<%\D
  571. XM*$]"2BD@9FEL96EO7R0H3T)**2!U=&EL7R0H3T)**2!<#0H)9VQO8F%L<R0H
  572. XM3T)**2 D*$]"2D\I7R0H3T)**0T*#0I/0DI.(#T@('II<&YO=&4D*$]"2BD@
  573. XM)"A/0DI5*0T*3T)*0R ]("!Z:7!C;&]A:R0H3T)**2!C<GEP=%\D*$]"2BD@
  574. XM)"A/0DI5*0T*3T)*4R ]("!Z:7!S<&QI="0H3T)**2 D*$]"2E4I#0H-"BYC
  575. XM)"A/0DHI.@T*"20H0T,I("UC("0H0T9,04=3*2 D/ T*#0IZ:7!S.@EZ:7 N
  576. XM97AE('II<&YO=&4N97AE('II<'-P;&ET+F5X92 D*$-,3T%+*0T*#0IZ:7 D
  577. XM*$]"2BDZ"7II<"YC('II<"YH('II<&5R<BYH('1A:6QO<BYH(')E=FES:6]N
  578. XM+F@-"GII<&9I;&4D*$]"2BDZ"7II<&9I;&4N8R!Z:7 N:"!Z:7!E<G(N:"!T
  579. XM86EL;W(N: T*>FEP=7 D*$]"2BDZ"7II<'5P+F,@>FEP+F@@>FEP97)R+F@@
  580. XM=&%I;&]R+F@@<F5V:7-I;VXN:"!O<S)Z:7 N: T*9FEL96EO)"A/0DHI.@EF
  581. XM:6QE:6\N8R!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N:"!O<S)Z:7 N: T*=71I
  582. XM;"0H3T)**3H)=71I;"YC('II<"YH('II<&5R<BYH('1A:6QO<BYH(&]S,GII
  583. XM<"YH#0IG;&]B86QS)"A/0DHI.@EG;&]B86QS+F,@>FEP+F@@>FEP97)R+F@@
  584. XM=&%I;&]R+F@-"F1E9FQA=&4D*$]"2BDZ"61E9FQA=&4N8R!Z:7 N:"!Z:7!E
  585. XM<G(N:"!T86EL;W(N: T*=')E97,D*$]"2BDZ"71R965S+F,@>FEP+F@@>FEP
  586. XM97)R+F@@=&%I;&]R+F@-"@DD*$-#*2 M8R D*$-&3$%'4RD@)"A.1DQ!1U,I
  587. XM("0J+F,-"F)I=',D*$]"2BDZ"6)I=',N8R!Z:7 N:"!Z:7!E<G(N:"!T86EL
  588. XM;W(N: T*8W)Y<'0D*$]"2BDZ"6-R>7!T+F,@>FEP+F@@>FEP97)R+F@@=&%I
  589. XM;&]R+F@-"F]S,GII<"0H3T)**3H);W,R>FEP+F,@;W,R>FEP+F@-"@T*;6%T
  590. XM8V@N;V)J.@EM871C:"YA<VT-"@DD*$%3*2 M8R D*$%31DQ!1U,I("0J+F%S
  591. XM;0T*(R!U<V4@=&AE(&9O;&QO=VEN9R!F;W(@34%332 U+C P(&EN<W1E860@
  592. XM;V8@-BXP, T*(PEM87-M("UM;" M=" D*BYA<VT[#0H-"FUA=&-H,S(N;V)J
  593. XM.@EM871C:#,R+F%S;0T*"20H05,I("UC("0H05-&3$%'4RD@)"HN87-M#0H-
  594. XM"FUA=&-H+F\Z"6UA=&-H+G,-"B,@;F]T92!T:&4@=7!P97)C87-E(%,@9F]R
  595. XM(&=C8R!T;R!R=6X@;6%T8V@N<R!T:')O=6=H(&-P<"$-"@DD*$%3*2 M8R D
  596. XM*$%31DQ!1U,I("0J+E,-"@T*>FEP8VQO86LD*$]"2BDZ"7II<&-L;V%K+F,@
  597. XM>FEP+F@@>FEP97)R+F@@=&%I;&]R+F@@<F5V:7-I;VXN: T*>FEP;F]T920H
  598. XM3T)**3H)>FEP;F]T92YC('II<"YH('II<&5R<BYH('1A:6QO<BYH(')E=FES
  599. XM:6]N+F@-"GII<'-P;&ET)"A/0DHI.B!Z:7!S<&QI="YC('II<"YH('II<&5R
  600. XM<BYH('1A:6QO<BYH(')E=FES:6]N+F@-"@T*>FEP9FEL95\D*$]"2BDZ"7II
  601. XM<&9I;&4N8R!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N: T*"20H0T,I("UC("0H
  602. XM0T9,04=3*2 M1%5424P@)"A/550I)$ @>FEP9FEL92YC#0H-"GII<'5P7R0H
  603. XM3T)**3H)>FEP=7 N8R!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N: T*"20H0T,I
  604. XM("UC("0H0T9,04=3*2 M1%5424P@)"A/550I)$ @>FEP=7 N8PT*#0IF:6QE
  605. XM:6]?)"A/0DHI.@EF:6QE:6\N8R!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N: T*
  606. XM"20H0T,I("UC("0H0T9,04=3*2 M1%5424P@)"A/550I)$ @9FEL96EO+F,-
  607. XM"@T*=71I;%\D*$]"2BDZ"75T:6PN8R!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N
  608. XM:"!O<S)Z:7 N: T*"20H0T,I("UC("0H0T9,04=3*2 M1%5424P@)"A/550I
  609. XM)$ @=71I;"YC#0H-"F-R>7!T7R0H3T)**3H)8W)Y<'0N8R!Z:7 N:"!Z:7!E
  610. XM<G(N:"!T86EL;W(N: T*"20H0T,I("UC("0H0T9,04=3*2 M1%5424P@)"A/
  611. XM550I)$ @8W)Y<'0N8PT*#0IO<S)Z:7!?)"A/0DHI.B!O<S)Z:7 N8R!O<S)Z
  612. XM:7 N: T*"20H0T,I("UC("0H0T9,04=3*2 M1%5424P@)"A/550I)$ @;W,R
  613. XM>FEP+F,-"@T*>FEP+F5X93H@)"A/0DI:*2 D*$]"2DDI("0H3T)*02D@)"A$
  614. XM148I#0H))"A#0RD@)"A,1$9,04=3*21 ("0H1$5&*2 D*$]"2EHI("0H3T)*
  615. XM22D@)"A/0DI!*2 D*$Q$1DQ!1U,R*0T*#0IZ:7!C;&]A:RYE>&4Z("0H3T)*
  616. XM0RD@)"A$148I#0H))"A#0RD@)"A,1$9,04=3*21 ("0H1$5&*2 D*$]"2D,I
  617. XM("0H3$1&3$%'4S(I#0H-"GII<&YO=&4N97AE.B D*$]"2DXI("0H1$5&*0T*
  618. XM"20H0T,I("0H3$1&3$%'4RDD0" D*$1%1BD@)"A/0DI.*2 D*$Q$1DQ!1U,R
  619. XM*0T*#0IZ:7!S<&QI="YE>&4Z("0H3T)*4RD@)"A$148I#0H))"A#0RD@)"A,
  620. XF1$9,04=3*21 ("0H1$5&*2 D*$]"2E,I("0H3$1&3$%'4S(I#0I#
  621. Xend
  622. END_OF_FILE
  623.  if test 8519 -ne `wc -c <'os2/makefile.os2.UU'`; then
  624.     echo shar: \"'os2/makefile.os2.UU'\" unpacked with wrong size!
  625.   else
  626.     echo shar: Uudecoding \"'os2/makefile.os2'\" \(6158 characters\)
  627.     cat os2/makefile.os2.UU | uudecode
  628.     if test 6158 -ne `wc -c <'os2/makefile.os2'`; then
  629.       echo shar: \"'os2/makefile.os2'\" uudecoded with wrong size!
  630.     else
  631.       rm os2/makefile.os2.UU
  632.     fi
  633.   fi
  634.   # end of 'os2/makefile.os2.UU'
  635. fi
  636. if test -f 'vms/VMSmunch.c' -a "${1}" != "-c" ; then 
  637.   echo shar: Will not clobber existing file \"'vms/VMSmunch.c'\"
  638. else
  639.   echo shar: Extracting \"'vms/VMSmunch.c'\" \(11629 characters\)
  640.   sed "s/^X//" >'vms/VMSmunch.c' <<'END_OF_FILE'
  641. X/*---------------------------------------------------------------------------
  642. X
  643. X  VMSmunch.c                    version 1.2                     28 Apr 1992
  644. X
  645. X  This routine is a blatant and unrepentent appropriation of all the nasty
  646. X  and difficult-to-do and complicated VMS shenanigans which Joe Meadows has
  647. X  so magnificently captured in his FILE utility.  Not only that, it's even
  648. X  allowed! (see below).  But let it be clear at the outset that Joe did all
  649. X  the work; yea, verily, he is truly a godlike unit.
  650. X
  651. X  The appropriations and modifications herein were performed primarily by
  652. X  him known as "Cave Newt," although the Info-ZIP working group probably had
  653. X  their fingers in it somewhere along the line.  The idea is to put the raw
  654. X  power of Joe's original routine at the disposal of various routines used
  655. X  by UnZip (and Zip, possibly), not least among them the utime() function.
  656. X  Read on for details...
  657. X
  658. X  ---------------------------------------------------------------------------
  659. X
  660. X  Usage (i.e., "interface," in geek-speak):
  661. X
  662. X     int VMSmunch( char *filename, int action, char *ptr );
  663. X
  664. X     filename   the name of the file on which to be operated, obviously
  665. X     action     an integer which specifies what action to take
  666. X     ptr        pointer to any extra item which may be needed (else NULL)
  667. X
  668. X  The possible values for the action argument are as follows:
  669. X
  670. X     GET_TIMES      get the creation and revision dates of filename; ptr
  671. X                    must point to an empty VMStimbuf struct, as defined below
  672. X                    (with room for at least 24 characters, including term.)
  673. X     SET_TIMES      set the creation and revision dates of filename (utime
  674. X                    option); ptr must point to a valid VMStimbuf struct,
  675. X                    as defined below
  676. X     GET_RTYPE      get the record type of filename; ptr must point to an
  677. X                    integer which, on return, is set to the type (as defined
  678. X                    in VMSmunch.h:  FAT$C_* defines)
  679. X     CHANGE_RTYPE   change the record type to that specified by the integer
  680. X                    to which ptr points; save the old record type (later
  681. X                    saves overwrite earlier ones)
  682. X     RESTORE_RTYPE  restore the record type to the previously saved value;
  683. X                    or, if none, set it to "fixed-length, 512-byte" record
  684. X                    format (ptr not used)
  685. X
  686. X  ---------------------------------------------------------------------------
  687. X
  688. X  Comments from FILE.C, a utility to modify file characteristics:
  689. X
  690. X     Written by Joe Meadows Jr, at the Fred Hutchinson Cancer Research Center
  691. X     BITNET: JOE@FHCRCVAX
  692. X     PHONE: (206) 467-4970
  693. X
  694. X     There are no restrictions on this code, you may sell it, include it 
  695. X     with any commercial package, or feed it to a whale.. However, I would 
  696. X     appreciate it if you kept this comment in the source code so that anyone
  697. X     receiving this code knows who to contact in case of problems. Note that 
  698. X     I do not demand this condition..
  699. X
  700. X  ---------------------------------------------------------------------------*/
  701. X
  702. X
  703. X
  704. X
  705. X/*****************************/
  706. X/*  Includes, Defines, etc.  */
  707. X/*****************************/
  708. X
  709. X#include <descrip.h>
  710. X#include <rms.h>
  711. X#include <stdio.h>
  712. X#include <iodef.h>
  713. X#include <atrdef.h>   /* this gets created with the c3.0 compiler */
  714. X#include <fibdef.h>   /* this gets created with the c3.0 compiler */
  715. X
  716. X#include "VMSmunch.h"  /* GET/SET_TIMES, RTYPE, fatdef.h, etc. */
  717. X
  718. X#define RTYPE     fat$r_rtype_overlay.fat$r_rtype_bits
  719. X#define RATTRIB   fat$r_rattrib_overlay.fat$r_rattrib_bits
  720. X
  721. Xstatic void asctim();
  722. Xstatic void bintim();
  723. X
  724. Xstruct VMStimbuf {      /* VMSmunch */
  725. X    char *actime;       /* VMS revision date, ASCII format */
  726. X    char *modtime;      /* VMS creation date, ASCII format */
  727. X};
  728. X
  729. X/* from <ssdef.h> */
  730. X#ifndef SS$_NORMAL
  731. X#  define SS$_NORMAL    1
  732. X#  define SS$_BADPARAM  20
  733. X#endif
  734. X
  735. X
  736. X
  737. X
  738. X
  739. X/*************************/
  740. X/*  Function VMSmunch()  */
  741. X/*************************/
  742. X
  743. Xint VMSmunch( filename, action, ptr )
  744. X    char  *filename, *ptr;
  745. X    int   action;
  746. X{
  747. X
  748. X    /* original file.c variables */
  749. X
  750. X    static struct FAB Fab;
  751. X    static struct NAM Nam;
  752. X    static struct fibdef Fib; /* short fib */
  753. X
  754. X    static struct dsc$descriptor FibDesc =
  755. X      {sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,&Fib};
  756. X    static struct dsc$descriptor_s DevDesc =
  757. X      {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
  758. X    static struct fatdef Fat;
  759. X    static union {
  760. X      struct fchdef fch;
  761. X      long int dummy;
  762. X    } uchar;
  763. X    static struct fjndef jnl;
  764. X    static long int Cdate[2],Rdate[2],Edate[2],Bdate[2];
  765. X    static short int revisions;
  766. X    static unsigned long uic;
  767. X    static union {
  768. X      unsigned short int value;
  769. X      struct {
  770. X        unsigned system : 4;
  771. X        unsigned owner : 4;
  772. X        unsigned group : 4;
  773. X        unsigned world : 4;
  774. X      } bits;
  775. X    } prot;
  776. X
  777. X    static struct atrdef Atr[] = {
  778. X      {sizeof(Fat),ATR$C_RECATTR,&Fat},        /* record attributes */
  779. X      {sizeof(uchar),ATR$C_UCHAR,&uchar},      /* File characteristics */
  780. X      {sizeof(Cdate),ATR$C_CREDATE,&Cdate[0]}, /* Creation date */
  781. X      {sizeof(Rdate),ATR$C_REVDATE,&Rdate[0]}, /* Revision date */
  782. X      {sizeof(Edate),ATR$C_EXPDATE,&Edate[0]}, /* Expiration date */
  783. X      {sizeof(Bdate),ATR$C_BAKDATE,&Bdate[0]}, /* Backup date */
  784. X      {sizeof(revisions),ATR$C_ASCDATES,&revisions}, /* number of revisions */
  785. X      {sizeof(prot),ATR$C_FPRO,&prot},         /* file protection  */
  786. X      {sizeof(uic),ATR$C_UIC,&uic},            /* file owner */
  787. X      {sizeof(jnl),ATR$C_JOURNAL,&jnl},        /* journal flags */
  788. X      {0,0,0}
  789. X    } ;
  790. X
  791. X    static char EName[NAM$C_MAXRSS];
  792. X    static char RName[NAM$C_MAXRSS];
  793. X    static struct dsc$descriptor_s FileName =
  794. X      {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  795. X    static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  796. X    static short int DevChan;
  797. X    static short int iosb[4];
  798. X
  799. X    static long int i,status;
  800. X/*  static char *retval;  */
  801. X
  802. X
  803. X    /* new VMSmunch variables */
  804. X
  805. X    static int  old_rtype=FAT$C_FIXED;   /* storage for record type */
  806. X
  807. X
  808. X
  809. X/*---------------------------------------------------------------------------
  810. X    Initialize attribute blocks, parse filename, resolve any wildcards, and
  811. X    get the file info.
  812. X  ---------------------------------------------------------------------------*/
  813. X
  814. X    /* initialize RMS structures, we need a NAM to retrieve the FID */
  815. X    Fab = cc$rms_fab;
  816. X    Fab.fab$l_fna = filename;
  817. X    Fab.fab$b_fns = strlen(filename);
  818. X    Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
  819. X    Nam = cc$rms_nam;
  820. X    Nam.nam$l_esa = &EName; /* expanded filename */
  821. X    Nam.nam$b_ess = sizeof(EName);
  822. X    Nam.nam$l_rsa = &RName; /* resultant filename */
  823. X    Nam.nam$b_rss = sizeof(RName);
  824. X
  825. X    /* do $PARSE and $SEARCH here */
  826. X    status = sys$parse(&Fab);
  827. X    if (!(status & 1)) return(status);
  828. X
  829. X    /* search for the first file.. If none signal error */
  830. X    status = sys$search(&Fab);
  831. X    if (!(status & 1)) return(status);
  832. X
  833. X    while (status & 1) {
  834. X        /* initialize Device name length, note that this points into the NAM
  835. X           to get the device name filled in by the $PARSE, $SEARCH services */
  836. X        DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
  837. X
  838. X        status = sys$assign(&DevDesc,&DevChan,0,0);
  839. X        if (!(status & 1)) return(status);
  840. X
  841. X        FileName.dsc$a_pointer = Nam.nam$l_name;
  842. X        FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
  843. X
  844. X        /* Initialize the FIB */
  845. X        for (i=0;i<3;i++)
  846. X            Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
  847. X        for (i=0;i<3;i++)
  848. X            Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
  849. X
  850. X        /* Use the IO$_ACCESS function to return info about the file */
  851. X        /* Note, used this way, the file is not opened, and the expiration */
  852. X        /* and revision dates are not modified */
  853. X        status = sys$qiow(0,DevChan,IO$_ACCESS,&iosb,0,0,
  854. X                          &FibDesc,&FileName,0,0,&Atr,0);
  855. X        if (!(status & 1)) return(status);
  856. X        status = iosb[0];
  857. X        if (!(status & 1)) return(status);
  858. X
  859. X    /*-----------------------------------------------------------------------
  860. X        We have the current information from the file:  now see what user
  861. X        wants done with it.
  862. X      -----------------------------------------------------------------------*/
  863. X
  864. X        switch (action) {
  865. X
  866. X          case GET_TIMES:
  867. X              asctim(((struct VMStimbuf *)ptr)->modtime, Cdate);
  868. X              asctim(((struct VMStimbuf *)ptr)->actime, Rdate);
  869. X              break;
  870. X
  871. X          case SET_TIMES:
  872. X              bintim(((struct VMStimbuf *)ptr)->modtime, Cdate);
  873. X              bintim(((struct VMStimbuf *)ptr)->actime, Rdate);
  874. X              break;
  875. X
  876. X          case GET_RTYPE:   /* non-modifying */
  877. X              *(int *)ptr = Fat.RTYPE.fat$v_rtype;
  878. X              return RMS$_NORMAL;     /* return to user */
  879. X              break;
  880. X
  881. X          case CHANGE_RTYPE:
  882. X              old_rtype = Fat.RTYPE.fat$v_rtype;         /* save current one */
  883. X              if ((*(int *)ptr < FAT$C_UNDEFINED) || 
  884. X                  (*(int *)ptr > FAT$C_STREAMCR))
  885. X                  Fat.RTYPE.fat$v_rtype = FAT$C_STREAMLF;  /* Unix I/O happy */
  886. X              else
  887. X                  Fat.RTYPE.fat$v_rtype = *(int *)ptr;
  888. X              break;
  889. X
  890. X          case RESTORE_RTYPE:
  891. X              Fat.RTYPE.fat$v_rtype = old_rtype;
  892. X              break;
  893. X
  894. X          default:
  895. X              return SS$_BADPARAM;   /* anything better? */
  896. X        }
  897. X
  898. X    /*-----------------------------------------------------------------------
  899. X        Go back and write modified data to the file header.
  900. X      -----------------------------------------------------------------------*/
  901. X
  902. X        /* note, part of the FIB was cleared by earlier QIOW, so reset it */
  903. X        Fib.fib$r_acctl_overlay.fib$l_acctl = FIB$M_NORECORD;
  904. X        for (i=0;i<3;i++)
  905. X            Fib.fib$r_fid_overlay.fib$w_fid[i]=Nam.nam$w_fid[i];
  906. X        for (i=0;i<3;i++)
  907. X            Fib.fib$r_did_overlay.fib$w_did[i]=Nam.nam$w_did[i];
  908. X
  909. X        /* Use the IO$_MODIFY function to change info about the file */
  910. X        /* Note, used this way, the file is not opened, however this would */
  911. X        /* normally cause the expiration and revision dates to be modified. */
  912. X        /* Using FIB$M_NORECORD prohibits this from happening. */
  913. X        status = sys$qiow(0,DevChan,IO$_MODIFY,&iosb,0,0,
  914. X                          &FibDesc,&FileName,0,0,&Atr,0);
  915. X        if (!(status & 1)) return(status);
  916. X
  917. X        status = iosb[0];
  918. X        if (!(status & 1)) return(status);
  919. X
  920. X        status = sys$dassgn(DevChan);
  921. X        if (!(status & 1)) return(status);
  922. X
  923. X        /* look for next file, if none, no big deal.. */
  924. X        status = sys$search(&Fab);
  925. X    }
  926. X} /* end function VMSmunch() */
  927. X
  928. X
  929. X
  930. X
  931. X
  932. X/***********************/
  933. X/*  Function bintim()  */
  934. X/***********************/
  935. X
  936. Xvoid asctim(time,binval)   /* convert 64-bit binval to string, put in time */
  937. X    char *time;
  938. X    long int binval[2];
  939. X{
  940. X    static struct dsc$descriptor date_str={23,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  941. X      /* dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer */
  942. X    date_str.dsc$a_pointer = time;
  943. X    sys$asctim(0, &date_str, binval, 0);
  944. X    time[23] = '\0';
  945. X}
  946. X
  947. X
  948. X
  949. X
  950. X
  951. X/***********************/
  952. X/*  Function bintim()  */
  953. X/***********************/
  954. X
  955. Xvoid bintim(time,binval)   /* convert time string to 64 bits, put in binval */
  956. X    char *time;
  957. X    long int binval[2];
  958. X{
  959. X    static struct dsc$descriptor date_str={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  960. X
  961. X    date_str.dsc$w_length = strlen(time);
  962. X    date_str.dsc$a_pointer = time;
  963. X    sys$bintim(&date_str, binval);
  964. X}
  965. END_OF_FILE
  966.   if test 11629 -ne `wc -c <'vms/VMSmunch.c'`; then
  967.     echo shar: \"'vms/VMSmunch.c'\" unpacked with wrong size!
  968.   fi
  969.   # end of 'vms/VMSmunch.c'
  970. fi
  971. if test -f 'zipnote.c' -a "${1}" != "-c" ; then 
  972.   echo shar: Will not clobber existing file \"'zipnote.c'\"
  973. else
  974.   echo shar: Extracting \"'zipnote.c'\" \(9993 characters\)
  975.   sed "s/^X//" >'zipnote.c' <<'END_OF_FILE'
  976. X/*
  977. X
  978. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  979. X Kai Uwe Rommel and Igor Mandrichenko.
  980. X Permission is granted to any individual or institution to use, copy, or
  981. X redistribute this software so long as all of the original files are included
  982. X unmodified, that it is not sold for profit, and that this copyright notice
  983. X is retained.
  984. X
  985. X*/
  986. X
  987. X/*
  988. X *  zipnote.c by Mark Adler.
  989. X */
  990. X
  991. X#define UTIL
  992. X#include "revision.h"
  993. X#include "zip.h"
  994. X#include <signal.h>
  995. X
  996. X
  997. X/* Character to mark zip entry names in the comment file */
  998. X#define MARK '@'
  999. X
  1000. X/* Temporary zip file name and file pointer */
  1001. Xlocal char *tempzip;
  1002. Xlocal FILE *tempzf;
  1003. X
  1004. X
  1005. X/* Local functions */
  1006. X#ifdef PROTO
  1007. X   local void handler(int);
  1008. X   local void license(void);
  1009. X   local void help(void);
  1010. X   local void putclean(char *, int);
  1011. X   local int catalloc(char * far *, char *);
  1012. X   void main(int, char **);
  1013. X#endif /* PROTO */
  1014. X
  1015. X
  1016. X
  1017. Xvoid err(c, h)
  1018. Xint c;                  /* error code from the ZE_ class */
  1019. Xchar *h;                /* message about how it happened */
  1020. X/* Issue a message for the error, clean up files and memory, and exit. */
  1021. X{
  1022. X  if (PERR(c))
  1023. X    perror("zipnote error");
  1024. X  fprintf(stderr, "zipnote error: %s (%s)\n", errors[c-1], h);
  1025. X  if (tempzf != NULL)
  1026. X    fclose(tempzf);
  1027. X  if (tempzip != NULL)
  1028. X  {
  1029. X    destroy(tempzip);
  1030. X    free((voidp *)tempzip);
  1031. X  }
  1032. X  if (zipfile != NULL)
  1033. X    free((voidp *)zipfile);
  1034. X#ifdef VMS
  1035. X  exit(0);
  1036. X#else /* !VMS */
  1037. X  exit(c);
  1038. X#endif /* ?VMS */
  1039. X}
  1040. X
  1041. X
  1042. Xlocal void handler(s)
  1043. Xint s;                  /* signal number (ignored) */
  1044. X/* Upon getting a user interrupt, abort cleanly using err(). */
  1045. X{
  1046. X#ifndef MSDOS
  1047. X  putc('\n', stderr);
  1048. X#endif /* !MSDOS */
  1049. X  err(ZE_ABORT, "aborting");
  1050. X  s++;                                  /* keep some compilers happy */
  1051. X}
  1052. X
  1053. X
  1054. Xvoid warn(a, b)
  1055. Xchar *a, *b;            /* message strings juxtaposed in output */
  1056. X/* Print a warning message to stderr and return. */
  1057. X{
  1058. X  fprintf(stderr, "zipnote warning: %s%s\n", a, b);
  1059. X}
  1060. X
  1061. X
  1062. Xlocal void license()
  1063. X/* Print license information to stdout. */
  1064. X{
  1065. X  extent i;             /* counter for copyright array */
  1066. X
  1067. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
  1068. X    printf(copyright[i], "zipnote");
  1069. X    putchar('\n');
  1070. X  }
  1071. X  for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
  1072. X    puts(disclaimer[i]);
  1073. X}
  1074. X
  1075. X
  1076. Xlocal void help()
  1077. X/* Print help (along with license info) to stdout. */
  1078. X{
  1079. X  extent i;             /* counter for help array */
  1080. X
  1081. X  /* help array */
  1082. X  static char *text[] = {
  1083. X"",
  1084. X"ZipNote %d.%d (%s)",
  1085. X"Usage:  zipnote [-w] [-b path] zipfile",
  1086. X"  the default action is to write the comments in zipfile to stdout",
  1087. X"  -w   write the zipfile comments from stdin",
  1088. X"  -b   use \"path\" for the temporary zip file",
  1089. X"  -h   show this help               -L   show software license",
  1090. X"",
  1091. X"Example:",
  1092. X#ifdef VMS
  1093. X"     define/user sys$output foo.tmp",
  1094. X"     zipnote foo.zip",
  1095. X"     edit foo.tmp",
  1096. X"     ... then you edit the comments, save, and exit ...",
  1097. X"     define/user sys$input foo.tmp",
  1098. X"     zipnote -w foo.zip"
  1099. X#else /* !VMS */
  1100. X"     zipnote foo.zip > foo.tmp",
  1101. X"     ed foo.tmp",
  1102. X"     ... then you edit the comments, save, and exit ...",
  1103. X"     zipnote -w foo.zip < foo.tmp"
  1104. X#endif /* ?VMS */
  1105. X  };
  1106. X
  1107. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
  1108. X    printf(copyright[i], "zipnote");
  1109. X    putchar('\n');
  1110. X  }
  1111. X  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
  1112. X  {
  1113. X    printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
  1114. X    putchar('\n');
  1115. X  }
  1116. X}
  1117. X
  1118. X
  1119. Xlocal void putclean(s, n)
  1120. Xchar *s;                /* string to write to stdout */
  1121. Xint n;                  /* length of string */
  1122. X/* Write the string s to stdout, filtering out control characters that are
  1123. X   not tab or newline (mainly to remove carriage returns), and prefix MARK's
  1124. X   and backslashes with a backslash.  Also, terminate with a newline if
  1125. X   needed. */
  1126. X{
  1127. X  int c;                /* next character in string */
  1128. X  int e;                /* last character written */
  1129. X
  1130. X  e = '\n';                     /* if empty, write nothing */
  1131. X  while (n--)
  1132. X  {
  1133. X    c = *(uch *)s++;
  1134. X    if (c == MARK || c == '\\')
  1135. X      putchar('\\');
  1136. X    if (c >= ' ' || c == '\t' || c == '\n')
  1137. X      putchar(e = c);
  1138. X  }
  1139. X  if (e != '\n')
  1140. X    putchar('\n');
  1141. X}
  1142. X
  1143. X
  1144. Xlocal int catalloc(a, s)
  1145. Xchar * far *a;          /* pointer to a pointer to a malloc'ed string */
  1146. Xchar *s;                /* string to concatenate on a */
  1147. X/* Concatentate the string s to the malloc'ed string pointed to by a.
  1148. X   Preprocess s by removing backslash escape characters. */
  1149. X{
  1150. X  char *p;              /* temporary pointer */
  1151. X  char *q;              /* temporary pointer */
  1152. X
  1153. X  for (p = q = s; *q; *p++ = *q++)
  1154. X    if (*q == '\\' && *(q+1))
  1155. X      q++;
  1156. X  *p = 0;
  1157. X  if ((p = malloc(strlen(*a) + strlen(s) + 3)) == NULL)
  1158. X    return ZE_MEM;
  1159. X  strcat(strcat(strcpy(p, *a), **a ? "\r\n" : ""), s);
  1160. X  free((voidp *)*a);
  1161. X  *a = p;
  1162. X  return ZE_OK;
  1163. X}
  1164. X
  1165. X
  1166. Xvoid main(argc, argv)
  1167. Xint argc;               /* number of tokens in command line */
  1168. Xchar **argv;            /* command line tokens */
  1169. X/* Write the comments in the zipfile to stdout, or read them from stdin. */
  1170. X{
  1171. X  char a[FNMAX+1];      /* input line buffer */
  1172. X  ulg c;                /* start of central directory */
  1173. X  int k;                /* next argument type */
  1174. X  char *q;              /* steps through option arguments */
  1175. X  int r;                /* arg counter, temporary variable */
  1176. X  ulg s;                /* length of central directory */
  1177. X  int t;                /* attributes of zip file */
  1178. X  int w;                /* true if updating zip file from stdin */
  1179. X  FILE *x, *y;          /* input and output zip files */
  1180. X  struct zlist far *z;  /* steps through zfiles linked list */
  1181. X
  1182. X
  1183. X  /* If no args, show help */
  1184. X  if (argc == 1)
  1185. X  {
  1186. X    help();
  1187. X    exit(0);
  1188. X  }
  1189. X
  1190. X  init_upper();           /* build case map table */
  1191. X
  1192. X  /* Go through args */
  1193. X  zipfile = tempzip = NULL;
  1194. X  tempzf = NULL;
  1195. X  signal(SIGINT, handler);
  1196. X  signal(SIGTERM, handler);
  1197. X  k = w = 0;
  1198. X  for (r = 1; r < argc; r++)
  1199. X    if (*argv[r] == '-')
  1200. X      if (argv[r][1])
  1201. X        for (q = argv[r]+1; *q; q++)
  1202. X          switch(*q)
  1203. X          {
  1204. X            case 'b':   /* Specify path for temporary file */
  1205. X              if (k)
  1206. X                err(ZE_PARMS, "use -b before zip file name");
  1207. X              else
  1208. X                k = 1;          /* Next non-option is path */
  1209. X              break;
  1210. X            case 'h':   /* Show help */
  1211. X              help();  exit(0);
  1212. X            case 'l':  case 'L':  /* Show copyright and disclaimer */
  1213. X              license();  exit(0);
  1214. X            case 'w':
  1215. X              w = 1;  break;
  1216. X            default:
  1217. X              err(ZE_PARMS, "unknown option");
  1218. X          }
  1219. X      else
  1220. X        err(ZE_PARMS, "zip file cannot be stdin");
  1221. X    else
  1222. X      if (k == 0)
  1223. X        if (zipfile == NULL)
  1224. X        {
  1225. X          if ((zipfile = ziptyp(argv[r])) == NULL)
  1226. X            err(ZE_MEM, "was processing arguments");
  1227. X        }
  1228. X        else
  1229. X          err(ZE_PARMS, "can only specify one zip file");
  1230. X      else
  1231. X      {
  1232. X        tempath = argv[r];
  1233. X        k = 0;
  1234. X      }
  1235. X  if (zipfile == NULL)
  1236. X    err(ZE_PARMS, "need to specify zip file");
  1237. X
  1238. X  /* Read zip file */
  1239. X  if ((r = readzipfile()) != ZE_OK)
  1240. X    err(r, zipfile);
  1241. X  if (zfiles == NULL)
  1242. X    err(ZE_NAME, zipfile);
  1243. X
  1244. X  /* Put comments to stdout, if not -w */
  1245. X  if (!w)
  1246. X  {
  1247. X    for (z = zfiles; z != NULL; z = z->nxt)
  1248. X    {
  1249. X      printf("%c %s\n", MARK, z->zname);
  1250. X      putclean(z->comment, z->com);
  1251. X      putchar(MARK);  putchar('\n');
  1252. X    }
  1253. X    putchar(MARK);  putchar('\n');
  1254. X    putclean(zcomment, zcomlen);
  1255. X    exit(ZE_OK);
  1256. X  }
  1257. X
  1258. X  /* If updating comments, make sure zip file is writeable */
  1259. X  if ((x = fopen(zipfile, "a")) == NULL)
  1260. X    err(ZE_CREAT, zipfile);
  1261. X  fclose(x);
  1262. X  t = getfileattr(zipfile);
  1263. X
  1264. X  /* Process stdin, replacing comments */
  1265. X  for (z = zfiles; z != NULL; z = z->nxt)
  1266. X  {
  1267. X    if (gets(a) == NULL || a[0] != MARK || a[1] != ' ' ||
  1268. X        strcmp(a + 2, z->zname))
  1269. X      err(ZE_NOTE, "missing entry name");
  1270. X    if (z->com)
  1271. X      free((voidp *)z->comment);
  1272. X    z->comment = malloc(1);  *(z->comment) = 0;
  1273. X    while (gets(a) != NULL && *a != MARK)
  1274. X      if ((r = catalloc(&(z->comment), a)) != ZE_OK)
  1275. X        err(r, "was building new comments");
  1276. X    if (a[1])
  1277. X      err(ZE_NOTE, "missing comment end line");
  1278. X    z->com = strlen(z->comment);
  1279. X  }
  1280. X  if (gets(a) == NULL || a[0] != MARK || a[1])
  1281. X    err(ZE_NOTE, "missing zip file comment marker line");
  1282. X  zcomment = malloc(1);  *zcomment = 0;
  1283. X  while (gets(a) != NULL)
  1284. X    if ((r = catalloc(&zcomment, a)) != ZE_OK)
  1285. X      err(r, "was building new comments");
  1286. X  zcomlen = strlen(zcomment);
  1287. X
  1288. X  /* Open output zip file for writing */
  1289. X  if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
  1290. X    err(ZE_TEMP, tempzip);
  1291. X
  1292. X  /* Open input zip file again, copy preamble if any */
  1293. X  if ((x = fopen(zipfile, FOPR)) == NULL)
  1294. X    err(ZE_NAME, zipfile);
  1295. X  if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
  1296. X    err(r, r == ZE_TEMP ? tempzip : zipfile);
  1297. X
  1298. X  /* Go through local entries, copying them over as is */
  1299. X  for (z = zfiles; z != NULL; z = z->nxt)
  1300. X    if ((r = zipcopy(z, x, y)) != ZE_OK)
  1301. X      err(r, "was copying an entry");
  1302. X  fclose(x);
  1303. X
  1304. X  /* Write central directory and end of central directory with new comments */
  1305. X  if ((c = ftell(y)) == -1L)    /* get start of central */
  1306. X    err(ZE_TEMP, tempzip);
  1307. X  for (z = zfiles; z != NULL; z = z->nxt)
  1308. X    if ((r = putcentral(z, y)) != ZE_OK)
  1309. X      err(r, tempzip);
  1310. X  if ((s = ftell(y)) == -1L)    /* get end of central */
  1311. X    err(ZE_TEMP, tempzip);
  1312. X  s -= c;                       /* compute length of central */
  1313. X  if ((r = putend((int)zcount, s, c, zcomlen, zcomment, y)) != ZE_OK)
  1314. X    err(r, tempzip);
  1315. X  tempzf = NULL;
  1316. X  if (fclose(y))
  1317. X    err(ZE_TEMP, tempzip);
  1318. X  if ((r = replace(zipfile, tempzip)) != ZE_OK)
  1319. X  {
  1320. X    warn("new zip file left as: ", tempzip);
  1321. X    free((voidp *)tempzip);
  1322. X    tempzip = NULL;
  1323. X    err(r, "was replacing the original zip file");
  1324. X  }
  1325. X  free((voidp *)tempzip);
  1326. X  tempzip = NULL;
  1327. X  setfileattr(zipfile, t);
  1328. X  free((voidp *)zipfile);
  1329. X  zipfile = NULL;
  1330. X
  1331. X  /* Done! */
  1332. X  exit(ZE_OK);
  1333. X}
  1334. END_OF_FILE
  1335.   if test 9993 -ne `wc -c <'zipnote.c'`; then
  1336.     echo shar: \"'zipnote.c'\" unpacked with wrong size!
  1337.   fi
  1338.   # end of 'zipnote.c'
  1339. fi
  1340. if test -f 'zipup.c' -a "${1}" != "-c" ; then 
  1341.   echo shar: Will not clobber existing file \"'zipup.c'\"
  1342. else
  1343.   echo shar: Extracting \"'zipup.c'\" \(12100 characters\)
  1344.   sed "s/^X//" >'zipup.c' <<'END_OF_FILE'
  1345. X/*
  1346. X
  1347. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  1348. X Kai Uwe Rommel and Igor Mandrichenko.
  1349. X Permission is granted to any individual or institution to use, copy, or
  1350. X redistribute this software so long as all of the original files are included
  1351. X unmodified, that it is not sold for profit, and that this copyright notice
  1352. X is retained.
  1353. X
  1354. X*/
  1355. X
  1356. X/*
  1357. X *  zipup.c by Mark Adler. Includes modifications by Jean-loup Gailly.
  1358. X */
  1359. X
  1360. X#define NOCPYRT         /* this is not a main module */
  1361. X#include <ctype.h>
  1362. X#include "zip.h"
  1363. X#include "revision.h"
  1364. X#ifdef OS2
  1365. X#  include "os2zip.h"
  1366. X#endif
  1367. X
  1368. X/* Use the raw functions for MSDOS and Unix to save on buffer space.
  1369. X   They're not used for VMS since it doesn't work (raw is weird on VMS).
  1370. X   (This sort of stuff belongs in fileio.c, but oh well.) */
  1371. X#ifdef VMS
  1372. X#  define fhow "r"
  1373. X#  define fbad NULL
  1374. X   typedef void *ftype;
  1375. X#  define zopen(n,p)   (vms_native?vms_open(n)    :(ftype)fopen((n),(p)))
  1376. X#  define zread(f,b,n) (vms_native?vms_read(f,b,n):fread((b),1,(n),(FILE*)(f)))
  1377. X#  define zclose(f)    (vms_native?vms_close(f)   :fclose((FILE*)(f)))
  1378. X#  define zerr(f)      (vms_native?vms_error(f)   :ferror((FILE*)(f)))
  1379. X#  define zstdin stdin
  1380. X   ftype vms_open OF((char *));
  1381. X   int vms_read OF((ftype, char *, int));
  1382. X   int vms_close OF((ftype));
  1383. X   int vms_error OF((ftype));
  1384. X#else /* !VMS */
  1385. X#  if defined(MSDOS) && !defined(ATARI_ST)
  1386. X#    include <io.h>
  1387. X#    include <fcntl.h>
  1388. X#    define fhow (O_RDONLY|O_BINARY)
  1389. X#  else /* !MSDOS */
  1390. X     int open OF((char *, int));
  1391. X     int read OF((int, char *, int));
  1392. X     int close OF((int));
  1393. X     int lseek OF((int, long, int));
  1394. X#    define fhow 0
  1395. X#  endif /* ?MSDOS */
  1396. X   typedef int ftype;
  1397. X#  define fbad (-1)
  1398. X#  define zopen(n,p) open(n,p)
  1399. X#  define zread(f,b,n) read(f,b,n)
  1400. X#  define zclose(f) close(f)
  1401. X#  define zerr(f) (k==(extent)(-1L))
  1402. X#  define zstdin 0
  1403. X#endif /* ?VMS */
  1404. X
  1405. X
  1406. X/* Local data */
  1407. X
  1408. X#ifndef UTIL
  1409. Xlocal ulg crc;       /* crc on uncompressed file data */
  1410. Xlocal ftype ifile;   /* file to compress */
  1411. X#endif
  1412. Xulg isize;           /* input file size. global only for debugging */    
  1413. X
  1414. X/* Local functions */
  1415. X#if defined(PROTO) && !defined(UTIL)
  1416. X   local int suffixes(char *, char *);
  1417. X#endif
  1418. X
  1419. X
  1420. X/* Note: a zip "entry" includes a local header (which includes the file
  1421. X   name), an encryption header if encrypting, the compressed data
  1422. X   and possibly an extended local header. */
  1423. X
  1424. Xint zipcopy(z, x, y)
  1425. Xstruct zlist far *z;    /* zip entry to copy */
  1426. XFILE *x, *y;            /* source and destination files */
  1427. X/* Copy the zip entry described by *z from file *x to file *y.  Return an
  1428. X   error code in the ZE_ class.  Also update tempzn by the number of bytes
  1429. X   copied. */
  1430. X{
  1431. X  ulg n;                /* holds local header offset */
  1432. X
  1433. X  if (fseek(x, z->off, SEEK_SET))
  1434. X    return ferror(x) ? ZE_READ : ZE_EOF;
  1435. X  z->off = tempzn;
  1436. X  n = 4 + LOCHEAD + (long)z->nam + (long)z->ext + z->siz;
  1437. X  /* copy the extended local header if there is one */
  1438. X  if (z->lflg & 8) n += 16;
  1439. X  tempzn += n;
  1440. X  return fcopy(x, y, n);
  1441. X}
  1442. X
  1443. X
  1444. X#ifndef UTIL
  1445. X
  1446. Xint percent(n, m)
  1447. Xlong n, m;               /* n is the original size, m is the new size */
  1448. X/* Return the percentage compression from n to m using only integer
  1449. X   operations */
  1450. X{
  1451. X  if (n > 0xffffffL)            /* If n >= 16M */
  1452. X  {                             /*  then divide n and m by 256 */
  1453. X    n += 0x80;  n >>= 8;
  1454. X    m += 0x80;  m >>= 8;
  1455. X  }
  1456. X  return n ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;
  1457. X}
  1458. X
  1459. Xlocal int suffixes(a, s)
  1460. Xchar *a;                /* name to check suffix of */
  1461. Xchar *s;                /* list of suffixes separated by : or ; */
  1462. X/* Return true if a ends in any of the suffixes in the list s. */
  1463. X{
  1464. X  int m;                /* true if suffix matches so far */
  1465. X  char *p;              /* pointer into special */
  1466. X  char *q;              /* pointer into name a */
  1467. X
  1468. X  m = 1;
  1469. X#ifdef VMS
  1470. X  if( (q = strrchr(a,';')) != NULL )    /* Cut out VMS file version */
  1471. X    --q;
  1472. X  else
  1473. X    q = a + strlen(a) - 1;
  1474. X#else
  1475. X  q = a + strlen(a) - 1;
  1476. X#endif
  1477. X  for (p = s + strlen(s) - 1; p >= s; p--)
  1478. X    if (*p == ':' || *p == ';')
  1479. X      if (m)
  1480. X        return 1;
  1481. X      else
  1482. X      {
  1483. X        m = 1;
  1484. X#ifdef VMS
  1485. X        if( (q = strrchr(a,';')) != NULL )      /* Cut out VMS file version */
  1486. X          --q;
  1487. X        else
  1488. X          q = a + strlen(a) - 1;
  1489. X#else
  1490. X        q = a + strlen(a) - 1;
  1491. X#endif
  1492. X      }
  1493. X    else
  1494. X    {
  1495. X      m = m && q >= a && case_map(*p) == case_map(*q);
  1496. X      q--;
  1497. X    }
  1498. X  return m;
  1499. X}
  1500. X
  1501. Xint zipup(z, y)
  1502. Xstruct zlist far *z;    /* zip entry to compress */
  1503. XFILE *y;                /* output file */
  1504. X/* Compress the file z->name into the zip entry described by *z and write
  1505. X   it to the file *y. Encrypt if requested.  Return an error code in the
  1506. X   ZE_ class.  Also, update tempzn by the number of bytes written. */
  1507. X{
  1508. X  ulg a = 0L;           /* attributes returned by filetime() */
  1509. X  char *b;              /* malloc'ed file buffer */
  1510. X  extent k = 0;         /* result of zread */
  1511. X  int l = 0;            /* true if this file is a symbolic link */
  1512. X  int m;                /* method for this entry */
  1513. X  ulg o, p;             /* offsets in zip file */
  1514. X  long q = -2L;         /* size returned by filetime */
  1515. X  int r;                /* temporary variable */
  1516. X  ulg s = 0L;           /* size of compressed data */
  1517. X
  1518. X  if ((z->tim = filetime(z->name, &a, &q)) == 0 || q < -1L)
  1519. X    return ZE_OPEN;
  1520. X  /* q is set to -1 if the input file is a device */
  1521. X
  1522. X  z->nam = strlen(z->zname);
  1523. X
  1524. X  /* Select method based on the suffix and the global method */
  1525. X  m = special != NULL && suffixes(z->name, special) ? STORE : method;
  1526. X
  1527. X  /* Open file to zip up unless it is stdin */
  1528. X  if (strcmp(z->name, "-") == 0)
  1529. X  {
  1530. X    ifile = (ftype)zstdin;
  1531. X#ifdef MSDOS
  1532. X    setmode(zstdin, O_BINARY);
  1533. X#endif
  1534. X  }
  1535. X  else
  1536. X  {
  1537. X#ifdef VMS
  1538. X   if (vms_native)
  1539. X     get_vms_attributes(z);
  1540. X#endif
  1541. X#ifdef OS2
  1542. X    GetEAs(z->name, &z->extra, &z->ext, &z->cextra, &z->cext);
  1543. X    /* store data in local header, and size only in central headers */
  1544. X#endif
  1545. X    l = issymlnk(a);
  1546. X    if (l)
  1547. X      ifile = fbad;
  1548. X    else if (z->name[z->nam - 1] == '/') { /* directory */
  1549. X      ifile = fbad;
  1550. X      m = STORE;
  1551. X    }
  1552. X    else if ((ifile = zopen(z->name, fhow)) == fbad)
  1553. X      return ZE_OPEN;
  1554. X  }
  1555. X
  1556. X  if (l || q == 0)
  1557. X    m = STORE;
  1558. X  if (m == BEST)
  1559. X    m = DEFLATE;
  1560. X
  1561. X  /* Do not create STORED files with extended local headers if the
  1562. X   * input size is not known, because such files could not be extracted.
  1563. X   * So if the zip file is not seekable and the input file is not
  1564. X   * on disk, obey the -0 option by forcing deflation with stored block.
  1565. X   * Note however that using "zip -0" as filter is not very useful...
  1566. X   * ??? to be done.
  1567. X   */
  1568. X
  1569. X  /* Fill in header information and write local header to zip file.
  1570. X   * This header will later be re-written since compressed length and
  1571. X   * crc are not yet known.
  1572. X   */
  1573. X
  1574. X  /* (Assume ext, cext, com, and zname already filled in.) */
  1575. X#ifdef OS2
  1576. X  z->vem = z->dosflag ? 20 :            /* Made under MSDOS by PKZIP 2.0 */
  1577. X  /* We for a FAT file system, we must cheat and pretend that the
  1578. X   * file was not made on OS2 but under DOS. unzip is confused otherwise.
  1579. X   */
  1580. X#else
  1581. X  z->vem = dosify ? 20 :                /* Made under MSDOS by PKZIP 2.0 */
  1582. X#endif
  1583. X#ifdef VMS
  1584. X                    0x200 + REVISION;   /* Made under VMS by this Zip */
  1585. X#else /* !VMS */
  1586. X# ifdef OS2
  1587. X                    0x600 + REVISION;   /* Made under OS/2 by this Zip */
  1588. X# else /* !OS2 */
  1589. X#  ifdef MSDOS
  1590. X                    0     + REVISION;   /* Made under MSDOS by this Zip */
  1591. X#  else
  1592. X                    0x300 + REVISION;   /* Made under Unix by this Zip */
  1593. X#  endif /* MSDOS */
  1594. X# endif /* ?OS2 */
  1595. X#endif /* ?VMS */
  1596. X
  1597. X  z->ver = 20;                          /* Need PKUNZIP 2.0 */
  1598. X  z->crc = 0;  /* to be updated later */
  1599. X  /* Assume first that we will need an extended local header: */
  1600. X  z->flg = 8;  /* to be updated later */
  1601. X#ifdef CRYPT
  1602. X  if (key != NULL) {
  1603. X    z->flg |= 1;
  1604. X    /* Since we do not yet know the crc here, we pretend that the crc
  1605. X     * is the modification time:
  1606. X     */
  1607. X    z->crc = z->tim << 16;
  1608. X  }
  1609. X#endif
  1610. X  z->lflg = z->flg;
  1611. X  z->how = m;                             /* may be changed later  */
  1612. X  z->siz = m == STORE && q >= 0 ? q : 0;  /* will be changed later  */
  1613. X  z->len = q >= 0 ? q : 0;                /* may be changed later  */
  1614. X  z->dsk = 0;
  1615. X  z->att = BINARY;                        /* may be changed later */
  1616. X  z->atx = z->dosflag ? a & 0xff : a;      /* Attributes from filetime() */
  1617. X  z->off = tempzn;
  1618. X  if ((r = putlocal(z, y)) != ZE_OK)
  1619. X    return r;
  1620. X  tempzn += 4 + LOCHEAD + z->nam + z->ext;
  1621. X
  1622. X#ifdef CRYPT
  1623. X  if (key != NULL) {
  1624. X    crypthead(key, z->crc, y);
  1625. X    z->siz += 12;  /* to be updated later */
  1626. X    tempzn += 12;
  1627. X  }
  1628. X#endif
  1629. X  o = ftell(y); /* for debugging only */
  1630. X
  1631. X  /* Write stored or deflated file to zip file */
  1632. X  isize = 0L;
  1633. X  crc = updcrc((char *)NULL, 0);
  1634. X
  1635. X  if (m == DEFLATE) {
  1636. X     bi_init(y);
  1637. X     z->att = (ush)UNKNOWN;
  1638. X     ct_init(&z->att, &m);
  1639. X     lm_init(level, &z->flg);
  1640. X     s = deflate();
  1641. X  }
  1642. X  else
  1643. X  {
  1644. X    if ((b = malloc(CBSZ)) == NULL)
  1645. X       return ZE_MEM;
  1646. X
  1647. X    if (z->name[z->nam - 1] != '/') /* no read for directories */
  1648. X    while ((k = l ? rdsymlnk(z->name, b, CBSZ) : zread(ifile, b, CBSZ)) > 0)
  1649. X    {
  1650. X      isize += k;
  1651. X      crc = updcrc(b, k);
  1652. X      if (zfwrite(b, 1, k, y) != k)
  1653. X      {
  1654. X        free((voidp *)b);
  1655. X        return ZE_TEMP;
  1656. X      }
  1657. X#ifdef MINIX
  1658. X      if (l)
  1659. X        q = k;
  1660. X#endif /* MINIX */
  1661. X      if (l)
  1662. X        break;
  1663. X    }
  1664. X    free((voidp *)b);
  1665. X    s = isize;
  1666. X  }
  1667. X  if (ifile != fbad && zerr(ifile))
  1668. X    return ZE_READ;
  1669. X  if (ifile != fbad)
  1670. X    zclose(ifile);
  1671. X
  1672. X  tempzn += s;
  1673. X  p = tempzn; /* save for future fseek() */
  1674. X
  1675. X#ifndef VMS
  1676. X  /* Check input size (but not in VMS--variable record lengths mess it up) */
  1677. X  if (q >= 0 && isize != (ulg)q && !translate_eol)
  1678. X  {
  1679. X    fprintf(mesg, " i=%ld, q=%ld ", isize, q);
  1680. X    error("incorrect input size");
  1681. X  }
  1682. X#endif /* !VMS */
  1683. X
  1684. X  /* Try to rewrite the local header with correct information */
  1685. X  z->crc = crc;
  1686. X  z->siz = s;
  1687. X#ifdef CRYPT
  1688. X  if (key != NULL)
  1689. X    z->siz += 12;
  1690. X#endif
  1691. X  z->len = isize;
  1692. X  if (fseek(y, z->off, SEEK_SET)) {
  1693. X    if (z->how != (ush) m)
  1694. X       error("can't rewrite method");
  1695. X    if (m == STORE && q < 0)
  1696. X       error("zip -0 not allowed for input/output from/to pipe or device");
  1697. X    if ((r = putextended(z, y)) != ZE_OK)
  1698. X      return r;
  1699. X    tempzn += 16L;
  1700. X    z->flg = z->lflg; /* if flg modified by inflate */
  1701. X  } else {
  1702. X     /* seek ok, ftell() should work, check compressed size */
  1703. X#ifndef VMS
  1704. X    if (p - o != s) {
  1705. X      fprintf(mesg, " s=%ld, actual=%ld ", s, p-o);
  1706. X      error("incorrect compressed size");
  1707. X    }
  1708. X#endif
  1709. X    z->how = m;
  1710. X    if ((z->flg & 1) == 0)
  1711. X      z->flg &= ~8; /* clear the extended local header flag */
  1712. X    z->lflg = z->flg;
  1713. X    /* rewrite the local header: */
  1714. X    if ((r = putlocal(z, y)) != ZE_OK)
  1715. X      return r;
  1716. X    if (fseek(y, p, SEEK_SET))
  1717. X      return ZE_READ;
  1718. X    if ((z->flg & 1) != 0) {
  1719. X      /* encrypted file, extended header still required */
  1720. X      if ((r = putextended(z, y)) != ZE_OK)
  1721. X        return r;
  1722. X      tempzn += 16L;
  1723. X    }
  1724. X  }
  1725. X
  1726. X  /* Display statistics */
  1727. X  if (noisy)
  1728. X  {
  1729. X    if (verbose)
  1730. X      fprintf(mesg, " (in=%lu) (out=%lu)", isize, s);
  1731. X    if (m == DEFLATE)
  1732. X      fprintf(mesg, " (deflated %d%%)\n", percent(isize, s));
  1733. X    else
  1734. X      fprintf(mesg, " (stored 0%%)\n");
  1735. X    fflush(mesg);
  1736. X  }
  1737. X  return ZE_OK;
  1738. X}
  1739. X
  1740. X
  1741. Xint file_read(buf, size)
  1742. X  char *buf;
  1743. X  unsigned size;
  1744. X/* Read a new buffer from the current input file, and update the crc and
  1745. X * input file size.
  1746. X * IN assertion: size >= 2 (for end-of-line translation)
  1747. X */
  1748. X{
  1749. X  unsigned len;
  1750. X  char far *b;
  1751. X  if (translate_eol) {
  1752. X    /* static char last_byte = '\0'; */
  1753. X    size >>= 1;
  1754. X    b = buf+size;
  1755. X    size = len = zread(ifile, b, size);
  1756. X    if (len == (unsigned)EOF || len == 0) return len;
  1757. X    do {
  1758. X       /* ??? keep cr lf intact */
  1759. X       if ((*buf++ = *b++) == '\n') *(buf-1) = '\r', *buf++ = '\n', len++;
  1760. X    } while (--size != 0);
  1761. X    buf -= len;
  1762. X  } else {
  1763. X    len = zread(ifile, buf, size);
  1764. X    if (len == (unsigned)EOF || len == 0) return len;
  1765. X  }
  1766. X  crc = updcrc(buf, len);
  1767. X  isize += (ulg)len;
  1768. X  return len;
  1769. X}
  1770. X#endif /* !UTIL */
  1771. END_OF_FILE
  1772.   if test 12100 -ne `wc -c <'zipup.c'`; then
  1773.     echo shar: \"'zipup.c'\" unpacked with wrong size!
  1774.   fi
  1775.   # end of 'zipup.c'
  1776. fi
  1777. echo shar: End of archive 8 \(of 11\).
  1778. cp /dev/null ark8isdone
  1779. MISSING=""
  1780. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1781.     if test ! -f ark${I}isdone ; then
  1782.     MISSING="${MISSING} ${I}"
  1783.     fi
  1784. done
  1785. if test "${MISSING}" = "" ; then
  1786.     echo You have unpacked all 11 archives.
  1787.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1788. else
  1789.     echo You still must unpack the following archives:
  1790.     echo "        " ${MISSING}
  1791. fi
  1792. exit 0
  1793. exit 0 # Just in case...
  1794.