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