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