Fossil SCM

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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button