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