unzip.c
Go to the documentation of this file.
00001 /* unzip.c -- IO for uncompress .zip files using zlib
00002    Version 1.1, February 14h, 2010
00003    part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
00004 
00005          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
00006 
00007          Modifications of Unzip for Zip64
00008          Copyright (C) 2007-2008 Even Rouault
00009 
00010          Modifications for Zip64 support on both zip and unzip
00011          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
00012 
00013          For more info read MiniZip_info.txt
00014 
00015 
00016   ------------------------------------------------------------------------------------
00017   Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
00018   compatibility with older software. The following is from the original crypt.c.
00019   Code woven in by Terry Thorsen 1/2003.
00020 
00021   Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
00022 
00023   See the accompanying file LICENSE, version 2000-Apr-09 or later
00024   (the contents of which are also included in zip.h) for terms of use.
00025   If, for some reason, all these files are missing, the Info-ZIP license
00026   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
00027 
00028         crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
00029 
00030   The encryption/decryption parts of this source code (as opposed to the
00031   non-echoing password parts) were originally written in Europe.  The
00032   whole source package can be freely distributed, including from the USA.
00033   (Prior to January 2000, re-export from the US was a violation of US law.)
00034 
00035         This encryption code is a direct transcription of the algorithm from
00036   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
00037   file (appnote.txt) is distributed with the PKZIP program (even in the
00038   version without encryption capabilities).
00039 
00040         ------------------------------------------------------------------------------------
00041 
00042         Changes in unzip.c
00043 
00044         2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
00045   2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
00046   2007-2008 - Even Rouault - Remove old C style function prototypes
00047   2007-2008 - Even Rouault - Add unzip support for ZIP64
00048 
00049         Copyright (C) 2007-2008 Even Rouault
00050 
00051 
00052         Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
00053   Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
00054                                 should only read the compressed/uncompressed size from the Zip64 format if
00055                                 the size from normal header was 0xFFFFFFFF
00056   Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
00057         Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
00058                                 Patch created by Daniel Borca
00059 
00060   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
00061 
00062   Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
00063 
00064 */
00065 
00066 
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <string.h>
00070 
00071 #ifndef NOUNCRYPT
00072         #define NOUNCRYPT
00073 #endif
00074 
00075 #include "zlib.h"
00076 #include "unzip.h"
00077 
00078 #ifdef STDC
00079 #  include <stddef.h>
00080 #  include <string.h>
00081 #  include <stdlib.h>
00082 #endif
00083 #ifdef NO_ERRNO_H
00084     extern int errno;
00085 #else
00086 #   include <errno.h>
00087 #endif
00088 
00089 
00090 #ifndef local
00091 #  define local static
00092 #endif
00093 /* compile with -Dlocal if your debugger can't find static symbols */
00094 
00095 
00096 #ifndef CASESENSITIVITYDEFAULT_NO
00097 #  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
00098 #    define CASESENSITIVITYDEFAULT_NO
00099 #  endif
00100 #endif
00101 
00102 
00103 #ifndef UNZ_BUFSIZE
00104 #define UNZ_BUFSIZE (16384)
00105 #endif
00106 
00107 #ifndef UNZ_MAXFILENAMEINZIP
00108 #define UNZ_MAXFILENAMEINZIP (256)
00109 #endif
00110 
00111 #ifndef ALLOC
00112 # define ALLOC(size) (malloc(size))
00113 #endif
00114 #ifndef TRYFREE
00115 # define TRYFREE(p) {if (p) free(p);}
00116 #endif
00117 
00118 #define SIZECENTRALDIRITEM (0x2e)
00119 #define SIZEZIPLOCALHEADER (0x1e)
00120 
00121 
00122 const char unz_copyright[] =
00123    " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
00124 
00125 /* unz_file_info_interntal contain internal info about a file in zipfile*/
00126 typedef struct unz_file_info64_internal_s
00127 {
00128     ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
00129 } unz_file_info64_internal;
00130 
00131 
00132 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
00133     when reading and decompress it */
00134 typedef struct
00135 {
00136     char  *read_buffer;         /* internal buffer for compressed data */
00137     z_stream stream;            /* zLib stream structure for inflate */
00138 
00139 #ifdef HAVE_BZIP2
00140     bz_stream bstream;          /* bzLib stream structure for bziped */
00141 #endif
00142 
00143     ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
00144     uLong stream_initialised;   /* flag set if stream structure is initialised*/
00145 
00146     ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
00147     uInt  size_local_extrafield;/* size of the local extra field */
00148     ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
00149     ZPOS64_T total_out_64;
00150 
00151     uLong crc32;                /* crc32 of all data uncompressed */
00152     uLong crc32_wait;           /* crc32 we must obtain after decompress all */
00153     ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
00154     ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
00155     zlib_filefunc64_32_def z_filefunc;
00156     voidpf filestream;        /* io structore of the zipfile */
00157     uLong compression_method;   /* compression method (0==store) */
00158     ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
00159     int   raw;
00160 } file_in_zip64_read_info_s;
00161 
00162 
00163 /* unz64_s contain internal information about the zipfile
00164 */
00165 typedef struct
00166 {
00167     zlib_filefunc64_32_def z_filefunc;
00168     int is64bitOpenFunction;
00169     voidpf filestream;        /* io structore of the zipfile */
00170     unz_global_info64 gi;       /* public global information */
00171     ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
00172     ZPOS64_T num_file;             /* number of the current file in the zipfile*/
00173     ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
00174     ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
00175     ZPOS64_T central_pos;          /* position of the beginning of the central dir*/
00176 
00177     ZPOS64_T size_central_dir;     /* size of the central directory  */
00178     ZPOS64_T offset_central_dir;   /* offset of start of central directory with
00179                                    respect to the starting disk number */
00180 
00181     unz_file_info64 cur_file_info; /* public info about the current file in zip*/
00182     unz_file_info64_internal cur_file_info_internal; /* private info about it*/
00183     file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
00184                                         file if we are decompressing it */
00185     int encrypted;
00186 
00187     int isZip64;
00188 
00189 #    ifndef NOUNCRYPT
00190     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
00191     const unsigned long* pcrc_32_tab;
00192 #    endif
00193 } unz64_s;
00194 
00195 
00196 #ifndef NOUNCRYPT
00197 #include "crypt.h"
00198 #endif
00199 
00200 /* ===========================================================================
00201      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
00202    for end of file.
00203    IN assertion: the stream s has been sucessfully opened for reading.
00204 */
00205 
00206 
00207 local int unz64local_getByte OF((
00208     const zlib_filefunc64_32_def* pzlib_filefunc_def,
00209     voidpf filestream,
00210     int *pi));
00211 
00212 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
00213 {
00214     unsigned char c;
00215     int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
00216     if (err==1)
00217     {
00218         *pi = (int)c;
00219         return UNZ_OK;
00220     }
00221     else
00222     {
00223         if (ZERROR64(*pzlib_filefunc_def,filestream))
00224             return UNZ_ERRNO;
00225         else
00226             return UNZ_EOF;
00227     }
00228 }
00229 
00230 
00231 /* ===========================================================================
00232    Reads a long in LSB order from the given gz_stream. Sets
00233 */
00234 local int unz64local_getShort OF((
00235     const zlib_filefunc64_32_def* pzlib_filefunc_def,
00236     voidpf filestream,
00237     uLong *pX));
00238 
00239 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
00240                              voidpf filestream,
00241                              uLong *pX)
00242 {
00243     uLong x ;
00244     int i = 0;
00245     int err;
00246 
00247     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00248     x = (uLong)i;
00249 
00250     if (err==UNZ_OK)
00251         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00252     x |= ((uLong)i)<<8;
00253 
00254     if (err==UNZ_OK)
00255         *pX = x;
00256     else
00257         *pX = 0;
00258     return err;
00259 }
00260 
00261 local int unz64local_getLong OF((
00262     const zlib_filefunc64_32_def* pzlib_filefunc_def,
00263     voidpf filestream,
00264     uLong *pX));
00265 
00266 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
00267                             voidpf filestream,
00268                             uLong *pX)
00269 {
00270     uLong x ;
00271     int i = 0;
00272     int err;
00273 
00274     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00275     x = (uLong)i;
00276 
00277     if (err==UNZ_OK)
00278         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00279     x |= ((uLong)i)<<8;
00280 
00281     if (err==UNZ_OK)
00282         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00283     x |= ((uLong)i)<<16;
00284 
00285     if (err==UNZ_OK)
00286         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00287     x += ((uLong)i)<<24;
00288 
00289     if (err==UNZ_OK)
00290         *pX = x;
00291     else
00292         *pX = 0;
00293     return err;
00294 }
00295 
00296 local int unz64local_getLong64 OF((
00297     const zlib_filefunc64_32_def* pzlib_filefunc_def,
00298     voidpf filestream,
00299     ZPOS64_T *pX));
00300 
00301 
00302 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
00303                             voidpf filestream,
00304                             ZPOS64_T *pX)
00305 {
00306     ZPOS64_T x ;
00307     int i = 0;
00308     int err;
00309 
00310     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00311     x = (ZPOS64_T)i;
00312 
00313     if (err==UNZ_OK)
00314         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00315     x |= ((ZPOS64_T)i)<<8;
00316 
00317     if (err==UNZ_OK)
00318         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00319     x |= ((ZPOS64_T)i)<<16;
00320 
00321     if (err==UNZ_OK)
00322         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00323     x |= ((ZPOS64_T)i)<<24;
00324 
00325     if (err==UNZ_OK)
00326         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00327     x |= ((ZPOS64_T)i)<<32;
00328 
00329     if (err==UNZ_OK)
00330         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00331     x |= ((ZPOS64_T)i)<<40;
00332 
00333     if (err==UNZ_OK)
00334         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00335     x |= ((ZPOS64_T)i)<<48;
00336 
00337     if (err==UNZ_OK)
00338         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
00339     x |= ((ZPOS64_T)i)<<56;
00340 
00341     if (err==UNZ_OK)
00342         *pX = x;
00343     else
00344         *pX = 0;
00345     return err;
00346 }
00347 
00348 /* My own strcmpi / strcasecmp */
00349 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
00350 {
00351     for (;;)
00352     {
00353         char c1=*(fileName1++);
00354         char c2=*(fileName2++);
00355         if ((c1>='a') && (c1<='z'))
00356             c1 -= 0x20;
00357         if ((c2>='a') && (c2<='z'))
00358             c2 -= 0x20;
00359         if (c1=='\0')
00360             return ((c2=='\0') ? 0 : -1);
00361         if (c2=='\0')
00362             return 1;
00363         if (c1<c2)
00364             return -1;
00365         if (c1>c2)
00366             return 1;
00367     }
00368 }
00369 
00370 
00371 #ifdef  CASESENSITIVITYDEFAULT_NO
00372 #define CASESENSITIVITYDEFAULTVALUE 2
00373 #else
00374 #define CASESENSITIVITYDEFAULTVALUE 1
00375 #endif
00376 
00377 #ifndef STRCMPCASENOSENTIVEFUNCTION
00378 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
00379 #endif
00380 
00381 /*
00382    Compare two filename (fileName1,fileName2).
00383    If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
00384    If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
00385                                                                 or strcasecmp)
00386    If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
00387         (like 1 on Unix, 2 on Windows)
00388 
00389 */
00390 extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
00391                                                  const char*  fileName2,
00392                                                  int iCaseSensitivity)
00393 
00394 {
00395     if (iCaseSensitivity==0)
00396         iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
00397 
00398     if (iCaseSensitivity==1)
00399         return strcmp(fileName1,fileName2);
00400 
00401     return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
00402 }
00403 
00404 #ifndef BUFREADCOMMENT
00405 #define BUFREADCOMMENT (0x400)
00406 #endif
00407 
00408 /*
00409   Locate the Central directory of a zipfile (at the end, just before
00410     the global comment)
00411 */
00412 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
00413 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
00414 {
00415     unsigned char* buf;
00416     ZPOS64_T uSizeFile;
00417     ZPOS64_T uBackRead;
00418     ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
00419     ZPOS64_T uPosFound=0;
00420 
00421     if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
00422         return 0;
00423 
00424 
00425     uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
00426 
00427     if (uMaxBack>uSizeFile)
00428         uMaxBack = uSizeFile;
00429 
00430     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00431     if (buf==NULL)
00432         return 0;
00433 
00434     uBackRead = 4;
00435     while (uBackRead<uMaxBack)
00436     {
00437         uLong uReadSize;
00438         ZPOS64_T uReadPos ;
00439         int i;
00440         if (uBackRead+BUFREADCOMMENT>uMaxBack)
00441             uBackRead = uMaxBack;
00442         else
00443             uBackRead+=BUFREADCOMMENT;
00444         uReadPos = uSizeFile-uBackRead ;
00445 
00446         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
00447                      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
00448         if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00449             break;
00450 
00451         if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
00452             break;
00453 
00454         for (i=(int)uReadSize-3; (i--)>0;)
00455             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
00456                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
00457             {
00458                 uPosFound = uReadPos+i;
00459                 break;
00460             }
00461 
00462         if (uPosFound!=0)
00463             break;
00464     }
00465     TRYFREE(buf);
00466     return uPosFound;
00467 }
00468 
00469 
00470 /*
00471   Locate the Central directory 64 of a zipfile (at the end, just before
00472     the global comment)
00473 */
00474 local ZPOS64_T unz64local_SearchCentralDir64 OF((
00475     const zlib_filefunc64_32_def* pzlib_filefunc_def,
00476     voidpf filestream));
00477 
00478 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
00479                                       voidpf filestream)
00480 {
00481     unsigned char* buf;
00482     ZPOS64_T uSizeFile;
00483     ZPOS64_T uBackRead;
00484     ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
00485     ZPOS64_T uPosFound=0;
00486     uLong uL;
00487                 ZPOS64_T relativeOffset;
00488 
00489     if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
00490         return 0;
00491 
00492 
00493     uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
00494 
00495     if (uMaxBack>uSizeFile)
00496         uMaxBack = uSizeFile;
00497 
00498     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
00499     if (buf==NULL)
00500         return 0;
00501 
00502     uBackRead = 4;
00503     while (uBackRead<uMaxBack)
00504     {
00505         uLong uReadSize;
00506         ZPOS64_T uReadPos;
00507         int i;
00508         if (uBackRead+BUFREADCOMMENT>uMaxBack)
00509             uBackRead = uMaxBack;
00510         else
00511             uBackRead+=BUFREADCOMMENT;
00512         uReadPos = uSizeFile-uBackRead ;
00513 
00514         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
00515                      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
00516         if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00517             break;
00518 
00519         if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
00520             break;
00521 
00522         for (i=(int)uReadSize-3; (i--)>0;)
00523             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
00524                 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
00525             {
00526                 uPosFound = uReadPos+i;
00527                 break;
00528             }
00529 
00530         if (uPosFound!=0)
00531             break;
00532     }
00533     TRYFREE(buf);
00534     if (uPosFound == 0)
00535         return 0;
00536 
00537     /* Zip64 end of central directory locator */
00538     if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
00539         return 0;
00540 
00541     /* the signature, already checked */
00542     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
00543         return 0;
00544 
00545     /* number of the disk with the start of the zip64 end of  central directory */
00546     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
00547         return 0;
00548     if (uL != 0)
00549         return 0;
00550 
00551     /* relative offset of the zip64 end of central directory record */
00552     if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
00553         return 0;
00554 
00555     /* total number of disks */
00556     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
00557         return 0;
00558     if (uL != 1)
00559         return 0;
00560 
00561     /* Goto end of central directory record */
00562     if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
00563         return 0;
00564 
00565      /* the signature */
00566     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
00567         return 0;
00568 
00569     if (uL != 0x06064b50)
00570         return 0;
00571 
00572     return relativeOffset;
00573 }
00574 
00575 /*
00576   Open a Zip file. path contain the full pathname (by example,
00577      on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
00578      "zlib/zlib114.zip".
00579      If the zipfile cannot be opened (file doesn't exist or in not valid), the
00580        return value is NULL.
00581      Else, the return value is a unzFile Handle, usable with other function
00582        of this unzip package.
00583 */
00584 local unzFile unzOpenInternal (const void *path,
00585                                zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
00586                                int is64bitOpenFunction)
00587 {
00588     unz64_s us;
00589     unz64_s *s;
00590     ZPOS64_T central_pos;
00591     uLong   uL;
00592 
00593     uLong number_disk;          /* number of the current dist, used for
00594                                    spaning ZIP, unsupported, always 0*/
00595     uLong number_disk_with_CD;  /* number the the disk with central dir, used
00596                                    for spaning ZIP, unsupported, always 0*/
00597     ZPOS64_T number_entry_CD;      /* total number of entries in
00598                                    the central dir
00599                                    (same than number_entry on nospan) */
00600 
00601     int err=UNZ_OK;
00602 
00603     if (unz_copyright[0]!=' ')
00604         return NULL;
00605 
00606     us.z_filefunc.zseek32_file = NULL;
00607     us.z_filefunc.ztell32_file = NULL;
00608     if (pzlib_filefunc64_32_def==NULL)
00609         fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
00610     else
00611         us.z_filefunc = *pzlib_filefunc64_32_def;
00612     us.is64bitOpenFunction = is64bitOpenFunction;
00613 
00614 
00615 
00616     us.filestream = ZOPEN64(us.z_filefunc,
00617                                                  path,
00618                                                  ZLIB_FILEFUNC_MODE_READ |
00619                                                  ZLIB_FILEFUNC_MODE_EXISTING);
00620     if (us.filestream==NULL)
00621         return NULL;
00622 
00623     central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
00624     if (central_pos)
00625     {
00626         uLong uS;
00627         ZPOS64_T uL64;
00628 
00629         us.isZip64 = 1;
00630 
00631         if (ZSEEK64(us.z_filefunc, us.filestream,
00632                                       central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00633         err=UNZ_ERRNO;
00634 
00635         /* the signature, already checked */
00636         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
00637             err=UNZ_ERRNO;
00638 
00639         /* size of zip64 end of central directory record */
00640         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
00641             err=UNZ_ERRNO;
00642 
00643         /* version made by */
00644         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
00645             err=UNZ_ERRNO;
00646 
00647         /* version needed to extract */
00648         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
00649             err=UNZ_ERRNO;
00650 
00651         /* number of this disk */
00652         if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
00653             err=UNZ_ERRNO;
00654 
00655         /* number of the disk with the start of the central directory */
00656         if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
00657             err=UNZ_ERRNO;
00658 
00659         /* total number of entries in the central directory on this disk */
00660         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
00661             err=UNZ_ERRNO;
00662 
00663         /* total number of entries in the central directory */
00664         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
00665             err=UNZ_ERRNO;
00666 
00667         if ((number_entry_CD!=us.gi.number_entry) ||
00668             (number_disk_with_CD!=0) ||
00669             (number_disk!=0))
00670             err=UNZ_BADZIPFILE;
00671 
00672         /* size of the central directory */
00673         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
00674             err=UNZ_ERRNO;
00675 
00676         /* offset of start of central directory with respect to the
00677           starting disk number */
00678         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
00679             err=UNZ_ERRNO;
00680 
00681         us.gi.size_comment = 0;
00682     }
00683     else
00684     {
00685         central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
00686         if (central_pos==0)
00687             err=UNZ_ERRNO;
00688 
00689         us.isZip64 = 0;
00690 
00691         if (ZSEEK64(us.z_filefunc, us.filestream,
00692                                         central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
00693             err=UNZ_ERRNO;
00694 
00695         /* the signature, already checked */
00696         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
00697             err=UNZ_ERRNO;
00698 
00699         /* number of this disk */
00700         if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
00701             err=UNZ_ERRNO;
00702 
00703         /* number of the disk with the start of the central directory */
00704         if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
00705             err=UNZ_ERRNO;
00706 
00707         /* total number of entries in the central dir on this disk */
00708         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
00709             err=UNZ_ERRNO;
00710         us.gi.number_entry = uL;
00711 
00712         /* total number of entries in the central dir */
00713         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
00714             err=UNZ_ERRNO;
00715         number_entry_CD = uL;
00716 
00717         if ((number_entry_CD!=us.gi.number_entry) ||
00718             (number_disk_with_CD!=0) ||
00719             (number_disk!=0))
00720             err=UNZ_BADZIPFILE;
00721 
00722         /* size of the central directory */
00723         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
00724             err=UNZ_ERRNO;
00725         us.size_central_dir = uL;
00726 
00727         /* offset of start of central directory with respect to the
00728             starting disk number */
00729         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
00730             err=UNZ_ERRNO;
00731         us.offset_central_dir = uL;
00732 
00733         /* zipfile comment length */
00734         if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
00735             err=UNZ_ERRNO;
00736     }
00737 
00738     if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
00739         (err==UNZ_OK))
00740         err=UNZ_BADZIPFILE;
00741 
00742     if (err!=UNZ_OK)
00743     {
00744         ZCLOSE64(us.z_filefunc, us.filestream);
00745         return NULL;
00746     }
00747 
00748     us.byte_before_the_zipfile = central_pos -
00749                             (us.offset_central_dir+us.size_central_dir);
00750     us.central_pos = central_pos;
00751     us.pfile_in_zip_read = NULL;
00752     us.encrypted = 0;
00753 
00754 
00755     s=(unz64_s*)ALLOC(sizeof(unz64_s));
00756     if( s != NULL)
00757     {
00758         *s=us;
00759         unzGoToFirstFile((unzFile)s);
00760     }
00761     return (unzFile)s;
00762 }
00763 
00764 
00765 extern unzFile ZEXPORT unzOpen2 (const char *path,
00766                                         zlib_filefunc_def* pzlib_filefunc32_def)
00767 {
00768     if (pzlib_filefunc32_def != NULL)
00769     {
00770         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
00771         fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
00772         return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
00773     }
00774     else
00775         return unzOpenInternal(path, NULL, 0);
00776 }
00777 
00778 extern unzFile ZEXPORT unzOpen2_64 (const void *path,
00779                                      zlib_filefunc64_def* pzlib_filefunc_def)
00780 {
00781     if (pzlib_filefunc_def != NULL)
00782     {
00783         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
00784         zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
00785         zlib_filefunc64_32_def_fill.ztell32_file = NULL;
00786         zlib_filefunc64_32_def_fill.zseek32_file = NULL;
00787         return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
00788     }
00789     else
00790         return unzOpenInternal(path, NULL, 1);
00791 }
00792 
00793 extern unzFile ZEXPORT unzOpen (const char *path)
00794 {
00795     return unzOpenInternal(path, NULL, 0);
00796 }
00797 
00798 extern unzFile ZEXPORT unzOpen64 (const void *path)
00799 {
00800     return unzOpenInternal(path, NULL, 1);
00801 }
00802 
00803 /*
00804   Close a ZipFile opened with unzipOpen.
00805   If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
00806     these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
00807   return UNZ_OK if there is no problem. */
00808 extern int ZEXPORT unzClose (unzFile file)
00809 {
00810     unz64_s* s;
00811     if (file==NULL)
00812         return UNZ_PARAMERROR;
00813     s=(unz64_s*)file;
00814 
00815     if (s->pfile_in_zip_read!=NULL)
00816         unzCloseCurrentFile(file);
00817 
00818     ZCLOSE64(s->z_filefunc, s->filestream);
00819     TRYFREE(s);
00820     return UNZ_OK;
00821 }
00822 
00823 
00824 /*
00825   Write info about the ZipFile in the *pglobal_info structure.
00826   No preparation of the structure is needed
00827   return UNZ_OK if there is no problem. */
00828 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
00829 {
00830     unz64_s* s;
00831     if (file==NULL)
00832         return UNZ_PARAMERROR;
00833     s=(unz64_s*)file;
00834     *pglobal_info=s->gi;
00835     return UNZ_OK;
00836 }
00837 
00838 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
00839 {
00840     unz64_s* s;
00841     if (file==NULL)
00842         return UNZ_PARAMERROR;
00843     s=(unz64_s*)file;
00844     /* to do : check if number_entry is not truncated */
00845     pglobal_info32->number_entry = (uLong)s->gi.number_entry;
00846     pglobal_info32->size_comment = s->gi.size_comment;
00847     return UNZ_OK;
00848 }
00849 /*
00850    Translate date/time from Dos format to tm_unz (readable more easilty)
00851 */
00852 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
00853 {
00854     ZPOS64_T uDate;
00855     uDate = (ZPOS64_T)(ulDosDate>>16);
00856     ptm->tm_mday = (uInt)(uDate&0x1f) ;
00857     ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
00858     ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
00859 
00860     ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
00861     ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
00862     ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
00863 }
00864 
00865 /*
00866   Get Info about the current file in the zipfile, with internal only info
00867 */
00868 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
00869                                                   unz_file_info64 *pfile_info,
00870                                                   unz_file_info64_internal
00871                                                   *pfile_info_internal,
00872                                                   char *szFileName,
00873                                                   uLong fileNameBufferSize,
00874                                                   void *extraField,
00875                                                   uLong extraFieldBufferSize,
00876                                                   char *szComment,
00877                                                   uLong commentBufferSize));
00878 
00879 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
00880                                                   unz_file_info64 *pfile_info,
00881                                                   unz_file_info64_internal
00882                                                   *pfile_info_internal,
00883                                                   char *szFileName,
00884                                                   uLong fileNameBufferSize,
00885                                                   void *extraField,
00886                                                   uLong extraFieldBufferSize,
00887                                                   char *szComment,
00888                                                   uLong commentBufferSize)
00889 {
00890     unz64_s* s;
00891     unz_file_info64 file_info;
00892     unz_file_info64_internal file_info_internal;
00893     int err=UNZ_OK;
00894     uLong uMagic;
00895     long lSeek=0;
00896     uLong uL;
00897 
00898     if (file==NULL)
00899         return UNZ_PARAMERROR;
00900     s=(unz64_s*)file;
00901     if (ZSEEK64(s->z_filefunc, s->filestream,
00902               s->pos_in_central_dir+s->byte_before_the_zipfile,
00903               ZLIB_FILEFUNC_SEEK_SET)!=0)
00904         err=UNZ_ERRNO;
00905 
00906 
00907     /* we check the magic */
00908     if (err==UNZ_OK)
00909     {
00910         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
00911             err=UNZ_ERRNO;
00912         else if (uMagic!=0x02014b50)
00913             err=UNZ_BADZIPFILE;
00914     }
00915 
00916     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
00917         err=UNZ_ERRNO;
00918 
00919     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
00920         err=UNZ_ERRNO;
00921 
00922     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
00923         err=UNZ_ERRNO;
00924 
00925     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
00926         err=UNZ_ERRNO;
00927 
00928     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
00929         err=UNZ_ERRNO;
00930 
00931     unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
00932 
00933     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
00934         err=UNZ_ERRNO;
00935 
00936     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
00937         err=UNZ_ERRNO;
00938     file_info.compressed_size = uL;
00939 
00940     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
00941         err=UNZ_ERRNO;
00942     file_info.uncompressed_size = uL;
00943 
00944     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
00945         err=UNZ_ERRNO;
00946 
00947     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
00948         err=UNZ_ERRNO;
00949 
00950     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
00951         err=UNZ_ERRNO;
00952 
00953     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
00954         err=UNZ_ERRNO;
00955 
00956     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
00957         err=UNZ_ERRNO;
00958 
00959     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
00960         err=UNZ_ERRNO;
00961 
00962                 // relative offset of local header
00963     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
00964         err=UNZ_ERRNO;
00965     file_info_internal.offset_curfile = uL;
00966 
00967     lSeek+=file_info.size_filename;
00968     if ((err==UNZ_OK) && (szFileName!=NULL))
00969     {
00970         uLong uSizeRead ;
00971         if (file_info.size_filename<fileNameBufferSize)
00972         {
00973             *(szFileName+file_info.size_filename)='\0';
00974             uSizeRead = file_info.size_filename;
00975         }
00976         else
00977             uSizeRead = fileNameBufferSize;
00978 
00979         if ((file_info.size_filename>0) && (fileNameBufferSize>0))
00980             if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
00981                 err=UNZ_ERRNO;
00982         lSeek -= uSizeRead;
00983     }
00984 
00985     // Read extrafield
00986     if ((err==UNZ_OK) && (extraField!=NULL))
00987     {
00988         ZPOS64_T uSizeRead ;
00989         if (file_info.size_file_extra<extraFieldBufferSize)
00990             uSizeRead = file_info.size_file_extra;
00991         else
00992             uSizeRead = extraFieldBufferSize;
00993 
00994         if (lSeek!=0)
00995         {
00996             if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
00997                 lSeek=0;
00998             else
00999                 err=UNZ_ERRNO;
01000         }
01001 
01002         if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
01003             if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
01004                 err=UNZ_ERRNO;
01005 
01006         lSeek += file_info.size_file_extra - (uLong)uSizeRead;
01007     }
01008     else
01009         lSeek += file_info.size_file_extra;
01010 
01011 
01012     if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
01013     {
01014                                 uLong acc = 0;
01015 
01016         // since lSeek now points to after the extra field we need to move back
01017         lSeek -= file_info.size_file_extra;
01018 
01019         if (lSeek!=0)
01020         {
01021             if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
01022                 lSeek=0;
01023             else
01024                 err=UNZ_ERRNO;
01025         }
01026 
01027         while(acc < file_info.size_file_extra)
01028         {
01029             uLong headerId;
01030                                                 uLong dataSize;
01031 
01032             if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
01033                 err=UNZ_ERRNO;
01034 
01035             if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
01036                 err=UNZ_ERRNO;
01037 
01038             /* ZIP64 extra fields */
01039             if (headerId == 0x0001)
01040             {
01041                                                         uLong uL;
01042 
01043                                                                 if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1)
01044                                                                 {
01045                                                                         if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
01046                                                                                         err=UNZ_ERRNO;
01047                                                                 }
01048 
01049                                                                 if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1)
01050                                                                 {
01051                                                                         if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
01052                                                                                   err=UNZ_ERRNO;
01053                                                                 }
01054 
01055                                                                 if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1)
01056                                                                 {
01057                                                                         /* Relative Header offset */
01058                                                                         if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
01059                                                                                 err=UNZ_ERRNO;
01060                                                                 }
01061 
01062                                                                 if(file_info.disk_num_start == (unsigned long)-1)
01063                                                                 {
01064                                                                         /* Disk Start Number */
01065                                                                         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
01066                                                                                 err=UNZ_ERRNO;
01067                                                                 }
01068 
01069             }
01070             else
01071             {
01072                 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
01073                     err=UNZ_ERRNO;
01074             }
01075 
01076             acc += 2 + 2 + dataSize;
01077         }
01078     }
01079 
01080     if ((err==UNZ_OK) && (szComment!=NULL))
01081     {
01082         uLong uSizeRead ;
01083         if (file_info.size_file_comment<commentBufferSize)
01084         {
01085             *(szComment+file_info.size_file_comment)='\0';
01086             uSizeRead = file_info.size_file_comment;
01087         }
01088         else
01089             uSizeRead = commentBufferSize;
01090 
01091         if (lSeek!=0)
01092         {
01093             if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
01094                 lSeek=0;
01095             else
01096                 err=UNZ_ERRNO;
01097         }
01098 
01099         if ((file_info.size_file_comment>0) && (commentBufferSize>0))
01100             if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
01101                 err=UNZ_ERRNO;
01102         lSeek+=file_info.size_file_comment - uSizeRead;
01103     }
01104     else
01105         lSeek+=file_info.size_file_comment;
01106 
01107 
01108     if ((err==UNZ_OK) && (pfile_info!=NULL))
01109         *pfile_info=file_info;
01110 
01111     if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
01112         *pfile_info_internal=file_info_internal;
01113 
01114     return err;
01115 }
01116 
01117 
01118 
01119 /*
01120   Write info about the ZipFile in the *pglobal_info structure.
01121   No preparation of the structure is needed
01122   return UNZ_OK if there is no problem.
01123 */
01124 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
01125                                           unz_file_info64 * pfile_info,
01126                                           char * szFileName, uLong fileNameBufferSize,
01127                                           void *extraField, uLong extraFieldBufferSize,
01128                                           char* szComment,  uLong commentBufferSize)
01129 {
01130     return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
01131                                                 szFileName,fileNameBufferSize,
01132                                                 extraField,extraFieldBufferSize,
01133                                                 szComment,commentBufferSize);
01134 }
01135 
01136 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
01137                                           unz_file_info * pfile_info,
01138                                           char * szFileName, uLong fileNameBufferSize,
01139                                           void *extraField, uLong extraFieldBufferSize,
01140                                           char* szComment,  uLong commentBufferSize)
01141 {
01142     int err;
01143     unz_file_info64 file_info64;
01144     err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
01145                                                 szFileName,fileNameBufferSize,
01146                                                 extraField,extraFieldBufferSize,
01147                                                 szComment,commentBufferSize);
01148     if (err==UNZ_OK)
01149     {
01150         pfile_info->version = file_info64.version;
01151         pfile_info->version_needed = file_info64.version_needed;
01152         pfile_info->flag = file_info64.flag;
01153         pfile_info->compression_method = file_info64.compression_method;
01154         pfile_info->dosDate = file_info64.dosDate;
01155         pfile_info->crc = file_info64.crc;
01156 
01157         pfile_info->size_filename = file_info64.size_filename;
01158         pfile_info->size_file_extra = file_info64.size_file_extra;
01159         pfile_info->size_file_comment = file_info64.size_file_comment;
01160 
01161         pfile_info->disk_num_start = file_info64.disk_num_start;
01162         pfile_info->internal_fa = file_info64.internal_fa;
01163         pfile_info->external_fa = file_info64.external_fa;
01164 
01165         pfile_info->tmu_date = file_info64.tmu_date,
01166 
01167 
01168         pfile_info->compressed_size = (uLong)file_info64.compressed_size;
01169         pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
01170 
01171     }
01172     return err;
01173 }
01174 /*
01175   Set the current file of the zipfile to the first file.
01176   return UNZ_OK if there is no problem
01177 */
01178 extern int ZEXPORT unzGoToFirstFile (unzFile file)
01179 {
01180     int err=UNZ_OK;
01181     unz64_s* s;
01182     if (file==NULL)
01183         return UNZ_PARAMERROR;
01184     s=(unz64_s*)file;
01185     s->pos_in_central_dir=s->offset_central_dir;
01186     s->num_file=0;
01187     err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
01188                                              &s->cur_file_info_internal,
01189                                              NULL,0,NULL,0,NULL,0);
01190     s->current_file_ok = (err == UNZ_OK);
01191     return err;
01192 }
01193 
01194 /*
01195   Set the current file of the zipfile to the next file.
01196   return UNZ_OK if there is no problem
01197   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
01198 */
01199 extern int ZEXPORT unzGoToNextFile (unzFile  file)
01200 {
01201     unz64_s* s;
01202     int err;
01203 
01204     if (file==NULL)
01205         return UNZ_PARAMERROR;
01206     s=(unz64_s*)file;
01207     if (!s->current_file_ok)
01208         return UNZ_END_OF_LIST_OF_FILE;
01209     if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
01210       if (s->num_file+1==s->gi.number_entry)
01211         return UNZ_END_OF_LIST_OF_FILE;
01212 
01213     s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
01214             s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
01215     s->num_file++;
01216     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
01217                                                &s->cur_file_info_internal,
01218                                                NULL,0,NULL,0,NULL,0);
01219     s->current_file_ok = (err == UNZ_OK);
01220     return err;
01221 }
01222 
01223 
01224 /*
01225   Try locate the file szFileName in the zipfile.
01226   For the iCaseSensitivity signification, see unzipStringFileNameCompare
01227 
01228   return value :
01229   UNZ_OK if the file is found. It becomes the current file.
01230   UNZ_END_OF_LIST_OF_FILE if the file is not found
01231 */
01232 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
01233 {
01234     unz64_s* s;
01235     int err;
01236 
01237     /* We remember the 'current' position in the file so that we can jump
01238      * back there if we fail.
01239      */
01240     unz_file_info64 cur_file_infoSaved;
01241     unz_file_info64_internal cur_file_info_internalSaved;
01242     ZPOS64_T num_fileSaved;
01243     ZPOS64_T pos_in_central_dirSaved;
01244 
01245 
01246     if (file==NULL)
01247         return UNZ_PARAMERROR;
01248 
01249     if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
01250         return UNZ_PARAMERROR;
01251 
01252     s=(unz64_s*)file;
01253     if (!s->current_file_ok)
01254         return UNZ_END_OF_LIST_OF_FILE;
01255 
01256     /* Save the current state */
01257     num_fileSaved = s->num_file;
01258     pos_in_central_dirSaved = s->pos_in_central_dir;
01259     cur_file_infoSaved = s->cur_file_info;
01260     cur_file_info_internalSaved = s->cur_file_info_internal;
01261 
01262     err = unzGoToFirstFile(file);
01263 
01264     while (err == UNZ_OK)
01265     {
01266         char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
01267         err = unzGetCurrentFileInfo64(file,NULL,
01268                                     szCurrentFileName,sizeof(szCurrentFileName)-1,
01269                                     NULL,0,NULL,0);
01270         if (err == UNZ_OK)
01271         {
01272             if (unzStringFileNameCompare(szCurrentFileName,
01273                                             szFileName,iCaseSensitivity)==0)
01274                 return UNZ_OK;
01275             err = unzGoToNextFile(file);
01276         }
01277     }
01278 
01279     /* We failed, so restore the state of the 'current file' to where we
01280      * were.
01281      */
01282     s->num_file = num_fileSaved ;
01283     s->pos_in_central_dir = pos_in_central_dirSaved ;
01284     s->cur_file_info = cur_file_infoSaved;
01285     s->cur_file_info_internal = cur_file_info_internalSaved;
01286     return err;
01287 }
01288 
01289 
01290 /*
01292 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
01293 // I need random access
01294 //
01295 // Further optimization could be realized by adding an ability
01296 // to cache the directory in memory. The goal being a single
01297 // comprehensive file read to put the file I need in a memory.
01298 */
01299 
01300 /*
01301 typedef struct unz_file_pos_s
01302 {
01303     ZPOS64_T pos_in_zip_directory;   // offset in file
01304     ZPOS64_T num_of_file;            // # of file
01305 } unz_file_pos;
01306 */
01307 
01308 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
01309 {
01310     unz64_s* s;
01311 
01312     if (file==NULL || file_pos==NULL)
01313         return UNZ_PARAMERROR;
01314     s=(unz64_s*)file;
01315     if (!s->current_file_ok)
01316         return UNZ_END_OF_LIST_OF_FILE;
01317 
01318     file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
01319     file_pos->num_of_file           = s->num_file;
01320 
01321     return UNZ_OK;
01322 }
01323 
01324 extern int ZEXPORT unzGetFilePos(
01325     unzFile file,
01326     unz_file_pos* file_pos)
01327 {
01328     unz64_file_pos file_pos64;
01329     int err = unzGetFilePos64(file,&file_pos64);
01330     if (err==UNZ_OK)
01331     {
01332         file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
01333         file_pos->num_of_file = (uLong)file_pos64.num_of_file;
01334     }
01335     return err;
01336 }
01337 
01338 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
01339 {
01340     unz64_s* s;
01341     int err;
01342 
01343     if (file==NULL || file_pos==NULL)
01344         return UNZ_PARAMERROR;
01345     s=(unz64_s*)file;
01346 
01347     /* jump to the right spot */
01348     s->pos_in_central_dir = file_pos->pos_in_zip_directory;
01349     s->num_file           = file_pos->num_of_file;
01350 
01351     /* set the current file */
01352     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
01353                                                &s->cur_file_info_internal,
01354                                                NULL,0,NULL,0,NULL,0);
01355     /* return results */
01356     s->current_file_ok = (err == UNZ_OK);
01357     return err;
01358 }
01359 
01360 extern int ZEXPORT unzGoToFilePos(
01361     unzFile file,
01362     unz_file_pos* file_pos)
01363 {
01364     unz64_file_pos file_pos64;
01365     if (file_pos == NULL)
01366         return UNZ_PARAMERROR;
01367 
01368     file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
01369     file_pos64.num_of_file = file_pos->num_of_file;
01370     return unzGoToFilePos64(file,&file_pos64);
01371 }
01372 
01373 /*
01374 // Unzip Helper Functions - should be here?
01376 */
01377 
01378 /*
01379   Read the local header of the current zipfile
01380   Check the coherency of the local header and info in the end of central
01381         directory about this file
01382   store in *piSizeVar the size of extra info in local header
01383         (filename and size of extra field data)
01384 */
01385 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
01386                                                     ZPOS64_T * poffset_local_extrafield,
01387                                                     uInt  * psize_local_extrafield)
01388 {
01389     uLong uMagic,uData,uFlags;
01390     uLong size_filename;
01391     uLong size_extra_field;
01392     int err=UNZ_OK;
01393 
01394     *piSizeVar = 0;
01395     *poffset_local_extrafield = 0;
01396     *psize_local_extrafield = 0;
01397 
01398     if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
01399                                 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
01400         return UNZ_ERRNO;
01401 
01402 
01403     if (err==UNZ_OK)
01404     {
01405         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
01406             err=UNZ_ERRNO;
01407         else if (uMagic!=0x04034b50)
01408             err=UNZ_BADZIPFILE;
01409     }
01410 
01411     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
01412         err=UNZ_ERRNO;
01413 /*
01414     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
01415         err=UNZ_BADZIPFILE;
01416 */
01417     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
01418         err=UNZ_ERRNO;
01419 
01420     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
01421         err=UNZ_ERRNO;
01422     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
01423         err=UNZ_BADZIPFILE;
01424 
01425     if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
01426 /* #ifdef HAVE_BZIP2 */
01427                          (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
01428 /* #endif */
01429                          (s->cur_file_info.compression_method!=Z_DEFLATED))
01430         err=UNZ_BADZIPFILE;
01431 
01432     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
01433         err=UNZ_ERRNO;
01434 
01435     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
01436         err=UNZ_ERRNO;
01437     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
01438         err=UNZ_BADZIPFILE;
01439 
01440     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
01441         err=UNZ_ERRNO;
01442     else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
01443         err=UNZ_BADZIPFILE;
01444 
01445     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
01446         err=UNZ_ERRNO;
01447     else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
01448         err=UNZ_BADZIPFILE;
01449 
01450     if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
01451         err=UNZ_ERRNO;
01452     else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
01453         err=UNZ_BADZIPFILE;
01454 
01455     *piSizeVar += (uInt)size_filename;
01456 
01457     if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
01458         err=UNZ_ERRNO;
01459     *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
01460                                     SIZEZIPLOCALHEADER + size_filename;
01461     *psize_local_extrafield = (uInt)size_extra_field;
01462 
01463     *piSizeVar += (uInt)size_extra_field;
01464 
01465     return err;
01466 }
01467 
01468 /*
01469   Open for reading data the current file in the zipfile.
01470   If there is no error and the file is opened, the return value is UNZ_OK.
01471 */
01472 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
01473                                             int* level, int raw, const char* password)
01474 {
01475     int err=UNZ_OK;
01476     uInt iSizeVar;
01477     unz64_s* s;
01478     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01479     ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
01480     uInt  size_local_extrafield;    /* size of the local extra field */
01481 #    ifndef NOUNCRYPT
01482     char source[12];
01483 #    else
01484     if (password != NULL)
01485         return UNZ_PARAMERROR;
01486 #    endif
01487 
01488     if (file==NULL)
01489         return UNZ_PARAMERROR;
01490     s=(unz64_s*)file;
01491     if (!s->current_file_ok)
01492         return UNZ_PARAMERROR;
01493 
01494     if (s->pfile_in_zip_read != NULL)
01495         unzCloseCurrentFile(file);
01496 
01497     if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
01498         return UNZ_BADZIPFILE;
01499 
01500     pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
01501     if (pfile_in_zip_read_info==NULL)
01502         return UNZ_INTERNALERROR;
01503 
01504     pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
01505     pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
01506     pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
01507     pfile_in_zip_read_info->pos_local_extrafield=0;
01508     pfile_in_zip_read_info->raw=raw;
01509 
01510     if (pfile_in_zip_read_info->read_buffer==NULL)
01511     {
01512         TRYFREE(pfile_in_zip_read_info);
01513         return UNZ_INTERNALERROR;
01514     }
01515 
01516     pfile_in_zip_read_info->stream_initialised=0;
01517 
01518     if (method!=NULL)
01519         *method = (int)s->cur_file_info.compression_method;
01520 
01521     if (level!=NULL)
01522     {
01523         *level = 6;
01524         switch (s->cur_file_info.flag & 0x06)
01525         {
01526           case 6 : *level = 1; break;
01527           case 4 : *level = 2; break;
01528           case 2 : *level = 9; break;
01529         }
01530     }
01531 
01532     if ((s->cur_file_info.compression_method!=0) &&
01533 /* #ifdef HAVE_BZIP2 */
01534         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
01535 /* #endif */
01536         (s->cur_file_info.compression_method!=Z_DEFLATED))
01537 
01538         err=UNZ_BADZIPFILE;
01539 
01540     pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
01541     pfile_in_zip_read_info->crc32=0;
01542     pfile_in_zip_read_info->total_out_64=0;
01543     pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
01544     pfile_in_zip_read_info->filestream=s->filestream;
01545     pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
01546     pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
01547 
01548     pfile_in_zip_read_info->stream.total_out = 0;
01549 
01550     if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
01551     {
01552 #ifdef HAVE_BZIP2
01553       pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
01554       pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
01555       pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
01556       pfile_in_zip_read_info->bstream.state = (voidpf)0;
01557 
01558       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
01559       pfile_in_zip_read_info->stream.zfree = (free_func)0;
01560       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
01561       pfile_in_zip_read_info->stream.next_in = (voidpf)0;
01562       pfile_in_zip_read_info->stream.avail_in = 0;
01563 
01564       err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
01565       if (err == Z_OK)
01566         pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
01567       else
01568       {
01569         TRYFREE(pfile_in_zip_read_info);
01570         return err;
01571       }
01572 #else
01573       pfile_in_zip_read_info->raw=1;
01574 #endif
01575     }
01576     else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
01577     {
01578       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
01579       pfile_in_zip_read_info->stream.zfree = (free_func)0;
01580       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
01581       pfile_in_zip_read_info->stream.next_in = 0;
01582       pfile_in_zip_read_info->stream.avail_in = 0;
01583 
01584       err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
01585       if (err == Z_OK)
01586         pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
01587       else
01588       {
01589         TRYFREE(pfile_in_zip_read_info);
01590         return err;
01591       }
01592         /* windowBits is passed < 0 to tell that there is no zlib header.
01593          * Note that in this case inflate *requires* an extra "dummy" byte
01594          * after the compressed stream in order to complete decompression and
01595          * return Z_STREAM_END.
01596          * In unzip, i don't wait absolutely Z_STREAM_END because I known the
01597          * size of both compressed and uncompressed data
01598          */
01599     }
01600     pfile_in_zip_read_info->rest_read_compressed =
01601             s->cur_file_info.compressed_size ;
01602     pfile_in_zip_read_info->rest_read_uncompressed =
01603             s->cur_file_info.uncompressed_size ;
01604 
01605 
01606     pfile_in_zip_read_info->pos_in_zipfile =
01607             s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
01608               iSizeVar;
01609 
01610     pfile_in_zip_read_info->stream.avail_in = (uInt)0;
01611 
01612     s->pfile_in_zip_read = pfile_in_zip_read_info;
01613                 s->encrypted = 0;
01614 
01615 #    ifndef NOUNCRYPT
01616     if (password != NULL)
01617     {
01618         int i;
01619         s->pcrc_32_tab = get_crc_table();
01620         init_keys(password,s->keys,s->pcrc_32_tab);
01621         if (ZSEEK64(s->z_filefunc, s->filestream,
01622                   s->pfile_in_zip_read->pos_in_zipfile +
01623                      s->pfile_in_zip_read->byte_before_the_zipfile,
01624                   SEEK_SET)!=0)
01625             return UNZ_INTERNALERROR;
01626         if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
01627             return UNZ_INTERNALERROR;
01628 
01629         for (i = 0; i<12; i++)
01630             zdecode(s->keys,s->pcrc_32_tab,source[i]);
01631 
01632         s->pfile_in_zip_read->pos_in_zipfile+=12;
01633         s->encrypted=1;
01634     }
01635 #    endif
01636 
01637 
01638     return UNZ_OK;
01639 }
01640 
01641 extern int ZEXPORT unzOpenCurrentFile (unzFile file)
01642 {
01643     return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
01644 }
01645 
01646 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
01647 {
01648     return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
01649 }
01650 
01651 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
01652 {
01653     return unzOpenCurrentFile3(file, method, level, raw, NULL);
01654 }
01655 
01658 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
01659 {
01660     unz64_s* s;
01661     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01662     s=(unz64_s*)file;
01663     if (file==NULL)
01664         return 0; //UNZ_PARAMERROR;
01665     pfile_in_zip_read_info=s->pfile_in_zip_read;
01666     if (pfile_in_zip_read_info==NULL)
01667         return 0; //UNZ_PARAMERROR;
01668     return pfile_in_zip_read_info->pos_in_zipfile +
01669                          pfile_in_zip_read_info->byte_before_the_zipfile;
01670 }
01671 
01674 /*
01675   Read bytes from the current file.
01676   buf contain buffer where data must be copied
01677   len the size of buf.
01678 
01679   return the number of byte copied if somes bytes are copied
01680   return 0 if the end of file was reached
01681   return <0 with error code if there is an error
01682     (UNZ_ERRNO for IO error, or zLib error for uncompress error)
01683 */
01684 extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
01685 {
01686     int err=UNZ_OK;
01687     uInt iRead = 0;
01688     unz64_s* s;
01689     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01690     if (file==NULL)
01691         return UNZ_PARAMERROR;
01692     s=(unz64_s*)file;
01693     pfile_in_zip_read_info=s->pfile_in_zip_read;
01694 
01695     if (pfile_in_zip_read_info==NULL)
01696         return UNZ_PARAMERROR;
01697 
01698 
01699     if ((pfile_in_zip_read_info->read_buffer == NULL))
01700         return UNZ_END_OF_LIST_OF_FILE;
01701     if (len==0)
01702         return 0;
01703 
01704     pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
01705 
01706     pfile_in_zip_read_info->stream.avail_out = (uInt)len;
01707 
01708     if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
01709         (!(pfile_in_zip_read_info->raw)))
01710         pfile_in_zip_read_info->stream.avail_out =
01711             (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
01712 
01713     if ((len>pfile_in_zip_read_info->rest_read_compressed+
01714            pfile_in_zip_read_info->stream.avail_in) &&
01715          (pfile_in_zip_read_info->raw))
01716         pfile_in_zip_read_info->stream.avail_out =
01717             (uInt)pfile_in_zip_read_info->rest_read_compressed+
01718             pfile_in_zip_read_info->stream.avail_in;
01719 
01720     while (pfile_in_zip_read_info->stream.avail_out>0)
01721     {
01722         if ((pfile_in_zip_read_info->stream.avail_in==0) &&
01723             (pfile_in_zip_read_info->rest_read_compressed>0))
01724         {
01725             uInt uReadThis = UNZ_BUFSIZE;
01726             if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
01727                 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
01728             if (uReadThis == 0)
01729                 return UNZ_EOF;
01730             if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
01731                       pfile_in_zip_read_info->filestream,
01732                       pfile_in_zip_read_info->pos_in_zipfile +
01733                          pfile_in_zip_read_info->byte_before_the_zipfile,
01734                          ZLIB_FILEFUNC_SEEK_SET)!=0)
01735                 return UNZ_ERRNO;
01736             if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
01737                       pfile_in_zip_read_info->filestream,
01738                       pfile_in_zip_read_info->read_buffer,
01739                       uReadThis)!=uReadThis)
01740                 return UNZ_ERRNO;
01741 
01742 
01743 #            ifndef NOUNCRYPT
01744             if(s->encrypted)
01745             {
01746                 uInt i;
01747                 for(i=0;i<uReadThis;i++)
01748                   pfile_in_zip_read_info->read_buffer[i] =
01749                       zdecode(s->keys,s->pcrc_32_tab,
01750                               pfile_in_zip_read_info->read_buffer[i]);
01751             }
01752 #            endif
01753 
01754 
01755             pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
01756 
01757             pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
01758 
01759             pfile_in_zip_read_info->stream.next_in =
01760                 (Bytef*)pfile_in_zip_read_info->read_buffer;
01761             pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
01762         }
01763 
01764         if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
01765         {
01766             uInt uDoCopy,i ;
01767 
01768             if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
01769                 (pfile_in_zip_read_info->rest_read_compressed == 0))
01770                 return (iRead==0) ? UNZ_EOF : iRead;
01771 
01772             if (pfile_in_zip_read_info->stream.avail_out <
01773                             pfile_in_zip_read_info->stream.avail_in)
01774                 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
01775             else
01776                 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
01777 
01778             for (i=0;i<uDoCopy;i++)
01779                 *(pfile_in_zip_read_info->stream.next_out+i) =
01780                         *(pfile_in_zip_read_info->stream.next_in+i);
01781 
01782             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
01783 
01784             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
01785                                 pfile_in_zip_read_info->stream.next_out,
01786                                 uDoCopy);
01787             pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
01788             pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
01789             pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
01790             pfile_in_zip_read_info->stream.next_out += uDoCopy;
01791             pfile_in_zip_read_info->stream.next_in += uDoCopy;
01792             pfile_in_zip_read_info->stream.total_out += uDoCopy;
01793             iRead += uDoCopy;
01794         }
01795         else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
01796         {
01797 #ifdef HAVE_BZIP2
01798             uLong uTotalOutBefore,uTotalOutAfter;
01799             const Bytef *bufBefore;
01800             uLong uOutThis;
01801 
01802             pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
01803             pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
01804             pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
01805             pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
01806             pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
01807             pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
01808             pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
01809             pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
01810 
01811             uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
01812             bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
01813 
01814             err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
01815 
01816             uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
01817             uOutThis = uTotalOutAfter-uTotalOutBefore;
01818 
01819             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
01820 
01821             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
01822             pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
01823             iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
01824 
01825             pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
01826             pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
01827             pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
01828             pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
01829             pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
01830             pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
01831 
01832             if (err==BZ_STREAM_END)
01833               return (iRead==0) ? UNZ_EOF : iRead;
01834             if (err!=BZ_OK)
01835               break;
01836 #endif
01837         } // end Z_BZIP2ED
01838         else
01839         {
01840             ZPOS64_T uTotalOutBefore,uTotalOutAfter;
01841             const Bytef *bufBefore;
01842             ZPOS64_T uOutThis;
01843             int flush=Z_SYNC_FLUSH;
01844 
01845             uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
01846             bufBefore = pfile_in_zip_read_info->stream.next_out;
01847 
01848             /*
01849             if ((pfile_in_zip_read_info->rest_read_uncompressed ==
01850                      pfile_in_zip_read_info->stream.avail_out) &&
01851                 (pfile_in_zip_read_info->rest_read_compressed == 0))
01852                 flush = Z_FINISH;
01853             */
01854             err=inflate(&pfile_in_zip_read_info->stream,flush);
01855 
01856             if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
01857               err = Z_DATA_ERROR;
01858 
01859             uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
01860             uOutThis = uTotalOutAfter-uTotalOutBefore;
01861 
01862             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
01863 
01864             pfile_in_zip_read_info->crc32 =
01865                 crc32(pfile_in_zip_read_info->crc32,bufBefore,
01866                         (uInt)(uOutThis));
01867 
01868             pfile_in_zip_read_info->rest_read_uncompressed -=
01869                 uOutThis;
01870 
01871             iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
01872 
01873             if (err==Z_STREAM_END)
01874                 return (iRead==0) ? UNZ_EOF : iRead;
01875             if (err!=Z_OK)
01876                 break;
01877         }
01878     }
01879 
01880     if (err==Z_OK)
01881         return iRead;
01882     return err;
01883 }
01884 
01885 
01886 /*
01887   Give the current position in uncompressed data
01888 */
01889 extern z_off_t ZEXPORT unztell (unzFile file)
01890 {
01891     unz64_s* s;
01892     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01893     if (file==NULL)
01894         return UNZ_PARAMERROR;
01895     s=(unz64_s*)file;
01896     pfile_in_zip_read_info=s->pfile_in_zip_read;
01897 
01898     if (pfile_in_zip_read_info==NULL)
01899         return UNZ_PARAMERROR;
01900 
01901     return (z_off_t)pfile_in_zip_read_info->stream.total_out;
01902 }
01903 
01904 extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
01905 {
01906 
01907     unz64_s* s;
01908     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01909     if (file==NULL)
01910         return (ZPOS64_T)-1;
01911     s=(unz64_s*)file;
01912     pfile_in_zip_read_info=s->pfile_in_zip_read;
01913 
01914     if (pfile_in_zip_read_info==NULL)
01915         return (ZPOS64_T)-1;
01916 
01917     return pfile_in_zip_read_info->total_out_64;
01918 }
01919 
01920 
01921 /*
01922   return 1 if the end of file was reached, 0 elsewhere
01923 */
01924 extern int ZEXPORT unzeof (unzFile file)
01925 {
01926     unz64_s* s;
01927     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01928     if (file==NULL)
01929         return UNZ_PARAMERROR;
01930     s=(unz64_s*)file;
01931     pfile_in_zip_read_info=s->pfile_in_zip_read;
01932 
01933     if (pfile_in_zip_read_info==NULL)
01934         return UNZ_PARAMERROR;
01935 
01936     if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
01937         return 1;
01938     else
01939         return 0;
01940 }
01941 
01942 
01943 
01944 /*
01945 Read extra field from the current file (opened by unzOpenCurrentFile)
01946 This is the local-header version of the extra field (sometimes, there is
01947 more info in the local-header version than in the central-header)
01948 
01949   if buf==NULL, it return the size of the local extra field that can be read
01950 
01951   if buf!=NULL, len is the size of the buffer, the extra header is copied in
01952     buf.
01953   the return value is the number of bytes copied in buf, or (if <0)
01954     the error code
01955 */
01956 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
01957 {
01958     unz64_s* s;
01959     file_in_zip64_read_info_s* pfile_in_zip_read_info;
01960     uInt read_now;
01961     ZPOS64_T size_to_read;
01962 
01963     if (file==NULL)
01964         return UNZ_PARAMERROR;
01965     s=(unz64_s*)file;
01966     pfile_in_zip_read_info=s->pfile_in_zip_read;
01967 
01968     if (pfile_in_zip_read_info==NULL)
01969         return UNZ_PARAMERROR;
01970 
01971     size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
01972                 pfile_in_zip_read_info->pos_local_extrafield);
01973 
01974     if (buf==NULL)
01975         return (int)size_to_read;
01976 
01977     if (len>size_to_read)
01978         read_now = (uInt)size_to_read;
01979     else
01980         read_now = (uInt)len ;
01981 
01982     if (read_now==0)
01983         return 0;
01984 
01985     if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
01986               pfile_in_zip_read_info->filestream,
01987               pfile_in_zip_read_info->offset_local_extrafield +
01988               pfile_in_zip_read_info->pos_local_extrafield,
01989               ZLIB_FILEFUNC_SEEK_SET)!=0)
01990         return UNZ_ERRNO;
01991 
01992     if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
01993               pfile_in_zip_read_info->filestream,
01994               buf,read_now)!=read_now)
01995         return UNZ_ERRNO;
01996 
01997     return (int)read_now;
01998 }
01999 
02000 /*
02001   Close the file in zip opened with unzipOpenCurrentFile
02002   Return UNZ_CRCERROR if all the file was read but the CRC is not good
02003 */
02004 extern int ZEXPORT unzCloseCurrentFile (unzFile file)
02005 {
02006     int err=UNZ_OK;
02007 
02008     unz64_s* s;
02009     file_in_zip64_read_info_s* pfile_in_zip_read_info;
02010     if (file==NULL)
02011         return UNZ_PARAMERROR;
02012     s=(unz64_s*)file;
02013     pfile_in_zip_read_info=s->pfile_in_zip_read;
02014 
02015     if (pfile_in_zip_read_info==NULL)
02016         return UNZ_PARAMERROR;
02017 
02018 
02019     if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
02020         (!pfile_in_zip_read_info->raw))
02021     {
02022         if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
02023             err=UNZ_CRCERROR;
02024     }
02025 
02026 
02027     TRYFREE(pfile_in_zip_read_info->read_buffer);
02028     pfile_in_zip_read_info->read_buffer = NULL;
02029     if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
02030         inflateEnd(&pfile_in_zip_read_info->stream);
02031 #ifdef HAVE_BZIP2
02032     else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
02033         BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
02034 #endif
02035 
02036 
02037     pfile_in_zip_read_info->stream_initialised = 0;
02038     TRYFREE(pfile_in_zip_read_info);
02039 
02040     s->pfile_in_zip_read=NULL;
02041 
02042     return err;
02043 }
02044 
02045 
02046 /*
02047   Get the global comment string of the ZipFile, in the szComment buffer.
02048   uSizeBuf is the size of the szComment buffer.
02049   return the number of byte copied or an error code <0
02050 */
02051 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
02052 {
02053     unz64_s* s;
02054     uLong uReadThis ;
02055     if (file==NULL)
02056         return (int)UNZ_PARAMERROR;
02057     s=(unz64_s*)file;
02058 
02059     uReadThis = uSizeBuf;
02060     if (uReadThis>s->gi.size_comment)
02061         uReadThis = s->gi.size_comment;
02062 
02063     if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
02064         return UNZ_ERRNO;
02065 
02066     if (uReadThis>0)
02067     {
02068       *szComment='\0';
02069       if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
02070         return UNZ_ERRNO;
02071     }
02072 
02073     if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
02074         *(szComment+s->gi.size_comment)='\0';
02075     return (int)uReadThis;
02076 }
02077 
02078 /* Additions by RX '2004 */
02079 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
02080 {
02081     unz64_s* s;
02082 
02083     if (file==NULL)
02084           return 0; //UNZ_PARAMERROR;
02085     s=(unz64_s*)file;
02086     if (!s->current_file_ok)
02087       return 0;
02088     if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
02089       if (s->num_file==s->gi.number_entry)
02090          return 0;
02091     return s->pos_in_central_dir;
02092 }
02093 
02094 extern uLong ZEXPORT unzGetOffset (unzFile file)
02095 {
02096     ZPOS64_T offset64;
02097 
02098     if (file==NULL)
02099           return 0; //UNZ_PARAMERROR;
02100     offset64 = unzGetOffset64(file);
02101     return (uLong)offset64;
02102 }
02103 
02104 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
02105 {
02106     unz64_s* s;
02107     int err;
02108 
02109     if (file==NULL)
02110         return UNZ_PARAMERROR;
02111     s=(unz64_s*)file;
02112 
02113     s->pos_in_central_dir = pos;
02114     s->num_file = s->gi.number_entry;      /* hack */
02115     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
02116                                               &s->cur_file_info_internal,
02117                                               NULL,0,NULL,0,NULL,0);
02118     s->current_file_ok = (err == UNZ_OK);
02119     return err;
02120 }
02121 
02122 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
02123 {
02124     return unzSetOffset64(file,pos);
02125 }


re_object_recorder
Author(s): Andreas Koch
autogenerated on Sun Jan 5 2014 11:39:12