File indexing completed on 2025-01-26 04:24:55

0001 /* unzip.c -- IO for uncompress .zip files using zlib
0002    Version 1.1, February 14h, 2010
0003    part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
0004 
0005          Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
0006 
0007          Modifications of Unzip for Zip64
0008          Copyright (C) 2007-2008 Even Rouault
0009 
0010          Modifications for Zip64 support on both zip and unzip
0011          Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
0012 
0013          Modifications for QIODevice support and other QuaZIP fixes
0014          Copyright (C) 2005-2014 Sergey A. Tachenov
0015 
0016          For more info read MiniZip_info.txt
0017 
0018 
0019   ------------------------------------------------------------------------------------
0020   Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
0021   compatibility with older software. The following is from the original crypt.c.
0022   Code woven in by Terry Thorsen 1/2003.
0023 
0024   Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
0025 
0026   See the accompanying file LICENSE, version 2000-Apr-09 or later
0027   (the contents of which are also included in zip.h) for terms of use.
0028   If, for some reason, all these files are missing, the Info-ZIP license
0029   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
0030 
0031         crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
0032 
0033   The encryption/decryption parts of this source code (as opposed to the
0034   non-echoing password parts) were originally written in Europe.  The
0035   whole source package can be freely distributed, including from the USA.
0036   (Prior to January 2000, re-export from the US was a violation of US law.)
0037 
0038         This encryption code is a direct transcription of the algorithm from
0039   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
0040   file (appnote.txt) is distributed with the PKZIP program (even in the
0041   version without encryption capabilities).
0042 
0043         ------------------------------------------------------------------------------------
0044 
0045         Changes in unzip.c
0046 
0047         2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
0048   2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
0049   2007-2008 - Even Rouault - Remove old C style function prototypes
0050   2007-2008 - Even Rouault - Add unzip support for ZIP64
0051 
0052         Copyright (C) 2007-2008 Even Rouault
0053 
0054 
0055         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).
0056   Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
0057                                 should only read the compressed/uncompressed size from the Zip64 format if
0058                                 the size from normal header was 0xFFFFFFFF
0059   Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
0060         Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
0061                                 Patch created by Daniel Borca
0062 
0063   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
0064 
0065   Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
0066 
0067 */
0068 
0069 
0070 #include <stdio.h>
0071 #include <stdlib.h>
0072 #include <string.h>
0073 
0074 #include "zlib.h"
0075 #if (ZLIB_VERNUM < 0x1270)
0076 typedef uLongf z_crc_t;
0077 #endif
0078 #include "unzip.h"
0079 
0080 #ifdef STDC
0081 #  include <stddef.h>
0082 #  include <string.h>
0083 #  include <stdlib.h>
0084 #endif
0085 #ifdef NO_ERRNO_H
0086     extern int errno;
0087 #else
0088 #   include <errno.h>
0089 #endif
0090 
0091 
0092 #ifndef local
0093 #  define local static
0094 #endif
0095 /* compile with -Dlocal if your debugger can't find static symbols */
0096 
0097 
0098 #ifndef CASESENSITIVITYDEFAULT_NO
0099 #  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
0100 #    define CASESENSITIVITYDEFAULT_NO
0101 #  endif
0102 #endif
0103 
0104 
0105 #ifndef UNZ_BUFSIZE
0106 #define UNZ_BUFSIZE (16384)
0107 #endif
0108 
0109 #ifndef UNZ_MAXFILENAMEINZIP
0110 #define UNZ_MAXFILENAMEINZIP (256)
0111 #endif
0112 
0113 #ifndef ALLOC
0114 # define ALLOC(size) (malloc(size))
0115 #endif
0116 #ifndef TRYFREE
0117 # define TRYFREE(p) {if (p) free(p);}
0118 #endif
0119 
0120 #define SIZECENTRALDIRITEM (0x2e)
0121 #define SIZEZIPLOCALHEADER (0x1e)
0122 
0123 
0124 const char unz_copyright[] =
0125    " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
0126 
0127 /* unz_file_info_interntal contain internal info about a file in zipfile*/
0128 typedef struct unz_file_info64_internal_s
0129 {
0130     ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
0131 } unz_file_info64_internal;
0132 
0133 
0134 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
0135     when reading and decompress it */
0136 typedef struct
0137 {
0138     char  *read_buffer;         /* internal buffer for compressed data */
0139     z_stream stream;            /* zLib stream structure for inflate */
0140 
0141 #ifdef HAVE_BZIP2
0142     bz_stream bstream;          /* bzLib stream structure for bziped */
0143 #endif
0144 
0145     ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
0146     uLong stream_initialised;   /* flag set if stream structure is initialised*/
0147 
0148     ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
0149     uInt  size_local_extrafield;/* size of the local extra field */
0150     ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
0151     ZPOS64_T total_out_64;
0152 
0153     uLong crc32;                /* crc32 of all data uncompressed */
0154     uLong crc32_wait;           /* crc32 we must obtain after decompress all */
0155     ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
0156     ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
0157     zlib_filefunc64_32_def z_filefunc;
0158     voidpf filestream;        /* io structore of the zipfile */
0159     uLong compression_method;   /* compression method (0==store) */
0160     ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
0161     int   raw;
0162 } file_in_zip64_read_info_s;
0163 
0164 
0165 /* unz64_s contain internal information about the zipfile
0166 */
0167 typedef struct
0168 {
0169     zlib_filefunc64_32_def z_filefunc;
0170     int is64bitOpenFunction;
0171     voidpf filestream;        /* io structore of the zipfile */
0172     unz_global_info64 gi;       /* public global information */
0173     ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
0174     ZPOS64_T num_file;             /* number of the current file in the zipfile*/
0175     ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
0176     ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
0177     ZPOS64_T central_pos;          /* position of the beginning of the central dir*/
0178 
0179     ZPOS64_T size_central_dir;     /* size of the central directory  */
0180     ZPOS64_T offset_central_dir;   /* offset of start of central directory with
0181                                    respect to the starting disk number */
0182 
0183     unz_file_info64 cur_file_info; /* public info about the current file in zip*/
0184     unz_file_info64_internal cur_file_info_internal; /* private info about it*/
0185     file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
0186                                         file if we are decompressing it */
0187     int encrypted;
0188 
0189     int isZip64;
0190     unsigned flags;
0191 
0192 #    ifndef NOUNCRYPT
0193     unsigned long keys[3];     /* keys defining the pseudo-random sequence */
0194     const z_crc_t FAR * pcrc_32_tab;
0195 #    endif
0196 } unz64_s;
0197 
0198 
0199 #ifndef NOUNCRYPT
0200 #include "crypt.h"
0201 #endif
0202 
0203 /* ===========================================================================
0204      Read a byte from a gz_stream; update next_in and avail_in. Return EOF
0205    for end of file.
0206    IN assertion: the stream s has been sucessfully opened for reading.
0207 */
0208 
0209 
0210 local int unz64local_getByte OF((
0211     const zlib_filefunc64_32_def* pzlib_filefunc_def,
0212     voidpf filestream,
0213     int *pi));
0214 
0215 local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
0216 {
0217     unsigned char c;
0218     int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
0219     if (err==1)
0220     {
0221         *pi = (int)c;
0222         return UNZ_OK;
0223     }
0224     else
0225     {
0226         if (ZERROR64(*pzlib_filefunc_def,filestream))
0227             return UNZ_ERRNO;
0228         else
0229             return UNZ_EOF;
0230     }
0231 }
0232 
0233 
0234 /* ===========================================================================
0235    Reads a long in LSB order from the given gz_stream. Sets
0236 */
0237 local int unz64local_getShort OF((
0238     const zlib_filefunc64_32_def* pzlib_filefunc_def,
0239     voidpf filestream,
0240     uLong *pX));
0241 
0242 local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
0243                              voidpf filestream,
0244                              uLong *pX)
0245 {
0246     uLong x ;
0247     int i = 0;
0248     int err;
0249 
0250     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0251     x = (uLong)i;
0252 
0253     if (err==UNZ_OK)
0254         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0255     x |= ((uLong)i)<<8;
0256 
0257     if (err==UNZ_OK)
0258         *pX = x;
0259     else
0260         *pX = 0;
0261     return err;
0262 }
0263 
0264 local int unz64local_getLong OF((
0265     const zlib_filefunc64_32_def* pzlib_filefunc_def,
0266     voidpf filestream,
0267     uLong *pX));
0268 
0269 local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
0270                             voidpf filestream,
0271                             uLong *pX)
0272 {
0273     uLong x ;
0274     int i = 0;
0275     int err;
0276 
0277     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0278     x = (uLong)i;
0279 
0280     if (err==UNZ_OK)
0281         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0282     x |= ((uLong)i)<<8;
0283 
0284     if (err==UNZ_OK)
0285         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0286     x |= ((uLong)i)<<16;
0287 
0288     if (err==UNZ_OK)
0289         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0290     x += ((uLong)i)<<24;
0291 
0292     if (err==UNZ_OK)
0293         *pX = x;
0294     else
0295         *pX = 0;
0296     return err;
0297 }
0298 
0299 local int unz64local_getLong64 OF((
0300     const zlib_filefunc64_32_def* pzlib_filefunc_def,
0301     voidpf filestream,
0302     ZPOS64_T *pX));
0303 
0304 
0305 local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
0306                             voidpf filestream,
0307                             ZPOS64_T *pX)
0308 {
0309     ZPOS64_T x ;
0310     int i = 0;
0311     int err;
0312 
0313     err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0314     x = (ZPOS64_T)i;
0315 
0316     if (err==UNZ_OK)
0317         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0318     x |= ((ZPOS64_T)i)<<8;
0319 
0320     if (err==UNZ_OK)
0321         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0322     x |= ((ZPOS64_T)i)<<16;
0323 
0324     if (err==UNZ_OK)
0325         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0326     x |= ((ZPOS64_T)i)<<24;
0327 
0328     if (err==UNZ_OK)
0329         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0330     x |= ((ZPOS64_T)i)<<32;
0331 
0332     if (err==UNZ_OK)
0333         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0334     x |= ((ZPOS64_T)i)<<40;
0335 
0336     if (err==UNZ_OK)
0337         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0338     x |= ((ZPOS64_T)i)<<48;
0339 
0340     if (err==UNZ_OK)
0341         err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
0342     x |= ((ZPOS64_T)i)<<56;
0343 
0344     if (err==UNZ_OK)
0345         *pX = x;
0346     else
0347         *pX = 0;
0348     return err;
0349 }
0350 
0351 /* My own strcmpi / strcasecmp */
0352 local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
0353 {
0354     for (;;)
0355     {
0356         char c1=*(fileName1++);
0357         char c2=*(fileName2++);
0358         if ((c1>='a') && (c1<='z'))
0359             c1 -= 0x20;
0360         if ((c2>='a') && (c2<='z'))
0361             c2 -= 0x20;
0362         if (c1=='\0')
0363             return ((c2=='\0') ? 0 : -1);
0364         if (c2=='\0')
0365             return 1;
0366         if (c1<c2)
0367             return -1;
0368         if (c1>c2)
0369             return 1;
0370     }
0371 }
0372 
0373 
0374 #ifdef  CASESENSITIVITYDEFAULT_NO
0375 #define CASESENSITIVITYDEFAULTVALUE 2
0376 #else
0377 #define CASESENSITIVITYDEFAULTVALUE 1
0378 #endif
0379 
0380 #ifndef STRCMPCASENOSENTIVEFUNCTION
0381 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
0382 #endif
0383 
0384 /*
0385    Compare two filename (fileName1,fileName2).
0386    If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
0387    If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
0388                                                                 or strcasecmp)
0389    If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
0390         (like 1 on Unix, 2 on Windows)
0391 
0392 */
0393 extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
0394                                                  const char*  fileName2,
0395                                                  int iCaseSensitivity)
0396 
0397 {
0398     if (iCaseSensitivity==0)
0399         iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
0400 
0401     if (iCaseSensitivity==1)
0402         return strcmp(fileName1,fileName2);
0403 
0404     return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
0405 }
0406 
0407 #ifndef BUFREADCOMMENT
0408 #define BUFREADCOMMENT (0x400)
0409 #endif
0410 
0411 /*
0412   Locate the Central directory of a zipfile (at the end, just before
0413     the global comment)
0414 */
0415 local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
0416 local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
0417 {
0418     unsigned char* buf;
0419     ZPOS64_T uSizeFile;
0420     ZPOS64_T uBackRead;
0421     ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
0422     ZPOS64_T uPosFound=0;
0423 
0424     if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
0425         return 0;
0426 
0427 
0428     uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
0429 
0430     if (uMaxBack>uSizeFile)
0431         uMaxBack = uSizeFile;
0432 
0433     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
0434     if (buf==NULL)
0435         return 0;
0436 
0437     uBackRead = 4;
0438     while (uBackRead<uMaxBack)
0439     {
0440         uLong uReadSize;
0441         ZPOS64_T uReadPos ;
0442         int i;
0443         if (uBackRead+BUFREADCOMMENT>uMaxBack)
0444             uBackRead = uMaxBack;
0445         else
0446             uBackRead+=BUFREADCOMMENT;
0447         uReadPos = uSizeFile-uBackRead ;
0448 
0449         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
0450                      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
0451         if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
0452             break;
0453 
0454         if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
0455             break;
0456 
0457         for (i=(int)uReadSize-3; (i--)>0;)
0458             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
0459                 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
0460             {
0461                 uPosFound = uReadPos+i;
0462                 break;
0463             }
0464 
0465         if (uPosFound!=0)
0466             break;
0467     }
0468     TRYFREE(buf);
0469     return uPosFound;
0470 }
0471 
0472 
0473 /*
0474   Locate the Central directory 64 of a zipfile (at the end, just before
0475     the global comment)
0476 */
0477 local ZPOS64_T unz64local_SearchCentralDir64 OF((
0478     const zlib_filefunc64_32_def* pzlib_filefunc_def,
0479     voidpf filestream));
0480 
0481 local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
0482                                       voidpf filestream)
0483 {
0484     unsigned char* buf;
0485     ZPOS64_T uSizeFile;
0486     ZPOS64_T uBackRead;
0487     ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
0488     ZPOS64_T uPosFound=0;
0489     uLong uL;
0490                 ZPOS64_T relativeOffset;
0491 
0492     if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
0493         return 0;
0494 
0495 
0496     uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
0497 
0498     if (uMaxBack>uSizeFile)
0499         uMaxBack = uSizeFile;
0500 
0501     buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
0502     if (buf==NULL)
0503         return 0;
0504 
0505     uBackRead = 4;
0506     while (uBackRead<uMaxBack)
0507     {
0508         uLong uReadSize;
0509         ZPOS64_T uReadPos;
0510         int i;
0511         if (uBackRead+BUFREADCOMMENT>uMaxBack)
0512             uBackRead = uMaxBack;
0513         else
0514             uBackRead+=BUFREADCOMMENT;
0515         uReadPos = uSizeFile-uBackRead ;
0516 
0517         uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
0518                      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
0519         if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
0520             break;
0521 
0522         if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
0523             break;
0524 
0525         for (i=(int)uReadSize-3; (i--)>0;)
0526             if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
0527                 ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
0528             {
0529                 uPosFound = uReadPos+i;
0530                 break;
0531             }
0532 
0533         if (uPosFound!=0)
0534             break;
0535     }
0536     TRYFREE(buf);
0537     if (uPosFound == 0)
0538         return 0;
0539 
0540     /* Zip64 end of central directory locator */
0541     if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
0542         return 0;
0543 
0544     /* the signature, already checked */
0545     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
0546         return 0;
0547 
0548     /* number of the disk with the start of the zip64 end of  central directory */
0549     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
0550         return 0;
0551     if (uL != 0)
0552         return 0;
0553 
0554     /* relative offset of the zip64 end of central directory record */
0555     if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
0556         return 0;
0557 
0558     /* total number of disks */
0559     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
0560         return 0;
0561     if (uL != 1)
0562         return 0;
0563 
0564     /* Goto end of central directory record */
0565     if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
0566         return 0;
0567 
0568      /* the signature */
0569     if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
0570         return 0;
0571 
0572     if (uL != 0x06064b50)
0573         return 0;
0574 
0575     return relativeOffset;
0576 }
0577 
0578 /*
0579   Open a Zip file. path contain the full pathname (by example,
0580      on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
0581      "zlib/zlib114.zip".
0582      If the zipfile cannot be opened (file doesn't exist or in not valid), the
0583        return value is NULL.
0584      Else, the return value is a unzFile Handle, usable with other function
0585        of this unzip package.
0586 */
0587 extern unzFile unzOpenInternal (voidpf file,
0588                                zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
0589                                int is64bitOpenFunction, unsigned flags)
0590 {
0591     unz64_s us;
0592     unz64_s *s;
0593     ZPOS64_T central_pos;
0594     uLong   uL;
0595 
0596     uLong number_disk;          /* number of the current dist, used for
0597                                    spaning ZIP, unsupported, always 0*/
0598     uLong number_disk_with_CD;  /* number the the disk with central dir, used
0599                                    for spaning ZIP, unsupported, always 0*/
0600     ZPOS64_T number_entry_CD;      /* total number of entries in
0601                                    the central dir
0602                                    (same than number_entry on nospan) */
0603 
0604     int err=UNZ_OK;
0605 
0606     if (unz_copyright[0]!=' ')
0607         return NULL;
0608 
0609     us.flags = flags;
0610     us.z_filefunc.zseek32_file = NULL;
0611     us.z_filefunc.ztell32_file = NULL;
0612     if (pzlib_filefunc64_32_def==NULL)
0613         fill_qiodevice64_filefunc(&us.z_filefunc.zfile_func64);
0614     else
0615         us.z_filefunc = *pzlib_filefunc64_32_def;
0616     us.is64bitOpenFunction = is64bitOpenFunction;
0617 
0618 
0619 
0620     us.filestream = ZOPEN64(us.z_filefunc,
0621                                                  file,
0622                                                  ZLIB_FILEFUNC_MODE_READ |
0623                                                  ZLIB_FILEFUNC_MODE_EXISTING);
0624     if (us.filestream==NULL)
0625         return NULL;
0626 
0627     central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
0628     if (central_pos)
0629     {
0630         uLong uS;
0631         ZPOS64_T uL64;
0632 
0633         us.isZip64 = 1;
0634 
0635         if (ZSEEK64(us.z_filefunc, us.filestream,
0636                                       central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
0637         err=UNZ_ERRNO;
0638 
0639         /* the signature, already checked */
0640         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
0641             err=UNZ_ERRNO;
0642 
0643         /* size of zip64 end of central directory record */
0644         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
0645             err=UNZ_ERRNO;
0646 
0647         /* version made by */
0648         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
0649             err=UNZ_ERRNO;
0650 
0651         /* version needed to extract */
0652         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
0653             err=UNZ_ERRNO;
0654 
0655         /* number of this disk */
0656         if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
0657             err=UNZ_ERRNO;
0658 
0659         /* number of the disk with the start of the central directory */
0660         if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
0661             err=UNZ_ERRNO;
0662 
0663         /* total number of entries in the central directory on this disk */
0664         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
0665             err=UNZ_ERRNO;
0666 
0667         /* total number of entries in the central directory */
0668         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
0669             err=UNZ_ERRNO;
0670 
0671         if ((number_entry_CD!=us.gi.number_entry) ||
0672             (number_disk_with_CD!=0) ||
0673             (number_disk!=0))
0674             err=UNZ_BADZIPFILE;
0675 
0676         /* size of the central directory */
0677         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
0678             err=UNZ_ERRNO;
0679 
0680         /* offset of start of central directory with respect to the
0681           starting disk number */
0682         if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
0683             err=UNZ_ERRNO;
0684 
0685         us.gi.size_comment = 0;
0686     }
0687     else
0688     {
0689         central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
0690         if (central_pos==0)
0691             err=UNZ_ERRNO;
0692 
0693         us.isZip64 = 0;
0694 
0695         if (ZSEEK64(us.z_filefunc, us.filestream,
0696                                         central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
0697             err=UNZ_ERRNO;
0698 
0699         /* the signature, already checked */
0700         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
0701             err=UNZ_ERRNO;
0702 
0703         /* number of this disk */
0704         if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
0705             err=UNZ_ERRNO;
0706 
0707         /* number of the disk with the start of the central directory */
0708         if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
0709             err=UNZ_ERRNO;
0710 
0711         /* total number of entries in the central dir on this disk */
0712         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
0713             err=UNZ_ERRNO;
0714         us.gi.number_entry = uL;
0715 
0716         /* total number of entries in the central dir */
0717         if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
0718             err=UNZ_ERRNO;
0719         number_entry_CD = uL;
0720 
0721         if ((number_entry_CD!=us.gi.number_entry) ||
0722             (number_disk_with_CD!=0) ||
0723             (number_disk!=0))
0724             err=UNZ_BADZIPFILE;
0725 
0726         /* size of the central directory */
0727         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
0728             err=UNZ_ERRNO;
0729         us.size_central_dir = uL;
0730 
0731         /* offset of start of central directory with respect to the
0732             starting disk number */
0733         if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
0734             err=UNZ_ERRNO;
0735         us.offset_central_dir = uL;
0736 
0737         /* zipfile comment length */
0738         if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
0739             err=UNZ_ERRNO;
0740     }
0741 
0742     if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
0743         (err==UNZ_OK))
0744         err=UNZ_BADZIPFILE;
0745 
0746     if (err!=UNZ_OK)
0747     {
0748         if ((us.flags & UNZ_AUTO_CLOSE) != 0)
0749             ZCLOSE64(us.z_filefunc, us.filestream);
0750         else
0751             ZFAKECLOSE64(us.z_filefunc, us.filestream);
0752         return NULL;
0753     }
0754 
0755     us.byte_before_the_zipfile = central_pos -
0756                             (us.offset_central_dir+us.size_central_dir);
0757     us.central_pos = central_pos;
0758     us.pfile_in_zip_read = NULL;
0759     us.encrypted = 0;
0760 
0761 
0762     s=(unz64_s*)ALLOC(sizeof(unz64_s));
0763     if( s != NULL)
0764     {
0765         *s=us;
0766         unzGoToFirstFile((unzFile)s);
0767     }
0768     return (unzFile)s;
0769 }
0770 
0771 
0772 extern unzFile ZEXPORT unzOpen2 (voidpf file,
0773                                         zlib_filefunc_def* pzlib_filefunc32_def)
0774 {
0775     if (pzlib_filefunc32_def != NULL)
0776     {
0777         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
0778         fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
0779         return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 0, UNZ_DEFAULT_FLAGS);
0780     }
0781     else
0782         return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS);
0783 }
0784 
0785 extern unzFile ZEXPORT unzOpen2_64 (voidpf file,
0786                                      zlib_filefunc64_def* pzlib_filefunc_def)
0787 {
0788     if (pzlib_filefunc_def != NULL)
0789     {
0790         zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
0791         zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
0792         zlib_filefunc64_32_def_fill.ztell32_file = NULL;
0793         zlib_filefunc64_32_def_fill.zseek32_file = NULL;
0794         return unzOpenInternal(file, &zlib_filefunc64_32_def_fill, 1, UNZ_DEFAULT_FLAGS);
0795     }
0796     else
0797         return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS);
0798 }
0799 
0800 extern unzFile ZEXPORT unzOpen (voidpf file)
0801 {
0802     return unzOpenInternal(file, NULL, 0, UNZ_DEFAULT_FLAGS);
0803 }
0804 
0805 extern unzFile ZEXPORT unzOpen64 (voidpf file)
0806 {
0807     return unzOpenInternal(file, NULL, 1, UNZ_DEFAULT_FLAGS);
0808 }
0809 
0810 /*
0811   Close a ZipFile opened with unzipOpen.
0812   If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
0813     these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
0814   return UNZ_OK if there is no problem. */
0815 extern int ZEXPORT unzClose (unzFile file)
0816 {
0817     unz64_s* s;
0818     if (file==NULL)
0819         return UNZ_PARAMERROR;
0820     s=(unz64_s*)file;
0821 
0822     if (s->pfile_in_zip_read!=NULL)
0823         unzCloseCurrentFile(file);
0824 
0825     if ((s->flags & UNZ_AUTO_CLOSE) != 0)
0826         ZCLOSE64(s->z_filefunc, s->filestream);
0827     else
0828         ZFAKECLOSE64(s->z_filefunc, s->filestream);
0829     TRYFREE(s);
0830     return UNZ_OK;
0831 }
0832 
0833 
0834 /*
0835   Write info about the ZipFile in the *pglobal_info structure.
0836   No preparation of the structure is needed
0837   return UNZ_OK if there is no problem. */
0838 extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
0839 {
0840     unz64_s* s;
0841     if (file==NULL)
0842         return UNZ_PARAMERROR;
0843     s=(unz64_s*)file;
0844     *pglobal_info=s->gi;
0845     return UNZ_OK;
0846 }
0847 
0848 extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
0849 {
0850     unz64_s* s;
0851     if (file==NULL)
0852         return UNZ_PARAMERROR;
0853     s=(unz64_s*)file;
0854     /* to do : check if number_entry is not truncated */
0855     pglobal_info32->number_entry = (uLong)s->gi.number_entry;
0856     pglobal_info32->size_comment = s->gi.size_comment;
0857     return UNZ_OK;
0858 }
0859 /*
0860    Translate date/time from Dos format to tm_unz (readable more easilty)
0861 */
0862 local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
0863 {
0864     ZPOS64_T uDate;
0865     uDate = (ZPOS64_T)(ulDosDate>>16);
0866     ptm->tm_mday = (uInt)(uDate&0x1f) ;
0867     ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
0868     ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
0869 
0870     ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
0871     ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
0872     ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
0873 }
0874 
0875 /*
0876   Get Info about the current file in the zipfile, with internal only info
0877 */
0878 local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
0879                                                   unz_file_info64 *pfile_info,
0880                                                   unz_file_info64_internal
0881                                                   *pfile_info_internal,
0882                                                   char *szFileName,
0883                                                   uLong fileNameBufferSize,
0884                                                   void *extraField,
0885                                                   uLong extraFieldBufferSize,
0886                                                   char *szComment,
0887                                                   uLong commentBufferSize));
0888 
0889 local int unz64local_GetCurrentFileInfoInternal (unzFile file,
0890                                                   unz_file_info64 *pfile_info,
0891                                                   unz_file_info64_internal
0892                                                   *pfile_info_internal,
0893                                                   char *szFileName,
0894                                                   uLong fileNameBufferSize,
0895                                                   void *extraField,
0896                                                   uLong extraFieldBufferSize,
0897                                                   char *szComment,
0898                                                   uLong commentBufferSize)
0899 {
0900     unz64_s* s;
0901     unz_file_info64 file_info;
0902     unz_file_info64_internal file_info_internal;
0903     int err=UNZ_OK;
0904     uLong uMagic;
0905     ZPOS64_T llSeek=0;
0906     uLong uL;
0907 
0908     if (file==NULL)
0909         return UNZ_PARAMERROR;
0910     s=(unz64_s*)file;
0911     if (ZSEEK64(s->z_filefunc, s->filestream,
0912               s->pos_in_central_dir+s->byte_before_the_zipfile,
0913               ZLIB_FILEFUNC_SEEK_SET)!=0)
0914         err=UNZ_ERRNO;
0915 
0916 
0917     /* we check the magic */
0918     if (err==UNZ_OK)
0919     {
0920         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
0921             err=UNZ_ERRNO;
0922         else if (uMagic!=0x02014b50)
0923             err=UNZ_BADZIPFILE;
0924     }
0925 
0926     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
0927         err=UNZ_ERRNO;
0928 
0929     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
0930         err=UNZ_ERRNO;
0931 
0932     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
0933         err=UNZ_ERRNO;
0934 
0935     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
0936         err=UNZ_ERRNO;
0937 
0938     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
0939         err=UNZ_ERRNO;
0940 
0941     unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
0942 
0943     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
0944         err=UNZ_ERRNO;
0945 
0946     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
0947         err=UNZ_ERRNO;
0948     file_info.compressed_size = uL;
0949 
0950     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
0951         err=UNZ_ERRNO;
0952     file_info.uncompressed_size = uL;
0953 
0954     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
0955         err=UNZ_ERRNO;
0956 
0957     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
0958         err=UNZ_ERRNO;
0959 
0960     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
0961         err=UNZ_ERRNO;
0962 
0963     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
0964         err=UNZ_ERRNO;
0965 
0966     if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
0967         err=UNZ_ERRNO;
0968 
0969     if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
0970         err=UNZ_ERRNO;
0971 
0972                 /* relative offset of local header */
0973     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
0974         err=UNZ_ERRNO;
0975     file_info_internal.offset_curfile = uL;
0976 
0977     llSeek+=file_info.size_filename;
0978     if ((err==UNZ_OK) && (szFileName!=NULL))
0979     {
0980         uLong uSizeRead ;
0981         if (file_info.size_filename<fileNameBufferSize)
0982         {
0983             *(szFileName+file_info.size_filename)='\0';
0984             uSizeRead = file_info.size_filename;
0985         }
0986         else
0987             uSizeRead = fileNameBufferSize;
0988 
0989         if ((file_info.size_filename>0) && (fileNameBufferSize>0))
0990             if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
0991                 err=UNZ_ERRNO;
0992         llSeek -= uSizeRead;
0993     }
0994 
0995     /* Read extrafield */
0996     if ((err==UNZ_OK) && (extraField!=NULL))
0997     {
0998         ZPOS64_T uSizeRead ;
0999         if (file_info.size_file_extra<extraFieldBufferSize)
1000             uSizeRead = file_info.size_file_extra;
1001         else
1002             uSizeRead = extraFieldBufferSize;
1003 
1004         if (llSeek!=0)
1005         {
1006             if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1007                 llSeek=0;
1008             else
1009                 err=UNZ_ERRNO;
1010         }
1011 
1012         if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
1013             if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
1014                 err=UNZ_ERRNO;
1015 
1016         llSeek += file_info.size_file_extra - (uLong)uSizeRead;
1017     }
1018     else
1019         llSeek += file_info.size_file_extra;
1020 
1021 
1022     if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
1023     {
1024                                 uLong acc = 0;
1025 
1026         /* since lSeek now points to after the extra field we need to move back */
1027         llSeek -= file_info.size_file_extra;
1028 
1029         if (llSeek!=0)
1030         {
1031             if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1032                 llSeek=0;
1033             else
1034                 err=UNZ_ERRNO;
1035         }
1036 
1037         while(acc < file_info.size_file_extra)
1038         {
1039             uLong headerId;
1040                                                 uLong dataSize;
1041 
1042             if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
1043                 err=UNZ_ERRNO;
1044 
1045             if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
1046                 err=UNZ_ERRNO;
1047 
1048             /* ZIP64 extra fields */
1049             if (headerId == 0x0001)
1050             {
1051                 uLong uL;
1052 
1053                 if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu)
1054                 {
1055                     if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
1056                         err=UNZ_ERRNO;
1057                 }
1058 
1059                 if(file_info.compressed_size == (ZPOS64_T)0xFFFFFFFFu)
1060                 {
1061                     if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
1062                         err=UNZ_ERRNO;
1063                 }
1064 
1065                 if(file_info_internal.offset_curfile == (ZPOS64_T)0xFFFFFFFFu)
1066                 {
1067                     /* Relative Header offset */
1068                     if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
1069                         err=UNZ_ERRNO;
1070                 }
1071 
1072                 if(file_info.disk_num_start == 0xFFFFFFFFu)
1073                 {
1074                     /* Disk Start Number */
1075                     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
1076                         err=UNZ_ERRNO;
1077                 }
1078 
1079             }
1080             else
1081             {
1082                 if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
1083                     err=UNZ_ERRNO;
1084             }
1085 
1086             acc += 2 + 2 + dataSize;
1087         }
1088     }
1089 
1090     if ((err==UNZ_OK) && (szComment!=NULL))
1091     {
1092         uLong uSizeRead ;
1093         if (file_info.size_file_comment<commentBufferSize)
1094         {
1095             *(szComment+file_info.size_file_comment)='\0';
1096             uSizeRead = file_info.size_file_comment;
1097         }
1098         else
1099             uSizeRead = commentBufferSize;
1100 
1101         if (llSeek!=0)
1102         {
1103             if (ZSEEK64(s->z_filefunc, s->filestream,llSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
1104                 llSeek=0;
1105             else
1106                 err=UNZ_ERRNO;
1107         }
1108 
1109         if ((file_info.size_file_comment>0) && (commentBufferSize>0))
1110             if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
1111                 err=UNZ_ERRNO;
1112         llSeek+=file_info.size_file_comment - uSizeRead;
1113     }
1114     else
1115         llSeek+=file_info.size_file_comment;
1116 
1117 
1118     if ((err==UNZ_OK) && (pfile_info!=NULL))
1119         *pfile_info=file_info;
1120 
1121     if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
1122         *pfile_info_internal=file_info_internal;
1123 
1124     return err;
1125 }
1126 
1127 
1128 
1129 /*
1130   Write info about the ZipFile in the *pglobal_info structure.
1131   No preparation of the structure is needed
1132   return UNZ_OK if there is no problem.
1133 */
1134 extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
1135                                           unz_file_info64 * pfile_info,
1136                                           char * szFileName, uLong fileNameBufferSize,
1137                                           void *extraField, uLong extraFieldBufferSize,
1138                                           char* szComment,  uLong commentBufferSize)
1139 {
1140     return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
1141                                                 szFileName,fileNameBufferSize,
1142                                                 extraField,extraFieldBufferSize,
1143                                                 szComment,commentBufferSize);
1144 }
1145 
1146 extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
1147                                           unz_file_info * pfile_info,
1148                                           char * szFileName, uLong fileNameBufferSize,
1149                                           void *extraField, uLong extraFieldBufferSize,
1150                                           char* szComment,  uLong commentBufferSize)
1151 {
1152     int err;
1153     unz_file_info64 file_info64;
1154     err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
1155                                                 szFileName,fileNameBufferSize,
1156                                                 extraField,extraFieldBufferSize,
1157                                                 szComment,commentBufferSize);
1158     if (err==UNZ_OK && pfile_info != NULL)
1159     {
1160         pfile_info->version = file_info64.version;
1161         pfile_info->version_needed = file_info64.version_needed;
1162         pfile_info->flag = file_info64.flag;
1163         pfile_info->compression_method = file_info64.compression_method;
1164         pfile_info->dosDate = file_info64.dosDate;
1165         pfile_info->crc = file_info64.crc;
1166 
1167         pfile_info->size_filename = file_info64.size_filename;
1168         pfile_info->size_file_extra = file_info64.size_file_extra;
1169         pfile_info->size_file_comment = file_info64.size_file_comment;
1170 
1171         pfile_info->disk_num_start = file_info64.disk_num_start;
1172         pfile_info->internal_fa = file_info64.internal_fa;
1173         pfile_info->external_fa = file_info64.external_fa;
1174 
1175         pfile_info->tmu_date = file_info64.tmu_date,
1176 
1177 
1178         pfile_info->compressed_size = (uLong)file_info64.compressed_size;
1179         pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
1180 
1181     }
1182     return err;
1183 }
1184 /*
1185   Set the current file of the zipfile to the first file.
1186   return UNZ_OK if there is no problem
1187 */
1188 extern int ZEXPORT unzGoToFirstFile (unzFile file)
1189 {
1190     int err=UNZ_OK;
1191     unz64_s* s;
1192     if (file==NULL)
1193         return UNZ_PARAMERROR;
1194     s=(unz64_s*)file;
1195     s->pos_in_central_dir=s->offset_central_dir;
1196     s->num_file=0;
1197     err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1198                                              &s->cur_file_info_internal,
1199                                              NULL,0,NULL,0,NULL,0);
1200     s->current_file_ok = (err == UNZ_OK);
1201     return err;
1202 }
1203 
1204 /*
1205   Set the current file of the zipfile to the next file.
1206   return UNZ_OK if there is no problem
1207   return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
1208 */
1209 extern int ZEXPORT unzGoToNextFile (unzFile  file)
1210 {
1211     unz64_s* s;
1212     int err;
1213 
1214     if (file==NULL)
1215         return UNZ_PARAMERROR;
1216     s=(unz64_s*)file;
1217     if (!s->current_file_ok)
1218         return UNZ_END_OF_LIST_OF_FILE;
1219     if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
1220       if (s->num_file+1==s->gi.number_entry)
1221         return UNZ_END_OF_LIST_OF_FILE;
1222 
1223     s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
1224             s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
1225     s->num_file++;
1226     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1227                                                &s->cur_file_info_internal,
1228                                                NULL,0,NULL,0,NULL,0);
1229     s->current_file_ok = (err == UNZ_OK);
1230     return err;
1231 }
1232 
1233 
1234 /*
1235   Try locate the file szFileName in the zipfile.
1236   For the iCaseSensitivity signification, see unzipStringFileNameCompare
1237 
1238   return value :
1239   UNZ_OK if the file is found. It becomes the current file.
1240   UNZ_END_OF_LIST_OF_FILE if the file is not found
1241 */
1242 extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
1243 {
1244     unz64_s* s;
1245     int err;
1246 
1247     /* We remember the 'current' position in the file so that we can jump
1248      * back there if we fail.
1249      */
1250     unz_file_info64 cur_file_infoSaved;
1251     unz_file_info64_internal cur_file_info_internalSaved;
1252     ZPOS64_T num_fileSaved;
1253     ZPOS64_T pos_in_central_dirSaved;
1254 
1255 
1256     if (file==NULL)
1257         return UNZ_PARAMERROR;
1258 
1259     if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
1260         return UNZ_PARAMERROR;
1261 
1262     s=(unz64_s*)file;
1263     if (!s->current_file_ok)
1264         return UNZ_END_OF_LIST_OF_FILE;
1265 
1266     /* Save the current state */
1267     num_fileSaved = s->num_file;
1268     pos_in_central_dirSaved = s->pos_in_central_dir;
1269     cur_file_infoSaved = s->cur_file_info;
1270     cur_file_info_internalSaved = s->cur_file_info_internal;
1271 
1272     err = unzGoToFirstFile(file);
1273 
1274     while (err == UNZ_OK)
1275     {
1276         char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
1277         err = unzGetCurrentFileInfo64(file,NULL,
1278                                     szCurrentFileName,sizeof(szCurrentFileName)-1,
1279                                     NULL,0,NULL,0);
1280         if (err == UNZ_OK)
1281         {
1282             if (unzStringFileNameCompare(szCurrentFileName,
1283                                             szFileName,iCaseSensitivity)==0)
1284                 return UNZ_OK;
1285             err = unzGoToNextFile(file);
1286         }
1287     }
1288 
1289     /* We failed, so restore the state of the 'current file' to where we
1290      * were.
1291      */
1292     s->num_file = num_fileSaved ;
1293     s->pos_in_central_dir = pos_in_central_dirSaved ;
1294     s->cur_file_info = cur_file_infoSaved;
1295     s->cur_file_info_internal = cur_file_info_internalSaved;
1296     return err;
1297 }
1298 
1299 
1300 /*
1301 ///////////////////////////////////////////
1302 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
1303 // I need random access
1304 //
1305 // Further optimization could be realized by adding an ability
1306 // to cache the directory in memory. The goal being a single
1307 // comprehensive file read to put the file I need in a memory.
1308 */
1309 
1310 /*
1311 typedef struct unz_file_pos_s
1312 {
1313     ZPOS64_T pos_in_zip_directory;   // offset in file
1314     ZPOS64_T num_of_file;            // # of file
1315 } unz_file_pos;
1316 */
1317 
1318 extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
1319 {
1320     unz64_s* s;
1321 
1322     if (file==NULL || file_pos==NULL)
1323         return UNZ_PARAMERROR;
1324     s=(unz64_s*)file;
1325     if (!s->current_file_ok)
1326         return UNZ_END_OF_LIST_OF_FILE;
1327 
1328     file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
1329     file_pos->num_of_file           = s->num_file;
1330 
1331     return UNZ_OK;
1332 }
1333 
1334 extern int ZEXPORT unzGetFilePos(
1335     unzFile file,
1336     unz_file_pos* file_pos)
1337 {
1338     unz64_file_pos file_pos64;
1339     int err = unzGetFilePos64(file,&file_pos64);
1340     if (err==UNZ_OK)
1341     {
1342         file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
1343         file_pos->num_of_file = (uLong)file_pos64.num_of_file;
1344     }
1345     return err;
1346 }
1347 
1348 extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
1349 {
1350     unz64_s* s;
1351     int err;
1352 
1353     if (file==NULL || file_pos==NULL)
1354         return UNZ_PARAMERROR;
1355     s=(unz64_s*)file;
1356 
1357     /* jump to the right spot */
1358     s->pos_in_central_dir = file_pos->pos_in_zip_directory;
1359     s->num_file           = file_pos->num_of_file;
1360 
1361     /* set the current file */
1362     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
1363                                                &s->cur_file_info_internal,
1364                                                NULL,0,NULL,0,NULL,0);
1365     /* return results */
1366     s->current_file_ok = (err == UNZ_OK);
1367     return err;
1368 }
1369 
1370 extern int ZEXPORT unzGoToFilePos(
1371     unzFile file,
1372     unz_file_pos* file_pos)
1373 {
1374     unz64_file_pos file_pos64;
1375     if (file_pos == NULL)
1376         return UNZ_PARAMERROR;
1377 
1378     file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
1379     file_pos64.num_of_file = file_pos->num_of_file;
1380     return unzGoToFilePos64(file,&file_pos64);
1381 }
1382 
1383 /* Unzip Helper Functions - should be here? */
1384 /*///////////////////////////////////////// */
1385 
1386 /*
1387   Read the local header of the current zipfile
1388   Check the coherency of the local header and info in the end of central
1389         directory about this file
1390   store in *piSizeVar the size of extra info in local header
1391         (filename and size of extra field data)
1392 */
1393 local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
1394                                                     ZPOS64_T * poffset_local_extrafield,
1395                                                     uInt  * psize_local_extrafield)
1396 {
1397     uLong uMagic,uData,uFlags;
1398     uLong size_filename;
1399     uLong size_extra_field;
1400     int err=UNZ_OK;
1401 
1402     *piSizeVar = 0;
1403     *poffset_local_extrafield = 0;
1404     *psize_local_extrafield = 0;
1405 
1406     if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
1407                                 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
1408         return UNZ_ERRNO;
1409 
1410 
1411     if (err==UNZ_OK)
1412     {
1413         if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
1414             err=UNZ_ERRNO;
1415         else if (uMagic!=0x04034b50)
1416             err=UNZ_BADZIPFILE;
1417     }
1418 
1419     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1420         err=UNZ_ERRNO;
1421 /*
1422     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
1423         err=UNZ_BADZIPFILE;
1424 */
1425     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
1426         err=UNZ_ERRNO;
1427 
1428     if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
1429         err=UNZ_ERRNO;
1430     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
1431         err=UNZ_BADZIPFILE;
1432 
1433     if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
1434 /* #ifdef HAVE_BZIP2 */
1435                          (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1436 /* #endif */
1437                          (s->cur_file_info.compression_method!=Z_DEFLATED))
1438         err=UNZ_BADZIPFILE;
1439 
1440     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1441         err=UNZ_ERRNO;
1442 
1443     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1444         err=UNZ_ERRNO;
1445     else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
1446         err=UNZ_BADZIPFILE;
1447 
1448     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1449         err=UNZ_ERRNO;
1450     else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
1451         err=UNZ_BADZIPFILE;
1452 
1453     if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1454         err=UNZ_ERRNO;
1455     else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
1456         err=UNZ_BADZIPFILE;
1457 
1458     if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1459         err=UNZ_ERRNO;
1460     else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1461         err=UNZ_BADZIPFILE;
1462 
1463     *piSizeVar += (uInt)size_filename;
1464 
1465     if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1466         err=UNZ_ERRNO;
1467     *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1468                                     SIZEZIPLOCALHEADER + size_filename;
1469     *psize_local_extrafield = (uInt)size_extra_field;
1470 
1471     *piSizeVar += (uInt)size_extra_field;
1472 
1473     return err;
1474 }
1475 
1476 /*
1477   Open for reading data the current file in the zipfile.
1478   If there is no error and the file is opened, the return value is UNZ_OK.
1479 */
1480 extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
1481                                             int* level, int raw, const char* password)
1482 {
1483     int err=UNZ_OK;
1484     uInt iSizeVar;
1485     unz64_s* s;
1486     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1487     ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
1488     uInt  size_local_extrafield;    /* size of the local extra field */
1489 #    ifndef NOUNCRYPT
1490     char source[12];
1491 #    else
1492     if (password != NULL)
1493         return UNZ_PARAMERROR;
1494 #    endif
1495 
1496     if (file==NULL)
1497         return UNZ_PARAMERROR;
1498     s=(unz64_s*)file;
1499     if (!s->current_file_ok)
1500         return UNZ_PARAMERROR;
1501 
1502     if (s->pfile_in_zip_read != NULL)
1503         unzCloseCurrentFile(file);
1504 
1505     if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1506         return UNZ_BADZIPFILE;
1507 
1508     pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
1509     if (pfile_in_zip_read_info==NULL)
1510         return UNZ_INTERNALERROR;
1511 
1512     pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1513     pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1514     pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1515     pfile_in_zip_read_info->pos_local_extrafield=0;
1516     pfile_in_zip_read_info->raw=raw;
1517 
1518     if (pfile_in_zip_read_info->read_buffer==NULL)
1519     {
1520         TRYFREE(pfile_in_zip_read_info);
1521         return UNZ_INTERNALERROR;
1522     }
1523 
1524     pfile_in_zip_read_info->stream_initialised=0;
1525 
1526     if (method!=NULL)
1527         *method = (int)s->cur_file_info.compression_method;
1528 
1529     if (level!=NULL)
1530     {
1531         *level = 6;
1532         switch (s->cur_file_info.flag & 0x06)
1533         {
1534           case 6 : *level = 1; break;
1535           case 4 : *level = 2; break;
1536           case 2 : *level = 9; break;
1537         }
1538     }
1539 
1540     if ((s->cur_file_info.compression_method!=0) &&
1541 /* #ifdef HAVE_BZIP2 */
1542         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
1543 /* #endif */
1544         (s->cur_file_info.compression_method!=Z_DEFLATED))
1545 
1546         err=UNZ_BADZIPFILE;
1547 
1548     pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1549     pfile_in_zip_read_info->crc32=0;
1550     pfile_in_zip_read_info->total_out_64=0;
1551     pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
1552     pfile_in_zip_read_info->filestream=s->filestream;
1553     pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1554     pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1555 
1556     pfile_in_zip_read_info->stream.total_out = 0;
1557 
1558     if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
1559     {
1560 #ifdef HAVE_BZIP2
1561       pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
1562       pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
1563       pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
1564       pfile_in_zip_read_info->bstream.state = (voidpf)0;
1565 
1566       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1567       pfile_in_zip_read_info->stream.zfree = (free_func)0;
1568       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1569       pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1570       pfile_in_zip_read_info->stream.avail_in = 0;
1571 
1572       err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
1573       if (err == Z_OK)
1574         pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
1575       else
1576       {
1577         TRYFREE(pfile_in_zip_read_info);
1578         return err;
1579       }
1580 #else
1581       pfile_in_zip_read_info->raw=1;
1582 #endif
1583     }
1584     else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
1585     {
1586       pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1587       pfile_in_zip_read_info->stream.zfree = (free_func)0;
1588       pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1589       pfile_in_zip_read_info->stream.next_in = 0;
1590       pfile_in_zip_read_info->stream.avail_in = 0;
1591 
1592       err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1593       if (err == Z_OK)
1594         pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
1595       else
1596       {
1597         TRYFREE(pfile_in_zip_read_info);
1598         return err;
1599       }
1600         /* windowBits is passed < 0 to tell that there is no zlib header.
1601          * Note that in this case inflate *requires* an extra "dummy" byte
1602          * after the compressed stream in order to complete decompression and
1603          * return Z_STREAM_END.
1604          * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1605          * size of both compressed and uncompressed data
1606          */
1607     }
1608     pfile_in_zip_read_info->rest_read_compressed =
1609             s->cur_file_info.compressed_size ;
1610     pfile_in_zip_read_info->rest_read_uncompressed =
1611             s->cur_file_info.uncompressed_size ;
1612 
1613 
1614     pfile_in_zip_read_info->pos_in_zipfile =
1615             s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1616               iSizeVar;
1617 
1618     pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1619 
1620     s->pfile_in_zip_read = pfile_in_zip_read_info;
1621                 s->encrypted = 0;
1622 
1623 #    ifndef NOUNCRYPT
1624     if (password != NULL)
1625     {
1626         int i;
1627         s->pcrc_32_tab = get_crc_table();
1628         init_keys(password,s->keys,s->pcrc_32_tab);
1629         if (ZSEEK64(s->z_filefunc, s->filestream,
1630                   s->pfile_in_zip_read->pos_in_zipfile +
1631                      s->pfile_in_zip_read->byte_before_the_zipfile,
1632                   SEEK_SET)!=0)
1633             return UNZ_INTERNALERROR;
1634         if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
1635             return UNZ_INTERNALERROR;
1636 
1637         for (i = 0; i<12; i++)
1638             zdecode(s->keys,s->pcrc_32_tab,source[i]);
1639 
1640         s->pfile_in_zip_read->pos_in_zipfile+=12;
1641         s->encrypted=1;
1642     }
1643 #    endif
1644 
1645 
1646     return UNZ_OK;
1647 }
1648 
1649 extern int ZEXPORT unzOpenCurrentFile (unzFile file)
1650 {
1651     return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1652 }
1653 
1654 extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
1655 {
1656     return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1657 }
1658 
1659 extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
1660 {
1661     return unzOpenCurrentFile3(file, method, level, raw, NULL);
1662 }
1663 
1664 /** Addition for GDAL : START */
1665 
1666 extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
1667 {
1668     unz64_s* s;
1669     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1670     s=(unz64_s*)file;
1671     if (file==NULL)
1672         return 0; /*UNZ_PARAMERROR; */
1673     pfile_in_zip_read_info=s->pfile_in_zip_read;
1674     if (pfile_in_zip_read_info==NULL)
1675         return 0; /*UNZ_PARAMERROR; */
1676     return pfile_in_zip_read_info->pos_in_zipfile +
1677                          pfile_in_zip_read_info->byte_before_the_zipfile;
1678 }
1679 
1680 /** Addition for GDAL : END */
1681 
1682 /*
1683   Read bytes from the current file.
1684   buf contain buffer where data must be copied
1685   len the size of buf.
1686 
1687   return the number of byte copied if somes bytes are copied
1688   return 0 if the end of file was reached
1689   return <0 with error code if there is an error
1690     (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1691 */
1692 extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
1693 {
1694     int err=UNZ_OK;
1695     uInt iRead = 0;
1696     unz64_s* s;
1697     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1698     if (file==NULL)
1699         return UNZ_PARAMERROR;
1700     s=(unz64_s*)file;
1701     pfile_in_zip_read_info=s->pfile_in_zip_read;
1702 
1703     if (pfile_in_zip_read_info==NULL)
1704         return UNZ_PARAMERROR;
1705 
1706 
1707     if (pfile_in_zip_read_info->read_buffer == NULL)
1708         return UNZ_END_OF_LIST_OF_FILE;
1709     if (len==0)
1710         return 0;
1711 
1712     pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1713 
1714     pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1715 
1716     if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
1717         (!(pfile_in_zip_read_info->raw)))
1718         pfile_in_zip_read_info->stream.avail_out =
1719             (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1720 
1721     if ((len>pfile_in_zip_read_info->rest_read_compressed+
1722            pfile_in_zip_read_info->stream.avail_in) &&
1723          (pfile_in_zip_read_info->raw))
1724         pfile_in_zip_read_info->stream.avail_out =
1725             (uInt)pfile_in_zip_read_info->rest_read_compressed+
1726             pfile_in_zip_read_info->stream.avail_in;
1727 
1728     while (pfile_in_zip_read_info->stream.avail_out>0)
1729     {
1730         if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1731             (pfile_in_zip_read_info->rest_read_compressed>0))
1732         {
1733             uInt uReadThis = UNZ_BUFSIZE;
1734             if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1735                 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1736             if (uReadThis == 0)
1737                 return UNZ_EOF;
1738             if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1739                       pfile_in_zip_read_info->filestream,
1740                       pfile_in_zip_read_info->pos_in_zipfile +
1741                          pfile_in_zip_read_info->byte_before_the_zipfile,
1742                          ZLIB_FILEFUNC_SEEK_SET)!=0)
1743                 return UNZ_ERRNO;
1744             if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1745                       pfile_in_zip_read_info->filestream,
1746                       pfile_in_zip_read_info->read_buffer,
1747                       uReadThis)!=uReadThis)
1748                 return UNZ_ERRNO;
1749 
1750 
1751 #            ifndef NOUNCRYPT
1752             if(s->encrypted)
1753             {
1754                 uInt i;
1755                 for(i=0;i<uReadThis;i++)
1756                   pfile_in_zip_read_info->read_buffer[i] =
1757                       zdecode(s->keys,s->pcrc_32_tab,
1758                               pfile_in_zip_read_info->read_buffer[i]);
1759             }
1760 #            endif
1761 
1762 
1763             pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1764 
1765             pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1766 
1767             pfile_in_zip_read_info->stream.next_in =
1768                 (Bytef*)pfile_in_zip_read_info->read_buffer;
1769             pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1770         }
1771 
1772         if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1773         {
1774             uInt uDoCopy,i ;
1775 
1776             if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1777                 (pfile_in_zip_read_info->rest_read_compressed == 0))
1778                 return (iRead==0) ? UNZ_EOF : iRead;
1779 
1780             if (pfile_in_zip_read_info->stream.avail_out <
1781                             pfile_in_zip_read_info->stream.avail_in)
1782                 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1783             else
1784                 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1785 
1786             for (i=0;i<uDoCopy;i++)
1787                 *(pfile_in_zip_read_info->stream.next_out+i) =
1788                         *(pfile_in_zip_read_info->stream.next_in+i);
1789 
1790             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
1791 
1792             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1793                                 pfile_in_zip_read_info->stream.next_out,
1794                                 uDoCopy);
1795             pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1796             pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1797             pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1798             pfile_in_zip_read_info->stream.next_out += uDoCopy;
1799             pfile_in_zip_read_info->stream.next_in += uDoCopy;
1800             pfile_in_zip_read_info->stream.total_out += uDoCopy;
1801             iRead += uDoCopy;
1802         }
1803         else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
1804         {
1805 #ifdef HAVE_BZIP2
1806             uLong uTotalOutBefore,uTotalOutAfter;
1807             const Bytef *bufBefore;
1808             uLong uOutThis;
1809 
1810             pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
1811             pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
1812             pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
1813             pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
1814             pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
1815             pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
1816             pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
1817             pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
1818 
1819             uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
1820             bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
1821 
1822             err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
1823 
1824             uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
1825             uOutThis = uTotalOutAfter-uTotalOutBefore;
1826 
1827             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1828 
1829             pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
1830             pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1831             iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1832 
1833             pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
1834             pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
1835             pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
1836             pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
1837             pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
1838             pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
1839 
1840             if (err==BZ_STREAM_END)
1841               return (iRead==0) ? UNZ_EOF : iRead;
1842             if (err!=BZ_OK)
1843               break;
1844 #endif
1845         } /* end Z_BZIP2ED */
1846         else
1847         {
1848             uInt uAvailOutBefore,uAvailOutAfter;
1849             const Bytef *bufBefore;
1850             uInt uOutThis;
1851             int flush=Z_SYNC_FLUSH;
1852 
1853             uAvailOutBefore = pfile_in_zip_read_info->stream.avail_out;
1854             bufBefore = pfile_in_zip_read_info->stream.next_out;
1855 
1856             err=inflate(&pfile_in_zip_read_info->stream,flush);
1857 
1858             if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
1859               err = Z_DATA_ERROR;
1860 
1861             uAvailOutAfter = pfile_in_zip_read_info->stream.avail_out;
1862             uOutThis = uAvailOutBefore - uAvailOutAfter;
1863 
1864             pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
1865 
1866             pfile_in_zip_read_info->crc32
1867                     = crc32(pfile_in_zip_read_info->crc32,bufBefore, uOutThis);
1868 
1869             pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
1870 
1871             iRead += uAvailOutBefore - uAvailOutAfter;
1872 
1873             if (err==Z_STREAM_END)
1874                 return (iRead==0) ? UNZ_EOF : iRead;
1875             if (err!=Z_OK)
1876                 break;
1877         }
1878     }
1879 
1880     if (err==Z_OK)
1881         return iRead;
1882     return err;
1883 }
1884 
1885 
1886 /*
1887   Give the current position in uncompressed data
1888 */
1889 extern z_off_t ZEXPORT unztell (unzFile file)
1890 {
1891     unz64_s* s;
1892     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1893     if (file==NULL)
1894         return UNZ_PARAMERROR;
1895     s=(unz64_s*)file;
1896     pfile_in_zip_read_info=s->pfile_in_zip_read;
1897 
1898     if (pfile_in_zip_read_info==NULL)
1899         return UNZ_PARAMERROR;
1900 
1901     return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1902 }
1903 
1904 extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
1905 {
1906 
1907     unz64_s* s;
1908     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1909     if (file==NULL)
1910         return (ZPOS64_T)-1;
1911     s=(unz64_s*)file;
1912     pfile_in_zip_read_info=s->pfile_in_zip_read;
1913 
1914     if (pfile_in_zip_read_info==NULL)
1915         return (ZPOS64_T)-1;
1916 
1917     return pfile_in_zip_read_info->total_out_64;
1918 }
1919 
1920 
1921 /*
1922   return 1 if the end of file was reached, 0 elsewhere
1923 */
1924 extern int ZEXPORT unzeof (unzFile file)
1925 {
1926     unz64_s* s;
1927     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1928     if (file==NULL)
1929         return UNZ_PARAMERROR;
1930     s=(unz64_s*)file;
1931     pfile_in_zip_read_info=s->pfile_in_zip_read;
1932 
1933     if (pfile_in_zip_read_info==NULL)
1934         return UNZ_PARAMERROR;
1935 
1936     if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1937         return 1;
1938     else
1939         return 0;
1940 }
1941 
1942 
1943 
1944 /*
1945 Read extra field from the current file (opened by unzOpenCurrentFile)
1946 This is the local-header version of the extra field (sometimes, there is
1947 more info in the local-header version than in the central-header)
1948 
1949   if buf==NULL, it return the size of the local extra field that can be read
1950 
1951   if buf!=NULL, len is the size of the buffer, the extra header is copied in
1952     buf.
1953   the return value is the number of bytes copied in buf, or (if <0)
1954     the error code
1955 */
1956 extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
1957 {
1958     unz64_s* s;
1959     file_in_zip64_read_info_s* pfile_in_zip_read_info;
1960     uInt read_now;
1961     ZPOS64_T size_to_read;
1962 
1963     if (file==NULL)
1964         return UNZ_PARAMERROR;
1965     s=(unz64_s*)file;
1966     pfile_in_zip_read_info=s->pfile_in_zip_read;
1967 
1968     if (pfile_in_zip_read_info==NULL)
1969         return UNZ_PARAMERROR;
1970 
1971     size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1972                 pfile_in_zip_read_info->pos_local_extrafield);
1973 
1974     if (buf==NULL)
1975         return (int)size_to_read;
1976 
1977     if (len>size_to_read)
1978         read_now = (uInt)size_to_read;
1979     else
1980         read_now = (uInt)len ;
1981 
1982     if (read_now==0)
1983         return 0;
1984 
1985     if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
1986               pfile_in_zip_read_info->filestream,
1987               pfile_in_zip_read_info->offset_local_extrafield +
1988               pfile_in_zip_read_info->pos_local_extrafield,
1989               ZLIB_FILEFUNC_SEEK_SET)!=0)
1990         return UNZ_ERRNO;
1991 
1992     if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
1993               pfile_in_zip_read_info->filestream,
1994               buf,read_now)!=read_now)
1995         return UNZ_ERRNO;
1996 
1997     return (int)read_now;
1998 }
1999 
2000 /*
2001   Close the file in zip opened with unzipOpenCurrentFile
2002   Return UNZ_CRCERROR if all the file was read but the CRC is not good
2003 */
2004 extern int ZEXPORT unzCloseCurrentFile (unzFile file)
2005 {
2006     int err=UNZ_OK;
2007 
2008     unz64_s* s;
2009     file_in_zip64_read_info_s* pfile_in_zip_read_info;
2010     if (file==NULL)
2011         return UNZ_PARAMERROR;
2012     s=(unz64_s*)file;
2013     pfile_in_zip_read_info=s->pfile_in_zip_read;
2014 
2015     if (pfile_in_zip_read_info==NULL)
2016         return UNZ_PARAMERROR;
2017 
2018 
2019     if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
2020         (!pfile_in_zip_read_info->raw))
2021     {
2022         if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
2023             err=UNZ_CRCERROR;
2024     }
2025 
2026 
2027     TRYFREE(pfile_in_zip_read_info->read_buffer);
2028     pfile_in_zip_read_info->read_buffer = NULL;
2029     if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
2030         inflateEnd(&pfile_in_zip_read_info->stream);
2031 #ifdef HAVE_BZIP2
2032     else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
2033         BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
2034 #endif
2035 
2036 
2037     pfile_in_zip_read_info->stream_initialised = 0;
2038     TRYFREE(pfile_in_zip_read_info);
2039 
2040     s->pfile_in_zip_read=NULL;
2041 
2042     return err;
2043 }
2044 
2045 
2046 /*
2047   Get the global comment string of the ZipFile, in the szComment buffer.
2048   uSizeBuf is the size of the szComment buffer.
2049   return the number of byte copied or an error code <0
2050 */
2051 extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
2052 {
2053     unz64_s* s;
2054     uLong uReadThis ;
2055     if (file==NULL)
2056         return (int)UNZ_PARAMERROR;
2057     s=(unz64_s*)file;
2058 
2059     uReadThis = uSizeBuf;
2060     if (uReadThis>s->gi.size_comment)
2061         uReadThis = s->gi.size_comment;
2062 
2063     if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
2064         return UNZ_ERRNO;
2065 
2066     if (uReadThis>0)
2067     {
2068       *szComment='\0';
2069       if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
2070         return UNZ_ERRNO;
2071     }
2072 
2073     if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
2074         *(szComment+s->gi.size_comment)='\0';
2075     return (int)uReadThis;
2076 }
2077 
2078 /* Additions by RX '2004 */
2079 extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
2080 {
2081     unz64_s* s;
2082 
2083     if (file==NULL)
2084           return 0; /*UNZ_PARAMERROR; */
2085     s=(unz64_s*)file;
2086     if (!s->current_file_ok)
2087       return 0;
2088     if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
2089       if (s->num_file==s->gi.number_entry)
2090          return 0;
2091     return s->pos_in_central_dir;
2092 }
2093 
2094 extern uLong ZEXPORT unzGetOffset (unzFile file)
2095 {
2096     ZPOS64_T offset64;
2097 
2098     if (file==NULL)
2099           return 0; /*UNZ_PARAMERROR; */
2100     offset64 = unzGetOffset64(file);
2101     return (uLong)offset64;
2102 }
2103 
2104 extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
2105 {
2106     unz64_s* s;
2107     int err;
2108 
2109     if (file==NULL)
2110         return UNZ_PARAMERROR;
2111     s=(unz64_s*)file;
2112 
2113     s->pos_in_central_dir = pos;
2114     s->num_file = s->gi.number_entry;      /* hack */
2115     err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
2116                                               &s->cur_file_info_internal,
2117                                               NULL,0,NULL,0,NULL,0);
2118     s->current_file_ok = (err == UNZ_OK);
2119     return err;
2120 }
2121 
2122 extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
2123 {
2124     return unzSetOffset64(file,pos);
2125 }
2126 
2127 
2128 int ZEXPORT unzSetFlags(unzFile file, unsigned flags)
2129 {
2130     unz64_s* s;
2131     if (file == NULL)
2132         return UNZ_PARAMERROR;
2133     s = (unz64_s*)file;
2134     s->flags |= flags;
2135     return UNZ_OK;
2136 }
2137 
2138 
2139 int ZEXPORT unzClearFlags(unzFile file, unsigned flags)
2140 {
2141     unz64_s* s;
2142     if (file == NULL)
2143         return UNZ_PARAMERROR;
2144     s = (unz64_s*)file;
2145     s->flags &= ~flags;
2146     return UNZ_OK;
2147 }