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