home *** CD-ROM | disk | FTP | other *** search
/ Palm Utilities / Palm_Utilities_CD-ROM_2001_2001.iso / files / utils misc / Boxer 0.18 / Boxer018.exe / boxer / PalmBoxer / unzip.c < prev   
Encoding:
C/C++ Source or Header  |  2000-07-09  |  12.7 KB  |  488 lines

  1. #define IGNORE_STDIO_STUBS
  2. #define __string_h
  3.  
  4. #ifdef OLDGCC
  5.  
  6. #include <Common.h>
  7. #include <System/SysAll.h>
  8. #include <UI/UIAll.h>
  9.  
  10. #else
  11.  
  12. #include <PalmOS.h>
  13. #include <PalmCompatibility.h>
  14.  
  15. #endif
  16.  
  17. #include <Unix/sys_socket.h>
  18. #include <Unix/sys_types.h>
  19. #include <System/SysEvtMgr.h>
  20. #include "stringil.h"
  21. #include "stdio2.h"
  22. #include "zlib.h"
  23.  
  24. #ifdef __PALMOS_TRAPS__
  25. Err errno;
  26. #endif
  27.  
  28. int fgetc(FILE * fp)
  29. {
  30.   unsigned char lastchr;
  31.   if (1 == fread(&lastchr, 1, 1, fp))
  32.     return lastchr;
  33.   else
  34.     return -1;
  35. }
  36.  
  37. FILE *fopen(char *name, char *mode)
  38. {
  39.   // Modes need lots of work
  40.   return FileOpen(0, name, 'DATA', 'BOXR',
  41.                   (*mode == 'r' ? fileModeReadOnly : fileModeReadWrite)
  42.                   | fileModeAnyTypeCreator, NULL);
  43. }
  44.  
  45. #define STORED            0     /* compression methods */
  46. #define DEFLATED          8
  47.  
  48. #  define CRCVAL_INITIAL  0L
  49.  
  50. /* PKZIP header definitions */
  51. #define ZIPMAG 0x4b50           /* two-byte zip lead-in */
  52. #define LOCREM 0x0403           /* remaining two bytes in zip signature */
  53. #define LOCSIG 0x04034b50L      /* full signature */
  54. #define LOCFLG 4                /* offset of bit flag */
  55. #define  CRPFLG 1               /*  bit for encrypted entry */
  56. #define  EXTFLG 8               /*  bit for extended local header */
  57. #define LOCHOW 6                /* offset of compression method */
  58. #define LOCTIM 8                /* file mod time (for decryption) */
  59. #define LOCCRC 12               /* offset of crc */
  60. #define LOCSIZ 16               /* offset of compressed size */
  61. #define LOCLEN 20               /* offset of uncompressed length */
  62. #define LOCFIL 24               /* offset of file name field length */
  63. #define LOCEXT 26               /* offset of extra field length */
  64. #define LOCHDR 28               /* size of local header, including LOCREM */
  65. #define EXTHDR 16               /* size of extended local header, inc sig */
  66.  
  67. /* GZIP header definitions */
  68. #define GZPMAG 0x8b1f           /* two-byte gzip lead-in */
  69. #define GZPHOW 0                /* offset of method number */
  70. #define GZPFLG 1                /* offset of gzip flags */
  71. #define  GZPMUL 2               /* bit for multiple-part gzip file */
  72. #define  GZPISX 4               /* bit for extra field present */
  73. #define  GZPISF 8               /* bit for filename present */
  74. #define  GZPISC 16              /* bit for comment present */
  75. #define  GZPISE 32              /* bit for encryption */
  76. #define GZPTIM 2                /* offset of Unix file modification time */
  77. #define GZPEXF 6                /* offset of extra flags */
  78. #define GZPCOS 7                /* offset of operating system compressed on */
  79. #define GZPHDR 8                /* length of minimal gzip header */
  80.  
  81. /* Macros for getting two-byte and four-byte header values */
  82. #define SH(p) ((unsigned short int)(unsigned char)((p)[0]) | ((unsigned short int)(unsigned char)((p)[1]) << 8))
  83. #define LG(p) ((unsigned long)(SH(p)) | ((unsigned long)(SH((p)+2)) << 16))
  84.  
  85. /* Globals */
  86.  
  87. #define BSIZ 128
  88.  
  89. #define err(n, m) {fprintf(stderr,m );return n;}
  90.  
  91. int unzipdir(FILE * infile, char *dir, long int *loc)
  92. {
  93.   int encrypted;                /* flag to turn on decryption */
  94.   unsigned long total, disp = 0, i=0;
  95.   unsigned short int n;
  96.   unsigned char h[LOCHDR];      /* first local header (GZPHDR < LOCHDR) */
  97.   unsigned char ibuf[BSIZ];
  98.   char *c;
  99.   int max;
  100.  
  101.   DmSet(dir,0,2,0);
  102.   max = 0;
  103.  
  104.   fseek(infile, 0, SEEK_SET);
  105.  
  106.   /* read ZIPal header, check validity */
  107.   n = fgetc(infile);
  108.   if (n > 255 || feof(infile))
  109.     return 0;
  110.   n |= fgetc(infile) << 8;
  111.  
  112.   if (n != ZIPMAG)
  113.     return 0;
  114.  
  115.   fseek(infile, 0, SEEK_SET);
  116.  
  117.   for (;;) {
  118.     /* read local header, check validity, and skip name and extra fields */
  119.     n = fgetc(infile);
  120.     if (n > 255 || feof(infile))
  121.       return max;
  122.  
  123.     n |= fgetc(infile) << 8;
  124.  
  125.     if (n != ZIPMAG)
  126.       return max;
  127.  
  128.     total = ftell(infile) - 2L;
  129.     DmWrite(loc,(i++)*4,&total,4);
  130.  
  131.     fread((char *) h, 1, LOCHDR, infile);
  132.     if (SH(h) == 0x0201)
  133.       return max;               // start of central directory
  134.     if (SH(h) != LOCREM)
  135.       err(3, "invalid zipfile");
  136.  
  137.     /* FILENAME */
  138.     ibuf[SH(h + LOCFIL)] = 0;
  139.     fread(ibuf, 1, SH(h + LOCFIL), infile);
  140.  
  141.     for (n = SH(h + LOCEXT); n--;)
  142.       fgetc(infile);
  143.     encrypted = h[LOCFLG] & CRPFLG;
  144.  
  145.     total = LG(h + LOCSIZ);
  146.     c = ibuf;
  147.     while (*c) {
  148.       if (*c <= ' ' || *c >= 0x7f)
  149.         *c = '_';
  150.       c++;
  151.     }
  152.     c = ibuf;
  153.     if (strlen(ibuf) > 32)
  154.       c += strlen(ibuf) - 32;
  155.  
  156.     DmWrite(dir,disp,c,strlen(c)+1);
  157.     disp += strlen(c)+1;
  158.     DmSet(dir,disp,1,0);
  159.  
  160.     /* if entry encrypted, decrypt and validate encryption header */
  161.     if (encrypted)
  162.       err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
  163.  
  164.     fseek(infile, total, SEEK_CUR);
  165.  
  166.     /* if extended header, get it */
  167.     if ((h[LOCFLG] & EXTFLG) &&
  168.         fread((char *) h + LOCCRC - 4, 1, EXTHDR, infile) != EXTHDR)
  169.       err(3, "zipfile ended prematurely");
  170.  
  171.     max++;
  172.  
  173.   }
  174.  
  175. }
  176.  
  177. /* ************************************************************************ */
  178.  
  179. int unzip(FILE * infile, long int loc)
  180. {
  181.   FILE *outfile;
  182.   unsigned long crc32val;
  183.   unsigned long outsiz;         /* total bytes written to out */
  184.   int encrypted;                /* flag to turn on decryption */
  185.   unsigned long total, itot;
  186.   unsigned short int n;
  187.   unsigned char h[LOCHDR];      /* first local header (GZPHDR < LOCHDR) */
  188.   int k = 0, got;
  189.   unsigned char ibuf[BSIZ], obuf[BSIZ];
  190.   z_stream pgpz;
  191.   int gz = 0;                   /* true if gzip format */
  192.   char *c;
  193.   RectangleType r;
  194.   DmOpenRef db;
  195.  
  196.   fseek(infile, 0, SEEK_SET);
  197.   /* read ZIPal header, check validity */
  198.   n = fgetc(infile);
  199.   if (n > 255 || feof(infile))
  200.     return 0;
  201.   n |= fgetc(infile) << 8;
  202.  
  203.   if (n != ZIPMAG && n != GZPMAG)
  204.     return -1;
  205.  
  206.   total = sizeof(db);
  207.   FileControl(fileOpGetOpenDbRef, infile, &db, &total);
  208.  
  209.   FileTell(infile, &total, NULL);
  210.  
  211.   if (loc == -1) {
  212.     fseek(infile, 0, SEEK_SET);
  213.     FileControl(fileOpDestructiveReadMode, infile, NULL, NULL);
  214.   } else
  215.     fseek(infile, loc, SEEK_SET);
  216.  
  217.   for (;;) {
  218.  
  219.     /* read local header, check validity, and skip name and extra fields */
  220.     n = fgetc(infile);
  221.     if (n > 255 || feof(infile))
  222.       return 0;
  223.  
  224.     n |= fgetc(infile) << 8;
  225.  
  226.     r.topLeft.x = 0, r.topLeft.y = 15, r.extent.x = 160, r.extent.y = 30;
  227.     WinEraseRectangle(&r, 0);
  228.  
  229.     if (n == ZIPMAG) {
  230.       fread((char *) h, 1, LOCHDR, infile);
  231.       if (SH(h) == 0x0201)
  232.         return 0;               // start of central directory
  233.       if (SH(h) != LOCREM)
  234.         err(3, "invalid zipfile");
  235.       if (SH(h + LOCHOW) != STORED && SH(h + LOCHOW) != DEFLATED)
  236.         err(3, "entry not deflated or stored--cannot unpack");
  237.  
  238.       /* FILENAME */
  239.       ibuf[SH(h + LOCFIL)] = 0;
  240.       fread(ibuf, 1, SH(h + LOCFIL), infile);
  241.  
  242.       for (n = SH(h + LOCEXT); n--;)
  243.         gz = fgetc(infile);
  244.       gz = 0;
  245.       encrypted = h[LOCFLG] & CRPFLG;
  246.     }
  247.  
  248.     else if (n == GZPMAG) {
  249.       fread((char *) h, 1, GZPHDR, infile);
  250.       if ((h[GZPHOW] != DEFLATED) || (h[GZPFLG] & GZPMUL))
  251.         err(3, "cannot handle this gzip file");
  252.  
  253.       if (h[GZPFLG] & GZPISX) {
  254.         n = fgetc(infile);
  255.         n |= fgetc(infile) << 8;
  256.         fread(ibuf, 1, n, infile);
  257.       }
  258.  
  259.       if (h[GZPFLG] & GZPISF) {
  260.         c = ibuf;
  261.         while ((*c++ = fgetc(infile)) != 0);
  262.       } else {
  263.         LocalID lid;
  264.         UInt16 cardno;
  265.  
  266.         // Mung the name for gzips if one isn't within the file
  267.         DmOpenDatabaseInfo(db, &lid, NULL, NULL, &cardno, NULL);
  268.         DmDatabaseInfo(cardno, lid, ibuf, NULL, NULL, NULL, NULL,
  269.                        NULL, NULL, NULL, NULL, NULL, NULL);
  270.  
  271.         c = &ibuf[strlen(ibuf) - 4];
  272.         if (!strcmp(c, ".tgz") || !strcmp(c, ".TGZ"))
  273.           c[2] = 'a', c[3] = 'r';
  274.         else if (!strcmp(++c, ".gz") || !strcmp(c, ".GZ"))
  275.           *c = 0;
  276.         else
  277.           strcat(ibuf, ".guz");
  278.       }
  279.  
  280.       if (h[GZPFLG] & GZPISC)
  281.         while ((gz = fgetc(infile)) != 0 && gz != -1);
  282.  
  283.       gz = 1;
  284.       encrypted = h[GZPFLG] & GZPISE;
  285.     }
  286.  
  287.     else
  288.       return 1;
  289.  
  290.     if( !gz )
  291.       total = LG(h + LOCSIZ);
  292.     if (!total) {
  293.       if (loc == -1)
  294.         continue;
  295.       else
  296.         return -1;
  297.     }
  298.  
  299.     /* fix filename and open for write */
  300.     c = ibuf;
  301.     while (*c) {
  302.       if (*c <= ' ' || *c >= 0x7f)
  303.         *c = '_';
  304.       c++;
  305.     }
  306.     c = ibuf;
  307.     if (strlen(ibuf) > 32)
  308.       c += strlen(ibuf) - 32;
  309.     outfile = fopen(c, "w");
  310.     WinDrawChars(c, strlen(c), 0, 15);
  311.  
  312.     /* if entry encrypted, decrypt and validate encryption header */
  313.     if (encrypted)
  314.       err(3, "cannot decrypt entry (need to recompile with full crypt.c)");
  315.  
  316.     itot = total;
  317.     outsiz = 0L;
  318.     crc32val = CRCVAL_INITIAL;
  319.  
  320.     r.topLeft.y = 30, r.extent.y = 15;
  321.  
  322.     /* decompress */
  323.     if (gz || h[LOCHOW]) {      /* deflated entry */
  324.       outsiz = 0;
  325.       memset(&pgpz, 0, sizeof(pgpz));
  326.       inflateInit2(&pgpz, -15);
  327.  
  328.       do {
  329.         while (total && !feof(infile)) {
  330.  
  331.           if (0 > (got = fread(ibuf, 1, total > BSIZ ? BSIZ : total, infile)))
  332.             break;
  333.  
  334.           total -= got;
  335. #if 0
  336.           if (gz)
  337.             WinDrawChars(gz++ & 1 ? "\\" : "/", 1, 0, 30);
  338.           else
  339. #endif
  340.  {
  341.             r.extent.x = 160 - (160 * total / itot);
  342.             WinDrawRectangle(&r, 0);
  343.           }
  344.  
  345.           pgpz.next_in = ibuf;
  346.           pgpz.avail_in = got;
  347.           while (pgpz.avail_in || !total || feof(infile)) {
  348.             pgpz.next_out = obuf;
  349.             pgpz.avail_out = BSIZ;
  350.             k = inflate(&pgpz, !total || !feof(infile) ? 0 : Z_FINISH);
  351.             fwrite(obuf, 1, BSIZ - pgpz.avail_out, outfile);
  352.  
  353.             outsiz += BSIZ - pgpz.avail_out;
  354.             crc32val = crc32(crc32val, obuf, BSIZ - pgpz.avail_out);
  355.  
  356.             if (k == Z_BUF_ERROR && pgpz.avail_out != BSIZ
  357.                 && (total || feof(infile))) continue; /* for undoc zlib */
  358.             if (k != Z_OK)
  359.               break;
  360.           }
  361.         }
  362.       } while (total && !feof(infile));
  363.       inflateEnd(&pgpz);
  364.  
  365.       //error status:       (k == Z_STREAM_END);
  366.     }
  367.  
  368.  
  369.     else {                      /* stored entry */
  370.  
  371.       got = LG(h + LOCLEN);
  372.       if (got != LG(h + LOCSIZ))
  373.         err(4, "invalid compressed data--length mismatch");
  374.  
  375.       total = got;
  376.       while (total) {
  377.         got = fread(ibuf, 1, total > BSIZ ? BSIZ : total, infile);
  378.         outsiz += got;
  379.         total -= got;
  380.         r.extent.x = 160 * total / itot;
  381.         WinDrawRectangle(&r, 0);
  382.         crc32val = crc32(crc32val, ibuf, got);
  383.  
  384.         fwrite(ibuf, 1, got, outfile);
  385.       }
  386.     }
  387.     fclose(outfile);
  388.     EvtResetAutoOffTimer();
  389.  
  390.     /* if extended header, get it */
  391.     if (gz) {
  392.       if (pgpz.avail_in < 8)
  393.         err(3, "gzip ended prematurely");
  394.       memcpy((char *) h + LOCCRC, pgpz.next_in, 8);
  395.  
  396.       break;                    //THIS DOESN'T WORK HERE
  397.     }
  398.       else
  399.       if ((h[LOCFLG] & EXTFLG) &&
  400.           fread((char *) h + LOCCRC - 4, 1, EXTHDR, infile) != EXTHDR)
  401.         err(3, "zipfile ended prematurely");
  402.  
  403.     /* validate decompression */
  404.     if (LG(h + LOCCRC) != crc32val)
  405.       err(4, "invalid compressed data--crc error");
  406.  
  407.     if (LG((gz ? (h + LOCSIZ) : (h + LOCLEN))) != outsiz)
  408.       err(4, "invalid compressed data--length error");
  409.  
  410.     if (loc != -1)
  411.       break;
  412.  
  413.   }
  414.  
  415.   return 0;
  416. }
  417.  
  418.  
  419. char gzhead[10] = {0x1f , 0x8b, 8 , 0,0,0,0,0,0,3 };
  420.  
  421.  
  422. #define OBSIZ 512               /* (8383+NTPSIZ*2) */
  423. #define IBSIZ 128
  424.  
  425. int gzip(FILE * inf, FILE * outf)
  426. {
  427.   z_stream gzipit;
  428.   int readgot, isav;
  429.   unsigned char ibuf[IBSIZ], obuf[OBSIZ];
  430.   unsigned long crc32val, itotal, total = 0;
  431.   RectangleType r;
  432.  
  433.   r.topLeft.x = 0, r.topLeft.y = 30, r.extent.x = 160, r.extent.y = 15;
  434.  
  435.   WinDrawChars("GZipping:",9 , 0, 15);
  436.  
  437.   memset(&gzipit, 0, sizeof(gzipit));
  438.  
  439.   fwrite(gzhead, 1, 10, outf);
  440.  
  441.   FileTell(inf,&itotal, NULL);
  442.   crc32val = CRCVAL_INITIAL;
  443.  
  444.   gzipit.next_out = obuf;
  445.   gzipit.avail_out = OBSIZ;
  446.  
  447.   // level 6, 8=deflate, 12 bits of compression
  448.   // 5 is a memlevel that shouldn't overflow
  449.   deflateInit2(&gzipit, 6, 8, -12, 5, 0);
  450.   readgot = IBSIZ;
  451.  
  452.   while (!feof(inf) && readgot == IBSIZ) {
  453.     if (0 >= (readgot = fread(ibuf, 1, IBSIZ, inf)))
  454.       break;
  455.  
  456.     crc32val = crc32(crc32val, ibuf, readgot);
  457.     total += readgot;
  458.     r.extent.x = 160 * total / itotal;
  459.     WinDrawRectangle(&r, 0);
  460.  
  461.     gzipit.next_in = ibuf;
  462.     gzipit.avail_in = readgot;
  463.  
  464.     while (gzipit.avail_in || readgot != IBSIZ) {
  465.       isav = deflate(&gzipit, readgot == IBSIZ ? 0 : Z_FINISH);
  466.       fwrite(obuf, 1, OBSIZ - gzipit.avail_out, outf);
  467.       gzipit.avail_out = OBSIZ;
  468.       gzipit.next_out = obuf;
  469.       if (isav != Z_OK)
  470.         break;
  471.     }
  472.  
  473.   }
  474.  
  475.   fwrite(obuf, 1, OBSIZ - gzipit.avail_out, outf);
  476.  
  477.   deflateEnd(&gzipit);
  478.  
  479.   memcpy(obuf,&crc32val,4);
  480.   itotal = LG(obuf);
  481.   fwrite(&itotal, 1, 4, outf);
  482.   memcpy(obuf,&total,4);
  483.   itotal = LG(obuf);
  484.   fwrite(&itotal, 1, 4, outf);
  485.  
  486.   return 0;
  487. }
  488.