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