"Fossies" - the Fresh Open Source Software Archive

Member "muscle/zlib/zlib/contrib/minizip/mztools.c" (21 Nov 2020, 8146 Bytes) of package /linux/privat/muscle7.62.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mztools.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 7.61_vs_7.62.

    1 /*
    2   Additional tools for Minizip
    3   Code: Xavier Roche '2004
    4   License: Same as ZLIB (www.gzip.org)
    5 */
    6 
    7 /* Code */
    8 #include <stdio.h>
    9 #include <stdlib.h>
   10 #include <string.h>
   11 #include "zlib.h"
   12 #include "unzip.h"
   13 
   14 #define READ_8(adr)  ((unsigned char)*(adr))
   15 #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
   16 #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
   17 
   18 #define WRITE_8(buff, n) do { \
   19   *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
   20 } while(0)
   21 #define WRITE_16(buff, n) do { \
   22   WRITE_8((unsigned char*)(buff), n); \
   23   WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
   24 } while(0)
   25 #define WRITE_32(buff, n) do { \
   26   WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
   27   WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
   28 } while(0)
   29 
   30 extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
   31 const char* file;
   32 const char* fileOut;
   33 const char* fileOutTmp;
   34 uLong* nRecovered;
   35 uLong* bytesRecovered;
   36 {
   37   int err = Z_OK;
   38   FILE* fpZip = fopen(file, "rb");
   39   FILE* fpOut = fopen(fileOut, "wb");
   40   FILE* fpOutCD = fopen(fileOutTmp, "wb");
   41   if (fpZip != NULL &&  fpOut != NULL) {
   42     int entries = 0;
   43     uLong totalBytes = 0;
   44     char header[30];
   45     char filename[1024];
   46     char extra[1024];
   47     int offset = 0;
   48     int offsetCD = 0;
   49     while ( fread(header, 1, 30, fpZip) == 30 ) {
   50       int currentOffset = offset;
   51 
   52       /* File entry */
   53       if (READ_32(header) == 0x04034b50) {
   54         unsigned int version = READ_16(header + 4);
   55         unsigned int gpflag = READ_16(header + 6);
   56         unsigned int method = READ_16(header + 8);
   57         unsigned int filetime = READ_16(header + 10);
   58         unsigned int filedate = READ_16(header + 12);
   59         unsigned int crc = READ_32(header + 14); /* crc */
   60         unsigned int cpsize = READ_32(header + 18); /* compressed size */
   61         unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
   62         unsigned int fnsize = READ_16(header + 26); /* file name length */
   63         unsigned int extsize = READ_16(header + 28); /* extra field length */
   64         filename[0] = extra[0] = '\0';
   65 
   66         /* Header */
   67         if (fwrite(header, 1, 30, fpOut) == 30) {
   68           offset += 30;
   69         } else {
   70           err = Z_ERRNO;
   71           break;
   72         }
   73 
   74         /* Filename */
   75         if (fnsize > 0) {
   76           if (fnsize < sizeof(filename)) {
   77             if (fread(filename, 1, fnsize, fpZip) == fnsize) {
   78                 if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
   79                 offset += fnsize;
   80               } else {
   81                 err = Z_ERRNO;
   82                 break;
   83               }
   84             } else {
   85               err = Z_ERRNO;
   86               break;
   87             }
   88           } else {
   89             err = Z_ERRNO;
   90             break;
   91           }
   92         } else {
   93           err = Z_STREAM_ERROR;
   94           break;
   95         }
   96 
   97         /* Extra field */
   98         if (extsize > 0) {
   99           if (extsize < sizeof(extra)) {
  100             if (fread(extra, 1, extsize, fpZip) == extsize) {
  101               if (fwrite(extra, 1, extsize, fpOut) == extsize) {
  102                 offset += extsize;
  103                 } else {
  104                 err = Z_ERRNO;
  105                 break;
  106               }
  107             } else {
  108               err = Z_ERRNO;
  109               break;
  110             }
  111           } else {
  112             err = Z_ERRNO;
  113             break;
  114           }
  115         }
  116 
  117         /* Data */
  118         {
  119           int dataSize = cpsize;
  120           if (dataSize == 0) {
  121             dataSize = uncpsize;
  122           }
  123           if (dataSize > 0) {
  124             char* data = malloc(dataSize);
  125             if (data != NULL) {
  126               if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
  127                 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
  128                   offset += dataSize;
  129                   totalBytes += dataSize;
  130                 } else {
  131                   err = Z_ERRNO;
  132                 }
  133               } else {
  134                 err = Z_ERRNO;
  135               }
  136               free(data);
  137               if (err != Z_OK) {
  138                 break;
  139               }
  140             } else {
  141               err = Z_MEM_ERROR;
  142               break;
  143             }
  144           }
  145         }
  146 
  147         /* Central directory entry */
  148         {
  149           char header[46];
  150           char* comment = "";
  151           int comsize = (int) strlen(comment);
  152           WRITE_32(header, 0x02014b50);
  153           WRITE_16(header + 4, version);
  154           WRITE_16(header + 6, version);
  155           WRITE_16(header + 8, gpflag);
  156           WRITE_16(header + 10, method);
  157           WRITE_16(header + 12, filetime);
  158           WRITE_16(header + 14, filedate);
  159           WRITE_32(header + 16, crc);
  160           WRITE_32(header + 20, cpsize);
  161           WRITE_32(header + 24, uncpsize);
  162           WRITE_16(header + 28, fnsize);
  163           WRITE_16(header + 30, extsize);
  164           WRITE_16(header + 32, comsize);
  165           WRITE_16(header + 34, 0);     /* disk # */
  166           WRITE_16(header + 36, 0);     /* int attrb */
  167           WRITE_32(header + 38, 0);     /* ext attrb */
  168           WRITE_32(header + 42, currentOffset);
  169           /* Header */
  170           if (fwrite(header, 1, 46, fpOutCD) == 46) {
  171             offsetCD += 46;
  172 
  173             /* Filename */
  174             if (fnsize > 0) {
  175               if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
  176                 offsetCD += fnsize;
  177               } else {
  178                 err = Z_ERRNO;
  179                 break;
  180               }
  181             } else {
  182               err = Z_STREAM_ERROR;
  183               break;
  184             }
  185 
  186             /* Extra field */
  187             if (extsize > 0) {
  188               if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
  189                 offsetCD += extsize;
  190               } else {
  191                 err = Z_ERRNO;
  192                 break;
  193               }
  194             }
  195 
  196             /* Comment field */
  197             if (comsize > 0) {
  198               if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
  199                 offsetCD += comsize;
  200               } else {
  201                 err = Z_ERRNO;
  202                 break;
  203               }
  204             }
  205 
  206 
  207           } else {
  208             err = Z_ERRNO;
  209             break;
  210           }
  211         }
  212 
  213         /* Success */
  214         entries++;
  215 
  216       } else {
  217         break;
  218       }
  219     }
  220 
  221     /* Final central directory  */
  222     {
  223       int entriesZip = entries;
  224       char header[22];
  225       char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
  226       int comsize = (int) strlen(comment);
  227       if (entriesZip > 0xffff) {
  228         entriesZip = 0xffff;
  229       }
  230       WRITE_32(header, 0x06054b50);
  231       WRITE_16(header + 4, 0);    /* disk # */
  232       WRITE_16(header + 6, 0);    /* disk # */
  233       WRITE_16(header + 8, entriesZip);   /* hack */
  234       WRITE_16(header + 10, entriesZip);  /* hack */
  235       WRITE_32(header + 12, offsetCD);    /* size of CD */
  236       WRITE_32(header + 16, offset);      /* offset to CD */
  237       WRITE_16(header + 20, comsize);     /* comment */
  238 
  239       /* Header */
  240       if (fwrite(header, 1, 22, fpOutCD) == 22) {
  241 
  242         /* Comment field */
  243         if (comsize > 0) {
  244           if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
  245             err = Z_ERRNO;
  246           }
  247         }
  248 
  249       } else {
  250         err = Z_ERRNO;
  251       }
  252     }
  253 
  254     /* Final merge (file + central directory) */
  255     fclose(fpOutCD);
  256     if (err == Z_OK) {
  257       fpOutCD = fopen(fileOutTmp, "rb");
  258       if (fpOutCD != NULL) {
  259         int nRead;
  260         char buffer[8192];
  261         while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
  262           if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
  263             err = Z_ERRNO;
  264             break;
  265           }
  266         }
  267         fclose(fpOutCD);
  268       }
  269     }
  270 
  271     /* Close */
  272     fclose(fpZip);
  273     fclose(fpOut);
  274 
  275     /* Wipe temporary file */
  276     (void)remove(fileOutTmp);
  277 
  278     /* Number of recovered entries */
  279     if (err == Z_OK) {
  280       if (nRecovered != NULL) {
  281         *nRecovered = entries;
  282       }
  283       if (bytesRecovered != NULL) {
  284         *bytesRecovered = totalBytes;
  285       }
  286     }
  287   } else {
  288     err = Z_STREAM_ERROR;
  289   }
  290   return err;
  291 }