LCOV - code coverage report
Current view: directory - port - cpl_minizip_unzip.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 704 310 44.0 %
Date: 2010-01-09 Functions: 34 20 58.8 %

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

Generated by: LCOV version 1.7