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