~psiphon-inc/psiphon/trunk

« back to all changes in this revision

Viewing changes to trunk/PsiphonX/libraries/src/zlib/unzip.c

  • Committer: Adam Kruger
  • Date: 2011-02-07 20:43:10 UTC
  • mfrom: (157.1.3 psiphon-with-psiphonx)
  • Revision ID: akruger@kruger-xps-20110207204310-6ph82r21rce8ldze
Merge PsiphonX.

Show diffs side-by-side

added added

removed removed

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