* basic-block.h (rtl_bb_info): Break out head_, end_,
[official-gcc.git] / zlib / contrib / minizip / unzip.c
blobf08f624f00f270d33fcfa9bb5dcd09da8dfe706f
1 /* unzip.c -- IO for uncompress .zip files using zlib
2 Version 1.00, September 10th, 2003
4 Copyright (C) 1998-2003 Gilles Vollant
6 Read unzip.h for more info
7 */
9 /* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
10 compatibility with older software. The following is from the original crypt.c. Code
11 woven in by Terry Thorsen 1/2003.
14 Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
16 See the accompanying file LICENSE, version 2000-Apr-09 or later
17 (the contents of which are also included in zip.h) for terms of use.
18 If, for some reason, all these files are missing, the Info-ZIP license
19 also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
22 crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
24 The encryption/decryption parts of this source code (as opposed to the
25 non-echoing password parts) were originally written in Europe. The
26 whole source package can be freely distributed, including from the USA.
27 (Prior to January 2000, re-export from the US was a violation of US law.)
31 This encryption code is a direct transcription of the algorithm from
32 Roger Schlafly, described by Phil Katz in the file appnote.txt. This
33 file (appnote.txt) is distributed with the PKZIP program (even in the
34 version without encryption capabilities).
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include "zlib.h"
42 #include "unzip.h"
44 #ifdef STDC
45 # include <stddef.h>
46 # include <string.h>
47 # include <stdlib.h>
48 #endif
49 #ifdef NO_ERRNO_H
50 extern int errno;
51 #else
52 # include <errno.h>
53 #endif
56 #ifndef local
57 # define local static
58 #endif
59 /* compile with -Dlocal if your debugger can't find static symbols */
62 #ifndef CASESENSITIVITYDEFAULT_NO
63 # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
64 # define CASESENSITIVITYDEFAULT_NO
65 # endif
66 #endif
69 #ifndef UNZ_BUFSIZE
70 #define UNZ_BUFSIZE (16384)
71 #endif
73 #ifndef UNZ_MAXFILENAMEINZIP
74 #define UNZ_MAXFILENAMEINZIP (256)
75 #endif
77 #ifndef ALLOC
78 # define ALLOC(size) (malloc(size))
79 #endif
80 #ifndef TRYFREE
81 # define TRYFREE(p) {if (p) free(p);}
82 #endif
84 #define SIZECENTRALDIRITEM (0x2e)
85 #define SIZEZIPLOCALHEADER (0x1e)
90 const char unz_copyright[] =
91 " unzip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll";
93 /* unz_file_info_interntal contain internal info about a file in zipfile*/
94 typedef struct unz_file_info_internal_s
96 uLong offset_curfile;/* relative offset of local header 4 bytes */
97 } unz_file_info_internal;
100 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
101 when reading and decompress it */
102 typedef struct
104 char *read_buffer; /* internal buffer for compressed data */
105 z_stream stream; /* zLib stream structure for inflate */
107 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
108 uLong stream_initialised; /* flag set if stream structure is initialised*/
110 uLong offset_local_extrafield;/* offset of the local extra field */
111 uInt size_local_extrafield;/* size of the local extra field */
112 uLong pos_local_extrafield; /* position in the local extra field in read*/
114 uLong crc32; /* crc32 of all data uncompressed */
115 uLong crc32_wait; /* crc32 we must obtain after decompress all */
116 uLong rest_read_compressed; /* number of byte to be decompressed */
117 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
118 zlib_filefunc_def z_filefunc;
119 voidpf filestream; /* io structore of the zipfile */
120 uLong compression_method; /* compression method (0==store) */
121 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
122 int raw;
123 } file_in_zip_read_info_s;
126 /* unz_s contain internal information about the zipfile
128 typedef struct
130 zlib_filefunc_def z_filefunc;
131 voidpf filestream; /* io structore of the zipfile */
132 unz_global_info gi; /* public global information */
133 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
134 uLong num_file; /* number of the current file in the zipfile*/
135 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
136 uLong current_file_ok; /* flag about the usability of the current file*/
137 uLong central_pos; /* position of the beginning of the central dir*/
139 uLong size_central_dir; /* size of the central directory */
140 uLong offset_central_dir; /* offset of start of central directory with
141 respect to the starting disk number */
143 unz_file_info cur_file_info; /* public info about the current file in zip*/
144 unz_file_info_internal cur_file_info_internal; /* private info about it*/
145 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
146 file if we are decompressing it */
147 int encrypted;
148 # ifndef NOUNCRYPT
149 unsigned long keys[3]; /* keys defining the pseudo-random sequence */
150 const unsigned long* pcrc_32_tab;
151 # endif
152 } unz_s;
155 #ifndef NOUNCRYPT
156 #include "crypt.h"
157 #endif
159 /* ===========================================================================
160 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
161 for end of file.
162 IN assertion: the stream s has been sucessfully opened for reading.
166 local int unzlocal_getByte OF((
167 const zlib_filefunc_def* pzlib_filefunc_def,
168 voidpf filestream,
169 int *pi));
171 local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
172 const zlib_filefunc_def* pzlib_filefunc_def;
173 voidpf filestream;
174 int *pi;
176 unsigned char c;
177 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
178 if (err==1)
180 *pi = (int)c;
181 return UNZ_OK;
183 else
185 if (ZERROR(*pzlib_filefunc_def,filestream))
186 return UNZ_ERRNO;
187 else
188 return UNZ_EOF;
193 /* ===========================================================================
194 Reads a long in LSB order from the given gz_stream. Sets
196 local int unzlocal_getShort OF((
197 const zlib_filefunc_def* pzlib_filefunc_def,
198 voidpf filestream,
199 uLong *pX));
201 local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
202 const zlib_filefunc_def* pzlib_filefunc_def;
203 voidpf filestream;
204 uLong *pX;
206 uLong x ;
207 int i;
208 int err;
210 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
211 x = (uLong)i;
213 if (err==UNZ_OK)
214 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
215 x += ((uLong)i)<<8;
217 if (err==UNZ_OK)
218 *pX = x;
219 else
220 *pX = 0;
221 return err;
224 local int unzlocal_getLong OF((
225 const zlib_filefunc_def* pzlib_filefunc_def,
226 voidpf filestream,
227 uLong *pX));
229 local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
230 const zlib_filefunc_def* pzlib_filefunc_def;
231 voidpf filestream;
232 uLong *pX;
234 uLong x ;
235 int i;
236 int err;
238 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
239 x = (uLong)i;
241 if (err==UNZ_OK)
242 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
243 x += ((uLong)i)<<8;
245 if (err==UNZ_OK)
246 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
247 x += ((uLong)i)<<16;
249 if (err==UNZ_OK)
250 err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
251 x += ((uLong)i)<<24;
253 if (err==UNZ_OK)
254 *pX = x;
255 else
256 *pX = 0;
257 return err;
261 /* My own strcmpi / strcasecmp */
262 local int strcmpcasenosensitive_internal (fileName1,fileName2)
263 const char* fileName1;
264 const char* fileName2;
266 for (;;)
268 char c1=*(fileName1++);
269 char c2=*(fileName2++);
270 if ((c1>='a') && (c1<='z'))
271 c1 -= 0x20;
272 if ((c2>='a') && (c2<='z'))
273 c2 -= 0x20;
274 if (c1=='\0')
275 return ((c2=='\0') ? 0 : -1);
276 if (c2=='\0')
277 return 1;
278 if (c1<c2)
279 return -1;
280 if (c1>c2)
281 return 1;
286 #ifdef CASESENSITIVITYDEFAULT_NO
287 #define CASESENSITIVITYDEFAULTVALUE 2
288 #else
289 #define CASESENSITIVITYDEFAULTVALUE 1
290 #endif
292 #ifndef STRCMPCASENOSENTIVEFUNCTION
293 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
294 #endif
297 Compare two filename (fileName1,fileName2).
298 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
299 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
300 or strcasecmp)
301 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
302 (like 1 on Unix, 2 on Windows)
305 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
306 const char* fileName1;
307 const char* fileName2;
308 int iCaseSensitivity;
310 if (iCaseSensitivity==0)
311 iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
313 if (iCaseSensitivity==1)
314 return strcmp(fileName1,fileName2);
316 return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
319 #ifndef BUFREADCOMMENT
320 #define BUFREADCOMMENT (0x400)
321 #endif
324 Locate the Central directory of a zipfile (at the end, just before
325 the global comment)
327 local uLong unzlocal_SearchCentralDir OF((
328 const zlib_filefunc_def* pzlib_filefunc_def,
329 voidpf filestream));
331 local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
332 const zlib_filefunc_def* pzlib_filefunc_def;
333 voidpf filestream;
335 unsigned char* buf;
336 uLong uSizeFile;
337 uLong uBackRead;
338 uLong uMaxBack=0xffff; /* maximum size of global comment */
339 uLong uPosFound=0;
341 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
342 return 0;
345 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
347 if (uMaxBack>uSizeFile)
348 uMaxBack = uSizeFile;
350 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
351 if (buf==NULL)
352 return 0;
354 uBackRead = 4;
355 while (uBackRead<uMaxBack)
357 uLong uReadSize,uReadPos ;
358 int i;
359 if (uBackRead+BUFREADCOMMENT>uMaxBack)
360 uBackRead = uMaxBack;
361 else
362 uBackRead+=BUFREADCOMMENT;
363 uReadPos = uSizeFile-uBackRead ;
365 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
366 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
367 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
368 break;
370 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
371 break;
373 for (i=(int)uReadSize-3; (i--)>0;)
374 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
375 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
377 uPosFound = uReadPos+i;
378 break;
381 if (uPosFound!=0)
382 break;
384 TRYFREE(buf);
385 return uPosFound;
389 Open a Zip file. path contain the full pathname (by example,
390 on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
391 "zlib/zlib114.zip".
392 If the zipfile cannot be opened (file doesn't exist or in not valid), the
393 return value is NULL.
394 Else, the return value is a unzFile Handle, usable with other function
395 of this unzip package.
397 extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
398 const char *path;
399 zlib_filefunc_def* pzlib_filefunc_def;
401 unz_s us;
402 unz_s *s;
403 uLong central_pos,uL;
405 uLong number_disk; /* number of the current dist, used for
406 spaning ZIP, unsupported, always 0*/
407 uLong number_disk_with_CD; /* number the the disk with central dir, used
408 for spaning ZIP, unsupported, always 0*/
409 uLong number_entry_CD; /* total number of entries in
410 the central dir
411 (same than number_entry on nospan) */
413 int err=UNZ_OK;
415 if (unz_copyright[0]!=' ')
416 return NULL;
418 if (pzlib_filefunc_def==NULL)
419 fill_fopen_filefunc(&us.z_filefunc);
420 else
421 us.z_filefunc = *pzlib_filefunc_def;
423 us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
424 path,
425 ZLIB_FILEFUNC_MODE_READ |
426 ZLIB_FILEFUNC_MODE_EXISTING);
427 if (us.filestream==NULL)
428 return NULL;
430 central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
431 if (central_pos==0)
432 err=UNZ_ERRNO;
434 if (ZSEEK(us.z_filefunc, us.filestream,
435 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
436 err=UNZ_ERRNO;
438 /* the signature, already checked */
439 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
440 err=UNZ_ERRNO;
442 /* number of this disk */
443 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
444 err=UNZ_ERRNO;
446 /* number of the disk with the start of the central directory */
447 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
448 err=UNZ_ERRNO;
450 /* total number of entries in the central dir on this disk */
451 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
452 err=UNZ_ERRNO;
454 /* total number of entries in the central dir */
455 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
456 err=UNZ_ERRNO;
458 if ((number_entry_CD!=us.gi.number_entry) ||
459 (number_disk_with_CD!=0) ||
460 (number_disk!=0))
461 err=UNZ_BADZIPFILE;
463 /* size of the central directory */
464 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
465 err=UNZ_ERRNO;
467 /* offset of start of central directory with respect to the
468 starting disk number */
469 if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
470 err=UNZ_ERRNO;
472 /* zipfile comment length */
473 if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
474 err=UNZ_ERRNO;
476 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
477 (err==UNZ_OK))
478 err=UNZ_BADZIPFILE;
480 if (err!=UNZ_OK)
482 ZCLOSE(us.z_filefunc, us.filestream);
483 return NULL;
486 us.byte_before_the_zipfile = central_pos -
487 (us.offset_central_dir+us.size_central_dir);
488 us.central_pos = central_pos;
489 us.pfile_in_zip_read = NULL;
490 us.encrypted = 0;
493 s=(unz_s*)ALLOC(sizeof(unz_s));
494 *s=us;
495 unzGoToFirstFile((unzFile)s);
496 return (unzFile)s;
500 extern unzFile ZEXPORT unzOpen (path)
501 const char *path;
503 return unzOpen2(path, NULL);
507 Close a ZipFile opened with unzipOpen.
508 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
509 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
510 return UNZ_OK if there is no problem. */
511 extern int ZEXPORT unzClose (file)
512 unzFile file;
514 unz_s* s;
515 if (file==NULL)
516 return UNZ_PARAMERROR;
517 s=(unz_s*)file;
519 if (s->pfile_in_zip_read!=NULL)
520 unzCloseCurrentFile(file);
522 ZCLOSE(s->z_filefunc, s->filestream);
523 TRYFREE(s);
524 return UNZ_OK;
529 Write info about the ZipFile in the *pglobal_info structure.
530 No preparation of the structure is needed
531 return UNZ_OK if there is no problem. */
532 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
533 unzFile file;
534 unz_global_info *pglobal_info;
536 unz_s* s;
537 if (file==NULL)
538 return UNZ_PARAMERROR;
539 s=(unz_s*)file;
540 *pglobal_info=s->gi;
541 return UNZ_OK;
546 Translate date/time from Dos format to tm_unz (readable more easilty)
548 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
549 uLong ulDosDate;
550 tm_unz* ptm;
552 uLong uDate;
553 uDate = (uLong)(ulDosDate>>16);
554 ptm->tm_mday = (uInt)(uDate&0x1f) ;
555 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
556 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
558 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
559 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
560 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
564 Get Info about the current file in the zipfile, with internal only info
566 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
567 unz_file_info *pfile_info,
568 unz_file_info_internal
569 *pfile_info_internal,
570 char *szFileName,
571 uLong fileNameBufferSize,
572 void *extraField,
573 uLong extraFieldBufferSize,
574 char *szComment,
575 uLong commentBufferSize));
577 local int unzlocal_GetCurrentFileInfoInternal (file,
578 pfile_info,
579 pfile_info_internal,
580 szFileName, fileNameBufferSize,
581 extraField, extraFieldBufferSize,
582 szComment, commentBufferSize)
583 unzFile file;
584 unz_file_info *pfile_info;
585 unz_file_info_internal *pfile_info_internal;
586 char *szFileName;
587 uLong fileNameBufferSize;
588 void *extraField;
589 uLong extraFieldBufferSize;
590 char *szComment;
591 uLong commentBufferSize;
593 unz_s* s;
594 unz_file_info file_info;
595 unz_file_info_internal file_info_internal;
596 int err=UNZ_OK;
597 uLong uMagic;
598 long lSeek=0;
600 if (file==NULL)
601 return UNZ_PARAMERROR;
602 s=(unz_s*)file;
603 if (ZSEEK(s->z_filefunc, s->filestream,
604 s->pos_in_central_dir+s->byte_before_the_zipfile,
605 ZLIB_FILEFUNC_SEEK_SET)!=0)
606 err=UNZ_ERRNO;
609 /* we check the magic */
610 if (err==UNZ_OK)
611 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
612 err=UNZ_ERRNO;
613 else if (uMagic!=0x02014b50)
614 err=UNZ_BADZIPFILE;
616 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
617 err=UNZ_ERRNO;
619 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
620 err=UNZ_ERRNO;
622 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
623 err=UNZ_ERRNO;
625 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
626 err=UNZ_ERRNO;
628 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
629 err=UNZ_ERRNO;
631 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
633 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
634 err=UNZ_ERRNO;
636 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
637 err=UNZ_ERRNO;
639 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
640 err=UNZ_ERRNO;
642 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
643 err=UNZ_ERRNO;
645 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
646 err=UNZ_ERRNO;
648 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
649 err=UNZ_ERRNO;
651 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
652 err=UNZ_ERRNO;
654 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
655 err=UNZ_ERRNO;
657 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
658 err=UNZ_ERRNO;
660 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
661 err=UNZ_ERRNO;
663 lSeek+=file_info.size_filename;
664 if ((err==UNZ_OK) && (szFileName!=NULL))
666 uLong uSizeRead ;
667 if (file_info.size_filename<fileNameBufferSize)
669 *(szFileName+file_info.size_filename)='\0';
670 uSizeRead = file_info.size_filename;
672 else
673 uSizeRead = fileNameBufferSize;
675 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
676 if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
677 err=UNZ_ERRNO;
678 lSeek -= uSizeRead;
682 if ((err==UNZ_OK) && (extraField!=NULL))
684 uLong uSizeRead ;
685 if (file_info.size_file_extra<extraFieldBufferSize)
686 uSizeRead = file_info.size_file_extra;
687 else
688 uSizeRead = extraFieldBufferSize;
690 if (lSeek!=0)
691 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
692 lSeek=0;
693 else
694 err=UNZ_ERRNO;
695 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
696 if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
697 err=UNZ_ERRNO;
698 lSeek += file_info.size_file_extra - uSizeRead;
700 else
701 lSeek+=file_info.size_file_extra;
704 if ((err==UNZ_OK) && (szComment!=NULL))
706 uLong uSizeRead ;
707 if (file_info.size_file_comment<commentBufferSize)
709 *(szComment+file_info.size_file_comment)='\0';
710 uSizeRead = file_info.size_file_comment;
712 else
713 uSizeRead = commentBufferSize;
715 if (lSeek!=0)
716 if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
717 lSeek=0;
718 else
719 err=UNZ_ERRNO;
720 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
721 if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
722 err=UNZ_ERRNO;
723 lSeek+=file_info.size_file_comment - uSizeRead;
725 else
726 lSeek+=file_info.size_file_comment;
728 if ((err==UNZ_OK) && (pfile_info!=NULL))
729 *pfile_info=file_info;
731 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
732 *pfile_info_internal=file_info_internal;
734 return err;
740 Write info about the ZipFile in the *pglobal_info structure.
741 No preparation of the structure is needed
742 return UNZ_OK if there is no problem.
744 extern int ZEXPORT unzGetCurrentFileInfo (file,
745 pfile_info,
746 szFileName, fileNameBufferSize,
747 extraField, extraFieldBufferSize,
748 szComment, commentBufferSize)
749 unzFile file;
750 unz_file_info *pfile_info;
751 char *szFileName;
752 uLong fileNameBufferSize;
753 void *extraField;
754 uLong extraFieldBufferSize;
755 char *szComment;
756 uLong commentBufferSize;
758 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
759 szFileName,fileNameBufferSize,
760 extraField,extraFieldBufferSize,
761 szComment,commentBufferSize);
765 Set the current file of the zipfile to the first file.
766 return UNZ_OK if there is no problem
768 extern int ZEXPORT unzGoToFirstFile (file)
769 unzFile file;
771 int err=UNZ_OK;
772 unz_s* s;
773 if (file==NULL)
774 return UNZ_PARAMERROR;
775 s=(unz_s*)file;
776 s->pos_in_central_dir=s->offset_central_dir;
777 s->num_file=0;
778 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
779 &s->cur_file_info_internal,
780 NULL,0,NULL,0,NULL,0);
781 s->current_file_ok = (err == UNZ_OK);
782 return err;
786 Set the current file of the zipfile to the next file.
787 return UNZ_OK if there is no problem
788 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
790 extern int ZEXPORT unzGoToNextFile (file)
791 unzFile file;
793 unz_s* s;
794 int err;
796 if (file==NULL)
797 return UNZ_PARAMERROR;
798 s=(unz_s*)file;
799 if (!s->current_file_ok)
800 return UNZ_END_OF_LIST_OF_FILE;
801 if (s->num_file+1==s->gi.number_entry)
802 return UNZ_END_OF_LIST_OF_FILE;
804 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
805 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
806 s->num_file++;
807 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
808 &s->cur_file_info_internal,
809 NULL,0,NULL,0,NULL,0);
810 s->current_file_ok = (err == UNZ_OK);
811 return err;
816 Try locate the file szFileName in the zipfile.
817 For the iCaseSensitivity signification, see unzipStringFileNameCompare
819 return value :
820 UNZ_OK if the file is found. It becomes the current file.
821 UNZ_END_OF_LIST_OF_FILE if the file is not found
823 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
824 unzFile file;
825 const char *szFileName;
826 int iCaseSensitivity;
828 unz_s* s;
829 int err;
831 /* We remember the 'current' position in the file so that we can jump
832 * back there if we fail.
834 unz_file_info cur_file_infoSaved;
835 unz_file_info_internal cur_file_info_internalSaved;
836 uLong num_fileSaved;
837 uLong pos_in_central_dirSaved;
840 if (file==NULL)
841 return UNZ_PARAMERROR;
843 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
844 return UNZ_PARAMERROR;
846 s=(unz_s*)file;
847 if (!s->current_file_ok)
848 return UNZ_END_OF_LIST_OF_FILE;
850 /* Save the current state */
851 num_fileSaved = s->num_file;
852 pos_in_central_dirSaved = s->pos_in_central_dir;
853 cur_file_infoSaved = s->cur_file_info;
854 cur_file_info_internalSaved = s->cur_file_info_internal;
856 err = unzGoToFirstFile(file);
858 while (err == UNZ_OK)
860 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
861 err = unzGetCurrentFileInfo(file,NULL,
862 szCurrentFileName,sizeof(szCurrentFileName)-1,
863 NULL,0,NULL,0);
864 if (err == UNZ_OK)
866 if (unzStringFileNameCompare(szCurrentFileName,
867 szFileName,iCaseSensitivity)==0)
868 return UNZ_OK;
869 err = unzGoToNextFile(file);
873 /* We failed, so restore the state of the 'current file' to where we
874 * were.
876 s->num_file = num_fileSaved ;
877 s->pos_in_central_dir = pos_in_central_dirSaved ;
878 s->cur_file_info = cur_file_infoSaved;
879 s->cur_file_info_internal = cur_file_info_internalSaved;
880 return err;
885 ///////////////////////////////////////////
886 // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
887 // I need random access
889 // Further optimization could be realized by adding an ability
890 // to cache the directory in memory. The goal being a single
891 // comprehensive file read to put the file I need in a memory.
895 typedef struct unz_file_pos_s
897 uLong pos_in_zip_directory; // offset in file
898 uLong num_of_file; // # of file
899 } unz_file_pos;
902 extern int ZEXPORT unzGetFilePos(file, file_pos)
903 unzFile file;
904 unz_file_pos* file_pos;
906 unz_s* s;
908 if (file==NULL || file_pos==NULL)
909 return UNZ_PARAMERROR;
910 s=(unz_s*)file;
911 if (!s->current_file_ok)
912 return UNZ_END_OF_LIST_OF_FILE;
914 file_pos->pos_in_zip_directory = s->pos_in_central_dir;
915 file_pos->num_of_file = s->num_file;
917 return UNZ_OK;
920 extern int ZEXPORT unzGoToFilePos(file, file_pos)
921 unzFile file;
922 unz_file_pos* file_pos;
924 unz_s* s;
925 int err;
927 if (file==NULL || file_pos==NULL)
928 return UNZ_PARAMERROR;
929 s=(unz_s*)file;
931 /* jump to the right spot */
932 s->pos_in_central_dir = file_pos->pos_in_zip_directory;
933 s->num_file = file_pos->num_of_file;
935 /* set the current file */
936 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
937 &s->cur_file_info_internal,
938 NULL,0,NULL,0,NULL,0);
939 /* return results */
940 s->current_file_ok = (err == UNZ_OK);
941 return err;
945 // Unzip Helper Functions - should be here?
946 ///////////////////////////////////////////
950 Read the local header of the current zipfile
951 Check the coherency of the local header and info in the end of central
952 directory about this file
953 store in *piSizeVar the size of extra info in local header
954 (filename and size of extra field data)
956 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
957 poffset_local_extrafield,
958 psize_local_extrafield)
959 unz_s* s;
960 uInt* piSizeVar;
961 uLong *poffset_local_extrafield;
962 uInt *psize_local_extrafield;
964 uLong uMagic,uData,uFlags;
965 uLong size_filename;
966 uLong size_extra_field;
967 int err=UNZ_OK;
969 *piSizeVar = 0;
970 *poffset_local_extrafield = 0;
971 *psize_local_extrafield = 0;
973 if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
974 s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
975 return UNZ_ERRNO;
978 if (err==UNZ_OK)
979 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
980 err=UNZ_ERRNO;
981 else if (uMagic!=0x04034b50)
982 err=UNZ_BADZIPFILE;
984 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
985 err=UNZ_ERRNO;
987 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
988 err=UNZ_BADZIPFILE;
990 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
991 err=UNZ_ERRNO;
993 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
994 err=UNZ_ERRNO;
995 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
996 err=UNZ_BADZIPFILE;
998 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
999 (s->cur_file_info.compression_method!=Z_DEFLATED))
1000 err=UNZ_BADZIPFILE;
1002 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
1003 err=UNZ_ERRNO;
1005 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
1006 err=UNZ_ERRNO;
1007 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
1008 ((uFlags & 8)==0))
1009 err=UNZ_BADZIPFILE;
1011 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
1012 err=UNZ_ERRNO;
1013 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
1014 ((uFlags & 8)==0))
1015 err=UNZ_BADZIPFILE;
1017 if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
1018 err=UNZ_ERRNO;
1019 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
1020 ((uFlags & 8)==0))
1021 err=UNZ_BADZIPFILE;
1024 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
1025 err=UNZ_ERRNO;
1026 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
1027 err=UNZ_BADZIPFILE;
1029 *piSizeVar += (uInt)size_filename;
1031 if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
1032 err=UNZ_ERRNO;
1033 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
1034 SIZEZIPLOCALHEADER + size_filename;
1035 *psize_local_extrafield = (uInt)size_extra_field;
1037 *piSizeVar += (uInt)size_extra_field;
1039 return err;
1043 Open for reading data the current file in the zipfile.
1044 If there is no error and the file is opened, the return value is UNZ_OK.
1046 extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
1047 unzFile file;
1048 int* method;
1049 int* level;
1050 int raw;
1051 const char* password;
1053 int err=UNZ_OK;
1054 uInt iSizeVar;
1055 unz_s* s;
1056 file_in_zip_read_info_s* pfile_in_zip_read_info;
1057 uLong offset_local_extrafield; /* offset of the local extra field */
1058 uInt size_local_extrafield; /* size of the local extra field */
1059 # ifndef NOUNCRYPT
1060 char source[12];
1061 # else
1062 if (password != NULL)
1063 return UNZ_PARAMERROR;
1064 # endif
1066 if (file==NULL)
1067 return UNZ_PARAMERROR;
1068 s=(unz_s*)file;
1069 if (!s->current_file_ok)
1070 return UNZ_PARAMERROR;
1072 if (s->pfile_in_zip_read != NULL)
1073 unzCloseCurrentFile(file);
1075 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1076 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1077 return UNZ_BADZIPFILE;
1079 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1080 ALLOC(sizeof(file_in_zip_read_info_s));
1081 if (pfile_in_zip_read_info==NULL)
1082 return UNZ_INTERNALERROR;
1084 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1085 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1086 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1087 pfile_in_zip_read_info->pos_local_extrafield=0;
1088 pfile_in_zip_read_info->raw=raw;
1090 if (pfile_in_zip_read_info->read_buffer==NULL)
1092 TRYFREE(pfile_in_zip_read_info);
1093 return UNZ_INTERNALERROR;
1096 pfile_in_zip_read_info->stream_initialised=0;
1098 if (method!=NULL)
1099 *method = (int)s->cur_file_info.compression_method;
1101 if (level!=NULL)
1103 *level = 6;
1104 switch (s->cur_file_info.flag & 0x06)
1106 case 6 : *level = 1; break;
1107 case 4 : *level = 2; break;
1108 case 2 : *level = 9; break;
1112 if ((s->cur_file_info.compression_method!=0) &&
1113 (s->cur_file_info.compression_method!=Z_DEFLATED))
1114 err=UNZ_BADZIPFILE;
1116 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1117 pfile_in_zip_read_info->crc32=0;
1118 pfile_in_zip_read_info->compression_method =
1119 s->cur_file_info.compression_method;
1120 pfile_in_zip_read_info->filestream=s->filestream;
1121 pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
1122 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1124 pfile_in_zip_read_info->stream.total_out = 0;
1126 if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
1127 (!raw))
1129 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1130 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1131 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1132 pfile_in_zip_read_info->stream.next_in = (voidpf)0;
1133 pfile_in_zip_read_info->stream.avail_in = 0;
1135 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1136 if (err == Z_OK)
1137 pfile_in_zip_read_info->stream_initialised=1;
1138 else
1139 return err;
1140 /* windowBits is passed < 0 to tell that there is no zlib header.
1141 * Note that in this case inflate *requires* an extra "dummy" byte
1142 * after the compressed stream in order to complete decompression and
1143 * return Z_STREAM_END.
1144 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1145 * size of both compressed and uncompressed data
1148 pfile_in_zip_read_info->rest_read_compressed =
1149 s->cur_file_info.compressed_size ;
1150 pfile_in_zip_read_info->rest_read_uncompressed =
1151 s->cur_file_info.uncompressed_size ;
1154 pfile_in_zip_read_info->pos_in_zipfile =
1155 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1156 iSizeVar;
1158 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1160 s->pfile_in_zip_read = pfile_in_zip_read_info;
1162 # ifndef NOUNCRYPT
1163 if (password != NULL)
1165 int i;
1166 s->pcrc_32_tab = get_crc_table();
1167 init_keys(password,s->keys,s->pcrc_32_tab);
1168 if (ZSEEK(s->z_filefunc, s->filestream,
1169 s->pfile_in_zip_read->pos_in_zipfile +
1170 s->pfile_in_zip_read->byte_before_the_zipfile,
1171 SEEK_SET)!=0)
1172 return UNZ_INTERNALERROR;
1173 if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
1174 return UNZ_INTERNALERROR;
1176 for (i = 0; i<12; i++)
1177 zdecode(s->keys,s->pcrc_32_tab,source[i]);
1179 s->pfile_in_zip_read->pos_in_zipfile+=12;
1180 s->encrypted=1;
1182 # endif
1185 return UNZ_OK;
1188 extern int ZEXPORT unzOpenCurrentFile (file)
1189 unzFile file;
1191 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
1194 extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
1195 unzFile file;
1196 const char* password;
1198 return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
1201 extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
1202 unzFile file;
1203 int* method;
1204 int* level;
1205 int raw;
1207 return unzOpenCurrentFile3(file, method, level, raw, NULL);
1211 Read bytes from the current file.
1212 buf contain buffer where data must be copied
1213 len the size of buf.
1215 return the number of byte copied if somes bytes are copied
1216 return 0 if the end of file was reached
1217 return <0 with error code if there is an error
1218 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1220 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1221 unzFile file;
1222 voidp buf;
1223 unsigned len;
1225 int err=UNZ_OK;
1226 uInt iRead = 0;
1227 unz_s* s;
1228 file_in_zip_read_info_s* pfile_in_zip_read_info;
1229 if (file==NULL)
1230 return UNZ_PARAMERROR;
1231 s=(unz_s*)file;
1232 pfile_in_zip_read_info=s->pfile_in_zip_read;
1234 if (pfile_in_zip_read_info==NULL)
1235 return UNZ_PARAMERROR;
1238 if ((pfile_in_zip_read_info->read_buffer == NULL))
1239 return UNZ_END_OF_LIST_OF_FILE;
1240 if (len==0)
1241 return 0;
1243 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1245 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1247 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1248 pfile_in_zip_read_info->stream.avail_out =
1249 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1251 while (pfile_in_zip_read_info->stream.avail_out>0)
1253 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1254 (pfile_in_zip_read_info->rest_read_compressed>0))
1256 uInt uReadThis = UNZ_BUFSIZE;
1257 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1258 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1259 if (uReadThis == 0)
1260 return UNZ_EOF;
1261 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1262 pfile_in_zip_read_info->filestream,
1263 pfile_in_zip_read_info->pos_in_zipfile +
1264 pfile_in_zip_read_info->byte_before_the_zipfile,
1265 ZLIB_FILEFUNC_SEEK_SET)!=0)
1266 return UNZ_ERRNO;
1267 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1268 pfile_in_zip_read_info->filestream,
1269 pfile_in_zip_read_info->read_buffer,
1270 uReadThis)!=uReadThis)
1271 return UNZ_ERRNO;
1274 # ifndef NOUNCRYPT
1275 if(s->encrypted)
1277 uInt i;
1278 for(i=0;i<uReadThis;i++)
1279 pfile_in_zip_read_info->read_buffer[i] =
1280 zdecode(s->keys,s->pcrc_32_tab,
1281 pfile_in_zip_read_info->read_buffer[i]);
1283 # endif
1286 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1288 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1290 pfile_in_zip_read_info->stream.next_in =
1291 (Bytef*)pfile_in_zip_read_info->read_buffer;
1292 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1295 if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
1297 uInt uDoCopy,i ;
1299 if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
1300 (pfile_in_zip_read_info->rest_read_compressed == 0))
1301 return (iRead==0) ? UNZ_EOF : iRead;
1303 if (pfile_in_zip_read_info->stream.avail_out <
1304 pfile_in_zip_read_info->stream.avail_in)
1305 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1306 else
1307 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1309 for (i=0;i<uDoCopy;i++)
1310 *(pfile_in_zip_read_info->stream.next_out+i) =
1311 *(pfile_in_zip_read_info->stream.next_in+i);
1313 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1314 pfile_in_zip_read_info->stream.next_out,
1315 uDoCopy);
1316 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1317 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1318 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1319 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1320 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1321 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1322 iRead += uDoCopy;
1324 else
1326 uLong uTotalOutBefore,uTotalOutAfter;
1327 const Bytef *bufBefore;
1328 uLong uOutThis;
1329 int flush=Z_SYNC_FLUSH;
1331 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1332 bufBefore = pfile_in_zip_read_info->stream.next_out;
1335 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1336 pfile_in_zip_read_info->stream.avail_out) &&
1337 (pfile_in_zip_read_info->rest_read_compressed == 0))
1338 flush = Z_FINISH;
1340 err=inflate(&pfile_in_zip_read_info->stream,flush);
1342 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1343 uOutThis = uTotalOutAfter-uTotalOutBefore;
1345 pfile_in_zip_read_info->crc32 =
1346 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1347 (uInt)(uOutThis));
1349 pfile_in_zip_read_info->rest_read_uncompressed -=
1350 uOutThis;
1352 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1354 if (err==Z_STREAM_END)
1355 return (iRead==0) ? UNZ_EOF : iRead;
1356 if (err!=Z_OK)
1357 break;
1361 if (err==Z_OK)
1362 return iRead;
1363 return err;
1368 Give the current position in uncompressed data
1370 extern z_off_t ZEXPORT unztell (file)
1371 unzFile file;
1373 unz_s* s;
1374 file_in_zip_read_info_s* pfile_in_zip_read_info;
1375 if (file==NULL)
1376 return UNZ_PARAMERROR;
1377 s=(unz_s*)file;
1378 pfile_in_zip_read_info=s->pfile_in_zip_read;
1380 if (pfile_in_zip_read_info==NULL)
1381 return UNZ_PARAMERROR;
1383 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1388 return 1 if the end of file was reached, 0 elsewhere
1390 extern int ZEXPORT unzeof (file)
1391 unzFile file;
1393 unz_s* s;
1394 file_in_zip_read_info_s* pfile_in_zip_read_info;
1395 if (file==NULL)
1396 return UNZ_PARAMERROR;
1397 s=(unz_s*)file;
1398 pfile_in_zip_read_info=s->pfile_in_zip_read;
1400 if (pfile_in_zip_read_info==NULL)
1401 return UNZ_PARAMERROR;
1403 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1404 return 1;
1405 else
1406 return 0;
1412 Read extra field from the current file (opened by unzOpenCurrentFile)
1413 This is the local-header version of the extra field (sometimes, there is
1414 more info in the local-header version than in the central-header)
1416 if buf==NULL, it return the size of the local extra field that can be read
1418 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1419 buf.
1420 the return value is the number of bytes copied in buf, or (if <0)
1421 the error code
1423 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1424 unzFile file;
1425 voidp buf;
1426 unsigned len;
1428 unz_s* s;
1429 file_in_zip_read_info_s* pfile_in_zip_read_info;
1430 uInt read_now;
1431 uLong size_to_read;
1433 if (file==NULL)
1434 return UNZ_PARAMERROR;
1435 s=(unz_s*)file;
1436 pfile_in_zip_read_info=s->pfile_in_zip_read;
1438 if (pfile_in_zip_read_info==NULL)
1439 return UNZ_PARAMERROR;
1441 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1442 pfile_in_zip_read_info->pos_local_extrafield);
1444 if (buf==NULL)
1445 return (int)size_to_read;
1447 if (len>size_to_read)
1448 read_now = (uInt)size_to_read;
1449 else
1450 read_now = (uInt)len ;
1452 if (read_now==0)
1453 return 0;
1455 if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
1456 pfile_in_zip_read_info->filestream,
1457 pfile_in_zip_read_info->offset_local_extrafield +
1458 pfile_in_zip_read_info->pos_local_extrafield,
1459 ZLIB_FILEFUNC_SEEK_SET)!=0)
1460 return UNZ_ERRNO;
1462 if (ZREAD(pfile_in_zip_read_info->z_filefunc,
1463 pfile_in_zip_read_info->filestream,
1464 buf,size_to_read)!=size_to_read)
1465 return UNZ_ERRNO;
1467 return (int)read_now;
1471 Close the file in zip opened with unzipOpenCurrentFile
1472 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1474 extern int ZEXPORT unzCloseCurrentFile (file)
1475 unzFile file;
1477 int err=UNZ_OK;
1479 unz_s* s;
1480 file_in_zip_read_info_s* pfile_in_zip_read_info;
1481 if (file==NULL)
1482 return UNZ_PARAMERROR;
1483 s=(unz_s*)file;
1484 pfile_in_zip_read_info=s->pfile_in_zip_read;
1486 if (pfile_in_zip_read_info==NULL)
1487 return UNZ_PARAMERROR;
1490 if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
1491 (!pfile_in_zip_read_info->raw))
1493 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1494 err=UNZ_CRCERROR;
1498 TRYFREE(pfile_in_zip_read_info->read_buffer);
1499 pfile_in_zip_read_info->read_buffer = NULL;
1500 if (pfile_in_zip_read_info->stream_initialised)
1501 inflateEnd(&pfile_in_zip_read_info->stream);
1503 pfile_in_zip_read_info->stream_initialised = 0;
1504 TRYFREE(pfile_in_zip_read_info);
1506 s->pfile_in_zip_read=NULL;
1508 return err;
1513 Get the global comment string of the ZipFile, in the szComment buffer.
1514 uSizeBuf is the size of the szComment buffer.
1515 return the number of byte copied or an error code <0
1517 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1518 unzFile file;
1519 char *szComment;
1520 uLong uSizeBuf;
1522 int err=UNZ_OK;
1523 unz_s* s;
1524 uLong uReadThis ;
1525 if (file==NULL)
1526 return UNZ_PARAMERROR;
1527 s=(unz_s*)file;
1529 uReadThis = uSizeBuf;
1530 if (uReadThis>s->gi.size_comment)
1531 uReadThis = s->gi.size_comment;
1533 if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
1534 return UNZ_ERRNO;
1536 if (uReadThis>0)
1538 *szComment='\0';
1539 if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
1540 return UNZ_ERRNO;
1543 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1544 *(szComment+s->gi.size_comment)='\0';
1545 return (int)uReadThis;