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

  1. Newsgroups: comp.sources.misc
  2. From: zip-bugs@cs.ucla.edu (Info-ZIP group)
  3. Subject:  v31i099:  zip19 - Info-ZIP portable Zip, version 1.9, Part07/11
  4. Message-ID: <1992Aug23.064739.29343@sparky.imd.sterling.com>
  5. X-Md4-Signature: 78834c85a8bc38b5c3e178b5fc3ec576
  6. Date: Sun, 23 Aug 1992 06:47:39 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 99
  11. Archive-name: zip19/part07
  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:  msdos/makefile.gcc.UU vms/vms.c vms/vms_zip.rnh zipsplit.c
  22. # Wrapped by kent@sparky on Sun Aug 23 01:00:45 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 7 (of 11)."'
  26. if test -f 'msdos/makefile.gcc.UU' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'msdos/makefile.gcc.UU'\"
  28. else
  29.   echo shar: Extracting \"'msdos/makefile.gcc.UU'\" \(2879 characters\)
  30.   sed "s/^X//" >'msdos/makefile.gcc.UU' <<'END_OF_FILE'
  31. Xbegin 666 msdos/makefile.gcc
  32. XM(R!-86ME9FEL92!F;W(@6FEP+"!::7!#;&]A:RP@6FEP3F]T92!A;F0@6FEP
  33. XM4W!L:70@9F]R#0HC(&1J9V-C(#$N,#8-"@T*0U)94%1//0T*0TQ/04L]#0I#
  34. XM4D9,04<]#0H-"B,@("HJ*B!&;W(@96YC<GEP=&EO;B!V97)S:6]N+"!R96UO
  35. XM=F4@=&AE(",@870@=&AE(&9R;VYT(&]F(&YE>'0@,R!L:6YE<R J*BH-"B-#
  36. XM4EE05$\]8W)Y<'0N;PT*(T-,3T%+/7II<&-L;V%K+F5X90T*(T-21DQ!1STM
  37. XM1$-265!4#0H-"B,@+2TM+2TM+2TM+2TM+2!D:F=C8R M+2TM+2TM+2TM+2TM
  38. XM#0I#1DQ!1U,]+5=A;&P@+4\R("U$3D]?05--("0H0U)&3$%'*0T*551)3$9,
  39. XM04=3/2U$551)3" D*$-&3$%'4RD@+6\-"D-#/6=C8PT*3$0]9V-C#0I,1$9,
  40. XM04=3/2US#0H-"B,@=F%R:6%B;&5S#0I/0DI:(#T@>FEP+F\@>FEP9FEL92YO
  41. XM('II<'5P+F\@9FEL96EO+F\@=71I;"YO(&=L;V)A;',N;R D*$-265!43RD-
  42. XM"@T*3T)*52 ]('II<&9I;&5?+F\@>FEP=7!?+F\@9FEL96EO7RYO('5T:6Q?
  43. XM+F\@9VQO8F%L<RYO#0I/0DI.(#T@>FEP;F]T92YO(" D*$]"2E4I#0I/0DI#
  44. XM(#T@>FEP8VQO86LN;R D*$]"2E4I(&-R>7!T7RYO#0I/0DI3(#T@>FEP<W!L
  45. XM:70N;R D*$]"2E4I#0H-"GII<',Z"7II<"!Z:7!N;W1E('II<'-P;&ET("0H
  46. XM0TQ/04LI#0H-"GII<"YO.@D@(" @("!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N
  47. XM:"!R979I<VEO;BYH('II<"YC#0H-"GII<&9I;&4N;SH@(" @>FEP+F@@>FEP
  48. XM97)R+F@@=&%I;&]R+F@@>FEP9FEL92YC#0H-"GII<'5P+F\Z(" @(" @>FEP
  49. XM+F@@>FEP97)R+F@@=&%I;&]R+F@@<F5V:7-I;VXN:"!Z:7!U<"YC#0H-"F9I
  50. XM;&5I;RYO.B @(" @>FEP+F@@>FEP97)R+F@@=&%I;&]R+F@@9FEL96EO+F,-
  51. XM"@T*=71I;"YO.B @(" @("!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N:"!U=&EL
  52. XM+F,-"@T*9VQO8F%L<RYO.B @("!Z:7 N:"!Z:7!E<G(N:"!T86EL;W(N:"!G
  53. XM;&]B86QS+F,-"@T*9&5F;&%T92YO.B @("!Z:7 N:"!Z:7!E<G(N:"!T86EL
  54. XM;W(N:"!D969L871E+F,-"@T*=')E97,N;SH@(" @("!Z:7 N:"!Z:7!E<G(N
  55. XM:"!T86EL;W(N:"!T<F5E<RYC#0H-"F)I=',N;SH@(" @(" @>FEP+F@@>FEP
  56. XM97)R+F@@=&%I;&]R+F@@8FET<RYC#0H-"F-R>7!T+F\Z(" @(" @>FEP+F@@
  57. XM>FEP97)R+F@@=&%I;&]R+F@@8W)Y<'0N8PT*#0IZ:7!C;&]A:RYO.B @('II
  58. XM<"YH('II<&5R<BYH('1A:6QO<BYH(')E=FES:6]N+F@@>FEP8VQO86LN8PT*
  59. XM#0IZ:7!N;W1E+F\Z(" @('II<"YH('II<&5R<BYH('1A:6QO<BYH(')E=FES
  60. XM:6]N+F@@>FEP;F]T92YC#0H-"GII<'-P;&ET+F\Z(" @>FEP<W!L:70N8R!Z
  61. XM:7 N:"!Z:7!E<G(N:"!T86EL;W(N:"!R979I<VEO;BYH#0H-"GII<&9I;&5?
  62. XM+F\Z(" @>FEP9FEL92YC('II<"YH('II<&5R<BYH('1A:6QO<BYH#0H))"A#
  63. XM0RD@+6,@)"A55$E,1DQ!1U,I("1 ('II<&9I;&4N8PT*#0IZ:7!U<%\N;SH@
  64. XM(" @('II<'5P+F,@>FEP+F@@>FEP97)R+F@@=&%I;&]R+F@-"@DD*$-#*2 M
  65. XM8R D*%5424Q&3$%'4RD@)$ @>FEP=7 N8PT*#0IF:6QE:6]?+F\Z(" @(&9I
  66. XM;&5I;RYC('II<"YH('II<&5R<BYH('1A:6QO<BYH#0H))"A#0RD@+6,@)"A5
  67. XM5$E,1DQ!1U,I("1 (&9I;&5I;RYC#0H-"G5T:6Q?+F\Z(" @('5T:6PN8R!Z
  68. XM:7 N:"!Z:7!E<G(N:"!T86EL;W(N: T*"20H0T,I("UC("0H551)3$9,04=3
  69. XM*2 D0"!F:6QE:6\N8PT*#0IC<GEP=%\N;SH@(" @(&-R>7!T+F,@>FEP+F@-
  70. XM"@DD*$-#*2 M8R D*%5424Q&3$%'4RD@)$ @8W)Y<'0N8PT*#0IZ:7 Z("0H
  71. XM3T)*6BD@)"A/0DI)*0T*"20H3$0I("0H3$1&3$%'4RD@)"A/0DI:*2 D*$]"
  72. XM2DDI("UO("1 #0H)86]U=#)E>&4@)$ -"@ED96P@)$ -"@T*>FEP8VQO86LZ
  73. XM("0H3T)*0RD-"@DD*$Q$*2 D*$Q$1DQ!1U,I("0H3T)*0RD@+6\@)$ -"@EA
  74. XM;W5T,F5X92 D0 T*"61E;" D0 T*#0IZ:7!N;W1E.B D*$]"2DXI#0H))"A,
  75. XM1"D@)"A,1$9,04=3*2 D*$]"2DXI("UO("1 #0H)86]U=#)E>&4@)$ -"@ED
  76. XM96P@)$ -"@T*>FEP<W!L:70Z("0H3T)*4RD-"@DD*$Q$*2 D*$Q$1D%'4RD@
  77. XF)"A/0DI3*2 M;R D0 T*"6%O=70R97AE("1 #0H)9&5L("1 #0I$
  78. Xend
  79. END_OF_FILE
  80.   if test 2879 -ne `wc -c <'msdos/makefile.gcc.UU'`; then
  81.     echo shar: \"'msdos/makefile.gcc.UU'\" unpacked with wrong size!
  82.   else
  83.     echo shar: Uudecoding \"'msdos/makefile.gcc'\" \(2063 characters\)
  84.     cat msdos/makefile.gcc.UU | uudecode
  85.     if test 2063 -ne `wc -c <'msdos/makefile.gcc'`; then
  86.       echo shar: \"'msdos/makefile.gcc'\" uudecoded with wrong size!
  87.     else
  88.       rm msdos/makefile.gcc.UU
  89.     fi
  90.   fi
  91.   # end of 'msdos/makefile.gcc.UU'
  92. fi
  93. if test -f 'vms/vms.c' -a "${1}" != "-c" ; then 
  94.   echo shar: Will not clobber existing file \"'vms/vms.c'\"
  95. else
  96.   echo shar: Extracting \"'vms/vms.c'\" \(18616 characters\)
  97.   sed "s/^X//" >'vms/vms.c' <<'END_OF_FILE'
  98. X/*************************************************************************
  99. X *                                                                       *
  100. X * VMS portions copyright (C) 1992 Igor Mandrichenko.                    *
  101. X * Permission is granted to any individual or institution to use, copy,  *
  102. X * or redistribute this software so long as all of the original files    *
  103. X * are included unmodified, that it is not sold for profit, and that     *
  104. X * this copyright notice is retained.                                    *
  105. X *                                                                       *
  106. X *************************************************************************/
  107. X
  108. X/*
  109. X *  vms.c (zip) by Igor Mandrichenko    Version 2.1-1
  110. X *
  111. X *  Revision history:
  112. X *  ...
  113. X *  2.1-1       16-feb-1992     I.Mandrichenko  
  114. X *      Get file size from XABFHC and check bytes rest in file before
  115. X *      reading. 
  116. X *  2.1-2       2-mar-1992      I.Mandrichenko
  117. X *      Make code more standard
  118. X *  2.2         21-jun-1992     I.Mandrichenko
  119. X *      Free all allocated space, use more static storage.
  120. X *      Use memcompress() from bits.c (deflation) for block compression.
  121. X *      To revert to old compression method #define OLD_COMPRESS
  122. X */
  123. X
  124. X#ifdef VMS                      /* For VMS only ! */
  125. X
  126. X#define OLD_COMPRESS    /*To use old compression method define it.*/
  127. X
  128. X#include <rms.h>
  129. X#include <descrip.h>
  130. X#include <syidef.h>
  131. X
  132. X#ifndef VAXC
  133. X                                /* This definition may be missed */
  134. Xstruct XAB {
  135. X    unsigned char xab$b_cod;
  136. X    unsigned char xab$b_bln;
  137. X    short int xabdef$$_fill_1;
  138. X    char *xab$l_nxt;
  139. X};
  140. X
  141. X#endif
  142. X
  143. X#ifndef SYI$_VERSION
  144. X#define SYI$_VERSION 4096       /* VMS 5.4 definition */
  145. X#endif
  146. X
  147. X#include "zip.h"
  148. X
  149. X#define ERR(s)  !((s)&1)
  150. X
  151. X#define RET_ERROR 1
  152. X#define RET_SUCCESS 0
  153. X#define RET_EOF 0
  154. X
  155. X#define Kbyte 1024
  156. X
  157. Xtypedef struct XAB *xabptr;
  158. X
  159. X/*
  160. X*   Extra record format
  161. X*   ===================
  162. X*   signature       (2 bytes)   = 'I','M'
  163. X*   size            (2 bytes)
  164. X*   block signature (4 bytes)
  165. X*   flags           (2 butes)
  166. X*   uncomprssed size(2 bytes)
  167. X*   reserved        (4 bytes)
  168. X*   data            (size-12 bytes)
  169. X*   ....
  170. X*/
  171. X
  172. X
  173. X/*
  174. X*   Extra field signature and block signatures
  175. X*/
  176. X#define SIGNATURE "IM"
  177. X#define EXTBSL  4               /* Block signature length   */
  178. X#define RESL    8
  179. X
  180. X#define BC_MASK         07      /* 3 bits for compression type */       
  181. X#define BC_STORED       0       /* Stored */
  182. X#define BC_00           1       /* 0byte -> 0bit compression */
  183. X#define BC_DEFL         2       /* Deflated */
  184. X
  185. Xstruct extra_block
  186. X{       ush     im_sig;
  187. X        ush     size;
  188. X        ulg     block_sig;
  189. X        ush     flags;
  190. X        ush     length;
  191. X        ulg     reserved;
  192. X        uch     body[1];        /* The actual size is unknown */
  193. X};
  194. X
  195. X#define FABSIG  "VFAB"
  196. X#define XALLSIG "VALL"
  197. X#define XFHCSIG "VFHC"
  198. X#define XDATSIG "VDAT"
  199. X#define XRDTSIG "VRDT"
  200. X#define XPROSIG "VPRO"
  201. X#define XKEYSIG "VKEY"
  202. X#define VERSIG  "VMSV"
  203. X/*
  204. X*   Block sizes
  205. X*/
  206. X#define FABL    (cc$rms_fab.fab$b_bln)
  207. X#define RABL    (cc$rms_rab.rab$b_bln)
  208. X#define XALLL   (cc$rms_xaball.xab$b_bln)
  209. X#define XDATL   (cc$rms_xabdat.xab$b_bln)
  210. X#define XFHCL   (cc$rms_xabfhc.xab$b_bln)
  211. X#define XKEYL   (cc$rms_xabkey.xab$b_bln)
  212. X#define XPROL   (cc$rms_xabpro.xab$b_bln)
  213. X#define XRDTL   (cc$rms_xabrdt.xab$b_bln)
  214. X#define XSUML   (cc$rms_xabsum.xab$b_bln)
  215. X#define EXTHL   (4+EXTBSL+RESL)
  216. X#define EXTL0   ((FABL + EXTHL)+        \
  217. X                (XFHCL + EXTHL)+        \
  218. X                (XPROL + EXTHL)+        \
  219. X                (XDATL + EXTHL)+        \
  220. X                (XRDTL + EXTHL))
  221. X
  222. X#ifdef OLD_COMPRESS
  223. X#define PAD     sizeof(uch)
  224. X#else
  225. X#define PAD     10*sizeof(ush)          /* Two extra bytes for compr. header */
  226. X#endif
  227. X
  228. X#define PAD0    (5*PAD)                 /* Reserve space for the case when
  229. X                                        *  compression failes */
  230. Xstatic int _compress();
  231. X
  232. X/***********************************
  233. X *   Function get_vms_attributes   *
  234. X ***********************************/
  235. X
  236. Xstatic uch *_compress_block();
  237. Xstatic int get_vms_version();
  238. X
  239. Xint get_vms_attributes(z)
  240. X  struct zlist *z;
  241. X/*
  242. X *      Get file VMS file attributes and store them into extent fields.
  243. X *      Store VMS version also.
  244. X *      On error leave z intact.
  245. X */
  246. X{
  247. X    int status;
  248. X    uch *extra=(uch*)NULL, *scan;
  249. X    extent extra_l;
  250. X    static struct FAB fab;
  251. X    static struct XABSUM xabsum;
  252. X    static struct XABFHC xabfhc;
  253. X    static struct XABDAT xabdat;
  254. X    static struct XABPRO xabpro;
  255. X    static struct XABRDT xabrdt;
  256. X    xabptr x = (xabptr)NULL, xab_chain = (xabptr)NULL, last_xab = (xabptr)NULL;
  257. X    int nk, na;
  258. X    int i;
  259. X    int rc=RET_ERROR;
  260. X    char verbuf[80];
  261. X    int verlen = 0;
  262. X
  263. X    /*
  264. X    *   Initialize RMS control blocks and link them
  265. X    */
  266. X
  267. X    fab =    cc$rms_fab;
  268. X    xabsum = cc$rms_xabsum;
  269. X    xabdat = cc$rms_xabdat;
  270. X    xabfhc = cc$rms_xabfhc;
  271. X    xabpro = cc$rms_xabpro;
  272. X    xabrdt = cc$rms_xabrdt;
  273. X
  274. X
  275. X    fab.fab$l_xab = (char*)&xabsum;
  276. X    /*
  277. X    *   Open the file and read summary information.
  278. X    */
  279. X    fab.fab$b_fns = strlen(z->name);
  280. X    fab.fab$l_fna = z->name;
  281. X
  282. X    status = sys$open(&fab);
  283. X    if (ERR(status))
  284. X    {
  285. X#ifdef DEBUG
  286. X        printf("get_vms_attributes: sys$open for file %s:\n  error status = %d\n",
  287. X               z->name, status);
  288. X#endif
  289. X        goto err_exit;
  290. X    }
  291. X
  292. X    nk = xabsum.xab$b_nok;
  293. X    na = xabsum.xab$b_noa;
  294. X#ifdef DEBUG
  295. X    printf("%d keys, %d alls\n", nk, na);
  296. X#endif
  297. X
  298. X    /*
  299. X    *   Allocate XABKEY and XABALL blocks ind link them
  300. X    */
  301. X
  302. X    xabfhc.xab$l_nxt = (char*)&xabdat;
  303. X    xabdat.xab$l_nxt = (char*)&xabpro;
  304. X    xabpro.xab$l_nxt = (char*)&xabrdt;
  305. X    xabrdt.xab$l_nxt = (char*)0L;
  306. X
  307. X    xab_chain = (xabptr)(&xabfhc);
  308. X    last_xab  = (xabptr)(&xabrdt);
  309. X
  310. X#define INIT(ptr,size,init)     \
  311. X        if( (ptr = (uch*)malloc(size)) == NULL )        \
  312. X        {                                               \
  313. X              printf( "get_vms_attributes: Insufficient memory.\n" );   \
  314. X                      goto err_exit;                    \
  315. X        }                                               \
  316. X        *(ptr) = (init);
  317. X    /*
  318. X    *   Allocate and initialize all needed XABKEYs and XABALLs
  319. X    */
  320. X    for (i = 0; i < nk; i++)
  321. X    {
  322. X        struct XABKEY *k;
  323. X        INIT(k, XKEYL, cc$rms_xabkey);
  324. X        k->xab$b_ref = i;
  325. X        if (last_xab != 0L)
  326. X            last_xab->xab$l_nxt = (char*)k;
  327. X        last_xab = (xabptr)k;
  328. X    }
  329. X    for (i = 0; i < na; i++)
  330. X    {
  331. X        struct XABALL *a;
  332. X        INIT(a, XALLL, cc$rms_xaball);
  333. X        a->xab$b_aid = i;
  334. X        if (last_xab != 0L)
  335. X            last_xab->xab$l_nxt = (char*)a;
  336. X        last_xab = (xabptr)a;
  337. X    }
  338. X
  339. X    fab.fab$l_xab = (char*)xab_chain;
  340. X#ifdef DEBUG
  341. X    printf("Dump of XAB chain before DISPLAY:\n");
  342. X    for (x = xab_chain; x != 0L; x = x->xab$l_nxt)
  343. X        dump_rms_block(x);
  344. X#endif
  345. X    /*
  346. X    *   Get information on the file structure etc.
  347. X    */
  348. X    status = sys$display(&fab, 0, 0);
  349. X    if (ERR(status))
  350. X    {
  351. X#ifdef DEBUG
  352. X        printf("get_vms_attributes: sys$display for file %s:\n  error status = %d\n",
  353. X               z->name, status);
  354. X#endif
  355. X        goto err_exit;
  356. X    }
  357. X
  358. X#ifdef DEBUG
  359. X    printf("\nDump of XAB chain after DISPLAY:\n");
  360. X    for (x = xab_chain; x != 0L; x = x->xab$l_nxt)
  361. X        dump_rms_block(x);
  362. X#endif
  363. X
  364. X    fab.fab$l_xab = 0;  /* Keep XABs */
  365. X    status = sys$close(&fab);
  366. X    if (ERR(status))
  367. X    {
  368. X#ifdef DEBUG
  369. X        printf("get_vms_attributes: sys$close for file %s:\n  error status = %d\n",
  370. X               z->name, status);
  371. X#endif
  372. X        goto err_exit;
  373. X    }
  374. X
  375. X    extra_l = EXTL0 + nk * (XKEYL + EXTHL) + na * (XALLL + EXTHL);
  376. X#ifndef OLD_COMPRESS
  377. X    extra_l += PAD0 + (nk+na) * PAD;
  378. X#endif
  379. X
  380. X    if( verlen = get_vms_version(verbuf,sizeof(verbuf)) )
  381. X    {   extra_l += verlen + EXTHL;
  382. X#ifndef OLD_COMPRESS
  383. X        extra_l += PAD;
  384. X#endif
  385. X    }
  386. X
  387. X    if ((scan = extra = (uch *) malloc(extra_l)) == (uch*)NULL)
  388. X    {
  389. X#ifdef DEBUG
  390. X        printf("get_vms_attributes: Insufficient memory to allocate extra buffer\n");
  391. X#endif
  392. X        goto err_exit;
  393. X    }
  394. X
  395. X
  396. X    if( verlen > 0 )
  397. X        scan = _compress_block(scan,verbuf, verlen, VERSIG);
  398. X
  399. X    /*
  400. X     *  Zero all unusable fields to improve compression
  401. X     */
  402. X    fab.fab$b_fns = fab.fab$b_shr = fab.fab$b_dns = fab.fab$b_fac = 0;
  403. X    fab.fab$w_ifi = 0;
  404. X    fab.fab$l_stv = fab.fab$l_sts = fab.fab$l_ctx = 0;
  405. X    fab.fab$l_fna = fab.fab$l_nam = fab.fab$l_xab = fab.fab$l_dna = (char*)0L;
  406. X
  407. X#ifdef DEBUG
  408. X    dump_rms_block( &fab );
  409. X#endif
  410. X    scan = _compress_block(scan,&fab, FABL, FABSIG);
  411. X    for (x = xab_chain; x != 0L;)
  412. X    {
  413. X        int bln;
  414. X        char *sig;
  415. X        xabptr next;
  416. X
  417. X        next = (xabptr)(x->xab$l_nxt);
  418. X        x->xab$l_nxt = 0;
  419. X
  420. X        switch (x->xab$b_cod)
  421. X        {
  422. X            case XAB$C_ALL:
  423. X                bln = XALLL;
  424. X                sig = XALLSIG;
  425. X                break;
  426. X            case XAB$C_KEY:
  427. X                bln = XKEYL;
  428. X                sig = XKEYSIG;
  429. X                break;
  430. X            case XAB$C_PRO:
  431. X                bln = XPROL;
  432. X                sig = XPROSIG;
  433. X                break;
  434. X            case XAB$C_FHC:
  435. X                bln = XFHCL;
  436. X                sig = XFHCSIG;
  437. X                break;
  438. X            case XAB$C_DAT:
  439. X                bln = XDATL;
  440. X                sig = XDATSIG;
  441. X                break;
  442. X            case XAB$C_RDT:
  443. X                bln = XRDTL;
  444. X                sig = XRDTSIG;
  445. X                break;
  446. X            default:
  447. X                bln = 0;
  448. X                sig = 0L;
  449. X                break;
  450. X        }
  451. X        if (bln > 0)
  452. X            scan = _compress_block(scan,x, bln, sig);
  453. X        x = next;
  454. X    }
  455. X
  456. X    z->ext = z->cext = scan-extra;
  457. X    z->extra = z->cextra = (char*)extra;
  458. X    rc = RET_SUCCESS;
  459. X
  460. Xerr_exit:
  461. X    /*
  462. X    * Give up all allocated blocks
  463. X    */
  464. X    for(x = (struct XAB *)xab_chain; x != 0L; )
  465. X    {   struct XAB *next;
  466. X        next = (xabptr)(x->xab$l_nxt);
  467. X        if( x->xab$b_cod == XAB$C_ALL || x->xab$b_cod == XAB$C_KEY )
  468. X                free(x);
  469. X        x = next;
  470. X    }
  471. X    return rc;
  472. X}
  473. X
  474. Xstatic int get_vms_version(verbuf,len)
  475. Xchar *verbuf;
  476. Xint len;
  477. X{   int i = SYI$_VERSION;
  478. X    int verlen = 0;
  479. X    struct dsc$descriptor version;
  480. X    char *m;
  481. X
  482. X    version.dsc$a_pointer = verbuf;
  483. X    version.dsc$w_length  = len-1;
  484. X    version.dsc$b_dtype   = DSC$K_DTYPE_B;
  485. X    version.dsc$b_class   = DSC$K_CLASS_S;
  486. X
  487. X    if (ERR(lib$getsyi(&i, 0, &version, &verlen, 0, 0)) || verlen == 0)
  488. X        return 0;
  489. X
  490. X    /* Cut out trailing spaces "V5.4-3   " -> "V5.4-3" */
  491. X    for(m=verbuf+verlen,i=verlen-1; i>0 && verbuf[i]==' '; --i) 
  492. X        --m;
  493. X    *m = 0;
  494. X
  495. X    /* Cut out release number "V5.4-3" -> "V5.4" */
  496. X    if( (m=strrchr(verbuf,'-')) != (char*)NULL )
  497. X        *m = 0;
  498. X    return strlen(verbuf)+1;    /* Transmit ending 0 too */
  499. X}
  500. X
  501. X#define CTXSIG ((ulg)('CtXx'))
  502. X
  503. Xtypedef struct user_context
  504. X{
  505. X    ulg sig;
  506. X    struct FAB *fab;
  507. X    struct RAB *rab;
  508. X    ulg size,rest;
  509. X    int status;
  510. X} Ctx, *Ctxptr;
  511. X
  512. XCtx init_ctx =  
  513. X{       CTXSIG,
  514. X        0L,
  515. X        0L,
  516. X        0L,
  517. X        0L,
  518. X        0
  519. X};
  520. X
  521. X#define CTXL    sizeof(Ctx)
  522. X#define CHECK_RAB(_r) ( (_r) != 0 &&                            \
  523. X                        (_r) -> rab$b_bid == RAB$C_BID &&       \
  524. X                        (_r) -> rab$b_bln == RAB$C_BLN &&       \
  525. X                        (_r) -> rab$l_ctx != 0L     &&          \
  526. X                        (_r) -> rab$l_fab != 0L )
  527. X
  528. X/**************************
  529. X *   Function vms_open    *
  530. X **************************/
  531. Xstruct RAB *vms_open(name)
  532. X    char *name;
  533. X{
  534. X    struct RAB *rab;
  535. X    struct FAB *fab;
  536. X    struct XABFHC *fhc;
  537. X    Ctxptr ctx;
  538. X
  539. X    if ((fab = (struct FAB *) malloc(FABL)) == (struct FAB *)NULL)
  540. X        return 0;
  541. X    if ((rab = (struct RAB *) malloc(RABL)) == (struct RAB *)NULL)
  542. X    {
  543. X        free(fab);
  544. X        return 0;
  545. X    }
  546. X    if ((fhc = (struct XABFHC *) malloc(XFHCL)) == (struct XABFHC *)NULL)
  547. X    {
  548. X        free(rab);
  549. X        free(fab);
  550. X        return 0;
  551. X    }
  552. X    if ((ctx = (Ctxptr) malloc(CTXL)) == (Ctxptr)NULL)
  553. X    {
  554. X        free(fhc);
  555. X        free(fab);
  556. X        free(rab);
  557. X        return 0;
  558. X    }
  559. X    *fab = cc$rms_fab;
  560. X    *rab = cc$rms_rab;
  561. X    *fhc = cc$rms_xabfhc;
  562. X
  563. X    fab->fab$l_fna = name;
  564. X    fab->fab$b_fns = strlen(name);
  565. X    fab->fab$b_fac = FAB$M_GET | FAB$M_BIO;
  566. X    fab->fab$l_xab = (char*)fhc;
  567. X
  568. X    if (ERR(sys$open(fab)))
  569. X    {
  570. X        sys$close(fab);
  571. X        free(fhc);
  572. X        free(fab);
  573. X        free(rab);
  574. X        free(ctx);
  575. X        return 0;
  576. X    }
  577. X
  578. X    rab->rab$l_fab = fab;
  579. X    rab->rab$l_rop = RAB$M_BIO;
  580. X
  581. X    if (ERR(sys$connect(rab)))
  582. X    {
  583. X        sys$close(fab);
  584. X        free(fab);
  585. X        free(rab);
  586. X        free(ctx);
  587. X        return 0;
  588. X    }
  589. X
  590. X    *ctx = init_ctx;
  591. X    ctx->rab = rab;
  592. X    ctx->fab = fab;
  593. X
  594. X    if( fhc->xab$l_ebk > 0 )
  595. X        ctx->size = ctx->rest = ( fhc->xab$l_ebk-1 ) * 512 + fhc->xab$w_ffb;
  596. X    else
  597. X        ctx->size = ctx->rest = 0;
  598. X    free(fhc);
  599. X    fab -> fab$l_xab = 0;
  600. X    rab->rab$l_ctx = (long)ctx;
  601. X    return rab;
  602. X}
  603. X
  604. X/**************************
  605. X *   Function vms_close   *
  606. X **************************/
  607. Xint vms_close(rab)
  608. X    struct RAB *rab;
  609. X{
  610. X    struct FAB *fab;
  611. X    Ctxptr ctx;
  612. X
  613. X    if (!CHECK_RAB(rab))
  614. X        return RET_ERROR;
  615. X    fab = (ctx = (Ctxptr)(rab->rab$l_ctx))->fab;
  616. X    sys$close(fab);
  617. X
  618. X    free(fab);
  619. X    free(rab);
  620. X    free(ctx);
  621. X
  622. X    return RET_SUCCESS;
  623. X}
  624. X
  625. X/**************************
  626. X *   Function vms_rewind  *
  627. X **************************/
  628. Xint vms_rewind(rab)
  629. X    struct RAB *rab;
  630. X{
  631. X    Ctxptr ctx;
  632. X
  633. X    int status;
  634. X    if (!CHECK_RAB(rab))
  635. X        return RET_ERROR;
  636. X
  637. X    ctx = (Ctxptr) (rab->rab$l_ctx);
  638. X    if (ERR(status = sys$rewind(rab)))
  639. X    {
  640. X        ctx->status = status;
  641. X        return RET_ERROR;
  642. X    }
  643. X
  644. X    ctx->status = 0;
  645. X    ctx->rest = ctx->size;
  646. X    
  647. X    return RET_SUCCESS;
  648. X}
  649. X
  650. X/**************************
  651. X *   Function vms_read    *
  652. X **************************/
  653. Xint vms_read(rab, buf, size)
  654. X    struct RAB *rab;
  655. Xchar *buf;
  656. Xint size;
  657. X/*
  658. X*       size must be greater or equal to 512 !
  659. X*/
  660. X{
  661. X    int status;
  662. X    Ctxptr ctx;
  663. X
  664. X    ctx = (Ctxptr)rab->rab$l_ctx;
  665. X
  666. X    if (!CHECK_RAB(rab))
  667. X        return 0;
  668. X
  669. X    if (ctx -> rest <= 0)
  670. X        return 0;               /* Eof */
  671. X
  672. X    if(size > 16*Kbyte)         /* RMS can not read too much */
  673. X        size = 16*Kbyte;
  674. X    else
  675. X        size &= ~511L;
  676. X
  677. X    rab->rab$l_ubf = buf;
  678. X    rab->rab$w_usz = size;
  679. X    status = sys$read(rab);
  680. X    if (!ERR(status) && rab->rab$w_rsz > 0)
  681. X    {
  682. X        ctx -> status = 0;
  683. X        ctx -> rest -= rab->rab$w_rsz;
  684. X        return rab->rab$w_rsz;
  685. X    }
  686. X    else
  687. X    {
  688. X        ctx->status = (status==RMS$_EOF ? 0:status);
  689. X        if(status == RMS$_EOF)
  690. X                ctx -> rest = 0L;
  691. X        return 0;
  692. X    }
  693. X}
  694. X
  695. X/**************************
  696. X *   Function vms_error   *
  697. X **************************/
  698. Xint vms_error(rab)
  699. X    struct RAB *rab;
  700. X{
  701. X    if (!CHECK_RAB(rab))
  702. X        return RET_ERROR;
  703. X    return ((Ctxptr) (rab->rab$l_ctx))->status;
  704. X}
  705. X
  706. X
  707. Xdump_rms_block(p)
  708. X    unsigned char *p;
  709. X{
  710. X    unsigned char bid, len;
  711. X    int err;
  712. X    char *type;
  713. X    char buf[132];
  714. X    int i;
  715. X
  716. X    err = 0;
  717. X    bid = p[0];
  718. X    len = p[1];
  719. X    switch (bid)
  720. X    {
  721. X        case FAB$C_BID:
  722. X            type = "FAB";
  723. X            break;
  724. X        case XAB$C_ALL:
  725. X            type = "xabALL";
  726. X            break;
  727. X        case XAB$C_KEY:
  728. X            type = "xabKEY";
  729. X            break;
  730. X        case XAB$C_DAT:
  731. X            type = "xabDAT";
  732. X            break;
  733. X        case XAB$C_RDT:
  734. X            type = "xabRDT";
  735. X            break;
  736. X        case XAB$C_FHC:
  737. X            type = "xabFHC";
  738. X            break;
  739. X        case XAB$C_PRO:
  740. X            type = "xabPRO";
  741. X            break;
  742. X        default:
  743. X            type = "Unknown";
  744. X            err = 1;
  745. X            break;
  746. X    }
  747. X    printf("Block @%08X of type %s (%d).", p, type, bid);
  748. X    if (err)
  749. X    {
  750. X        printf("\n");
  751. X        return;
  752. X    }
  753. X    printf(" Size = %d\n", len);
  754. X    printf(" Offset - Hex - Dec\n");
  755. X    for (i = 0; i < len; i += 8)
  756. X    {
  757. X        int j;
  758. X        printf("%3d - ", i);
  759. X        for (j = 0; j < 8; j++)
  760. X            if (i + j < len)
  761. X                printf("%02X ", p[i + j]);
  762. X            else
  763. X                printf("   ");
  764. X        printf(" - ");
  765. X        for (j = 0; j < 8; j++)
  766. X            if (i + j < len)
  767. X                printf("%03d ", p[i + j]);
  768. X            else
  769. X                printf("    ");
  770. X        printf("\n");
  771. X    }
  772. X}
  773. X
  774. X#ifdef OLD_COMPRESS
  775. X# define BC_METHOD      BC_00
  776. X# define        COMP_BLK(to,tos,from,froms) _compress( from,to,froms )
  777. X#else
  778. X# define BC_METHOD      BC_DEFL
  779. X# define        COMP_BLK(to,tos,from,froms) memcompress(to,tos,from,froms)
  780. X#endif
  781. X
  782. Xstatic uch *_compress_block(to,from,size,sig)
  783. Xregister struct extra_block *to;
  784. Xuch *from,*sig;
  785. Xint size;
  786. X{                               
  787. X        ulg cl;
  788. X        to -> im_sig =  *(ush*)SIGNATURE;
  789. X        to -> block_sig =       *(ulg*)(sig);
  790. X        to -> flags =           BC_METHOD;
  791. X        to -> length =  size;
  792. X#ifdef DEBUG
  793. X        printf("\nmemcompr(%d,%d,%d,%d)\n",&(to->body[0]),size+PAD,from,size);
  794. X#endif
  795. X        cl = COMP_BLK( &(to->body[0]), size+PAD, from, size );
  796. X#ifdef DEBUG
  797. X        printf("Compressed to %d\n",cl);
  798. X#endif
  799. X        if( cl >= size )
  800. X        {       memcpy(&(to->body[0]), from, size);
  801. X                to->flags = BC_STORED;
  802. X                cl = size;
  803. X#ifdef DEBUG
  804. X                printf("Storing block...\n");
  805. X#endif
  806. X        }
  807. X        return (uch*)(to) + (to->size = cl + EXTBSL + RESL) + 4;
  808. X}
  809. X
  810. X#define NBITS 32
  811. X
  812. Xstatic int _compress(from,to,size)
  813. Xuch *from,*to;
  814. Xint size;
  815. X{
  816. X    int off=0;
  817. X    ulg bitbuf=0;
  818. X    int bitcnt=0;
  819. X    int i;
  820. X
  821. X#define _BIT(val,len)   {                       \
  822. X        if(bitcnt + (len) > NBITS)              \
  823. X            while(bitcnt >= 8)                  \
  824. X            {                                   \
  825. X                to[off++] = (uch)bitbuf;        \
  826. X                bitbuf >>= 8;                   \
  827. X                bitcnt -= 8;                    \
  828. X            }                                   \
  829. X        bitbuf |= ((ulg)(val))<<bitcnt;         \
  830. X        bitcnt += len;                          \
  831. X    }
  832. X
  833. X#define _FLUSH  {                               \
  834. X            while(bitcnt>0)                     \
  835. X            {                                   \
  836. X                to[off++] = (uch)bitbuf;        \
  837. X                bitbuf >>= 8;                   \
  838. X                bitcnt -= 8;                    \
  839. X            }                                   \
  840. X        }
  841. X
  842. X    for(i=0; i<size; i++)
  843. X    {
  844. X        if( from[i] )
  845. X        {
  846. X                _BIT(1,1);
  847. X                _BIT(from[i],8);
  848. X        }
  849. X        else
  850. X            _BIT(0,1);
  851. X    }
  852. X    _FLUSH;
  853. X    return off;
  854. X}
  855. X
  856. X#endif                          /* ?VMS */
  857. END_OF_FILE
  858.   if test 18616 -ne `wc -c <'vms/vms.c'`; then
  859.     echo shar: \"'vms/vms.c'\" unpacked with wrong size!
  860.   fi
  861.   # end of 'vms/vms.c'
  862. fi
  863. if test -f 'vms/vms_zip.rnh' -a "${1}" != "-c" ; then 
  864.   echo shar: Will not clobber existing file \"'vms/vms_zip.rnh'\"
  865. else
  866.   echo shar: Extracting \"'vms/vms_zip.rnh'\" \(18026 characters\)
  867.   sed "s/^X//" >'vms/vms_zip.rnh' <<'END_OF_FILE'
  868. X.!
  869. X.!  File:    ZIP.RNH
  870. X.!
  871. X.!  Author:    Hunter Goatley
  872. X.!
  873. X.!  Date:    October 22, 1991
  874. X.!
  875. X.!  Description:
  876. X.!
  877. X.!    RUNOFF source file for portable ZIP on-line help for VMS.
  878. X.!    Adapted from ZIP.DOC, distributed with ZIP.
  879. X.!
  880. X.!    To build:    $ RUNOFF ZIP.RNH
  881. X.!            $ LIBR/HELP/INSERT libr ZIP
  882. X.!
  883. X.!  Modification history:
  884. X.!
  885. X.!    Hunter Goatley        22-OCT-1991 20:45
  886. X.!        Genesis.
  887. X.!    Jean-loup Gailly    25 March 92
  888. X.!        Adaptation to zip 1.6.
  889. X.!    Igor Mandrichenko    9-JUN-1992
  890. X.!        Added explanation of -V option.
  891. X.!    Jean-loup Gailly    14 June 92
  892. X.!        Adaptation to zip 1.8.
  893. X.!    Jean-loup Gailly    20 Aug 92
  894. X.!        Adaptation to zip 1.9.
  895. X.!
  896. X.noflags
  897. X.lm4 .rm72
  898. X.indent -4
  899. X1 ZIP
  900. X.br
  901. XZip is a compression and file packaging utility for Unix, MSDOS, OS/2, and
  902. XVMS.  It is analogous to a combination of tar and compress and is
  903. Xcompatible with PKZIP (Phil Katz ZIP) for MSDOS systems.
  904. X.sk
  905. XThere is a companion to Zip called UnZip (of course).  Zip and UnZip can
  906. Xwork with files produced by PKZIP under MSDOS, and PKZIP and PKUNZIP can
  907. Xwork with files produced by Zip.
  908. X.sk
  909. XZip 1.9 is compatible with PKZIP 1.93a.
  910. XNote that pkunzip 1.10 cannot extract files produced by pkzip 1.93a
  911. Xor zip 1.9. You must use pkzip 1.93a or unzip 5.0 to extract them.
  912. X.sk
  913. XFor a brief help on Zip and Unzip, run each without specifying any
  914. Xparameters on the command line.
  915. X.sk
  916. XZip puts one or more compressed files into a single "zip file" along with
  917. Xinformation about the files, including the name, path if requested, date
  918. Xand time last modified, protection, and check information to verify the
  919. Xfidelity of each entry.  Zip can pack an entire directory structure in a
  920. Xzip file with a single command.  Compression ratios of 2:1 to 3:1 are
  921. Xcommon for text files.  Zip has has one compression method (deflation) and
  922. Xcan also store files without compression. It automatically chooses the better
  923. Xof the two for each file to be compressed.
  924. X.sk
  925. XZip is useful for packaging a set of files to send to someone or for
  926. Xdistribution; for archiving or backing up files; and for saving disk space
  927. Xby temporarily compressing unused files or directories.
  928. X.sk
  929. XFormat:
  930. X.sk;.lm+1;.literal
  931. XZIP [-options] [-b path] [-n suffixes] [-t mmddyy] zipfile file(s) [-x list]
  932. X.end literal;.lm-1
  933. X.!------------------------------------------------------------------------------
  934. X.indent -4
  935. X2 Options
  936. X.br
  937. XThe default action of Zip is to add or replace zipfile entries from list, which
  938. Xcan include the special name -@ to read names from SYS$INPUT.  The following
  939. Xlist of options was taken from the on-line help generated when Zip is run
  940. Xwithout any command-line parameters:
  941. X.sk
  942. X.literal
  943. X  -f   freshen: only changed files
  944. X  -d   delete entries in zipfile
  945. X  -k   simulate PKZIP made zipfile
  946. X  -h   show this help
  947. X  -r   recurse into directories
  948. X  -q   quiet operation
  949. X  -c   add one-line comments
  950. X  -b   use "path" for temp files
  951. X  -o   make zipfile as old as latest entry
  952. X  -w   append the VMS version number to name stored in zip file
  953. X  -x   exclude the names that follow from those operated on
  954. X  -u   update: only changed or new files
  955. X  -m   move into zipfile (delete files)
  956. X  -g   allow growing existing zipfile
  957. X  -l   translate end-of-lines
  958. X  -j   junk (don't record) directory names
  959. X  -0   store only
  960. X  -1   compress faster
  961. X  -9   compress better
  962. X  -n   don't compress theses suffixes
  963. X  -z   add zipfile comment
  964. X  -t   only do files after "mmddyy"
  965. X  -L   show software license
  966. X  -V   save VMS file attributes
  967. X.end literal
  968. X.!------------------------------------------------------------------------------
  969. X.indent -4
  970. X2 How_To_Use_Zip
  971. X.br
  972. XThe simplest use of Zip is as follows:
  973. X.sk;.indent 10;$ zip stuff *
  974. X.sk
  975. XThis will create the file "STUFF.ZIP" (assuming it does not exist) and put
  976. Xall the files in the current directory in STUFF.ZIP in a compressed form.
  977. XThe .ZIP suffix is added automatically, unless that file name given
  978. Xcontains a dot already.  This allows specifying suffixes other than ".ZIP".
  979. X.sk
  980. XTo zip up an entire directory, the command:
  981. X.sk;.indent 10
  982. X$ zip -r foo *.*
  983. X.sk
  984. Xwill create the file "FOO.ZIP" containing all the files and directories in
  985. Xthe in the current directory.  The "r" option means recurse through the
  986. Xdirectory structure.
  987. X.sk
  988. XYou may want to make a zip file that contains the files in [.FOO], but not
  989. Xrecord the directory name, FOO.  You can use the -j (junk path) option to
  990. Xleave off the path:
  991. X.sk;.indent 10
  992. X$ zip -j foo [.foo]*.*
  993. X.sk
  994. XYou might be zipping to save disk space, in which case you could:
  995. X.sk;.indent 10
  996. X$ zip -rm foo *.txt
  997. X.sk
  998. Xwhere the "m" option means "move".  This will delete all files matching
  999. X*.txt after making FOO.ZIP.  No deletions will be done until the zip has
  1000. Xcompleted with no errors.  This option is obviously more dangerous and
  1001. Xshould be used with care.
  1002. X.sk
  1003. XIf the zip file already exists, these commands will replace existing or add
  1004. Xnew entries to the zip file.  For example, if you were really short on disk
  1005. Xspace, you might not have enough room simultaneously to hold the directory
  1006. X[.FOO] and the compressed FOO.ZIP.  In this case, you could do it in steps.
  1007. XIf [.FOO] contained the subdirectories [.TOM], [.DICK], and [.HARRY], then
  1008. Xyou could:
  1009. X.sk;
  1010. X.indent 10;$ zip -rm foo [.foo.tom]
  1011. X.indent 10;$ zip -rm foo [.foo.dick]
  1012. X.indent 10;$ zip -rm foo [.foo.harry]
  1013. X.sk
  1014. Xwhere the first command would create FOO.ZIP, and the next two would add to
  1015. Xit.  At the completion of each zip command, the files in the directory just
  1016. Xzipped would be deleted, making room in which the next Zip command could
  1017. Xwork.
  1018. X.!------------------------------------------------------------------------------
  1019. X.indent -4
  1020. X2 Modifying_Existing_Zip_Files
  1021. X.br
  1022. XWhen given the name of an existing zip file with the above commands, Zip
  1023. Xwill replace identically named entries in the Zip file or add entries for
  1024. Xnew names.  For example, if FOO.ZIP exists and contains foo/file1 and
  1025. Xfoo/file2, and the directory [.FOO] contains the files foo/file1 and
  1026. Xfoo/file3, then:
  1027. X.sk;.indent 10
  1028. X$ zip -r foo foo
  1029. X.sk
  1030. Xwill replace foo/file1 in foo.zip and add foo/file3 to FOO.ZIP.  After
  1031. Xthis, FOO.ZIP contains foo/file1, foo/file2, and foo/file3, with foo/file2
  1032. Xunchanged from before.
  1033. X.sk
  1034. XWhen changing an existing zip file, Zip will write a temporary file with
  1035. Xthe new contents, and only replace the old one when the zip has completed
  1036. Xwith no errors. You can use
  1037. Xthe -b option to specify a different path (usually a different dev- ice) to
  1038. Xput the temporary files in.  For example:
  1039. X.sk;.indent 10
  1040. X$ zip -b scratch$:[tmp] stuff *
  1041. X.sk
  1042. Xwill put the temporary zip file and the temporary compression files in the
  1043. Xdirectory "SCRATCH$:[TMP]", copying over STUFF.ZIP in the current directory
  1044. Xwhen done.
  1045. X.sk
  1046. XIf you are only adding entries to a zip file, not replacing, and the -g
  1047. Xoption is given, then Zip grows (appends to) the file instead of copying
  1048. Xit.  The danger of this is that if the operation fails, the original zip
  1049. Xfile is corrupted and lost.
  1050. X.sk
  1051. XThere are two other ways to change or add entries in a zip file that are
  1052. Xrestrictions of simple addition or replacement.  The first is -u (update)
  1053. Xwhich will add new entries to the zip file as before but will replace
  1054. Xexisting entries only if the modified date of the file is more recent than
  1055. Xthe date recorded for that name in the zip file.  For example:
  1056. X.sk;.indent 10
  1057. X$ zip -u stuff *
  1058. X.sk
  1059. Xwill add any new files in the current directory, and update any changed
  1060. Xfiles in the zip file STUFF.ZIP.  Note that Zip will not try to pack
  1061. XSTUFF.ZIP into itself when you do this. Zip will always exclude the zip
  1062. Xfile from the files on which to be operated.
  1063. X.sk
  1064. XThe second restriction is -f (freshen) which, like update, will only
  1065. Xreplace entries with newer files; unlike update, will not add files that
  1066. Xare not already in the zip file. For this option, you may want to simply
  1067. Xfreshen all of the files that are in the specified zip file.  To do this
  1068. Xyou would simply:
  1069. X.sk;.indent 10
  1070. X$ zip -f foo
  1071. X.sk
  1072. XNote that the -f option with no arguments freshens all the entries in the
  1073. Xzip file.  The same is true of -u, and hence "zip -u foo" and "zip -f foo"
  1074. Xboth do the same thing.
  1075. X.sk
  1076. XThis command should be run from the same directory from which the original
  1077. Xzip command was run, since paths stored in zip files are always relative.
  1078. X.sk
  1079. XAnother restriction that can be used with adding, updating, or freshening
  1080. Xis -t (time), which will not operate on files modified earlier than the
  1081. Xspecified date.  For example:
  1082. X.sk;.indent 10
  1083. X$ zip -rt 120791 infamy [.FOO]*.*
  1084. X.sk
  1085. Xwill add all the files in [.FOO] and its subdirectories that were last
  1086. Xmodified on December 7, 1991, or later to the zip file INFAMY.ZIP.
  1087. X.sk
  1088. XAlso, files can be explicitly excluded using the -x option:
  1089. X.sk;.indent 10
  1090. X$ zip -r foo [.FOO] -x *.obj
  1091. X.sk
  1092. Xwhich will zip up the contents of [.FOO] into FOO.ZIP but exclude all the
  1093. Xfiles that end in ".OBJ".
  1094. X.sk
  1095. XThe last operation is -d (delete) which will remove entries from a zip
  1096. Xfile.  An example might be:
  1097. X.sk;.indent 10
  1098. X$ zip -d foo foo/harry/*.* *.obj
  1099. X.sk
  1100. Xwhich will remove all of the files that start with "foo/harry/" and all of
  1101. Xthe files that end with ".OBJ" (in any path).
  1102. X.sk
  1103. XUnder MSDOS, -d is case sensitive when it matches names in the zip file.
  1104. XThis allows deleting names that were zipped on other systems, but requires
  1105. Xthat the names be entered in upper case if they were zipped on an MSDOS
  1106. Xsystem, so that the names can be found in the zip file and deleted.
  1107. X.!------------------------------------------------------------------------------
  1108. X.indent -4
  1109. X2 More_Options
  1110. X.br
  1111. XAs mentioned before, Zip will use the best of two methods: deflate or store.
  1112. XThe option -0 will force Zip to use store on all files. For example:
  1113. X.sk;.indent 10
  1114. Xzip -r0 foo foo
  1115. X.sk
  1116. Xwill zip up the directory foo into foo.zip using only store.
  1117. X.sk
  1118. XThe speed of deflation can also be controlled with options -1 (fastest
  1119. Xmethod but less compression) to -9 (best compression but slower). The
  1120. Xdefault value is -5. For example:
  1121. X.sk;.indent 10
  1122. Xzip -r8 foo foo
  1123. X.sk
  1124. XIn nearly all cases, a file that is already compressed cannot be compressed
  1125. Xfurther by Zip, or if it can, the effect is minimal.  The -n option
  1126. Xprevents Zip from trying to compress files that have the
  1127. Xgiven suffixes.  Such files are simply stored (0%
  1128. Xcompression) in the
  1129. Xoutput zip file, so that Zip doesn't waste its time trying to compress
  1130. Xthem. The suffixes are separated by
  1131. Xeither colons or semicolons.  For example, in DCL:
  1132. X.sk
  1133. X.indent 10;$ zip -rn ".Z:.zip:.tiff:.gif:.snd" foo [.FOO]*.*
  1134. X.sk
  1135. Xwill put everything in [.FOO] into FOO.ZIP, but will store any files that end
  1136. Xin .Z, .ZIP, .TIFF, .GIF, or .SND without trying to compress them.  (Image and
  1137. Xsound files often have their own specialized compression methods.)
  1138. XThe default suffix list is ".Z:.zip;.zoo:.arc:.lzh:.arj".
  1139. XThe environment variable ZIPOPT can be used to change this default. For
  1140. Xexample:
  1141. X.sk
  1142. X.indent 10;$ ZIPOPT == "-n .Z:.zip:.tiff:.gif:.snd"
  1143. X.sk
  1144. XThe variable ZIPOPT can be used for any option and can include several
  1145. Xoptions.
  1146. X.sk
  1147. XUnder Unix and under OS/2 (if files from a HPFS are stored), Zip will store
  1148. Xthe full path (relative to the current path) and name of the file (or just
  1149. Xthe name if -j is specified) in the zip file along with the Unix
  1150. Xattributes, and it will mark the entry as made under Unix.  If the zip file
  1151. Xis intended for PKUNZIP under MSDOS, then the -k (Katz) option should be
  1152. Xused to attempt to convert the names and paths to conform to MSDOS, store
  1153. Xonly the MSDOS attribute (just the user write attribute from Unix), and
  1154. Xmark the entry as made under MSDOS (even though it wasn't).
  1155. X.sk
  1156. XThe -o (older) option will set the "last modified" time of the zip file to
  1157. Xthe latest "last modified" time of the entries in the zip file.  This can
  1158. Xbe used without any other operations, if desired.  For example:
  1159. X.sk;.indent 10
  1160. X$ zip -o foo
  1161. X.sk
  1162. Xwill change the last modified time of FOO.ZIP to the latest time of the
  1163. Xentries in FOO.ZIP.
  1164. X.sk
  1165. XThe -e and -c options operate on all files updated or added to the zip
  1166. Xfile.  Encryption (-e) will prompt for a password on the terminal and will
  1167. Xnot echo the password as it is typed (if stderr is not a TTY, Zip will exit
  1168. Xwith an error). New zip entries will be encrypted using that password.  For
  1169. Xadded peace of mind, you can use -ee, which will prompt for the password
  1170. Xtwice, checking that the two are the same before using it.
  1171. X.sk
  1172. XOne-line comments can be added for each file with the -c option.  The zip
  1173. Xfile operations (adding or updating) will be done first, and you will then
  1174. Xbe prompted for a one-line comment for each file.  You can then enter the
  1175. Xcomment followed by return, or just return for no comment.
  1176. X.sk
  1177. XThe -z option will prompt you for a multi-line comment for the entire zip
  1178. Xfile.  This option can be used by itself, or in combination with other
  1179. Xoptions.  The comment is ended by a line containing just a period, or an
  1180. Xend of file condition (^D on Unix, ^Z on MSDOS, OS/2, and VAX/VMS).
  1181. X.sk
  1182. XThe -q (quiet) option eliminates the informational messages and comment
  1183. Xprompts while Zip is operating.  This might be used in shell scripts, for
  1184. Xexample, or if the zip operation is being performed as a background task
  1185. X("$ spawn/nowait zip -q foo *.c").
  1186. X.sk
  1187. XZip can take a list of file names to operate on from SYS$INPUT using the
  1188. X"-@"
  1189. Xoption.
  1190. X.!  In Unix, this option can be used with the find command to extend
  1191. X.!greatly the functionality of Zip. For example, to zip up all the C source
  1192. X.!files in the current directory and its subdirectories, you can:
  1193. X.!.sk
  1194. X.!find . -type f -name "*.[ch]" -print | zip source -@
  1195. X.!.sk
  1196. X.!Note that the pattern must be quoted to keep the shell from expanding it.
  1197. X.sk
  1198. XUnder VMS only, the -w option will append the version number of the files
  1199. Xto the name and zip up multiple versions of files.  Without -w, Zip will
  1200. Xonly use the most recent version of the specified file(s).
  1201. X.sk
  1202. XOne more option that valid only under VMS is -V option. This option saves
  1203. Xall (hopefully) file attributes needed to make EXACT copy of the
  1204. Xfile after extraction from archive. To extract a file with saved attributes
  1205. Xuse UnZip version 4.2 or later. Note that to specify this option you should
  1206. Xquote it ("-V"). Be carefull: it's rather hard (if possible at all) to extract
  1207. Xa file archived on VMS with this option specified on other systems. See 
  1208. Xdocumentation on UnZip for further information.
  1209. X.sk
  1210. XThe -l option translates the Unix end-of-line character LF into the
  1211. XMSDOS convention CR LF. This option should not be used on binary files.
  1212. XThis option can be used on Unix if the zip file is intended for PKUNZIP
  1213. Xunder MSDOS.
  1214. X.sk
  1215. XIf Zip is run with the -h option, or with no arguments and standard output is
  1216. Xa terminal, the license and the command-argument and option help is shown.
  1217. XThe -L option just shows the license.
  1218. X.!------------------------------------------------------------------------------
  1219. X.indent -4
  1220. X2 Copyright
  1221. X.br
  1222. X     Copyright (C) 1990,1991 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  1223. X     Igor Mandrichenko and Kai Uwe Rommel. Permission is granted to any
  1224. X     individual or institution to use, copy, or redistribute this software
  1225. X     so long as all of the original files are included unmodified,
  1226. X     that it is not sold for profit, and that this copyright
  1227. X     notice is retained.
  1228. X.!------------------------------------------------------------------------------
  1229. X.indent -4
  1230. X2 Acknowledgements
  1231. X.br
  1232. X     Thanks to R. P. Byrne for his Shrink.Pas program which
  1233. X     inspired this project; to Phil Katz for making the zip file format,
  1234. X     compression format, and .ZIP filename extension all public
  1235. X     domain; to Steve Burg and Phil Katz for help on unclear points of
  1236. X     the deflate format; to Keith Petersen for providing a mailing list and
  1237. X     ftp site for the INFO-ZIP group to use; and most importantly, to
  1238. X     the INFO-ZIP group itself (listed in the file
  1239. X     infozip.who) without whose tireless testing and bug-fixing
  1240. X     efforts a portable Zip would not have been possible.
  1241. X     Finally we should thank (blame) the INFO-ZIP moderator,
  1242. X     David Kirschbaum for getting us into this mess in the first
  1243. X     place.
  1244. X.!------------------------------------------------------------------------------
  1245. X.indent -4
  1246. X2 Bugs
  1247. X.sk
  1248. X     WARNING: zip files produced by this version of zip must not be
  1249. X     *updated* by zip 1.0 or pkzip 1.10 or pkzip 1.93a, if they contain
  1250. X     encrypted members, or if they have been produced in a pipe or on a non
  1251. X     seekable device. The old versions of zip or pkzip would destroy the
  1252. X     zip structure. The old versions can list the contents of the zip file
  1253. X     but cannot extract it anyway (because of the new compression algorithm).
  1254. X     If you do not use encryption and use regular disk files, you do
  1255. X     not have to care about this problem.
  1256. X.sk
  1257. X     Under VMS, not all of the odd file formats are treated properly.  Only
  1258. X     zip files of format stream-LF and fixed length 512 are expected to work
  1259. X     with Zip.  Others can be converted using Rahul Dhesi's BILF
  1260. X     program.  This version of Zip does handle some of the
  1261. X     conversion internally.
  1262. X     When using Kermit to transfer zip files from Vax to MSDOS, type "set
  1263. X     file type block" on the Vax.  When transfering from MSDOS to Vax, type
  1264. X     "set file type fixed" on the Vax.  In both cases, type "set file type
  1265. X     binary" on MSDOS.
  1266. X.sk
  1267. X     Under VMS, zip hangs for file specification that uses DECnet
  1268. X     syntax (foo::*.*).
  1269. X.sk
  1270. X     LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES
  1271. X     ARE PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY
  1272. X     KIND, EITHER EXPRESSED OR IMPLIED. IN NO EVENT WILL THE
  1273. X     COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES RESULTING FROM
  1274. X     THE USE OF THIS SOFTWARE.
  1275. X.sk
  1276. X     That having been said, please send any problems or comments
  1277. X     via email to the Internet address zip-bugs@cs.ucla.edu.  For
  1278. X     bug reports, please include the version of Zip, the make
  1279. X     options you used to compile it, the machine and operating
  1280. X     system you are using, and as much additional information as
  1281. X     possible.  Thank you for your support.
  1282. X.!------------------------------------------------------------------------------
  1283. END_OF_FILE
  1284.   if test 18026 -ne `wc -c <'vms/vms_zip.rnh'`; then
  1285.     echo shar: \"'vms/vms_zip.rnh'\" unpacked with wrong size!
  1286.   fi
  1287.   # end of 'vms/vms_zip.rnh'
  1288. fi
  1289. if test -f 'zipsplit.c' -a "${1}" != "-c" ; then 
  1290.   echo shar: Will not clobber existing file \"'zipsplit.c'\"
  1291. else
  1292.   echo shar: Extracting \"'zipsplit.c'\" \(17114 characters\)
  1293.   sed "s/^X//" >'zipsplit.c' <<'END_OF_FILE'
  1294. X/*
  1295. X
  1296. X Copyright (C) 1990-1992 Mark Adler, Richard B. Wales, Jean-loup Gailly,
  1297. X Kai Uwe Rommel and Igor Mandrichenko.
  1298. X Permission is granted to any individual or institution to use, copy, or
  1299. X redistribute this software so long as all of the original files are included
  1300. X unmodified, that it is not sold for profit, and that this copyright notice
  1301. X is retained.
  1302. X
  1303. X*/
  1304. X
  1305. X/*
  1306. X *  zipsplit.c by Mark Adler.
  1307. X */
  1308. X
  1309. X#define UTIL
  1310. X#include "revision.h"
  1311. X#include "zip.h"
  1312. X#include <signal.h>
  1313. X
  1314. X#define DEFSIZ 36000L   /* Default split size (change in help() too) */
  1315. X#ifdef MSDOS
  1316. X#  define NL 2          /* Number of bytes written for a \n */
  1317. X#else /* !MSDOS */
  1318. X#  define NL 1          /* Number of bytes written for a \n */
  1319. X#endif /* ?MSDOS */
  1320. X#define INDEX "zipsplit.idx"    /* Name of index file */
  1321. X
  1322. X
  1323. X/* Local functions */
  1324. X#ifdef PROTO
  1325. X   local void handler(int);
  1326. X   local void license(void);
  1327. X   local void help(void);
  1328. X   local extent simple(ulg *, extent, ulg, ulg);
  1329. X   local int descmp(voidp *, voidp *);
  1330. X   local extent greedy(ulg *, extent, ulg, ulg);
  1331. X   void main(int, char **);
  1332. X#endif /* PROTO */
  1333. X
  1334. X
  1335. X/* Output zip files */
  1336. Xlocal char template[16];        /* name template for output files */
  1337. Xlocal int zipsmade = 0;         /* number of zip files made */
  1338. Xlocal int indexmade = 0;        /* true if index file made */
  1339. Xlocal char *path = NULL;        /* space for full name */
  1340. Xlocal char *name;               /* where name goes in path[] */
  1341. X
  1342. X
  1343. Xvoid err(c, h)
  1344. Xint c;                  /* error code from the ZE_ class */
  1345. Xchar *h;                /* message about how it happened */
  1346. X/* Issue a message for the error, clean up files and memory, and exit. */
  1347. X{
  1348. X  if (PERR(c))
  1349. X    perror("zipsplit error");
  1350. X  fprintf(stderr, "zipsplit error: %s (%s)\n", errors[c-1], h);
  1351. X  if (indexmade)
  1352. X  {
  1353. X    strcpy(name, INDEX);
  1354. X    destroy(path);
  1355. X  }
  1356. X  for (; zipsmade; zipsmade--)
  1357. X  {
  1358. X    sprintf(name, template, zipsmade);
  1359. X    destroy(path);
  1360. X  }
  1361. X  if (path != NULL)
  1362. X    free((voidp *)path);
  1363. X  if (zipfile != NULL)
  1364. X    free((voidp *)zipfile);
  1365. X#ifdef VMS
  1366. X  exit(0);
  1367. X#else /* !VMS */
  1368. X  exit(c);
  1369. X#endif /* ?VMS */
  1370. X}
  1371. X
  1372. X
  1373. X
  1374. Xlocal void handler(s)
  1375. Xint s;                  /* signal number (ignored) */
  1376. X/* Upon getting a user interrupt, abort cleanly using err(). */
  1377. X{
  1378. X#ifndef MSDOS
  1379. X  putc('\n', stderr);
  1380. X#endif /* !MSDOS */
  1381. X  err(ZE_ABORT, "aborting");
  1382. X  s++;                                  /* keep some compilers happy */
  1383. X}
  1384. X
  1385. X
  1386. Xvoid warn(a, b)
  1387. Xchar *a, *b;            /* message strings juxtaposed in output */
  1388. X/* Print a warning message to stderr and return. */
  1389. X{
  1390. X  fprintf(stderr, "zipsplit warning: %s%s\n", a, b);
  1391. X}
  1392. X
  1393. X
  1394. Xlocal void license()
  1395. X/* Print license information to stdout. */
  1396. X{
  1397. X  extent i;             /* counter for copyright array */
  1398. X
  1399. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
  1400. X    printf(copyright[i], "zipsplit");
  1401. X    putchar('\n');
  1402. X  }
  1403. X  for (i = 0; i < sizeof(disclaimer)/sizeof(char *); i++)
  1404. X    puts(disclaimer[i]);
  1405. X}
  1406. X
  1407. X
  1408. Xlocal void help()
  1409. X/* Print help (along with license info) to stdout. */
  1410. X{
  1411. X  extent i;             /* counter for help array */
  1412. X
  1413. X  /* help array */
  1414. X  static char *text[] = {
  1415. X"",
  1416. X"ZipSplit %d.%d (%s)",
  1417. X"Usage:  zipsplit [-ti] [-n size] [-b path] zipfile",
  1418. X"  -t   report how many files it will take, but don't make them",
  1419. X"  -i   make index (zipsplit.idx) and count its size against first zip file",
  1420. X"  -n   make zip files no larger than \"size\" (default = 36000)",
  1421. X"  -b   use \"path\" for the output zip files",
  1422. X"  -s   do a sequential split even if it takes more zip files",
  1423. X"  -h   show this help               -L   show software license"
  1424. X  };
  1425. X
  1426. X  for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
  1427. X    printf(copyright[i], "zipsplit");
  1428. X    putchar('\n');
  1429. X  }
  1430. X  for (i = 0; i < sizeof(text)/sizeof(char *); i++)
  1431. X  {
  1432. X    printf(text[i], REVISION / 10, REVISION % 10, REVDATE);
  1433. X    putchar('\n');
  1434. X  }
  1435. X}
  1436. X
  1437. X
  1438. Xlocal extent simple(a, n, c, d)
  1439. Xulg *a;         /* items to put in bins, return value: destination bins */
  1440. Xextent n;       /* number of items */
  1441. Xulg c;          /* capacity of each bin */
  1442. Xulg d;          /* amount to deduct from first bin */
  1443. X/* Return the number of bins of capacity c that are needed to contain the
  1444. X   integers in a[0..n-1] placed sequentially into the bins.  The value d
  1445. X   is deducted initially from the first bin (space for index).  The entries
  1446. X   in a[] are replaced by the destination bins. */
  1447. X{
  1448. X  extent k;     /* current bin number */
  1449. X  ulg t;        /* space used in current bin */
  1450. X
  1451. X  t = k = 0;
  1452. X  while (n--)
  1453. X  {
  1454. X    if (*a + t > c - (k == 0 ? d : 0))
  1455. X    {
  1456. X      k++;
  1457. X      t = 0;
  1458. X    }
  1459. X    t += *a;
  1460. X    *(ulg huge *)a++ = k;
  1461. X  }
  1462. X  return k + 1;
  1463. X}
  1464. X
  1465. X
  1466. Xlocal int descmp(a, b)
  1467. Xvoidp *a, *b;           /* pointers to pointers to ulg's to compare */
  1468. X/* Used by qsort() in greedy() to do a descending sort. */
  1469. X{
  1470. X  return **(ulg **)a < **(ulg **)b ? 1 : (**(ulg **)a > **(ulg **)b ? -1 : 0);
  1471. X}
  1472. X
  1473. X
  1474. Xlocal extent greedy(a, n, c, d)
  1475. Xulg *a;         /* items to put in bins, return value: destination bins */
  1476. Xextent n;       /* number of items */
  1477. Xulg c;          /* capacity of each bin */
  1478. Xulg d;          /* amount to deduct from first bin */
  1479. X/* Return the number of bins of capacity c that are needed to contain the
  1480. X   items with sizes a[0..n-1] placed non-sequentially into the bins.  The
  1481. X   value d is deducted initially from the first bin (space for index).
  1482. X   The entries in a[] are replaced by the destination bins. */
  1483. X{
  1484. X  ulg *b;       /* space left in each bin (malloc'ed for each m) */
  1485. X  ulg *e;       /* copy of argument a[] (malloc'ed) */
  1486. X  extent i;     /* steps through items */
  1487. X  extent j;     /* steps through bins */
  1488. X  extent k;     /* best bin to put current item in */
  1489. X  extent m;     /* current number of bins */
  1490. X  ulg **s;      /* pointers to e[], sorted descending (malloc'ed) */
  1491. X  ulg t;        /* space left in best bin (index k) */
  1492. X
  1493. X  /* Algorithm:
  1494. X     1. Copy a[] to e[] and sort pointers to e[0..n-1] (in s[]), in
  1495. X        descending order.
  1496. X     2. Compute total of s[] and set m to the smallest number of bins of
  1497. X        capacity c that can hold the total.
  1498. X     3. Allocate m bins.
  1499. X     4. For each item in s[], starting with the largest, put it in the
  1500. X        bin with the smallest current capacity greater than or equal to the
  1501. X        item's size.  If no bin has enough room, increment m and go to step 4.
  1502. X     5. Else, all items ended up in a bin--return m.
  1503. X  */
  1504. X
  1505. X  /* Copy a[] to e[], put pointers to e[] in s[], and sort s[].  Also compute
  1506. X     the initial number of bins (minus 1). */
  1507. X  if ((e = (ulg *)malloc(n * sizeof(ulg))) == NULL ||
  1508. X      (s = (ulg **)malloc(n * sizeof(ulg *))) == NULL)
  1509. X  {
  1510. X    if (e != NULL)
  1511. X      free((voidp *)e);
  1512. X    err(ZE_MEM, "was trying a smart split");
  1513. X    return 0;                           /* only to make compiler happy */
  1514. X  }
  1515. X  memcpy((char *)e, (char *)a, n * sizeof(ulg));
  1516. X  for (t = i = 0; i < n; i++)
  1517. X    t += *(s[i] = e + i);
  1518. X  m = (extent)((t + c - 1) / c) - 1;    /* pre-decrement for loop */
  1519. X  qsort((char *)s, n, sizeof(ulg *), descmp);
  1520. X
  1521. X  /* Stuff bins until successful */
  1522. X  do {
  1523. X    /* Increment the number of bins, allocate and initialize bins */
  1524. X    if ((b = (ulg *)malloc(++m * sizeof(ulg))) == NULL)
  1525. X    {
  1526. X      free((voidp *)s);
  1527. X      free((voidp *)e);
  1528. X      err(ZE_MEM, "was trying a smart split");
  1529. X    }
  1530. X    b[0] = c - d;                       /* leave space in first bin */
  1531. X    for (j = 1; j < m; j++)
  1532. X      b[j] = c;
  1533. X
  1534. X    /* Fill the bins greedily */
  1535. X    for (i = 0; i < n; i++)
  1536. X    {
  1537. X      /* Find smallest bin that will hold item i (size s[i]) */
  1538. X      t = c + 1;
  1539. X      for (k = j = 0; j < m; j++)
  1540. X        if (*s[i] <= b[j] && b[j] < t)
  1541. X          t = b[k = j];
  1542. X
  1543. X      /* If no bins big enough for *s[i], try next m */
  1544. X      if (t == c + 1)
  1545. X        break;
  1546. X
  1547. X      /* Diminish that bin and save where it goes */
  1548. X      b[k] -= *s[i];
  1549. X      a[(int)((ulg huge *)(s[i]) - (ulg huge *)e)] = k;
  1550. X    }
  1551. X
  1552. X    /* Clean up */
  1553. X    free((voidp *)b);
  1554. X
  1555. X    /* Do until all items put in a bin */
  1556. X  } while (i < n);
  1557. X
  1558. X  /* Done--clean up and return the number of bins needed */
  1559. X  free((voidp *)s);
  1560. X  free((voidp *)e);
  1561. X  return m;
  1562. X}
  1563. X
  1564. X
  1565. Xvoid main(argc, argv)
  1566. Xint argc;               /* number of tokens in command line */
  1567. Xchar **argv;            /* command line tokens */
  1568. X/* Split a zip file into several zip files less than a specified size.  See
  1569. X   the command help in help() above. */
  1570. X{
  1571. X  ulg *a;               /* malloc'ed list of sizes, dest bins */
  1572. X  extent *b;            /* heads of bin linked lists (malloc'ed) */
  1573. X  ulg c;                /* bin capacity, start of central directory */
  1574. X  int d;                /* if true, just report the number of disks */
  1575. X  FILE *e;              /* input zip file */
  1576. X  FILE *f;              /* output index and zip files */
  1577. X  extent g;             /* number of bins from greedy(), entry to write */
  1578. X  int h;                /* how to split--true means simple split, counter */
  1579. X  ulg i;                /* size of index file or zero if none */
  1580. X  extent j;             /* steps through zip entries, bins */
  1581. X  int k;                /* next argument type */
  1582. X  ulg *p;               /* malloc'ed list of sizes, dest bins for greedy() */
  1583. X  char *q;              /* steps through option characters */
  1584. X  int r;                /* temporary variable, counter */
  1585. X  extent s;             /* number of bins needed */
  1586. X  ulg t;                /* total of sizes, end of central directory */
  1587. X  struct zlist far **w; /* malloc'ed table for zfiles linked list */
  1588. X  int x;                /* if true, make an index file */
  1589. X  struct zlist far *z;  /* steps through zfiles linked list */
  1590. X
  1591. X
  1592. X  /* If no args, show help */
  1593. X  if (argc == 1)
  1594. X  {
  1595. X    help();
  1596. X    exit(0);
  1597. X  }
  1598. X
  1599. X  init_upper();           /* build case map table */
  1600. X
  1601. X  /* Go through args */
  1602. X  signal(SIGINT, handler);
  1603. X  signal(SIGTERM, handler);
  1604. X  k = h = x = d = 0;
  1605. X  c = DEFSIZ;
  1606. X  for (r = 1; r < argc; r++)
  1607. X    if (*argv[r] == '-')
  1608. X      if (argv[r][1])
  1609. X        for (q = argv[r]+1; *q; q++)
  1610. X          switch(*q)
  1611. X          {
  1612. X            case 'b':   /* Specify path for output files */
  1613. X              if (k)
  1614. X                err(ZE_PARMS, "options are separate and precede zip file");
  1615. X              else
  1616. X                k = 1;          /* Next non-option is path */
  1617. X              break;
  1618. X            case 'h':   /* Show help */
  1619. X              help();  exit(0);
  1620. X            case 'i':   /* Make an index file */
  1621. X              x = 1;
  1622. X              break;
  1623. X            case 'l': case 'L':  /* Show copyright and disclaimer */
  1624. X              license();  exit(0);
  1625. X            case 'n':   /* Specify maximum size of resulting zip files */
  1626. X              if (k)
  1627. X                err(ZE_PARMS, "options are separate and precede zip file");
  1628. X              else
  1629. X                k = 2;          /* Next non-option is size */
  1630. X              break;
  1631. X            case 's':
  1632. X              h = 1;    /* Only try simple */
  1633. X              break;
  1634. X            case 't':   /* Just report number of disks */
  1635. X              d = 1;
  1636. X              break;
  1637. X            default:
  1638. X              err(ZE_PARMS, "unknown option");
  1639. X          }
  1640. X      else
  1641. X        err(ZE_PARMS, "zip file cannot be stdin");
  1642. X    else
  1643. X      if (k == 0)
  1644. X        if (zipfile == NULL)
  1645. X        {
  1646. X          if ((zipfile = ziptyp(argv[r])) == NULL)
  1647. X            err(ZE_MEM, "was processing arguments");
  1648. X        }
  1649. X        else
  1650. X          err(ZE_PARMS, "can only specify one zip file");
  1651. X      else if (k == 1)
  1652. X      {
  1653. X        tempath = argv[r];
  1654. X        k = 0;
  1655. X      }
  1656. X      else              /* k must be 2 */
  1657. X      {
  1658. X        if ((c = (ulg)atol(argv[r])) < 100)     /* 100 is smallest zip file */
  1659. X          err(ZE_PARMS, "invalid size given");
  1660. X        k = 0;
  1661. X      }
  1662. X  if (zipfile == NULL)
  1663. X    err(ZE_PARMS, "need to specify zip file");
  1664. X
  1665. X
  1666. X  /* Read zip file */
  1667. X  if ((r = readzipfile()) != ZE_OK)
  1668. X    err(r, zipfile);
  1669. X  if (zfiles == NULL)
  1670. X    err(ZE_NAME, zipfile);
  1671. X
  1672. X  /* Make a list of sizes and check against capacity.  Also compute the
  1673. X     size of the index file. */
  1674. X  c -= ENDHEAD + 4;                     /* subtract overhead/zipfile */
  1675. X  if ((a = (ulg *)malloc(zcount * sizeof(ulg))) == NULL ||
  1676. X      (w = (struct zlist far **)malloc(zcount * sizeof(struct zlist far *))) ==
  1677. X       NULL)
  1678. X  {
  1679. X    if (a != NULL)
  1680. X      free((voidp *)a);
  1681. X    err(ZE_MEM, "was computing split");
  1682. X    return;
  1683. X  }
  1684. X  i = t = 0;
  1685. X  for (j = 0, z = zfiles; j < zcount; j++, z = z->nxt)
  1686. X  {
  1687. X    w[j] = z;
  1688. X    if (x)
  1689. X      i += z->nam + 6 + NL;
  1690. X    t += a[j] = 8 + LOCHEAD + CENHEAD +
  1691. X           2 * (ulg)z->nam + 2 * (ulg)z->ext + z->com + z->siz;
  1692. X    if (a[j] > c)
  1693. X    {
  1694. X      free((voidp *)w);  free((voidp *)a);
  1695. X      err(ZE_BIG, z->zname);
  1696. X    }
  1697. X  }
  1698. X
  1699. X  /* Decide on split to use, report number of files */
  1700. X  if (h)
  1701. X    s = simple(a, zcount, c, i);
  1702. X  else
  1703. X  {
  1704. X    if ((p = (ulg *)malloc(zcount * sizeof(ulg))) == NULL)
  1705. X    {
  1706. X      free((voidp *)w);  free((voidp *)a);
  1707. X      err(ZE_MEM, "was computing split");
  1708. X    }
  1709. X    memcpy((char *)p, (char *)a, zcount * sizeof(ulg));
  1710. X    s = simple(a, zcount, c, i);
  1711. X    g = greedy(p, zcount, c, i);
  1712. X    if (s <= g)
  1713. X      free((voidp *)p);
  1714. X    else
  1715. X    {
  1716. X      free((voidp *)a);
  1717. X      a = p;
  1718. X      s = g;
  1719. X    }
  1720. X  }
  1721. X  printf("%d zip files w%s be made (%d%% efficiency)\n",
  1722. X         s, d ? "ould" : "ill", ((200 * ((t + c - 1)/c)) / s + 1) >> 1);
  1723. X  if (d)
  1724. X  {
  1725. X    free((voidp *)w);  free((voidp *)a);
  1726. X    free((voidp *)zipfile);
  1727. X    zipfile = NULL;
  1728. X    return;
  1729. X  }
  1730. X
  1731. X  /* Set up path for output files */
  1732. X  if ((path = malloc(tempath == NULL ? 13 : strlen(tempath) + 14)) == NULL)
  1733. X    err(ZE_MEM, "was making output file names");
  1734. X  if (tempath == NULL)
  1735. X     name = path;
  1736. X  else
  1737. X  {
  1738. X    strcpy(path, tempath);
  1739. X    if (path[0] && path[strlen(path) - 1] != '/')
  1740. X      strcat(path, "/");
  1741. X    name = path + strlen(path);
  1742. X  }
  1743. X
  1744. X  /* Write the index file */
  1745. X  if (x)
  1746. X  {
  1747. X    strcpy(name, INDEX);
  1748. X    printf("creating %s\n", path);
  1749. X    indexmade = 1;
  1750. X    if ((f = fopen(path, "w")) == NULL)
  1751. X    {
  1752. X      free((voidp *)w);  free((voidp *)a);
  1753. X      err(ZE_CREAT, path);
  1754. X    }
  1755. X    for (j = 0; j < zcount; j++)
  1756. X      fprintf(f, "%5ld %s\n", a[j] + 1, w[j]->zname);
  1757. X    if ((j = ferror(f)) != 0 || fclose(f))
  1758. X    {
  1759. X      if (j)
  1760. X        fclose(f);
  1761. X      free((voidp *)w);  free((voidp *)a);
  1762. X      err(ZE_WRITE, path);
  1763. X    }
  1764. X  }
  1765. X
  1766. X  /* Make linked lists of results */
  1767. X  if ((b = (extent *)malloc(s * sizeof(extent))) == NULL)
  1768. X  {
  1769. X    free((voidp *)w);  free((voidp *)a);
  1770. X    err(ZE_MEM, "was computing split");
  1771. X  }
  1772. X  for (j = 0; j < s; j++)
  1773. X    b[j] = (extent)-1;
  1774. X  j = zcount;
  1775. X  while (j--)
  1776. X  {
  1777. X    g = (extent)a[j];
  1778. X    a[j] = b[g];
  1779. X    b[g] = j;
  1780. X  }
  1781. X
  1782. X  /* Make a name template for the zip files that is eight or less characters
  1783. X     before the .zip, and that will not overwrite the original zip file. */
  1784. X  for (k = 1, j = s; j >= 10; j /= 10)
  1785. X    k++;
  1786. X  if (k > 7)
  1787. X  {
  1788. X    free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1789. X    err(ZE_PARMS, "way too many zip files must be made");
  1790. X  }
  1791. X#ifdef VMS
  1792. X  if ((q = strrchr(zipfile, ']')) != NULL)
  1793. X#else /* !VMS */
  1794. X  if ((q = strrchr(zipfile, '/')) != NULL)
  1795. X#endif /* ?VMS */
  1796. X    q++;
  1797. X  else
  1798. X    q = zipfile;
  1799. X  r = 0;
  1800. X  while ((g = *q++) != 0 && g != '.' && r < 8 - k)
  1801. X    template[r++] = (char)g;
  1802. X  if (r == 0)
  1803. X    template[r++] = '_';
  1804. X  else if (g >= '0' && g <= '9')
  1805. X    template[r - 1] = (char)(template[r - 1] == '_' ? '-' : '_');
  1806. X  sprintf(template + r, "%%0%dd.zip", k);
  1807. X
  1808. X  /* Make the zip files from the linked lists of entry numbers */
  1809. X  if ((e = fopen(zipfile, FOPR)) == NULL)
  1810. X  {
  1811. X    free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1812. X    err(ZE_NAME, zipfile);
  1813. X  }
  1814. X  free((voidp *)zipfile);
  1815. X  zipfile = NULL;
  1816. X  for (j = 0; j < s; j++)
  1817. X  {
  1818. X    sprintf(name, template, j + 1);
  1819. X    printf("creating %s\n", path);
  1820. X    zipsmade = j + 1;
  1821. X    if ((f = fopen(path, FOPW)) == NULL)
  1822. X    {
  1823. X      free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1824. X      err(ZE_CREAT, path);
  1825. X    }
  1826. X    tempzn = 0;
  1827. X    for (g = b[j]; g != (extent)-1; g = (extent)a[g])
  1828. X    {
  1829. X      if (fseek(e, w[g]->off, SEEK_SET))
  1830. X      {
  1831. X        free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1832. X        err(ferror(e) ? ZE_READ : ZE_EOF, zipfile);
  1833. X      }
  1834. X      if ((r = zipcopy(w[g], e, f)) != ZE_OK)
  1835. X      {
  1836. X        free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1837. X        if (r == ZE_TEMP)
  1838. X          err(ZE_WRITE, path);
  1839. X        else
  1840. X          err(r, zipfile);
  1841. X      }
  1842. X    }
  1843. X    if ((c = ftell(f)) == -1L)
  1844. X    {
  1845. X      free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1846. X      err(ZE_WRITE, path);
  1847. X    }
  1848. X    for (g = b[j], k = 0; g != (extent)-1; g = (extent)a[g], k++)
  1849. X      if ((r = putcentral(w[g], f)) != ZE_OK)
  1850. X      {
  1851. X        free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1852. X        err(ZE_WRITE, path);
  1853. X      }
  1854. X    if ((t = ftell(f)) == -1L)
  1855. X    {
  1856. X      free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1857. X      err(ZE_WRITE, path);
  1858. X    }
  1859. X    if ((r = putend(k, t - c, c, (extent)0, (char *)NULL, f)) != ZE_OK)
  1860. X    {
  1861. X      free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1862. X      err(ZE_WRITE, path);
  1863. X    }
  1864. X    if (ferror(f) || fclose(f))
  1865. X    {
  1866. X      free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1867. X      err(ZE_WRITE, path);
  1868. X    }
  1869. X  }
  1870. X  free((voidp *)b);  free((voidp *)w);  free((voidp *)a);
  1871. X  fclose(e);
  1872. X
  1873. X  /* Done! */
  1874. X  exit(0);
  1875. X}
  1876. END_OF_FILE
  1877.   if test 17114 -ne `wc -c <'zipsplit.c'`; then
  1878.     echo shar: \"'zipsplit.c'\" unpacked with wrong size!
  1879.   fi
  1880.   # end of 'zipsplit.c'
  1881. fi
  1882. echo shar: End of archive 7 \(of 11\).
  1883. cp /dev/null ark7isdone
  1884. MISSING=""
  1885. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  1886.     if test ! -f ark${I}isdone ; then
  1887.     MISSING="${MISSING} ${I}"
  1888.     fi
  1889. done
  1890. if test "${MISSING}" = "" ; then
  1891.     echo You have unpacked all 11 archives.
  1892.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1893. else
  1894.     echo You still must unpack the following archives:
  1895.     echo "        " ${MISSING}
  1896. fi
  1897. exit 0
  1898. exit 0 # Just in case...
  1899.