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