Home | History | Annotate | Download | only in minizip
      1 /* unzip.c -- IO for uncompress .zip files using zlib
      2    Version 1.01e, February 12th, 2005
      3 
      4    Copyright (C) 1998-2005 Gilles Vollant
      5 
      6    Read unzip.h for more info
      7 */
      8 
      9 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
     10 compatibility with older software. The following is from the original crypt.c. Code
     11 woven in by Terry Thorsen 1/2003.
     12 */
     13 /*
     14   Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
     15 
     16   See the accompanying file LICENSE, version 2000-Apr-09 or later
     17   (the contents of which are also included in zip.h) for terms of use.
     18   If, for some reason, all these files are missing, the Info-ZIP license
     19   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
     20 */
     21 /*
     22   crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
     23 
     24   The encryption/decryption parts of this source code (as opposed to the
     25   non-echoing password parts) were originally written in Europe.  The
     26   whole source package can be freely distributed, including from the USA.
     27   (Prior to January 2000, re-export from the US was a violation of US law.)
     28  */
     29 
     30 /*
     31   This encryption code is a direct transcription of the algorithm from
     32   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
     33   file (appnote.txt) is distributed with the PKZIP program (even in the
     34   version without encryption capabilities).
     35  */
     36 
     37 
     38 #include <stdio.h>
     39 #include <stdlib.h>
     40 #include <string.h>
     41 #if defined(USE_SYSTEM_ZLIB)
     42 #include <zlib.h>
     43 #else
     44 #include "third_party/zlib/zlib.h"
     45 #endif
     46 #include "unzip.h"
     47 
     48 #ifdef STDC
     49 #  include <stddef.h>
     50 #  include <string.h>
     51 #  include <stdlib.h>
     52 #endif
     53 #ifdef NO_ERRNO_H
     54     extern int errno;
     55 #else
     56 #   include <errno.h>
     57 #endif
     58 
     59 
     60 #ifndef local
     61 #  define local static
     62 #endif
     63 /* compile with -Dlocal if your debugger can't find static symbols */
     64 
     65 
     66 #ifndef CASESENSITIVITYDEFAULT_NO
     67 #  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
     68 #    define CASESENSITIVITYDEFAULT_NO
     69 #  endif
     70 #endif
     71 
     72 
     73 #ifndef UNZ_BUFSIZE
     74 #define UNZ_BUFSIZE (16384)
     75 #endif
     76 
     77 #ifndef UNZ_MAXFILENAMEINZIP
     78 #define UNZ_MAXFILENAMEINZIP (256)
     79 #endif
     80 
     81 #ifndef ALLOC
     82 # define ALLOC(size) (malloc(size))
     83 #endif
     84 #ifndef TRYFREE
     85 # define TRYFREE(p) {if (p) free(p);}
     86 #endif
     87 
     88 #define SIZECENTRALDIRITEM (0x2e)
     89 #define SIZEZIPLOCALHEADER (0x1e)
     90 
     91 
     92 
     93 
     94 const char unz_copyright[] =
     95    " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
     96 
     97 /* unz_file_info_interntal contain internal info about a file in zipfile*/
     98 typedef struct unz_file_info_internal_s
     99 {
    100     uLong offset_curfile;/* relative offset of local header 4 bytes */
    101 } unz_file_info_internal;
    102 
    103 
    104 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
    105     when reading and decompress it */
    106 typedef struct
    107 {
    108     char  *read_buffer;         /* internal buffer for compressed data */
    109     z_stream stream;            /* zLib stream structure for inflate */
    110 
    111     uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
    112     uLong stream_initialised;   /* flag set if stream structure is initialised*/
    113 
    114     uLong offset_local_extrafield;/* offset of the local extra field */
    115     uInt  size_local_extrafield;/* size of the local extra field */
    116     uLong pos_local_extrafield;   /* position in the local extra field in read*/
    117 
    118     uLong crc32;                /* crc32 of all data uncompressed */
    119     uLong crc32_wait;           /* crc32 we must obtain after decompress all */
    120     uLong rest_read_compressed; /* number of byte to be decompressed */
    121     uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
    122     zlib_filefunc_def z_filefunc;
    123     voidpf filestream;        /* io structore of the zipfile */
    124     uLong compression_method;   /* compression method (0==store) */
    125     uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
    126     int   raw;
    127 } file_in_zip_read_info_s;
    128 
    129 
    130 /* unz_s contain internal information about the zipfile
    131 */
    132 typedef struct
    133 {
    134     zlib_filefunc_def z_filefunc;
    135     voidpf filestream;        /* io structore of the zipfile */
    136     unz_global_info gi;       /* public global information */
    137     uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
    138     uLong num_file;             /* number of the current file in the zipfile*/
    139     uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
    140     uLong current_file_ok;      /* flag about the usability of the current file*/
    141     uLong central_pos;          /* position of the beginning of the central dir*/
    142 
    143     uLong size_central_dir;     /* size of the central directory  */
    144     uLong offset_central_dir;   /* offset of start of central directory with
    145                                    respect to the starting disk number */
    146 
    147     unz_file_info cur_file_info; /* public info about the current file in zip*/
    148     unz_file_info_internal cur_file_info_internal; /* private info about it*/
    149     file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
    150                                         file if we are decompressing it */
    151     int encrypted;
    152 #    ifndef NOUNCRYPT
    153     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
    154     const unsigned long* pcrc_32_tab;
    155 #    endif
    156 } unz_s;
    157 
    158 
    159 #ifndef NOUNCRYPT
    160 #include "crypt.h"
    161 #endif
    162 
    163 /* ===========================================================================
    164      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
    165    for end of file.
    166    IN assertion: the stream s has been sucessfully opened for reading.
    167 */
    168 
    169 
    170 local int unzlocal_getByte OF((
    171     const zlib_filefunc_def* pzlib_filefunc_def,
    172     voidpf filestream,
    173     int *pi));
    174 
    175 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
    176     const zlib_filefunc_def* pzlib_filefunc_def;
    177     voidpf filestream;
    178     int *pi;
    179 {
    180     unsigned char c;
    181     int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
    182     if (err==1)
    183     {
    184         *pi = (int)c;
    185         return UNZ_OK;
    186     }
    187     else
    188     {
    189         if (ZERROR(*pzlib_filefunc_def,filestream))
    190             return UNZ_ERRNO;
    191         else
    192             return UNZ_EOF;
    193     }
    194 }
    195 
    196 
    197 /* ===========================================================================
    198    Reads a long in LSB order from the given gz_stream. Sets
    199 */
    200 local int unzlocal_getShort OF((
    201     const zlib_filefunc_def* pzlib_filefunc_def,
    202     voidpf filestream,
    203     uLong *pX));
    204 
    205 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
    206     const zlib_filefunc_def* pzlib_filefunc_def;
    207     voidpf filestream;
    208     uLong *pX;
    209 {
    210     uLong x ;
    211     int i;
    212     int err;
    213 
    214     err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
    215     x = (uLong)i;
    216 
    217     if (err==UNZ_OK)
    218         err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
    219     x += ((uLong)i)<<8;
    220 
    221     if (err==UNZ_OK)
    222         *pX = x;
    223     else
    224         *pX = 0;
    225     return err;
    226 }
    227 
    228 local int unzlocal_getLong OF((
    229     const zlib_filefunc_def* pzlib_filefunc_def,
    230     voidpf filestream,
    231     uLong *pX));
    232 
    233 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
    234     const zlib_filefunc_def* pzlib_filefunc_def;
    235     voidpf filestream;
    236     uLong *pX;
    237 {
    238     uLong x ;
    239     int i;
    240     int err;
    241 
    242     err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
    243     x = (uLong)i;
    244 
    245     if (err==UNZ_OK)
    246         err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
    247     x += ((uLong)i)<<8;
    248 
    249     if (err==UNZ_OK)
    250         err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
    251     x += ((uLong)i)<<16;
    252 
    253     if (err==UNZ_OK)
    254         err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
    255     x += ((uLong)i)<<24;
    256 
    257     if (err==UNZ_OK)
    258         *pX = x;
    259     else
    260         *pX = 0;
    261     return err;
    262 }
    263 
    264 
    265 /* My own strcmpi / strcasecmp */
    266 local int strcmpcasenosensitive_internal (fileName1,fileName2)
    267     const char* fileName1;
    268     const char* fileName2;
    269 {
    270     for (;;)
    271     {
    272         char c1=*(fileName1++);
    273         char c2=*(fileName2++);
    274         if ((c1>='a') && (c1<='z'))
    275             c1 -= 0x20;
    276         if ((c2>='a') && (c2<='z'))
    277             c2 -= 0x20;
    278         if (c1=='\0')
    279             return ((c2=='\0') ? 0 : -1);
    280         if (c2=='\0')
    281             return 1;
    282         if (c1<c2)
    283             return -1;
    284         if (c1>c2)
    285             return 1;
    286     }
    287 }
    288 
    289 
    290 #ifdef  CASESENSITIVITYDEFAULT_NO
    291 #define CASESENSITIVITYDEFAULTVALUE 2
    292 #else
    293 #define CASESENSITIVITYDEFAULTVALUE 1
    294 #endif
    295 
    296 #ifndef STRCMPCASENOSENTIVEFUNCTION
    297 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
    298 #endif
    299 
    300 /*
    301    Compare two filename (fileName1,fileName2).
    302    If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
    303    If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
    304                                                                 or strcasecmp)
    305    If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
    306         (like 1 on Unix, 2 on Windows)
    307 
    308 */
    309 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
    310     const char* fileName1;
    311     const char* fileName2;
    312     int iCaseSensitivity;
    313 {
    314     if (iCaseSensitivity==0)
    315         iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
    316 
    317     if (iCaseSensitivity==1)
    318         return strcmp(fileName1,fileName2);
    319 
    320     return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
    321 }
    322 
    323 #ifndef BUFREADCOMMENT
    324 #define BUFREADCOMMENT (0x400)
    325 #endif
    326 
    327 /*
    328   Locate the Central directory of a zipfile (at the end, just before
    329     the global comment)
    330 */
    331 local uLong unzlocal_SearchCentralDir OF((
    332     const zlib_filefunc_def* pzlib_filefunc_def,
    333     voidpf filestream));
    334 
    335 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
    336     const zlib_filefunc_def* pzlib_filefunc_def;
    337     voidpf filestream;
    338 {
    339     unsigned char* buf;
    340     uLong uSizeFile;
    341     uLong uBackRead;
    342     uLong uMaxBack=0xffff; /* maximum size of global comment */
    343     uLong uPosFound=0;
    344 
    345     if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
    346         return 0;
    347 
    348 
    349     uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
    350 
    351     if (uMaxBack>uSizeFile)
    352         uMaxBack = uSizeFile;
    353 
    354     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
    355     if (buf==NULL)
    356         return 0;
    357 
    358     uBackRead = 4;
    359     while (uBackRead<uMaxBack)
    360     {
    361         uLong uReadSize,uReadPos ;
    362         int i;
    363         if (uBackRead+BUFREADCOMMENT>uMaxBack)
    364             uBackRead = uMaxBack;
    365         else
    366             uBackRead+=BUFREADCOMMENT;
    367         uReadPos = uSizeFile-uBackRead ;
    368 
    369         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
    370                      (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
    371         if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
    372             break;
    373 
    374         if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
    375             break;
    376 
    377         for (i=(int)uReadSize-3; (i--)>0;)
    378             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
    379                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
    380             {
    381                 uPosFound = uReadPos+i;
    382                 break;
    383             }
    384 
    385         if (uPosFound!=0)
    386             break;
    387     }
    388     TRYFREE(buf);
    389     return uPosFound;
    390 }
    391 
    392 /*
    393   Open a Zip file. path contain the full pathname (by example,
    394      on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
    395      "zlib/zlib114.zip".
    396      If the zipfile cannot be opened (file doesn't exist or in not valid), the
    397        return value is NULL.
    398      Else, the return value is a unzFile Handle, usable with other function
    399        of this unzip package.
    400 */
    401 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
    402     const char *path;
    403     zlib_filefunc_def* pzlib_filefunc_def;
    404 {
    405     unz_s us;
    406     unz_s *s;
    407     uLong central_pos,uL;
    408 
    409     uLong number_disk;          /* number of the current dist, used for
    410                                    spaning ZIP, unsupported, always 0*/
    411     uLong number_disk_with_CD;  /* number the the disk with central dir, used
    412                                    for spaning ZIP, unsupported, always 0*/
    413     uLong number_entry_CD;      /* total number of entries in
    414                                    the central dir
    415                                    (same than number_entry on nospan) */
    416 
    417     int err=UNZ_OK;
    418 
    419     if (unz_copyright[0]!=' ')
    420         return NULL;
    421 
    422     if (pzlib_filefunc_def==NULL)
    423         fill_fopen_filefunc(&us.z_filefunc);
    424     else
    425         us.z_filefunc = *pzlib_filefunc_def;
    426 
    427     us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
    428                                                  path,
    429                                                  ZLIB_FILEFUNC_MODE_READ |
    430                                                  ZLIB_FILEFUNC_MODE_EXISTING);
    431     if (us.filestream==NULL)
    432         return NULL;
    433 
    434     central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
    435     if (central_pos==0)
    436         err=UNZ_ERRNO;
    437 
    438     if (ZSEEK(us.z_filefunc, us.filestream,
    439                                       central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
    440         err=UNZ_ERRNO;
    441 
    442     /* the signature, already checked */
    443     if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
    444         err=UNZ_ERRNO;
    445 
    446     /* number of this disk */
    447     if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
    448         err=UNZ_ERRNO;
    449 
    450     /* number of the disk with the start of the central directory */
    451     if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
    452         err=UNZ_ERRNO;
    453 
    454     /* total number of entries in the central dir on this disk */
    455     if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
    456         err=UNZ_ERRNO;
    457 
    458     /* total number of entries in the central dir */
    459     if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
    460         err=UNZ_ERRNO;
    461 
    462     if ((number_entry_CD!=us.gi.number_entry) ||
    463         (number_disk_with_CD!=0) ||
    464         (number_disk!=0))
    465         err=UNZ_BADZIPFILE;
    466 
    467     /* size of the central directory */
    468     if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
    469         err=UNZ_ERRNO;
    470 
    471     /* offset of start of central directory with respect to the
    472           starting disk number */
    473     if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
    474         err=UNZ_ERRNO;
    475 
    476     /* zipfile comment length */
    477     if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
    478         err=UNZ_ERRNO;
    479 
    480     if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
    481         (err==UNZ_OK))
    482         err=UNZ_BADZIPFILE;
    483 
    484     if (err!=UNZ_OK)
    485     {
    486         ZCLOSE(us.z_filefunc, us.filestream);
    487         return NULL;
    488     }
    489 
    490     us.byte_before_the_zipfile = central_pos -
    491                             (us.offset_central_dir+us.size_central_dir);
    492     us.central_pos = central_pos;
    493     us.pfile_in_zip_read = NULL;
    494     us.encrypted = 0;
    495 
    496 
    497     s=(unz_s*)ALLOC(sizeof(unz_s));
    498     *s=us;
    499     unzGoToFirstFile((unzFile)s);
    500     return (unzFile)s;
    501 }
    502 
    503 
    504 extern unzFile ZEXPORT unzOpen (path)
    505     const char *path;
    506 {
    507     return unzOpen2(path, NULL);
    508 }
    509 
    510 /*
    511   Close a ZipFile opened with unzipOpen.
    512   If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
    513     these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
    514   return UNZ_OK if there is no problem. */
    515 extern int ZEXPORT unzClose (file)
    516     unzFile file;
    517 {
    518     unz_s* s;
    519     if (file==NULL)
    520         return UNZ_PARAMERROR;
    521     s=(unz_s*)file;
    522 
    523     if (s->pfile_in_zip_read!=NULL)
    524         unzCloseCurrentFile(file);
    525 
    526     ZCLOSE(s->z_filefunc, s->filestream);
    527     TRYFREE(s);
    528     return UNZ_OK;
    529 }
    530 
    531 
    532 /*
    533   Write info about the ZipFile in the *pglobal_info structure.
    534   No preparation of the structure is needed
    535   return UNZ_OK if there is no problem. */
    536 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
    537     unzFile file;
    538     unz_global_info *pglobal_info;
    539 {
    540     unz_s* s;
    541     if (file==NULL)
    542         return UNZ_PARAMERROR;
    543     s=(unz_s*)file;
    544     *pglobal_info=s->gi;
    545     return UNZ_OK;
    546 }
    547 
    548 
    549 /*
    550    Translate date/time from Dos format to tm_unz (readable more easilty)
    551 */
    552 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
    553     uLong ulDosDate;
    554     tm_unz* ptm;
    555 {
    556     uLong uDate;
    557     uDate = (uLong)(ulDosDate>>16);
    558     ptm->tm_mday = (uInt)(uDate&0x1f) ;
    559     ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
    560     ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
    561 
    562     ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
    563     ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
    564     ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
    565 }
    566 
    567 /*
    568   Get Info about the current file in the zipfile, with internal only info
    569 */
    570 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
    571                                                   unz_file_info *pfile_info,
    572                                                   unz_file_info_internal
    573                                                   *pfile_info_internal,
    574                                                   char *szFileName,
    575                                                   uLong fileNameBufferSize,
    576                                                   void *extraField,
    577                                                   uLong extraFieldBufferSize,
    578                                                   char *szComment,
    579                                                   uLong commentBufferSize));
    580 
    581 local int unzlocal_GetCurrentFileInfoInternal (file,
    582                                               pfile_info,
    583                                               pfile_info_internal,
    584                                               szFileName, fileNameBufferSize,
    585                                               extraField, extraFieldBufferSize,
    586                                               szComment,  commentBufferSize)
    587     unzFile file;
    588     unz_file_info *pfile_info;
    589     unz_file_info_internal *pfile_info_internal;
    590     char *szFileName;
    591     uLong fileNameBufferSize;
    592     void *extraField;
    593     uLong extraFieldBufferSize;
    594     char *szComment;
    595     uLong commentBufferSize;
    596 {
    597     unz_s* s;
    598     unz_file_info file_info;
    599     unz_file_info_internal file_info_internal;
    600     int err=UNZ_OK;
    601     uLong uMagic;
    602     long lSeek=0;
    603 
    604     if (file==NULL)
    605         return UNZ_PARAMERROR;
    606     s=(unz_s*)file;
    607     if (ZSEEK(s->z_filefunc, s->filestream,
    608               s->pos_in_central_dir+s->byte_before_the_zipfile,
    609               ZLIB_FILEFUNC_SEEK_SET)!=0)
    610         err=UNZ_ERRNO;
    611 
    612 
    613     /* we check the magic */
    614     if (err==UNZ_OK) {
    615         if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
    616             err=UNZ_ERRNO;
    617         else if (uMagic!=0x02014b50)
    618             err=UNZ_BADZIPFILE;
    619     }
    620 
    621     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
    622         err=UNZ_ERRNO;
    623 
    624     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
    625         err=UNZ_ERRNO;
    626 
    627     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
    628         err=UNZ_ERRNO;
    629 
    630     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
    631         err=UNZ_ERRNO;
    632 
    633     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
    634         err=UNZ_ERRNO;
    635 
    636     unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
    637 
    638     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
    639         err=UNZ_ERRNO;
    640 
    641     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
    642         err=UNZ_ERRNO;
    643 
    644     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
    645         err=UNZ_ERRNO;
    646 
    647     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
    648         err=UNZ_ERRNO;
    649 
    650     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
    651         err=UNZ_ERRNO;
    652 
    653     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
    654         err=UNZ_ERRNO;
    655 
    656     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
    657         err=UNZ_ERRNO;
    658 
    659     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
    660         err=UNZ_ERRNO;
    661 
    662     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
    663         err=UNZ_ERRNO;
    664 
    665     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
    666         err=UNZ_ERRNO;
    667 
    668     lSeek+=file_info.size_filename;
    669     if ((err==UNZ_OK) && (szFileName!=NULL))
    670     {
    671         uLong uSizeRead ;
    672         if (file_info.size_filename<fileNameBufferSize)
    673         {
    674             *(szFileName+file_info.size_filename)='\0';
    675             uSizeRead = file_info.size_filename;
    676         }
    677         else
    678             uSizeRead = fileNameBufferSize;
    679 
    680         if ((file_info.size_filename>0) && (fileNameBufferSize>0))
    681             if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
    682                 err=UNZ_ERRNO;
    683         lSeek -= uSizeRead;
    684     }
    685 
    686 
    687     if ((err==UNZ_OK) && (extraField!=NULL))
    688     {
    689         uLong uSizeRead ;
    690         if (file_info.size_file_extra<extraFieldBufferSize)
    691             uSizeRead = file_info.size_file_extra;
    692         else
    693             uSizeRead = extraFieldBufferSize;
    694 
    695         if (lSeek!=0) {
    696             if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
    697                 lSeek=0;
    698             else
    699                 err=UNZ_ERRNO;
    700         }
    701         if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
    702             if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
    703                 err=UNZ_ERRNO;
    704         lSeek += file_info.size_file_extra - uSizeRead;
    705     }
    706     else
    707         lSeek+=file_info.size_file_extra;
    708 
    709 
    710     if ((err==UNZ_OK) && (szComment!=NULL))
    711     {
    712         uLong uSizeRead ;
    713         if (file_info.size_file_comment<commentBufferSize)
    714         {
    715             *(szComment+file_info.size_file_comment)='\0';
    716             uSizeRead = file_info.size_file_comment;
    717         }
    718         else
    719             uSizeRead = commentBufferSize;
    720 
    721         if (lSeek!=0) {
    722             if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
    723                 lSeek=0;
    724             else
    725                 err=UNZ_ERRNO;
    726         }
    727         if ((file_info.size_file_comment>0) && (commentBufferSize>0))
    728             if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
    729                 err=UNZ_ERRNO;
    730         lSeek+=file_info.size_file_comment - uSizeRead;
    731     }
    732     else
    733         lSeek+=file_info.size_file_comment;
    734 
    735     if ((err==UNZ_OK) && (pfile_info!=NULL))
    736         *pfile_info=file_info;
    737 
    738     if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
    739         *pfile_info_internal=file_info_internal;
    740 
    741     return err;
    742 }
    743 
    744 
    745 
    746 /*
    747   Write info about the ZipFile in the *pglobal_info structure.
    748   No preparation of the structure is needed
    749   return UNZ_OK if there is no problem.
    750 */
    751 extern int ZEXPORT unzGetCurrentFileInfo (file,
    752                                           pfile_info,
    753                                           szFileName, fileNameBufferSize,
    754                                           extraField, extraFieldBufferSize,
    755                                           szComment,  commentBufferSize)
    756     unzFile file;
    757     unz_file_info *pfile_info;
    758     char *szFileName;
    759     uLong fileNameBufferSize;
    760     void *extraField;
    761     uLong extraFieldBufferSize;
    762     char *szComment;
    763     uLong commentBufferSize;
    764 {
    765     return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
    766                                                 szFileName,fileNameBufferSize,
    767                                                 extraField,extraFieldBufferSize,
    768                                                 szComment,commentBufferSize);
    769 }
    770 
    771 /*
    772   Set the current file of the zipfile to the first file.
    773   return UNZ_OK if there is no problem
    774 */
    775 extern int ZEXPORT unzGoToFirstFile (file)
    776     unzFile file;
    777 {
    778     int err=UNZ_OK;
    779     unz_s* s;
    780     if (file==NULL)
    781         return UNZ_PARAMERROR;
    782     s=(unz_s*)file;
    783     s->pos_in_central_dir=s->offset_central_dir;
    784     s->num_file=0;
    785     err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
    786                                              &s->cur_file_info_internal,
    787                                              NULL,0,NULL,0,NULL,0);
    788     s->current_file_ok = (err == UNZ_OK);
    789     return err;
    790 }
    791 
    792 /*
    793   Set the current file of the zipfile to the next file.
    794   return UNZ_OK if there is no problem
    795   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
    796 */
    797 extern int ZEXPORT unzGoToNextFile (file)
    798     unzFile file;
    799 {
    800     unz_s* s;
    801     int err;
    802 
    803     if (file==NULL)
    804         return UNZ_PARAMERROR;
    805     s=(unz_s*)file;
    806     if (!s->current_file_ok)
    807         return UNZ_END_OF_LIST_OF_FILE;
    808     if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
    809       if (s->num_file+1==s->gi.number_entry)
    810         return UNZ_END_OF_LIST_OF_FILE;
    811 
    812     s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
    813             s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
    814     s->num_file++;
    815     err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
    816                                                &s->cur_file_info_internal,
    817                                                NULL,0,NULL,0,NULL,0);
    818     s->current_file_ok = (err == UNZ_OK);
    819     return err;
    820 }
    821 
    822 
    823 /*
    824   Try locate the file szFileName in the zipfile.
    825   For the iCaseSensitivity signification, see unzipStringFileNameCompare
    826 
    827   return value :
    828   UNZ_OK if the file is found. It becomes the current file.
    829   UNZ_END_OF_LIST_OF_FILE if the file is not found
    830 */
    831 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
    832     unzFile file;
    833     const char *szFileName;
    834     int iCaseSensitivity;
    835 {
    836     unz_s* s;
    837     int err;
    838 
    839     /* We remember the 'current' position in the file so that we can jump
    840      * back there if we fail.
    841      */
    842     unz_file_info cur_file_infoSaved;
    843     unz_file_info_internal cur_file_info_internalSaved;
    844     uLong num_fileSaved;
    845     uLong pos_in_central_dirSaved;
    846 
    847 
    848     if (file==NULL)
    849         return UNZ_PARAMERROR;
    850 
    851     if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
    852         return UNZ_PARAMERROR;
    853 
    854     s=(unz_s*)file;
    855     if (!s->current_file_ok)
    856         return UNZ_END_OF_LIST_OF_FILE;
    857 
    858     /* Save the current state */
    859     num_fileSaved = s->num_file;
    860     pos_in_central_dirSaved = s->pos_in_central_dir;
    861     cur_file_infoSaved = s->cur_file_info;
    862     cur_file_info_internalSaved = s->cur_file_info_internal;
    863 
    864     err = unzGoToFirstFile(file);
    865 
    866     while (err == UNZ_OK)
    867     {
    868         char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
    869         err = unzGetCurrentFileInfo(file,NULL,
    870                                     szCurrentFileName,sizeof(szCurrentFileName)-1,
    871                                     NULL,0,NULL,0);
    872         if (err == UNZ_OK)
    873         {
    874             if (unzStringFileNameCompare(szCurrentFileName,
    875                                             szFileName,iCaseSensitivity)==0)
    876                 return UNZ_OK;
    877             err = unzGoToNextFile(file);
    878         }
    879     }
    880 
    881     /* We failed, so restore the state of the 'current file' to where we
    882      * were.
    883      */
    884     s->num_file = num_fileSaved ;
    885     s->pos_in_central_dir = pos_in_central_dirSaved ;
    886     s->cur_file_info = cur_file_infoSaved;
    887     s->cur_file_info_internal = cur_file_info_internalSaved;
    888     return err;
    889 }
    890 
    891 
    892 /*
    893 ///////////////////////////////////////////
    894 // Contributed by Ryan Haksi (mailto://cryogen (at) infoserve.net)
    895 // I need random access
    896 //
    897 // Further optimization could be realized by adding an ability
    898 // to cache the directory in memory. The goal being a single
    899 // comprehensive file read to put the file I need in a memory.
    900 */
    901 
    902 /*
    903 typedef struct unz_file_pos_s
    904 {
    905     uLong pos_in_zip_directory;   // offset in file
    906     uLong num_of_file;            // # of file
    907 } unz_file_pos;
    908 */
    909 
    910 extern int ZEXPORT unzGetFilePos(file, file_pos)
    911     unzFile file;
    912     unz_file_pos* file_pos;
    913 {
    914     unz_s* s;
    915 
    916     if (file==NULL || file_pos==NULL)
    917         return UNZ_PARAMERROR;
    918     s=(unz_s*)file;
    919     if (!s->current_file_ok)
    920         return UNZ_END_OF_LIST_OF_FILE;
    921 
    922     file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
    923     file_pos->num_of_file           = s->num_file;
    924 
    925     return UNZ_OK;
    926 }
    927 
    928 extern int ZEXPORT unzGoToFilePos(file, file_pos)
    929     unzFile file;
    930     unz_file_pos* file_pos;
    931 {
    932     unz_s* s;
    933     int err;
    934 
    935     if (file==NULL || file_pos==NULL)
    936         return UNZ_PARAMERROR;
    937     s=(unz_s*)file;
    938 
    939     /* jump to the right spot */
    940     s->pos_in_central_dir = file_pos->pos_in_zip_directory;
    941     s->num_file           = file_pos->num_of_file;
    942 
    943     /* set the current file */
    944     err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
    945                                                &s->cur_file_info_internal,
    946                                                NULL,0,NULL,0,NULL,0);
    947     /* return results */
    948     s->current_file_ok = (err == UNZ_OK);
    949     return err;
    950 }
    951 
    952 /*
    953 // Unzip Helper Functions - should be here?
    954 ///////////////////////////////////////////
    955 */
    956 
    957 /*
    958   Read the local header of the current zipfile
    959   Check the coherency of the local header and info in the end of central
    960         directory about this file
    961   store in *piSizeVar the size of extra info in local header
    962         (filename and size of extra field data)
    963 */
    964 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
    965                                                     poffset_local_extrafield,
    966                                                     psize_local_extrafield)
    967     unz_s* s;
    968     uInt* piSizeVar;
    969     uLong *poffset_local_extrafield;
    970     uInt  *psize_local_extrafield;
    971 {
    972     uLong uMagic,uData,uFlags;
    973     uLong size_filename;
    974     uLong size_extra_field;
    975     int err=UNZ_OK;
    976 
    977     *piSizeVar = 0;
    978     *poffset_local_extrafield = 0;
    979     *psize_local_extrafield = 0;
    980 
    981     if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
    982                                 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
    983         return UNZ_ERRNO;
    984 
    985 
    986     if (err==UNZ_OK) {
    987         if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
    988             err=UNZ_ERRNO;
    989         else if (uMagic!=0x04034b50)
    990             err=UNZ_BADZIPFILE;
    991     }
    992 
    993     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
    994         err=UNZ_ERRNO;
    995 /*
    996     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
    997         err=UNZ_BADZIPFILE;
    998 */
    999     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
   1000         err=UNZ_ERRNO;
   1001 
   1002     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
   1003         err=UNZ_ERRNO;
   1004     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
   1005         err=UNZ_BADZIPFILE;
   1006 
   1007     if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
   1008                          (s->cur_file_info.compression_method!=Z_DEFLATED))
   1009         err=UNZ_BADZIPFILE;
   1010 
   1011     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
   1012         err=UNZ_ERRNO;
   1013 
   1014     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
   1015         err=UNZ_ERRNO;
   1016     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
   1017                               ((uFlags & 8)==0))
   1018         err=UNZ_BADZIPFILE;
   1019 
   1020     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
   1021         err=UNZ_ERRNO;
   1022     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
   1023                               ((uFlags & 8)==0))
   1024         err=UNZ_BADZIPFILE;
   1025 
   1026     if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
   1027         err=UNZ_ERRNO;
   1028     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
   1029                               ((uFlags & 8)==0))
   1030         err=UNZ_BADZIPFILE;
   1031 
   1032 
   1033     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
   1034         err=UNZ_ERRNO;
   1035     else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
   1036         err=UNZ_BADZIPFILE;
   1037 
   1038     *piSizeVar += (uInt)size_filename;
   1039 
   1040     if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
   1041         err=UNZ_ERRNO;
   1042     *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
   1043                                     SIZEZIPLOCALHEADER + size_filename;
   1044     *psize_local_extrafield = (uInt)size_extra_field;
   1045 
   1046     *piSizeVar += (uInt)size_extra_field;
   1047 
   1048     return err;
   1049 }
   1050 
   1051 /*
   1052   Open for reading data the current file in the zipfile.
   1053   If there is no error and the file is opened, the return value is UNZ_OK.
   1054 */
   1055 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
   1056     unzFile file;
   1057     int* method;
   1058     int* level;
   1059     int raw;
   1060     const char* password;
   1061 {
   1062     int err=UNZ_OK;
   1063     uInt iSizeVar;
   1064     unz_s* s;
   1065     file_in_zip_read_info_s* pfile_in_zip_read_info;
   1066     uLong offset_local_extrafield;  /* offset of the local extra field */
   1067     uInt  size_local_extrafield;    /* size of the local extra field */
   1068 #    ifndef NOUNCRYPT
   1069     char source[12];
   1070 #    else
   1071     if (password != NULL)
   1072         return UNZ_PARAMERROR;
   1073 #    endif
   1074 
   1075     if (file==NULL)
   1076         return UNZ_PARAMERROR;
   1077     s=(unz_s*)file;
   1078     if (!s->current_file_ok)
   1079         return UNZ_PARAMERROR;
   1080 
   1081     if (s->pfile_in_zip_read != NULL)
   1082         unzCloseCurrentFile(file);
   1083 
   1084     if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
   1085                 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
   1086         return UNZ_BADZIPFILE;
   1087 
   1088     pfile_in_zip_read_info = (file_in_zip_read_info_s*)
   1089                                         ALLOC(sizeof(file_in_zip_read_info_s));
   1090     if (pfile_in_zip_read_info==NULL)
   1091         return UNZ_INTERNALERROR;
   1092 
   1093     pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
   1094     pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
   1095     pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
   1096     pfile_in_zip_read_info->pos_local_extrafield=0;
   1097     pfile_in_zip_read_info->raw=raw;
   1098 
   1099     if (pfile_in_zip_read_info->read_buffer==NULL)
   1100     {
   1101         TRYFREE(pfile_in_zip_read_info);
   1102         return UNZ_INTERNALERROR;
   1103     }
   1104 
   1105     pfile_in_zip_read_info->stream_initialised=0;
   1106 
   1107     if (method!=NULL)
   1108         *method = (int)s->cur_file_info.compression_method;
   1109 
   1110     if (level!=NULL)
   1111     {
   1112         *level = 6;
   1113         switch (s->cur_file_info.flag & 0x06)
   1114         {
   1115           case 6 : *level = 1; break;
   1116           case 4 : *level = 2; break;
   1117           case 2 : *level = 9; break;
   1118         }
   1119     }
   1120 
   1121     if ((s->cur_file_info.compression_method!=0) &&
   1122         (s->cur_file_info.compression_method!=Z_DEFLATED))
   1123         err=UNZ_BADZIPFILE;
   1124 
   1125     pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
   1126     pfile_in_zip_read_info->crc32=0;
   1127     pfile_in_zip_read_info->compression_method =
   1128             s->cur_file_info.compression_method;
   1129     pfile_in_zip_read_info->filestream=s->filestream;
   1130     pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
   1131     pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
   1132 
   1133     pfile_in_zip_read_info->stream.total_out = 0;
   1134 
   1135     if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
   1136         (!raw))
   1137     {
   1138       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
   1139       pfile_in_zip_read_info->stream.zfree = (free_func)0;
   1140       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
   1141       pfile_in_zip_read_info->stream.next_in = (voidpf)0;
   1142       pfile_in_zip_read_info->stream.avail_in = 0;
   1143 
   1144       err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
   1145       if (err == Z_OK)
   1146         pfile_in_zip_read_info->stream_initialised=1;
   1147       else
   1148       {
   1149         TRYFREE(pfile_in_zip_read_info);
   1150         return err;
   1151       }
   1152         /* windowBits is passed < 0 to tell that there is no zlib header.
   1153          * Note that in this case inflate *requires* an extra "dummy" byte
   1154          * after the compressed stream in order to complete decompression and
   1155          * return Z_STREAM_END.
   1156          * In unzip, i don't wait absolutely Z_STREAM_END because I known the
   1157          * size of both compressed and uncompressed data
   1158          */
   1159     }
   1160     pfile_in_zip_read_info->rest_read_compressed =
   1161             s->cur_file_info.compressed_size ;
   1162     pfile_in_zip_read_info->rest_read_uncompressed =
   1163             s->cur_file_info.uncompressed_size ;
   1164 
   1165 
   1166     pfile_in_zip_read_info->pos_in_zipfile =
   1167             s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
   1168               iSizeVar;
   1169 
   1170     pfile_in_zip_read_info->stream.avail_in = (uInt)0;
   1171 
   1172     s->pfile_in_zip_read = pfile_in_zip_read_info;
   1173 
   1174 #    ifndef NOUNCRYPT
   1175     if (password != NULL)
   1176     {
   1177         int i;
   1178         s->pcrc_32_tab = get_crc_table();
   1179         init_keys(password,s->keys,s->pcrc_32_tab);
   1180         if (ZSEEK(s->z_filefunc, s->filestream,
   1181                   s->pfile_in_zip_read->pos_in_zipfile +
   1182                      s->pfile_in_zip_read->byte_before_the_zipfile,
   1183                   SEEK_SET)!=0)
   1184             return UNZ_INTERNALERROR;
   1185         if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
   1186             return UNZ_INTERNALERROR;
   1187 
   1188         for (i = 0; i<12; i++)
   1189             zdecode(s->keys,s->pcrc_32_tab,source[i]);
   1190 
   1191         s->pfile_in_zip_read->pos_in_zipfile+=12;
   1192         s->encrypted=1;
   1193     }
   1194 #    endif
   1195 
   1196 
   1197     return UNZ_OK;
   1198 }
   1199 
   1200 extern int ZEXPORT unzOpenCurrentFile (file)
   1201     unzFile file;
   1202 {
   1203     return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
   1204 }
   1205 
   1206 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
   1207     unzFile file;
   1208     const char* password;
   1209 {
   1210     return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
   1211 }
   1212 
   1213 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
   1214     unzFile file;
   1215     int* method;
   1216     int* level;
   1217     int raw;
   1218 {
   1219     return unzOpenCurrentFile3(file, method, level, raw, NULL);
   1220 }
   1221 
   1222 /*
   1223   Read bytes from the current file.
   1224   buf contain buffer where data must be copied
   1225   len the size of buf.
   1226 
   1227   return the number of byte copied if somes bytes are copied
   1228   return 0 if the end of file was reached
   1229   return <0 with error code if there is an error
   1230     (UNZ_ERRNO for IO error, or zLib error for uncompress error)
   1231 */
   1232 extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
   1233     unzFile file;
   1234     voidp buf;
   1235     unsigned len;
   1236 {
   1237     int err=UNZ_OK;
   1238     uInt iRead = 0;
   1239     unz_s* s;
   1240     file_in_zip_read_info_s* pfile_in_zip_read_info;
   1241     if (file==NULL)
   1242         return UNZ_PARAMERROR;
   1243     s=(unz_s*)file;
   1244     pfile_in_zip_read_info=s->pfile_in_zip_read;
   1245 
   1246     if (pfile_in_zip_read_info==NULL)
   1247         return UNZ_PARAMERROR;
   1248 
   1249 
   1250     if ((pfile_in_zip_read_info->read_buffer == NULL))
   1251         return UNZ_END_OF_LIST_OF_FILE;
   1252     if (len==0)
   1253         return 0;
   1254 
   1255     pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
   1256 
   1257     pfile_in_zip_read_info->stream.avail_out = (uInt)len;
   1258 
   1259     if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
   1260         (!(pfile_in_zip_read_info->raw)))
   1261         pfile_in_zip_read_info->stream.avail_out =
   1262             (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
   1263 
   1264     if ((len>pfile_in_zip_read_info->rest_read_compressed+
   1265            pfile_in_zip_read_info->stream.avail_in) &&
   1266          (pfile_in_zip_read_info->raw))
   1267         pfile_in_zip_read_info->stream.avail_out =
   1268             (uInt)pfile_in_zip_read_info->rest_read_compressed+
   1269             pfile_in_zip_read_info->stream.avail_in;
   1270 
   1271     while (pfile_in_zip_read_info->stream.avail_out>0)
   1272     {
   1273         if ((pfile_in_zip_read_info->stream.avail_in==0) &&
   1274             (pfile_in_zip_read_info->rest_read_compressed>0))
   1275         {
   1276             uInt uReadThis = UNZ_BUFSIZE;
   1277             if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
   1278                 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
   1279             if (uReadThis == 0)
   1280                 return UNZ_EOF;
   1281             if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
   1282                       pfile_in_zip_read_info->filestream,
   1283                       pfile_in_zip_read_info->pos_in_zipfile +
   1284                          pfile_in_zip_read_info->byte_before_the_zipfile,
   1285                          ZLIB_FILEFUNC_SEEK_SET)!=0)
   1286                 return UNZ_ERRNO;
   1287             if (ZREAD(pfile_in_zip_read_info->z_filefunc,
   1288                       pfile_in_zip_read_info->filestream,
   1289                       pfile_in_zip_read_info->read_buffer,
   1290                       uReadThis)!=uReadThis)
   1291                 return UNZ_ERRNO;
   1292 
   1293 
   1294 #            ifndef NOUNCRYPT
   1295             if(s->encrypted)
   1296             {
   1297                 uInt i;
   1298                 for(i=0;i<uReadThis;i++)
   1299                   pfile_in_zip_read_info->read_buffer[i] =
   1300                       zdecode(s->keys,s->pcrc_32_tab,
   1301                               pfile_in_zip_read_info->read_buffer[i]);
   1302             }
   1303 #            endif
   1304 
   1305 
   1306             pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
   1307 
   1308             pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
   1309 
   1310             pfile_in_zip_read_info->stream.next_in =
   1311                 (Bytef*)pfile_in_zip_read_info->read_buffer;
   1312             pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
   1313         }
   1314 
   1315         if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
   1316         {
   1317             uInt uDoCopy,i ;
   1318 
   1319             if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
   1320                 (pfile_in_zip_read_info->rest_read_compressed == 0))
   1321                 return (iRead==0) ? UNZ_EOF : iRead;
   1322 
   1323             if (pfile_in_zip_read_info->stream.avail_out <
   1324                             pfile_in_zip_read_info->stream.avail_in)
   1325                 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
   1326             else
   1327                 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
   1328 
   1329             for (i=0;i<uDoCopy;i++)
   1330                 *(pfile_in_zip_read_info->stream.next_out+i) =
   1331                         *(pfile_in_zip_read_info->stream.next_in+i);
   1332 
   1333             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
   1334                                 pfile_in_zip_read_info->stream.next_out,
   1335                                 uDoCopy);
   1336             pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
   1337             pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
   1338             pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
   1339             pfile_in_zip_read_info->stream.next_out += uDoCopy;
   1340             pfile_in_zip_read_info->stream.next_in += uDoCopy;
   1341             pfile_in_zip_read_info->stream.total_out += uDoCopy;
   1342             iRead += uDoCopy;
   1343         }
   1344         else
   1345         {
   1346             uLong uTotalOutBefore,uTotalOutAfter;
   1347             const Bytef *bufBefore;
   1348             uLong uOutThis;
   1349             int flush=Z_SYNC_FLUSH;
   1350 
   1351             uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
   1352             bufBefore = pfile_in_zip_read_info->stream.next_out;
   1353 
   1354             /*
   1355             if ((pfile_in_zip_read_info->rest_read_uncompressed ==
   1356                      pfile_in_zip_read_info->stream.avail_out) &&
   1357                 (pfile_in_zip_read_info->rest_read_compressed == 0))
   1358                 flush = Z_FINISH;
   1359             */
   1360             err=inflate(&pfile_in_zip_read_info->stream,flush);
   1361 
   1362             if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
   1363               err = Z_DATA_ERROR;
   1364 
   1365             uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
   1366             uOutThis = uTotalOutAfter-uTotalOutBefore;
   1367 
   1368             pfile_in_zip_read_info->crc32 =
   1369                 crc32(pfile_in_zip_read_info->crc32,bufBefore,
   1370                         (uInt)(uOutThis));
   1371 
   1372             pfile_in_zip_read_info->rest_read_uncompressed -=
   1373                 uOutThis;
   1374 
   1375             iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
   1376 
   1377             if (err==Z_STREAM_END)
   1378                 return (iRead==0) ? UNZ_EOF : iRead;
   1379             if (err!=Z_OK)
   1380                 break;
   1381         }
   1382     }
   1383 
   1384     if (err==Z_OK)
   1385         return iRead;
   1386     return err;
   1387 }
   1388 
   1389 
   1390 /*
   1391   Give the current position in uncompressed data
   1392 */
   1393 extern z_off_t ZEXPORT unztell (file)
   1394     unzFile file;
   1395 {
   1396     unz_s* s;
   1397     file_in_zip_read_info_s* pfile_in_zip_read_info;
   1398     if (file==NULL)
   1399         return UNZ_PARAMERROR;
   1400     s=(unz_s*)file;
   1401     pfile_in_zip_read_info=s->pfile_in_zip_read;
   1402 
   1403     if (pfile_in_zip_read_info==NULL)
   1404         return UNZ_PARAMERROR;
   1405 
   1406     return (z_off_t)pfile_in_zip_read_info->stream.total_out;
   1407 }
   1408 
   1409 
   1410 /*
   1411   return 1 if the end of file was reached, 0 elsewhere
   1412 */
   1413 extern int ZEXPORT unzeof (file)
   1414     unzFile file;
   1415 {
   1416     unz_s* s;
   1417     file_in_zip_read_info_s* pfile_in_zip_read_info;
   1418     if (file==NULL)
   1419         return UNZ_PARAMERROR;
   1420     s=(unz_s*)file;
   1421     pfile_in_zip_read_info=s->pfile_in_zip_read;
   1422 
   1423     if (pfile_in_zip_read_info==NULL)
   1424         return UNZ_PARAMERROR;
   1425 
   1426     if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
   1427         return 1;
   1428     else
   1429         return 0;
   1430 }
   1431 
   1432 
   1433 
   1434 /*
   1435   Read extra field from the current file (opened by unzOpenCurrentFile)
   1436   This is the local-header version of the extra field (sometimes, there is
   1437     more info in the local-header version than in the central-header)
   1438 
   1439   if buf==NULL, it return the size of the local extra field that can be read
   1440 
   1441   if buf!=NULL, len is the size of the buffer, the extra header is copied in
   1442     buf.
   1443   the return value is the number of bytes copied in buf, or (if <0)
   1444     the error code
   1445 */
   1446 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
   1447     unzFile file;
   1448     voidp buf;
   1449     unsigned len;
   1450 {
   1451     unz_s* s;
   1452     file_in_zip_read_info_s* pfile_in_zip_read_info;
   1453     uInt read_now;
   1454     uLong size_to_read;
   1455 
   1456     if (file==NULL)
   1457         return UNZ_PARAMERROR;
   1458     s=(unz_s*)file;
   1459     pfile_in_zip_read_info=s->pfile_in_zip_read;
   1460 
   1461     if (pfile_in_zip_read_info==NULL)
   1462         return UNZ_PARAMERROR;
   1463 
   1464     size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
   1465                 pfile_in_zip_read_info->pos_local_extrafield);
   1466 
   1467     if (buf==NULL)
   1468         return (int)size_to_read;
   1469 
   1470     if (len>size_to_read)
   1471         read_now = (uInt)size_to_read;
   1472     else
   1473         read_now = (uInt)len ;
   1474 
   1475     if (read_now==0)
   1476         return 0;
   1477 
   1478     if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
   1479               pfile_in_zip_read_info->filestream,
   1480               pfile_in_zip_read_info->offset_local_extrafield +
   1481               pfile_in_zip_read_info->pos_local_extrafield,
   1482               ZLIB_FILEFUNC_SEEK_SET)!=0)
   1483         return UNZ_ERRNO;
   1484 
   1485     if (ZREAD(pfile_in_zip_read_info->z_filefunc,
   1486               pfile_in_zip_read_info->filestream,
   1487               buf,read_now)!=read_now)
   1488         return UNZ_ERRNO;
   1489 
   1490     return (int)read_now;
   1491 }
   1492 
   1493 /*
   1494   Close the file in zip opened with unzipOpenCurrentFile
   1495   Return UNZ_CRCERROR if all the file was read but the CRC is not good
   1496 */
   1497 extern int ZEXPORT unzCloseCurrentFile (file)
   1498     unzFile file;
   1499 {
   1500     int err=UNZ_OK;
   1501 
   1502     unz_s* s;
   1503     file_in_zip_read_info_s* pfile_in_zip_read_info;
   1504     if (file==NULL)
   1505         return UNZ_PARAMERROR;
   1506     s=(unz_s*)file;
   1507     pfile_in_zip_read_info=s->pfile_in_zip_read;
   1508 
   1509     if (pfile_in_zip_read_info==NULL)
   1510         return UNZ_PARAMERROR;
   1511 
   1512 
   1513     if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
   1514         (!pfile_in_zip_read_info->raw))
   1515     {
   1516         if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
   1517             err=UNZ_CRCERROR;
   1518     }
   1519 
   1520 
   1521     TRYFREE(pfile_in_zip_read_info->read_buffer);
   1522     pfile_in_zip_read_info->read_buffer = NULL;
   1523     if (pfile_in_zip_read_info->stream_initialised)
   1524         inflateEnd(&pfile_in_zip_read_info->stream);
   1525 
   1526     pfile_in_zip_read_info->stream_initialised = 0;
   1527     TRYFREE(pfile_in_zip_read_info);
   1528 
   1529     s->pfile_in_zip_read=NULL;
   1530 
   1531     return err;
   1532 }
   1533 
   1534 
   1535 /*
   1536   Get the global comment string of the ZipFile, in the szComment buffer.
   1537   uSizeBuf is the size of the szComment buffer.
   1538   return the number of byte copied or an error code <0
   1539 */
   1540 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
   1541     unzFile file;
   1542     char *szComment;
   1543     uLong uSizeBuf;
   1544 {
   1545     //int err=UNZ_OK;
   1546     unz_s* s;
   1547     uLong uReadThis ;
   1548     if (file==NULL)
   1549         return UNZ_PARAMERROR;
   1550     s=(unz_s*)file;
   1551 
   1552     uReadThis = uSizeBuf;
   1553     if (uReadThis>s->gi.size_comment)
   1554         uReadThis = s->gi.size_comment;
   1555 
   1556     if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1557         return UNZ_ERRNO;
   1558 
   1559     if (uReadThis>0)
   1560     {
   1561       *szComment='\0';
   1562       if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
   1563         return UNZ_ERRNO;
   1564     }
   1565 
   1566     if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
   1567         *(szComment+s->gi.size_comment)='\0';
   1568     return (int)uReadThis;
   1569 }
   1570 
   1571 /* Additions by RX '2004 */
   1572 extern uLong ZEXPORT unzGetOffset (file)
   1573     unzFile file;
   1574 {
   1575     unz_s* s;
   1576 
   1577     if (file==NULL)
   1578           return UNZ_PARAMERROR;
   1579     s=(unz_s*)file;
   1580     if (!s->current_file_ok)
   1581       return 0;
   1582     if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
   1583       if (s->num_file==s->gi.number_entry)
   1584          return 0;
   1585     return s->pos_in_central_dir;
   1586 }
   1587 
   1588 extern int ZEXPORT unzSetOffset (file, pos)
   1589         unzFile file;
   1590         uLong pos;
   1591 {
   1592     unz_s* s;
   1593     int err;
   1594 
   1595     if (file==NULL)
   1596         return UNZ_PARAMERROR;
   1597     s=(unz_s*)file;
   1598 
   1599     s->pos_in_central_dir = pos;
   1600     s->num_file = s->gi.number_entry;      /* hack */
   1601     err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
   1602                                               &s->cur_file_info_internal,
   1603                                               NULL,0,NULL,0,NULL,0);
   1604     s->current_file_ok = (err == UNZ_OK);
   1605     return err;
   1606 }
   1607