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