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