home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume32 / xbbs / part05 / bbscunzip.c < prev   
C/C++ Source or Header  |  1992-09-08  |  23KB  |  965 lines

  1.  
  2. /*
  3.     If the computer is BIG ENDIAN, remove the comment from the next
  4.         line.
  5. #define BIGEND
  6. */
  7.  
  8. typedef unsigned char byte;    /* code assumes UNSIGNED bytes */
  9. typedef long longint;
  10. typedef unsigned short word;
  11. typedef char boolean;
  12.  
  13. #define STRSIZ 256
  14. #define BSIZE 512
  15.  
  16. #include <stdio.h>
  17. #include <ctype.h>
  18.  
  19. #ifdef __STDC__
  20.  
  21. #include <stdlib.h>
  22.  
  23. #else
  24.  
  25. char *malloc();
  26.  
  27. #endif
  28.  
  29. #define min(a,b) ((a) < (b) ? (a) : (b))
  30.  
  31. /*
  32.  * Zipfile layout declarations
  33.  *
  34.  */
  35.  
  36. #define LONGIP(l) ((longint *) &((l)[0]))
  37. #define LONGI(l) (*(LONGIP(l)))
  38.  
  39. typedef longint signature_type;
  40.  
  41.  
  42. #define LOCAL_FILE_HEADER_SIGNATURE  0x04034b50L
  43.  
  44.  
  45. typedef struct local_file_header {
  46.     word version_needed_to_extract;
  47.         word general_purpose_bit_flag;
  48.     word compression_method;
  49.     word last_mod_file_time;
  50.     word last_mod_file_date;
  51.     byte crc32[4];
  52.     byte compressed_size[4];
  53.         byte uncompressed_size[4];
  54.     word filename_length;
  55.     word extra_field_length;
  56. } local_file_header;
  57.  
  58.  
  59. #define CENTRAL_FILE_HEADER_SIGNATURE  0x02014b50L
  60.  
  61.  
  62. typedef struct central_directory_file_header {
  63.     word version_made_by;
  64.     word version_needed_to_extract;
  65.     word general_purpose_bit_flag;
  66.     word compression_method;
  67.     word last_mod_file_time;
  68.     word last_mod_file_date;
  69.     byte crc32[4];
  70.     byte compressed_size[4];
  71.     byte uncompressed_size[4];
  72.     word filename_length;
  73.     word extra_field_length;
  74.     word file_comment_length;
  75.     word disk_number_start;
  76.     word internal_file_attributes;
  77.     byte external_file_attributes[4];
  78.     byte relative_offset_local_header[4];
  79. } central_directory_file_header;
  80.  
  81.  
  82. #define END_CENTRAL_DIR_SIGNATURE  0x06054b50L
  83.  
  84.  
  85. typedef struct end_central_dir_record {
  86.     word number_this_disk;
  87.     word number_disk_with_start_central_directory;
  88.     word total_entries_central_dir_on_this_disk;
  89.     word total_entries_central_dir;
  90.     byte size_central_directory[4];
  91.     byte offset_start_central_directory[4];
  92.     word zipfile_comment_length;
  93. } end_central_dir_record;
  94.  
  95.  
  96. char *fnames[2] = {    /* default filenames vector */
  97.     "*",
  98.     NULL
  99. };
  100. char **fnv = &fnames[0];
  101.  
  102. int vflag;        /* -v: view directory */
  103.  
  104. int members;
  105. longint csize;
  106. longint ucsize;
  107. longint tot_csize;
  108. longint tot_ucsize;
  109.  
  110.  
  111. /*
  112.  * input file variables
  113.  *
  114.  */
  115.  
  116. #define INBUFSIZ BUFSIZ        /* same as stdio uses */
  117. byte *inbufchr;            /* input file buffer - any size is legal */
  118. byte *inptr;
  119.  
  120. int incnt;
  121. word bitbuf;
  122. int bits_left;
  123. boolean zipeof;
  124.  
  125. int zipfd;
  126. char zipfn[STRSIZ];
  127. local_file_header lrec;
  128.  
  129.  
  130. /*
  131.  * output stream variables
  132.  *
  133.  */
  134.  
  135. #define OUTBUFSIZ 0x2000        /* unImplode needs power of 2, >= 0x2000 */
  136. byte *outbufchr;                   /* buffer for rle look-back */
  137. byte *outptr;
  138.  
  139. longint outpos;            /* absolute position in outfile */
  140. int outcnt;            /* current position in outbufchr */
  141.  
  142. int outfd;
  143. char filename[STRSIZ];
  144. char extra[STRSIZ];
  145.  
  146. #define DLE 144
  147.  
  148.  
  149. /* ----------------------------------------------------------- */
  150. /*
  151.  * shrink/reduce working storage
  152.  *
  153.  */
  154.  
  155. int factor;
  156.  
  157. #define max_bits 13
  158. #define init_bits 9
  159. #define hsize 8192
  160. #define first_ent 257
  161. #define clear 256
  162.  
  163.  
  164. int codesize;
  165. int maxcode;
  166. int free_ent;
  167. int maxcodemax;
  168. int offset;
  169. int sizex;
  170.  
  171.  
  172.  
  173. /* ============================================================= */
  174. /*
  175.  * Host operating system details
  176.  *
  177.  */
  178.  
  179. /* On some systems the contents of sys/param.h duplicates the
  180.    contents of sys/types.h, so you don't need (and can't use)
  181.    sys/types.h. */
  182.  
  183. #include <sys/types.h>
  184. #include <sys/param.h>
  185. #include <time.h>
  186. struct tm *gmtime(), *localtime();
  187. #define ZSUFX ".zip"
  188.  
  189.  
  190. char *strchr(), *strrchr();
  191.  
  192. long lseek();
  193.  
  194. #define SEEK_SET  0
  195. #define SEEK_CUR  1
  196. #define SEEK_END  2
  197.  
  198. FILE *zipFILE;
  199.  
  200. #include <fcntl.h>
  201.  
  202. void set_file_time()
  203.  /*
  204.   * set the output file date/time stamp according to information from the
  205.   * zipfile directory record for this file 
  206.   */
  207.  
  208. {
  209.     time_t times[2];
  210.     struct tm *tmbuf;
  211.     long m_time;
  212.     int yr, mo, dy, hh, mm, ss, leap, days = 0;
  213.  
  214.  
  215.     yr = (((lrec.last_mod_file_date >> 9) & 0x7f) + 10);  /* dissect date */
  216.     mo = ((lrec.last_mod_file_date >> 5) & 0x0f);
  217.     dy = ((lrec.last_mod_file_date & 0x1f) - 1);
  218.  
  219.     hh = ((lrec.last_mod_file_time >> 11) & 0x1f);        /* dissect time */
  220.     mm = ((lrec.last_mod_file_time >> 5) & 0x3f);
  221.     ss = ((lrec.last_mod_file_time & 0x1f) * 2);
  222.  
  223.     /* leap = # of leap years from 1970 up to but not including
  224.        the current year */
  225.  
  226.     leap = ((yr+1969)/4);              /* Leap year base factor */
  227.  
  228.     /* How many days from 1970 to this year? */
  229.     days = (yr * 365) + (leap - 492);
  230.  
  231.     switch(mo)                   /* calculate expired days this year */
  232.     {
  233.     case 12:
  234.         days += 30;
  235.     case 11:
  236.         days += 31;
  237.     case 10:
  238.         days += 30;
  239.     case 9:
  240.         days += 31;
  241.     case 8:
  242.         days += 31;
  243.     case 7:
  244.         days += 30;
  245.     case 6:
  246.         days += 31;
  247.     case 5:
  248.         days += 30;
  249.     case 4:
  250.         days += 31;
  251.     case 3:
  252.         days += 28;                    /* account for leap years */
  253.         if (((yr+1970) % 4 == 0) && (yr+1970) != 2000)
  254.             ++days;
  255.     case 2:
  256.         days += 31;
  257.     }
  258.  
  259.     /* convert date & time to seconds relative to 00:00:00, 01/01/1970 */
  260.     m_time = ((days + dy) * 86400) + (hh * 3600) + (mm * 60) + ss;
  261.  
  262.     tmbuf = localtime(&m_time);
  263.     hh = tmbuf->tm_hour;
  264.     tmbuf = gmtime(&m_time);
  265.     hh = tmbuf->tm_hour - hh;
  266.     if (hh < 0)
  267.     hh += 24;
  268.     m_time += (hh * 3600);             /* account for timezone differences */
  269.  
  270.     times[0] = m_time;             /* set the stamp on the file */
  271.     times[1] = m_time;
  272.     utime(filename, times);
  273. }
  274.  
  275.  
  276. int open_input_file()
  277.  /* return non-0 if open failed */
  278. {
  279.     /*
  280.      * open the zipfile for reading and in BINARY mode to prevent cr/lf
  281.      * translation, which would corrupt the bitstreams 
  282.      */
  283.  
  284.     zipfd = open(zipfn, O_RDONLY);
  285.     return 0;
  286. }
  287.  
  288.  
  289. #ifdef BIGEND
  290.  
  291. void swap_bytes(wordp)
  292. word *wordp;
  293.  /* convert intel style 'short int' variable to host format */
  294. {
  295.     char *charp = (char *) wordp;
  296.     char temp;
  297.  
  298.     temp = charp[0];
  299.     charp[0] = charp[1];
  300.     charp[1] = temp;
  301. }
  302.  
  303. void swap_lbytes(longp)
  304. longint *longp;
  305.  /* convert intel style 'long' variable to host format */
  306. {
  307.     char *charp = (char *) longp;
  308.     char temp[4];
  309.  
  310.     temp[3] = charp[0];
  311.     temp[2] = charp[1];
  312.     temp[1] = charp[2];
  313.     temp[0] = charp[3];
  314.  
  315.     charp[0] = temp[0];
  316.     charp[1] = temp[1];
  317.     charp[2] = temp[2];
  318.     charp[3] = temp[3];
  319. }
  320.  
  321. #endif
  322.  
  323.  
  324.  
  325. /* ============================================================= */
  326.  
  327. int readbuf(fd, buf, size)
  328. int fd;
  329. char *buf;
  330. register unsigned size;
  331. {
  332.     register int count;
  333.     int n;
  334.  
  335.     n = size;
  336.     while (size)  {
  337.         if (incnt == 0)  {
  338.             if ((incnt = read(fd, inbufchr, INBUFSIZ)) <= 0)
  339.                 return(incnt);
  340.             inptr = inbufchr;
  341.         }
  342.         count = min(size, incnt);
  343.         memcpy(buf, inptr, count);
  344.         buf += count;
  345.         inptr += count;
  346.         incnt -= count;
  347.         size -= count;
  348.     }
  349.     return(n);
  350. }
  351.  
  352. int ReadByte(x)
  353. word *x;
  354.  /* read a byte; return 8 if byte available, 0 if not */
  355. {
  356.     if (csize-- <= 0)
  357.         return 0;
  358.     if (incnt == 0)  {
  359.         if ((incnt = read(zipfd, inbufchr, INBUFSIZ)) <= 0)
  360.             return 0;
  361.         inptr = inbufchr;
  362.     }
  363.     *x = *inptr++;
  364.     --incnt;
  365.     return 8;
  366. }
  367.  
  368.  
  369. /* ------------------------------------------------------------- */
  370. static word mask_bits[] =
  371.         {0,     0x0001, 0x0003, 0x0007, 0x000f,
  372.                 0x001f, 0x003f, 0x007f, 0x00ff,
  373.                 0x01ff, 0x03ff, 0x07ff, 0x0fff,
  374.                 0x1fff, 0x3fff, 0x7fff, 0xffff
  375.         };
  376.  
  377.  
  378. int FillBitBuffer(bits)
  379. register int bits;
  380. {
  381.     /* get the bits that are left and read the next word */
  382.         register int result = bitbuf;
  383.     word temp;
  384.     int sbits = bits_left;
  385.     bits -= bits_left;
  386.  
  387.     /* read next word of input */
  388.     bits_left = ReadByte(&bitbuf);
  389.     bits_left += ReadByte(&temp);
  390.     bitbuf |= (temp << 8);
  391.     if (bits_left == 0)
  392.         zipeof = 1;
  393.  
  394.     /* get the remaining bits */
  395.         result = result | (int) ((bitbuf & mask_bits[bits]) << sbits);
  396.         bitbuf >>= bits;
  397.         bits_left -= bits;
  398.         return result;
  399. }
  400.  
  401. #define READBIT(nbits,zdest) { if (nbits <= bits_left) { zdest = (int)(bitbuf & mask_bits[nbits]); bitbuf >>= nbits; bits_left -= nbits; } else zdest = FillBitBuffer(nbits);}
  402.  
  403.  
  404. /* ------------------------------------------------------------- */
  405.  
  406. unsigned long crc32val;
  407.  
  408. void UpdateCRC();
  409.  
  410.  
  411.  
  412. /* ----------------------------------------------------------- */
  413. /*
  414.  * The Reducing algorithm is actually a combination of two
  415.  * distinct algorithms.  The first algorithm compresses repeated
  416.  * byte sequences, and the second algorithm takes the compressed
  417.  * stream from the first algorithm and applies a probabilistic
  418.  * compression method.
  419.  */
  420.  
  421. int L_table[] = {0, 0x7f, 0x3f, 0x1f, 0x0f};
  422.  
  423. int D_shift[] = {0, 0x07, 0x06, 0x05, 0x04};
  424. int D_mask[]  = {0, 0x01, 0x03, 0x07, 0x0f};
  425.  
  426. int B_table[] = {8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
  427.          5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
  428.          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  429.          6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
  430.          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  431.          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  432.          7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  433.          7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  434.          8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  435.          8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  436.          8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  437.          8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  438.          8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  439.          8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  440.          8, 8, 8, 8};
  441.  
  442. /* ----------------------------------------------------------- */
  443.  
  444.  
  445. /*
  446.  Length  Method   Size  Ratio   Date    Time   CRC-32    Name
  447.  ------  ------   ----- -----   ----    ----   ------    ----
  448.   44004  Implode  13041  71%  11-02-89  19:34  88420727  DIFF3.C
  449.  */
  450.  
  451. void dir_member()
  452. {
  453.     char *method;
  454.     int ratio;
  455.     int yr, mo, dy, hh, mm;
  456.  
  457.     yr = (((lrec.last_mod_file_date >> 9) & 0x7f) + 80);
  458.     mo = ((lrec.last_mod_file_date >> 5) & 0x0f);
  459.     dy = (lrec.last_mod_file_date & 0x1f);
  460.  
  461.     hh = ((lrec.last_mod_file_time >> 11) & 0x1f);
  462.     mm = ((lrec.last_mod_file_time >> 5) & 0x3f);
  463.  
  464.     switch (lrec.compression_method)  {
  465.     case 0:
  466.         method = "Stored";
  467.         break;
  468.     case 1:
  469.         method = "Shrunk";
  470.         break;
  471.     case 2:
  472.         method = "Reduce1";
  473.         break;
  474.     case 3:
  475.         method = "Reduce2";
  476.         break;
  477.     case 4:
  478.         method = "Reduce3";
  479.         break;
  480.     case 5:
  481.         method = "Reduce4";
  482.         break;
  483.     case 6:
  484.         method = "Implode";
  485.         break;
  486.     case 7:
  487.         method = "Token";
  488.         break;
  489.     case 8:
  490.         method = "Deflate";
  491.         break;
  492.     default:
  493.         method = "Unknown";
  494.         break;
  495.     }
  496.  
  497.     if (ucsize != 0)  {
  498.         ratio = (int) ((1000L * (ucsize    - csize)) / ucsize);
  499.         if ((ratio % 10) >= 5)
  500.             ratio += 10;
  501.     }
  502.     else
  503.         ratio = 0;    /* can .zip contain 0-size file? */
  504.  
  505.     fprintf(zipFILE, "%7ld  %-7s%7ld %3d%%  %02d-%02d-%02d  %02d:%02d  \
  506. %08lx  %s\n", ucsize, method, csize,
  507.         ratio / 10, mo, dy, yr, hh, mm,
  508.         LONGI(lrec.crc32), filename);
  509.     tot_ucsize += ucsize;
  510.     tot_csize += csize;
  511.     ++members;
  512. }
  513.  
  514. /* ---------------------------------------------------------- */
  515.  
  516. void skip_member()
  517. {
  518.     register long pos;
  519.     long endbuf;
  520.     int offset;
  521.  
  522.     endbuf = lseek(zipfd, 0L, SEEK_CUR);    /* 1st byte beyond inbufchr */
  523.     pos = endbuf - incnt;            /* 1st compressed byte */
  524.     pos += csize;        /* next header signature */
  525.     if (pos < endbuf)  {
  526.         incnt -= csize;
  527.         inptr += csize;
  528.     }
  529.     else  {
  530.         offset = pos % BSIZE;        /* offset within block */
  531.         pos = (pos / BSIZE) * BSIZE;    /* block start */
  532.             lseek(zipfd, pos, SEEK_SET);
  533.         incnt = read(zipfd, inbufchr, INBUFSIZ);
  534.         incnt -= offset;
  535.         inptr = inbufchr + offset;
  536.     }
  537. }
  538.  
  539. /* ---------------------------------------------------------- */
  540.  
  541. void get_string(len, s)
  542. int len;
  543. char *s;
  544. {
  545.     readbuf(zipfd, s, len);
  546.     s[len] = 0;
  547. }
  548.  
  549.  
  550. /* ---------------------------------------------------------- */
  551.  
  552. void process_local_file_header(fnamev)
  553. char **fnamev;
  554. {
  555.     int extracted;
  556.  
  557.     readbuf(zipfd, &lrec, sizeof(lrec));
  558.  
  559. #ifdef BIGEND
  560.     swap_bytes(&lrec.filename_length);
  561.     swap_bytes(&lrec.extra_field_length);
  562.     swap_lbytes(LONGIP(lrec.compressed_size));
  563.     swap_lbytes(LONGIP(lrec.uncompressed_size));
  564.     swap_bytes(&lrec.compression_method);
  565.     swap_bytes(&lrec.version_needed_to_extract);
  566.         swap_bytes(&lrec.general_purpose_bit_flag);
  567.     swap_bytes(&lrec.last_mod_file_time);
  568.     swap_bytes(&lrec.last_mod_file_date);
  569.         swap_lbytes(LONGIP(lrec.crc32));
  570. #endif
  571.     csize = LONGI(lrec.compressed_size);
  572.     ucsize = LONGI(lrec.uncompressed_size);
  573.  
  574.     get_string(lrec.filename_length, filename);
  575.     get_string(lrec.extra_field_length, extra);
  576.  
  577.     extracted = 0;
  578.     for (--fnamev; *++fnamev; )  {
  579.         if (match(filename, *fnamev))  {
  580.                 dir_member();
  581.             break;
  582.         }
  583.     }
  584.         skip_member();
  585. }
  586.  
  587.  
  588. /* ---------------------------------------------------------- */
  589.  
  590. void process_central_file_header()
  591. {
  592.     central_directory_file_header rec;
  593.     char filename[STRSIZ];
  594.     char extra[STRSIZ];
  595.     char comment[STRSIZ];
  596.  
  597.     readbuf(zipfd, &rec, sizeof(rec));
  598.  
  599. #ifdef BIGEND
  600.     swap_bytes(&rec.filename_length);
  601.     swap_bytes(&rec.extra_field_length);
  602.     swap_bytes(&rec.file_comment_length);
  603. #endif
  604.  
  605.         get_string(rec.filename_length, filename);
  606.     get_string(rec.extra_field_length, extra);
  607.     get_string(rec.file_comment_length, comment);
  608. }
  609.  
  610.  
  611. /* ---------------------------------------------------------- */
  612.  
  613. void process_end_central_dir()
  614. {
  615.     end_central_dir_record rec;
  616.     char comment[STRSIZ];
  617.  
  618.     readbuf(zipfd, &rec, sizeof(rec));
  619.  
  620. #ifdef BIGEND
  621.     swap_bytes(&rec.zipfile_comment_length);
  622. #endif
  623.  
  624.     /* There seems to be no limit to the zipfile
  625.        comment length.  Some zipfiles have comments
  626.        longer than 256 bytes.  Currently no use is
  627.        made of the comment anyway.
  628.      */
  629. #if 0
  630.     get_string(rec.zipfile_comment_length, comment);
  631. #endif
  632. }
  633.  
  634.  
  635. /* ---------------------------------------------------------- */
  636.  
  637. void process_headers()
  638. {
  639.     int ratio;
  640.     longint sig;
  641.  
  642.     if (vflag)  {
  643.         members = 0;
  644.         tot_ucsize = tot_csize = 0;
  645.         fprintf(zipFILE,"\n Length  Method   Size  Ratio   Date    Time   \
  646. CRC-32    Name\n ------  ------   ----- -----   ----    ----   ------    \
  647. ----\n");
  648.     }
  649.  
  650.     while (1) {
  651.         if (readbuf(zipfd, &sig, sizeof(sig)) != sizeof(sig))
  652.             return;
  653.  
  654. #ifdef BIGEND
  655.         swap_lbytes(&sig);
  656. #endif
  657.  
  658.                 if (sig == LOCAL_FILE_HEADER_SIGNATURE)
  659.             process_local_file_header(fnv);
  660.                 else if (sig == CENTRAL_FILE_HEADER_SIGNATURE)
  661.             process_central_file_header();
  662.                 else if (sig == END_CENTRAL_DIR_SIGNATURE) {
  663.             process_end_central_dir();
  664.             break;
  665.         }
  666.                 else {
  667.             fprintf(stderr, "Invalid Zipfile Header\n");
  668.             return;
  669.         }
  670.     }
  671.     if (vflag)  {
  672.         if (tot_ucsize != 0)  {
  673.             ratio = (int) ((1000L * (tot_ucsize-tot_csize))
  674.                     / tot_ucsize);
  675.             if ((ratio % 10) >= 5)
  676.                 ratio += 10;
  677.         }
  678.         else
  679.             ratio = 0;
  680.         fprintf(zipFILE, " ------          ------  \
  681. ---                             -------\n\
  682. %7ld         %7ld %3d%%                             %7d\n",
  683.         tot_ucsize, tot_csize, ratio / 10, members);
  684.     }
  685. }
  686.  
  687.  
  688. /* ---------------------------------------------------------- */
  689.  
  690. void process_zipfile()
  691. {
  692.     /*
  693.      * open the zipfile for reading and in BINARY mode to prevent cr/lf
  694.      * translation, which would corrupt the bitstreams 
  695.      */
  696.  
  697.     if (open_input_file())
  698.         exit(1);
  699.  
  700.     process_headers();
  701.  
  702.     close(zipfd);
  703. }
  704.  
  705. /* ---------------------------------------------------------- */
  706. void listzip (fn, port_id)
  707. char *fn;
  708. char *port_id;
  709. {
  710.     char *s;
  711.     int c;
  712.     char buu[32];
  713.  
  714.     ++vflag;
  715.  
  716.     strcpy(zipfn, fn);
  717.         /* allocate i/o buffers */
  718.     inbufchr = (byte *) (malloc(INBUFSIZ));
  719.     outbufchr = (byte *) (malloc(OUTBUFSIZ));
  720.     if ((inbufchr == NULL) || (outbufchr == NULL)) {
  721.         fprintf(stderr, "Can't allocate buffers!\n");
  722.         exit(1);
  723.     }
  724.  
  725.         /* do the job... */
  726.     sprintf( buu, "/tmp/ziplst.%s", port_id);
  727.     zipFILE = fopen( buu, "w" );
  728.         process_zipfile();
  729.     free(inbufchr);
  730.     free(outbufchr);
  731.     fclose(zipFILE);
  732. }
  733.  
  734. #include <sys/dir.h>
  735. #include <ctype.h>
  736.  
  737. #define ASTERISK '*'        /* The '*' metacharacter */
  738. #define QUESTION '?'        /* The '?' metacharacter */
  739. #define BACK_SLASH '\\'         /* The '\' metacharacter */
  740. #define LEFT_BRACKET '['    /* The '[' metacharacter */
  741. #define RIGHT_BRACKET ']'    /* The ']' metacharacter */
  742.  
  743. #define IS_OCTAL(ch) (ch >= '0' && ch <= '7')
  744.  
  745. typedef short INT;
  746. typedef short BOOLEAN;
  747. #define TRUE 1
  748. #define FALSE 0
  749. #define EOS '\000'
  750.  
  751. static BOOLEAN do_list();
  752. static char nextch();
  753. static void list_parse();
  754.  
  755. int match(string, pattern)
  756. char *string;
  757. char *pattern;
  758. {
  759.     register int ismatch;
  760.  
  761.     ismatch = FALSE;
  762.     switch (*pattern)
  763.     {
  764.     case ASTERISK:
  765.         pattern++;
  766.         do
  767.         {
  768.             ismatch = match (string, pattern);
  769.         }
  770.         while (!ismatch && *string++ != EOS);
  771.         break;
  772.     case QUESTION:
  773.         if (*string != EOS)
  774.             ismatch = match (++string, ++pattern);
  775.         break;
  776.     case EOS:
  777.         if (*string == EOS)
  778.             ismatch = TRUE;
  779.         break;
  780.     case LEFT_BRACKET:
  781.         if (*string != EOS)
  782.             ismatch = do_list (string, pattern);
  783.         break;
  784.     case BACK_SLASH:
  785.         pattern++;
  786.     default:
  787.     if (toupper(*string) == toupper(*pattern))
  788.         {
  789.             string++;
  790.             pattern++;
  791.             ismatch = match (string, pattern);
  792.         }
  793.         else
  794.             ismatch = FALSE;
  795.         break;
  796.     }
  797.     return(ismatch);
  798. }
  799.  
  800. static BOOLEAN do_list (string, pattern)
  801. register char *string;
  802. char *pattern;
  803. {
  804.     register BOOLEAN ismatch;
  805.     register BOOLEAN if_found;
  806.     register BOOLEAN if_not_found;
  807.     auto char lower;
  808.     auto char upper;
  809.  
  810.     pattern++;
  811.     if (*pattern == '!')
  812.     {
  813.         if_found = FALSE;
  814.         if_not_found = TRUE;
  815.         pattern++;
  816.     }
  817.     else
  818.     {
  819.         if_found = TRUE;
  820.         if_not_found = FALSE;
  821.     }
  822.     ismatch = if_not_found;
  823.     while (*pattern != ']' && *pattern != EOS)
  824.     {
  825.         list_parse(&pattern, &lower, &upper);
  826.         if (*string >= lower && *string <= upper)
  827.         {
  828.             ismatch = if_found;
  829.             while (*pattern != ']' && *pattern != EOS) pattern++;
  830.         }
  831.     }
  832.  
  833.     if (*pattern++ != ']')
  834.     {
  835.         fprintf(stderr, "Character class error\n");
  836.     return;
  837.     }
  838.     else
  839.         if (ismatch)
  840.             ismatch = match (++string, pattern);
  841.  
  842.     return(ismatch);
  843. }
  844.  
  845. static void list_parse (patp, lowp, highp)
  846. char **patp;
  847. char *lowp;
  848. char *highp;
  849. {
  850.     *lowp = nextch (patp);
  851.     if (**patp == '-')
  852.     {
  853.         (*patp)++;
  854.         *highp = nextch(patp);
  855.     }
  856.     else
  857.         *highp = *lowp;
  858. }
  859.  
  860. static char nextch (patp)
  861. char **patp;
  862. {
  863.     register char ch;
  864.     register char chsum;
  865.     register INT count;
  866.  
  867.     ch = *(*patp)++;
  868.     if (ch == '\\')
  869.     {
  870.         ch = *(*patp)++;
  871.         if (IS_OCTAL (ch))
  872.         {
  873.             chsum = 0;
  874.             for (count = 0; count < 3 && IS_OCTAL (ch); count++)
  875.             {
  876.                 chsum *= 8;
  877.                 chsum += ch - '0';
  878.                 ch = *(*patp)++;
  879.             }
  880.             (*patp)--;
  881.             ch = chsum;
  882.         }
  883.     }
  884.     return(ch);
  885. }
  886.  
  887. long crc_32_tab[] = {
  888.       0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  889.       0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  890.       0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  891.       0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  892.       0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  893.       0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  894.       0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  895.       0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  896.       0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  897.       0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  898.       0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  899.       0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  900.       0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  901.       0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  902.       0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  903.       0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  904.       0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  905.       0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  906.       0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  907.       0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  908.       0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  909.       0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  910.       0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  911.       0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  912.       0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  913.       0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  914.       0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  915.       0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  916.       0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  917.       0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  918.       0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  919.       0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  920.       0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  921.       0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  922.       0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  923.       0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  924.       0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  925.       0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  926.       0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  927.       0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  928.       0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  929.       0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  930.       0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  931.       0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  932.       0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  933.       0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  934.       0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  935.       0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  936.       0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  937.       0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  938.       0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  939.       0x2d02ef8dL
  940.    };
  941.  
  942.  
  943. #define UPDCRC32(res,oct) res=crc_32_tab[(byte)res^(byte)oct] ^ ((res>>8) & 0x00FFFFFFL)
  944.  
  945. /* ------------------------------------------------------------- */
  946.  
  947. extern unsigned long crc32val;
  948.  
  949. void UpdateCRC(s, len)
  950. register unsigned char *s;
  951. register int len;
  952.  /* update running CRC calculation with contents of a buffer */
  953. {
  954.     register unsigned long crcval;
  955.  
  956.     crcval = crc32val;
  957.         while (len--) {
  958.         crcval = crc_32_tab[(byte)crcval ^ (byte)(*s++)]
  959.             ^ (crcval >> 8);
  960.         }
  961.     crc32val = crcval;
  962. }
  963.  
  964.  
  965.