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

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