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