home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / OS2UNZIP.ZIP / UNZIP.C next >
C/C++ Source or Header  |  1989-04-02  |  23KB  |  1,031 lines

  1.  
  2. /*
  3.  * Copyright 1987, 1989 Samuel H. Smith;  All rights reserved
  4.  *
  5.  * This is a component of the ProDoor System.
  6.  * Do not distribute modified versions without my permission.
  7.  * Do not remove or alter this notice or any other copyright notice.
  8.  * If you use this in your own program you must distribute source code.
  9.  * Do not use any of this in a commercial product.
  10.  *
  11.  */
  12.  
  13. /*
  14.  * UnZip - A simple zipfile extract utility
  15.  *
  16.  */ 
  17.  
  18. #define version  "UnZip:  Zipfile Extract v1.1ß of 03-06-89;  (C) 1989 S.H.Smith"
  19.  
  20. typedef unsigned char byte;
  21. typedef long longint;
  22. typedef unsigned word;
  23. typedef char boolean;
  24. #define STRSIZ  256
  25.  
  26. #include <stdio.h>
  27. #include <io.h>
  28. #include <stdlib.h>
  29. #include <fcntl.h>
  30. #include <string.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33.  
  34.  
  35.  
  36. /* ----------------------------------------------------------- */ 
  37. /*
  38.  * Zipfile layout declarations
  39.  *
  40.  */ 
  41.  
  42.    typedef longint       signature_type;
  43.  
  44.  
  45.    #define local_file_header_signature  0x04034b50L
  46.  
  47.  
  48.    typedef struct local_file_header { 
  49.       word         version_needed_to_extract; 
  50.       word         general_purpose_bit_flag; 
  51.       word         compression_method; 
  52.       word         last_mod_file_time; 
  53.       word         last_mod_file_date; 
  54.       longint      crc32; 
  55.       longint      compressed_size; 
  56.       longint      uncompressed_size; 
  57.       word         filename_length; 
  58.       word         extra_field_length; 
  59.    } local_file_header; 
  60.  
  61.  
  62.    #define central_file_header_signature  0x02014b50L
  63.  
  64.  
  65.    typedef struct central_directory_file_header { 
  66.       word         version_made_by; 
  67.       word         version_needed_to_extract; 
  68.       word         general_purpose_bit_flag; 
  69.       word         compression_method; 
  70.       word         last_mod_file_time; 
  71.       word         last_mod_file_date; 
  72.       longint      crc32; 
  73.       longint      compressed_size; 
  74.       longint      uncompressed_size; 
  75.       word         filename_length; 
  76.       word         extra_field_length; 
  77.       word         file_comment_length; 
  78.       word         disk_number_start; 
  79.       word         internal_file_attributes; 
  80.       longint      external_file_attributes; 
  81.       longint      relative_offset_local_header; 
  82.    } central_directory_file_header; 
  83.  
  84.  
  85.    #define end_central_dir_signature  0x06054b50L
  86.  
  87.  
  88.    typedef struct end_central_dir_record { 
  89.       word         number_this_disk; 
  90.       word         number_disk_with_start_central_directory; 
  91.       word         total_entries_central_dir_on_this_disk; 
  92.       word         total_entries_central_dir; 
  93.       longint      size_central_directory; 
  94.       longint      offset_start_central_directory; 
  95.       word         zipfile_comment_length; 
  96.    } end_central_dir_record; 
  97.  
  98.  
  99.  
  100. /* ----------------------------------------------------------- */ 
  101. /*
  102.  * input file variables
  103.  *
  104.  */ 
  105.  
  106.  
  107.    #define  uinbufsize    512L   /* input buffer size */
  108.    byte     inbuf[uinbufsize];
  109.  
  110.    boolean  zipeof;
  111.    longint  csize;
  112.    longint  cusize;
  113.    int      cmethod;
  114.    int      inpos;
  115.    int      incnt;
  116.    int      pc;
  117.    int      pcbits;
  118.    int      pcbitv;
  119.    
  120.    int      zipfd;
  121.    char     zipfn[STRSIZ];
  122.    local_file_header lrec;
  123.  
  124.  
  125.  
  126.  
  127. /* ----------------------------------------------------------- */ 
  128. /*
  129.  * output stream variables
  130.  *
  131.  */ 
  132.  
  133.  
  134.    byte     outbuf[4096];   /* for rle look-back */
  135.    longint  outpos;         /* absolute position in outfile */
  136.    int      outcnt;
  137.  
  138.    int      outfd;
  139.    char     filename[STRSIZ];
  140.    char     extra[STRSIZ];
  141.  
  142.  
  143.  
  144. /* ----------------------------------------------------------- */ 
  145. /*
  146.  * shrink/reduce working storage
  147.  *
  148.  */ 
  149.  
  150.  
  151.    int      factor;
  152.    byte     followers[256][64];
  153.    byte     Slen[256];
  154.    int      ExState;
  155.    int      C;
  156.    int      V;
  157.    int      Len;
  158.  
  159.    #define max_bits      13
  160.    #define init_bits     9
  161.    #define hsize         8192
  162.    #define first_ent     257
  163.    #define clear         256
  164.  
  165.    typedef int  hsize_array_integer[hsize+1];
  166.    typedef byte hsize_array_byte[hsize+1];
  167.  
  168.    hsize_array_integer prefix_of;
  169.    hsize_array_byte    suffix_of;
  170.    hsize_array_byte    stack;
  171.  
  172.    int      cbits;
  173.    int      maxcode;
  174.    int      free_ent;
  175.    int      maxcodemax;
  176.    int      offset;
  177.    int      sizex;
  178.  
  179. /*****************************************************/
  180. /*  Added for OS/2                                   */
  181. /*****************************************************/
  182. #include "os2def.h"
  183. #include "doscalls.h"
  184. #include "bsedos.h"
  185.  
  186. /* OPENFLAG variable */
  187. #define OF_FAILIFEXIST      0x00
  188. #define OF_OPENIFEXIST      0x01
  189. #define OF_FAILIFNEXIST     0x00
  190. #define OF_CREATEIFNEXIST   0x10
  191.  
  192. /* OPENMODE variable */
  193. #define OM_NORMALFILENAME   0x00
  194. #define OM_USEDOSCACHE      0x00
  195. #define OM_READONLY         0x00
  196. #define OM_WRITEONLY        0x01
  197. #define OM_READWRITE        0x02
  198. #define OM_EXCLUSIVEACC     0x10
  199. #define OM_PUBLICACC        0x40
  200. #define OM_PRIVATEHANDLE    0x80
  201.  
  202. FDATE myfdate;
  203. FTIME myftime;
  204. USHORT status,usBufsize;
  205. PFILESTATUS pfstsBuf;
  206. FILESTATUS fstsBuf;
  207. HFILE Phandle;
  208. USHORT ActionFlag;
  209. /*****************************************************/
  210.  
  211.  
  212. /* ------------------------------------------------------------- */ 
  213.  
  214. void         skip_csize(void)
  215.    lseek(zipfd,csize,SEEK_CUR);
  216.    zipeof = 1;
  217.    csize = 0L; 
  218.    incnt = 0; 
  219.  
  220.  
  221. /* ------------------------------------------------------------- */ 
  222.  
  223. void         ReadByte(int *       x)
  224.    if (incnt == 0) 
  225.    { 
  226.       if (csize == 0L) 
  227.       { 
  228.          zipeof = 1;
  229.          return;
  230.       } 
  231.  
  232.       inpos = sizeof(inbuf);
  233.       if (inpos > csize) 
  234.          inpos = (int)csize;
  235.       incnt = read(zipfd,inbuf,inpos);
  236.  
  237.       inpos = 1; 
  238.       csize -= incnt; 
  239.    } 
  240.  
  241.    *x = inbuf[inpos-1]; 
  242.    inpos++; 
  243.    incnt--; 
  244.  
  245.  
  246. /* ------------------------------------------------------------- */ 
  247.  
  248. void         ReadBits(int      bits,
  249.                       int *    x)
  250.      /* read the specified number of bits */ 
  251.    int      bit;
  252.    int      bitv;
  253.  
  254.    *x = 0;
  255.    bitv = 1;
  256.  
  257.    for (bit = 0; bit <= bits-1; bit++)
  258.    { 
  259.  
  260.       if (pcbits > 0) 
  261.       { 
  262.          pcbits--; 
  263.          pcbitv = pcbitv << 1; 
  264.       } 
  265.       else 
  266.  
  267.       { 
  268.          ReadByte(&pc); 
  269.          pcbits = 7; 
  270.          pcbitv = 1; 
  271.       } 
  272.  
  273.       if ((pc & pcbitv) != 0) 
  274.          *x = *x | bitv; 
  275.  
  276.       bitv = (int) (bitv << 1);
  277.    } 
  278.  
  279.  
  280.  
  281. /* ---------------------------------------------------------- */ 
  282.  
  283. void         get_string(int      len,
  284.                         char *   s)
  285.    read(zipfd,s,len);
  286.    s[len] = 0;
  287.  
  288.  
  289. /* ------------------------------------------------------------- */ 
  290.  
  291. void         OutByte(int      c)
  292.    /* output each character from archive to screen */ 
  293.    outbuf[outcnt /* outpos % sizeof(outbuf) */] = c;
  294.    outpos++; 
  295.    outcnt++;
  296.  
  297.    if (outcnt == sizeof(outbuf)) 
  298.    { 
  299.       write(outfd,outbuf,outcnt);
  300.       outcnt = 0; 
  301.       printf("."); 
  302.    } 
  303.  
  304.  
  305. /* ----------------------------------------------------------- */
  306.    
  307. int         reduce_L(int         x)
  308.    { 
  309.       switch (factor) {
  310.          case 1:   return x & 0x7f; 
  311.          case 2:   return x & 0x3f; 
  312.          case 3:   return x & 0x1f; 
  313.          case 4:   return x & 0x0f; 
  314.       } 
  315.     return 0; /* error */
  316.    } 
  317.  
  318.    
  319. int         reduce_F(int         x)
  320.    { 
  321.       switch (factor) {
  322.          case 1:   if (x == 127) return 2;  else return 3;
  323.          case 2:   if (x == 63) return 2;   else return 3;
  324.          case 3:   if (x == 31) return 2;   else return 3;
  325.          case 4:   if (x == 15) return 2;   else return 3;
  326.       } 
  327.     return 0; /* error */
  328.    } 
  329.  
  330.    
  331. int         reduce_D(int         x,
  332.                      int         y)
  333.    { 
  334.       switch (factor) {
  335.          case 1:   return ((x >> 7) & 0x01) * 256 + y + 1; 
  336.          case 2:   return ((x >> 6) & 0x03) * 256 + y + 1; 
  337.          case 3:   return ((x >> 5) & 0x07) * 256 + y + 1; 
  338.          case 4:   return ((x >> 4) & 0x0f) * 256 + y + 1; 
  339.       } 
  340.     return 0; /* error */
  341.    } 
  342.  
  343.  
  344. int         reduce_B(int         x)
  345.         /* number of bits needed to encode the specified number */ 
  346.    { 
  347.       switch (x - 1) {
  348.          
  349.          case 0:   
  350.          case 1:   return 1; 
  351.          
  352.          case 2:   
  353.          case 3:   return 2; 
  354.          
  355.          case 4:
  356.          case 5:   
  357.          case 6:   
  358.          case 7:   return 3; 
  359.          
  360.          case 8:   
  361.          case 9:   
  362.          case 10:   
  363.          case 11:   
  364.          case 12:   
  365.          case 13:   
  366.          case 14:   
  367.          case 15:   return 4; 
  368.         
  369.          case 16:
  370.          case 17:
  371.          case 18:
  372.          case 19:
  373.          case 20:
  374.          case 21:
  375.          case 22:
  376.          case 23:
  377.          case 24:
  378.          case 25:
  379.          case 26:
  380.          case 27:
  381.          case 28:
  382.          case 29:
  383.          case 30:
  384.          case 31:   return 5;
  385.         
  386.          case 32:
  387.          case 33:
  388.          case 34:
  389.          case 35:
  390.          case 36:
  391.          case 37:
  392.          case 38:
  393.          case 39:
  394.          case 40:
  395.          case 41:
  396.          case 42:
  397.          case 43:
  398.          case 44:
  399.          case 45:
  400.          case 46:
  401.          case 47:
  402.          case 48:
  403.          case 49:
  404.          case 50:
  405.          case 51:
  406.          case 52:
  407.          case 53:
  408.          case 54:
  409.          case 55:
  410.          case 56:
  411.          case 57:
  412.          case 58:
  413.          case 59:
  414.          case 60:
  415.          case 61:
  416.          case 62:
  417.          case 63:   return 6;
  418.  
  419.          case 64:
  420.          case 65:
  421.          case 66:
  422.          case 67:
  423.          case 68:
  424.          case 69:
  425.          case 70:
  426.          case 71:
  427.          case 72:
  428.          case 73:
  429.          case 74:
  430.          case 75:
  431.          case 76:
  432.          case 77:
  433.          case 78:
  434.          case 79:
  435.          case 80:
  436.          case 81:
  437.          case 82:
  438.          case 83:
  439.          case 84:
  440.          case 85:
  441.          case 86:
  442.          case 87:
  443.          case 88:
  444.          case 89:
  445.          case 90:
  446.          case 91:
  447.          case 92:
  448.          case 93:
  449.          case 94:
  450.          case 95:
  451.          case 96:
  452.          case 97:
  453.          case 98:
  454.          case 99:
  455.          case 100:
  456.          case 101:
  457.          case 102:
  458.          case 103:
  459.          case 104:
  460.          case 105:
  461.          case 106:
  462.          case 107:
  463.          case 108:
  464.          case 109:
  465.          case 110:
  466.          case 111:
  467.          case 112:
  468.          case 113:
  469.          case 114:
  470.          case 115:
  471.          case 116:
  472.          case 117:
  473.          case 118:
  474.          case 119:
  475.          case 120:
  476.          case 121:
  477.          case 122:
  478.          case 123:
  479.          case 124:
  480.          case 125:
  481.          case 126:
  482.          case 127:   return 7;
  483.       
  484.       default:       return 8;
  485.       } 
  486.    } 
  487.  
  488.  
  489.  
  490. /* ----------------------------------------------------------- */
  491.  
  492. void         Expand(int      c)
  493.    { 
  494.       #define DLE           144
  495.    
  496.       switch (ExState) {
  497.            
  498.            case 0:
  499.                if (c != DLE)
  500.                    OutByte(c);
  501.                else 
  502.                    ExState = 1; 
  503.            break; 
  504.            
  505.            case 1:
  506.                if (c != 0)
  507.                { 
  508.                    V = c; 
  509.                    Len = reduce_L(V);
  510.                    ExState = reduce_F(Len);
  511.                } 
  512.                else 
  513.                { 
  514.                    OutByte(DLE); 
  515.                    ExState = 0; 
  516.                } 
  517.            break; 
  518.            
  519.            case 2:   { 
  520.                   Len = Len + c; 
  521.                   ExState = 3; 
  522.                } 
  523.            break; 
  524.            
  525.            case 3:   { 
  526.                   int i;
  527.                   longint offset = reduce_D(V,c);
  528.                   longint op = outpos - offset;
  529.  
  530.                   for (i = 0; i <= Len + 2; i++) 
  531.                   { 
  532.                      if (op < 0L) 
  533.                         OutByte(0);
  534.                      else 
  535.                         OutByte(outbuf[(int)(op % sizeof(outbuf))]);
  536.                      op++; 
  537.                   } 
  538.  
  539.                   ExState = 0; 
  540.                } 
  541.          break;
  542.       } 
  543.    } 
  544.  
  545.  
  546. /* ----------------------------------------------------------- */
  547.    
  548. void         LoadFollowers(void)
  549.    { 
  550.       int      x;
  551.       int      i;
  552.       int      b;
  553.  
  554.       for (x = 255; x >= 0; x--) 
  555.       { 
  556.          ReadBits(6,&b); 
  557.          Slen[x] = b;
  558.  
  559.          for (i = 0; i < Slen[x]; i++)
  560.          { 
  561.             ReadBits(8,&b); 
  562.             followers[x][i] = b;
  563.          } 
  564.       } 
  565.    } 
  566.  
  567.  
  568.    
  569. /* ----------------------------------------------------------- */ 
  570.  
  571. /*
  572.  * The Reducing algorithm is actually a combination of two
  573.  * distinct algorithms.  The first algorithm compresses repeated
  574.  * byte sequences, and the second algorithm takes the compressed
  575.  * stream from the first algorithm and applies a probabilistic
  576.  * compression method.
  577.  *
  578.  */ 
  579.  
  580. void         unReduce(void)
  581.      /* expand probablisticly reduced data */ 
  582.  
  583.    { 
  584.  
  585.    int    lchar;
  586.    int    lout;
  587.    int    I;
  588.  
  589.    factor = cmethod - 1; 
  590.    if ((factor < 1) || (factor > 4)) 
  591.    { 
  592.       skip_csize(); 
  593.       return;
  594.    } 
  595.  
  596.    ExState = 0; 
  597.    LoadFollowers(); 
  598.    lchar =  0;
  599.  
  600.    while ((!zipeof) && (outpos < cusize))
  601.    { 
  602.  
  603.       if (Slen[lchar] == 0)
  604.          ReadBits(8,&lout);
  605.       else 
  606.  
  607.       { 
  608.          ReadBits(1,&lout); 
  609.          if (lout != 0) 
  610.             ReadBits(8,&lout);
  611.          else 
  612.          { 
  613.             ReadBits(reduce_B(Slen[lchar]),&I);
  614.             lout = followers[lchar][I];
  615.          } 
  616.       } 
  617.  
  618.       Expand(lout); 
  619.       lchar = lout; 
  620.    } 
  621.  
  622.  
  623. /* ------------------------------------------------------------- */
  624. /*
  625.  * Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm
  626.  * with partial clearing.
  627.  *
  628.  */ 
  629.  
  630. void         partial_clear(void)
  631.    int      pr;
  632.    int      cd;
  633.  
  634.  
  635.    /* mark all nodes as potentially unused */
  636.    for (cd = first_ent; cd < free_ent; cd++)
  637.       prefix_of[cd] |= 0x8000;
  638.  
  639.  
  640.    /* unmark those that are used by other nodes */
  641.    for (cd = first_ent; cd < free_ent; cd++)
  642.    { 
  643.       pr = prefix_of[cd] & 0x7fff;   /* reference to another node? */ 
  644.       if (pr >= first_ent)           /* flag node as referenced */
  645.          prefix_of[pr] &= 0x7fff;
  646.    } 
  647.  
  648.  
  649.    /* clear the ones that are still marked */ 
  650.    for (cd = first_ent; cd < free_ent; cd++)
  651.       if ((prefix_of[cd] & 0x8000) != 0) 
  652.          prefix_of[cd] = -1;
  653.  
  654.  
  655.    /* find first cleared node as next free_ent */ 
  656.    free_ent = first_ent; 
  657.    while ((free_ent < maxcodemax) && (prefix_of[free_ent] != -1)) 
  658.       free_ent++; 
  659.  
  660.  
  661. /* ------------------------------------------------------------- */
  662.  
  663. void         unShrink(void)
  664.  
  665.    int      stackp;
  666.    int      finchar;
  667.    int      code;
  668.    int      oldcode;
  669.    int      incode;
  670.  
  671.  
  672.    /* decompress the file */ 
  673.    maxcodemax = 1 << max_bits; 
  674.    cbits = init_bits; 
  675.    maxcode = (1 << cbits) - 1; 
  676.    free_ent = first_ent; 
  677.    offset = 0; 
  678.    sizex = 0; 
  679.  
  680.    for (code = maxcodemax; code > 255; code--)
  681.       prefix_of[code] = -1;
  682.  
  683.    for (code = 255; code >= 0; code--) 
  684.    { 
  685.       prefix_of[code] = 0;
  686.       suffix_of[code] = code;
  687.    } 
  688.  
  689.    ReadBits(cbits,&oldcode); 
  690.    if (zipeof) return;
  691.    finchar = oldcode; 
  692.  
  693.    OutByte(finchar); 
  694.  
  695.    stackp = 0; 
  696.  
  697.    while ((!zipeof)) 
  698.    { 
  699.       ReadBits(cbits,&code); 
  700.       if (zipeof) return;
  701.  
  702.       while (code == clear)
  703.       { 
  704.          ReadBits(cbits,&code); 
  705.  
  706.          switch (code) {
  707.             
  708.             case 1:   { 
  709.                   cbits++; 
  710.                   if (cbits == max_bits) 
  711.                      maxcode = maxcodemax;
  712.                   else 
  713.                      maxcode = (1 << cbits) - 1; 
  714.                } 
  715.             break;
  716.  
  717.             case 2:
  718.                   partial_clear();
  719.             break;
  720.          } 
  721.  
  722.          ReadBits(cbits,&code); 
  723.          if (zipeof) return;
  724.       } 
  725.  
  726.    
  727.       /* special case for KwKwK string */
  728.       incode = code;
  729.       if (prefix_of[code] == -1)
  730.       { 
  731.          stack[stackp] = finchar;
  732.          stackp++; 
  733.          code = oldcode; 
  734.       } 
  735.  
  736.  
  737.       /* generate output characters in reverse order */
  738.       while (code >= first_ent)
  739.       { 
  740.          stack[stackp] = suffix_of[code];
  741.          stackp++; 
  742.          code = prefix_of[code];
  743.       } 
  744.  
  745.       finchar = suffix_of[code];
  746.       stack[stackp] = finchar;
  747.       stackp++; 
  748.  
  749.  
  750.       /* and put them out in forward order */
  751.       while (stackp > 0)
  752.       { 
  753.          stackp--; 
  754.          OutByte(stack[stackp]);
  755.       } 
  756.  
  757.  
  758.       /* generate new entry */
  759.       code = free_ent;
  760.       if (code < maxcodemax) 
  761.       { 
  762.          prefix_of[code] = oldcode;
  763.          suffix_of[code] = finchar;
  764.          while ((free_ent < maxcodemax) && (prefix_of[free_ent] != -1))
  765.             free_ent++;
  766.       } 
  767.  
  768.  
  769.       /* remember previous code */
  770.       oldcode = incode; 
  771.    } 
  772.  
  773.  
  774.  
  775. /* ---------------------------------------------------------- */ 
  776.  
  777. void         extract_member(void)
  778.    int    b;
  779.  
  780. struct    ftime    {
  781.     unsigned    ft_tsec     : 5;    /* Two second interval */
  782.     unsigned    ft_min     : 6;    /* Minutes */
  783.     unsigned    ft_hour     : 5;    /* Hours */
  784.     unsigned    ft_day     : 5;    /* Days */
  785.     unsigned    ft_month : 4;    /* Months */
  786.     unsigned    ft_year     : 7;    /* Year */
  787.     };
  788.  
  789.    union {
  790.         struct ftime ft;
  791.         struct {
  792.             word ztime;
  793.             word zdate;
  794.         } zt;
  795.     } td;
  796.  
  797. for (b=0; b<sizeof(outbuf); b++) outbuf[b]=0;
  798.    pcbits = 0; 
  799.    incnt = 0; 
  800.    outpos = 0L; 
  801.    outcnt = 0; 
  802.    zipeof = 0;
  803.  
  804.    outfd = creat(filename,S_IWRITE|S_IREAD);
  805.    if (outfd < 1)
  806.    { 
  807.       printf("Can't create output: %s\n",filename); 
  808.       exit(0);
  809.    } 
  810.  
  811.    close(outfd);
  812.    outfd = open(filename,O_RDWR|O_BINARY);
  813.  
  814.  
  815.    switch (cmethod) {
  816.       
  817.       case 0:     /* stored */ 
  818.             { 
  819.                printf(" Extract: %s ...",filename); 
  820.                while ((!zipeof)) 
  821.                { 
  822.                   ReadByte(&b); 
  823.                   OutByte(b); 
  824.                } 
  825.             } 
  826.       break; 
  827.       
  828.       case 1:   { 
  829.                printf("UnShrink: %s ...",filename); 
  830.                unShrink(); 
  831.             } 
  832.       break; 
  833.       
  834.       case 2:   
  835.       case 3:   
  836.       case 4:   
  837.       case 5:   { 
  838.                printf("  Expand: %s ...",filename); 
  839.                unReduce(); 
  840.             } 
  841.       break; 
  842.       
  843.       default: printf("Unknown compression method."); 
  844.    } 
  845.  
  846.    if (outcnt > 0) 
  847.       write(outfd,outbuf,outcnt);
  848.  
  849.  
  850.    /* set output file date and time */
  851.    td.zt.ztime = lrec.last_mod_file_time;
  852.    td.zt.zdate = lrec.last_mod_file_date;
  853. /* setftime(outfd,&td.ft);*/
  854.  
  855.    close(outfd);
  856.  
  857. /*****************************************************/
  858. /*  OS/2 Equivalent of setftime                      */
  859. /*****************************************************/
  860.    usBufsize=sizeof(fstsBuf);
  861.    if (0 != (status = DosOpen( (PCH)filename,
  862.              (PHFILE)&Phandle,
  863.              &ActionFlag,        
  864.              0L,
  865.              0,
  866.              OF_OPENIFEXIST,
  867.              OM_PUBLICACC | OM_READWRITE,
  868.              0L)))
  869.      printf("Open status = %d\n",status);
  870.    memmove(&myfdate,&lrec.last_mod_file_date,2);
  871.    memmove(&myftime,&lrec.last_mod_file_time,2);
  872.    pfstsBuf=&fstsBuf;
  873.    if (0 != (status = DosQFileInfo(Phandle,
  874.                   (USHORT)0x0001, 
  875.                   (PFILESTATUS)pfstsBuf, 
  876.                   usBufsize)))
  877.      printf("Query status = %d\n",status);
  878.    fstsBuf.fdateLastWrite=myfdate;
  879.    fstsBuf.ftimeLastWrite=myftime;
  880.    if (0 != (status = DosSetFileInfo(Phandle,
  881.                   (USHORT)0x0001, 
  882.                   (PFILESTATUS)pfstsBuf, 
  883.                   usBufsize)))
  884.      printf("Datetime status = %d\n",status);
  885.    if (0 != (status = DosClose( Phandle )))
  886.      printf("Close status = %d\n",status);
  887. /*****************************************************/
  888.  
  889.    printf("  done.\n"); 
  890.  
  891.  
  892. /* ---------------------------------------------------------- */ 
  893.  
  894. void         process_local_file_header(void)
  895.    read(zipfd,&lrec,sizeof(lrec));
  896.    get_string(lrec.filename_length,filename);
  897.    get_string(lrec.extra_field_length,extra);
  898.    csize = lrec.compressed_size;
  899.    cusize = lrec.uncompressed_size;
  900.    cmethod = lrec.compression_method;
  901.    extract_member(); 
  902.  
  903.  
  904. /* ---------------------------------------------------------- */ 
  905.  
  906. void         process_central_file_header(void)
  907.    central_directory_file_header rec; 
  908.    char filename[STRSIZ];
  909.    char extra[STRSIZ];
  910.    char comment[STRSIZ];
  911.  
  912.    read(zipfd,&rec,sizeof(rec));
  913.    get_string(rec.filename_length,filename); 
  914.    get_string(rec.extra_field_length,extra); 
  915.    get_string(rec.file_comment_length,comment); 
  916.  
  917.  
  918. /* ---------------------------------------------------------- */ 
  919.  
  920. void         process_end_central_dir(void)
  921.    end_central_dir_record rec; 
  922.    char comment[STRSIZ];
  923.  
  924.    read(zipfd,&rec,sizeof(rec));
  925.    get_string(rec.zipfile_comment_length,comment); 
  926.  
  927.  
  928. /* ---------------------------------------------------------- */ 
  929.  
  930. void         process_headers(void)
  931.    longint sig;
  932.  
  933.    while (1)
  934.    { 
  935.       if (read(zipfd,&sig,sizeof(sig)) != sizeof(sig))
  936.          return;
  937.       else 
  938.  
  939.       if (sig == local_file_header_signature) 
  940.          process_local_file_header();
  941.       else 
  942.  
  943.       if (sig == central_file_header_signature) 
  944.          process_central_file_header();
  945.       else 
  946.  
  947.       if (sig == end_central_dir_signature) 
  948.       { 
  949.          process_end_central_dir(); 
  950.          return;
  951.       } 
  952.  
  953.       else 
  954.       { 
  955.          printf("Invalid Zipfile Header\n"); 
  956.          return;
  957.       } 
  958.    } 
  959.  
  960.  
  961.  
  962. /* ---------------------------------------------------------- */ 
  963.  
  964. void         extract_zipfile(void)
  965.    zipfd = open(zipfn,O_RDONLY|O_BINARY);
  966.    if (zipfd < 1) {
  967.       printf("Can't open input file: %s\n",zipfn);
  968.       return;
  969.    }
  970.  
  971.    process_headers();
  972.  
  973.    close(zipfd);
  974.  
  975.  
  976. /* ---------------------------------------------------------- */
  977. /*
  978.  * main program
  979.  *
  980.  */ 
  981.  
  982. void cdecl main(int argc, char **argv)
  983. {
  984.    printf("\n"); 
  985.    printf("%s\n",version); 
  986.    printf("Courtesy of:  S.H.Smith  and  The Tool Shop BBS,  (602) 279-2673.\n"); 
  987.    printf("OS/2 Conversion by Hollie Satterfield\n"); 
  988.    printf("\n");
  989.  
  990.    if (argc != 2)
  991.    { 
  992.       printf("Usage:  UnZip FILE[.zip]\n");
  993.       exit(0);
  994.    } 
  995.  
  996.    strcpy(zipfn,argv[1]);
  997.    if (strchr(zipfn,'.') == NULL)
  998.       strcat(zipfn,".ZIP");
  999.  
  1000.    extract_zipfile(); 
  1001.    exit(0);
  1002. }
  1003.  
  1004.