home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sources / misc / 3850 < prev    next >
Encoding:
Text File  |  1992-08-22  |  60.6 KB  |  1,802 lines

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