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