]> git.saurik.com Git - wxWidgets.git/blob - src/common/unzip.c
Elimiante include of defs.h for VisualAge compiles
[wxWidgets.git] / src / common / unzip.c
1 /*
2
3 This file was altered for needs of wxWindows.
4 $Id$
5
6 */
7
8 /* unzip.c -- IO on .zip files using zlib
9 Version 0.15 beta, Mar 19th, 1998,
10
11 Read unzip.h for more info
12
13 */
14
15 #ifndef __VISAGECPP__
16 #include "wx/defs.h"
17 #endif
18
19 #include "wx/setup.h"
20
21 #if wxUSE_ZLIB && wxUSE_ZIPSTREAM
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 /*
27 #include "zlib.h"
28 normally, the compiler options should contain -I../zlib, but it is
29 apparently not the case for all MSW makefiles and so, unless we use
30 configure (which defines __WX_SETUP_H__) or it is explicitly overridden by
31 the user (who can define wxUSE_ZLIB_H_IN_PATH), we hardcode the path here
32 */
33 #if defined(__WXMSW__) && !defined(__WX_SETUP_H__) && !defined(wxUSE_ZLIB_H_IN_PATH)
34 #include "../zlib/zlib.h"
35 #else
36 #include "zlib.h"
37 #endif
38
39
40 /* Not the right solution (paths in makefiles) but... */
41 #ifdef __BORLANDC__
42 #include "../common/unzip.h"
43 #else
44 #include "unzip.h"
45 #endif
46
47 #ifdef STDC
48 # include <stddef.h>
49 # include <string.h>
50 # include <stdlib.h>
51 #endif
52 #ifdef NO_ERRNO_H
53 extern int errno;
54 #else
55 # include <errno.h>
56 #endif
57
58
59 #ifndef local
60 # define local static
61 #endif
62 /* compile with -Dlocal if your debugger can't find static symbols */
63
64
65
66 #if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
67 !defined(CASESENSITIVITYDEFAULT_NO)
68 #define CASESENSITIVITYDEFAULT_NO
69 #endif
70
71
72 #ifndef UNZ_BUFSIZE
73 #define UNZ_BUFSIZE (16384)
74 #endif
75
76 #ifndef UNZ_MAXFILENAMEINZIP
77 #define UNZ_MAXFILENAMEINZIP (256)
78 #endif
79
80 #ifndef ALLOC
81 # define ALLOC(size) (malloc(size))
82 #endif
83 #ifndef TRYFREE
84 # define TRYFREE(p) {if (p) free(p);}
85 #endif
86
87 #define SIZECENTRALDIRITEM (0x2e)
88 #define SIZEZIPLOCALHEADER (0x1e)
89
90
91 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
92
93 #ifndef SEEK_CUR
94 #define SEEK_CUR 1
95 #endif
96
97 #ifndef SEEK_END
98 #define SEEK_END 2
99 #endif
100
101 #ifndef SEEK_SET
102 #define SEEK_SET 0
103 #endif
104
105 const char unz_copyright[] =
106 " unzip 0.15 Copyright 1998 Gilles Vollant ";
107
108 /* unz_file_info_interntal contain internal info about a file in zipfile*/
109 typedef struct unz_file_info_internal_s
110 {
111 uLong offset_curfile;/* relative offset of local header 4 bytes */
112 } unz_file_info_internal;
113
114
115 /* file_in_zip_read_info_s contain internal information about a file in zipfile,
116 when reading and decompress it */
117 typedef struct
118 {
119 char *read_buffer; /* internal buffer for compressed data */
120 z_stream stream; /* zLib stream structure for inflate */
121
122 uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
123 uLong stream_initialised; /* flag set if stream structure is initialised*/
124
125 uLong offset_local_extrafield;/* offset of the local extra field */
126 uInt size_local_extrafield;/* size of the local extra field */
127 uLong pos_local_extrafield; /* position in the local extra field in read*/
128
129 uLong crc32; /* crc32 of all data uncompressed */
130 uLong crc32_wait; /* crc32 we must obtain after decompress all */
131 uLong rest_read_compressed; /* number of byte to be decompressed */
132 uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
133 FILE* file; /* io structore of the zipfile */
134 uLong compression_method; /* compression method (0==store) */
135 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
136 } file_in_zip_read_info_s;
137
138
139 /* unz_s contain internal information about the zipfile
140 */
141 typedef struct
142 {
143 FILE* file; /* io structore of the zipfile */
144 unz_global_info gi; /* public global information */
145 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
146 uLong num_file; /* number of the current file in the zipfile*/
147 uLong pos_in_central_dir; /* pos of the current file in the central dir*/
148 uLong current_file_ok; /* flag about the usability of the current file*/
149 uLong central_pos; /* position of the beginning of the central dir*/
150
151 uLong size_central_dir; /* size of the central directory */
152 uLong offset_central_dir; /* offset of start of central directory with
153 respect to the starting disk number */
154
155 unz_file_info cur_file_info; /* public info about the current file in zip*/
156 unz_file_info_internal cur_file_info_internal; /* private info about it*/
157 file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
158 file if we are decompressing it */
159 } unz_s;
160
161 #if defined (__VISAGECPP__) || defined(__BORLANDC__)
162 /* VA always requires prototypes */
163 int unzlocal_CheckCurrentFileCoherencyHeader (unz_s*, uInt*, uLong*, uInt*);
164 #endif
165
166 /* disable warnings about K&R declarations until the end of file */
167 #ifdef _MSC_VER
168 #pragma warning(disable:4131)
169 #endif /* VC++ */
170
171 /* ===========================================================================
172 Read a byte from a gz_stream; update next_in and avail_in. Return EOF
173 for end of file.
174 IN assertion: the stream s has been sucessfully opened for reading.
175 */
176
177
178 local int unzlocal_getByte(fin,pi)
179 FILE *fin;
180 int *pi;
181 {
182 unsigned char c;
183 int err = fread(&c, 1, 1, fin);
184 if (err==1)
185 {
186 *pi = (int)c;
187 return UNZ_OK;
188 }
189 else
190 {
191 if (ferror(fin))
192 return UNZ_ERRNO;
193 else
194 return UNZ_EOF;
195 }
196 }
197
198
199 /* ===========================================================================
200 Reads a long in LSB order from the given gz_stream. Sets
201 */
202 local int unzlocal_getShort (fin,pX)
203 FILE* fin;
204 uLong *pX;
205 {
206 uLong x ;
207 int i;
208 int err;
209
210 err = unzlocal_getByte(fin,&i);
211 x = (uLong)i;
212
213 if (err==UNZ_OK)
214 err = unzlocal_getByte(fin,&i);
215 x += ((uLong)i)<<8;
216
217 if (err==UNZ_OK)
218 *pX = x;
219 else
220 *pX = 0;
221 return err;
222 }
223
224 local int unzlocal_getLong (fin,pX)
225 FILE* fin;
226 uLong *pX;
227 {
228 uLong x ;
229 int i;
230 int err;
231
232 err = unzlocal_getByte(fin,&i);
233 x = (uLong)i;
234
235 if (err==UNZ_OK)
236 err = unzlocal_getByte(fin,&i);
237 x += ((uLong)i)<<8;
238
239 if (err==UNZ_OK)
240 err = unzlocal_getByte(fin,&i);
241 x += ((uLong)i)<<16;
242
243 if (err==UNZ_OK)
244 err = unzlocal_getByte(fin,&i);
245 x += ((uLong)i)<<24;
246
247 if (err==UNZ_OK)
248 *pX = x;
249 else
250 *pX = 0;
251 return err;
252 }
253
254
255 /* My own strcmpi / strcasecmp */
256 local int strcmpcasenosensitive_internal (fileName1,fileName2)
257 const char* fileName1;
258 const char* fileName2;
259 {
260 for (;;)
261 {
262 char c1=*(fileName1++);
263 char c2=*(fileName2++);
264 if ((c1>='a') && (c1<='z'))
265 c1 -= 0x20;
266 if ((c2>='a') && (c2<='z'))
267 c2 -= 0x20;
268 if (c1=='\0')
269 return ((c2=='\0') ? 0 : -1);
270 if (c2=='\0')
271 return 1;
272 if (c1<c2)
273 return -1;
274 if (c1>c2)
275 return 1;
276 }
277 }
278
279
280 #ifdef CASESENSITIVITYDEFAULT_NO
281 #define CASESENSITIVITYDEFAULTVALUE 2
282 #else
283 #define CASESENSITIVITYDEFAULTVALUE 1
284 #endif
285
286 #ifndef STRCMPCASENOSENTIVEFUNCTION
287 #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
288 #endif
289
290 /*
291 Compare two filename (fileName1,fileName2).
292 If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
293 If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
294 or strcasecmp)
295 If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
296 (like 1 on Unix, 2 on Windows)
297
298 */
299 extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
300 const char* fileName1;
301 const char* fileName2;
302 int iCaseSensitivity;
303 {
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 #define BUFREADCOMMENT (0x400)
314
315 /*
316 Locate the Central directory of a zipfile (at the end, just before
317 the global comment)
318 */
319 local uLong unzlocal_SearchCentralDir(fin)
320 FILE *fin;
321 {
322 unsigned char* buf;
323 uLong uSizeFile;
324 uLong uBackRead;
325 uLong uMaxBack=0xffff; /* maximum size of global comment */
326 uLong uPosFound=0;
327
328 if (fseek(fin,0,SEEK_END) != 0)
329 return 0;
330
331
332 uSizeFile = ftell( fin );
333
334 if (uMaxBack>uSizeFile)
335 uMaxBack = uSizeFile;
336
337 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
338 if (buf==NULL)
339 return 0;
340
341 uBackRead = 4;
342 while (uBackRead<uMaxBack)
343 {
344 uLong uReadSize,uReadPos ;
345 int i;
346 if (uBackRead+BUFREADCOMMENT>uMaxBack)
347 uBackRead = uMaxBack;
348 else
349 uBackRead+=BUFREADCOMMENT;
350 uReadPos = uSizeFile-uBackRead ;
351
352 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
353 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
354 if (fseek(fin,uReadPos,SEEK_SET)!=0)
355 break;
356
357 if (fread(buf,(uInt)uReadSize,1,fin)!=1)
358 break;
359
360 for (i=(int)uReadSize-3; (i--)>0;)
361 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
362 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
363 {
364 uPosFound = uReadPos+i;
365 break;
366 }
367
368 if (uPosFound!=0)
369 break;
370 }
371 TRYFREE(buf);
372 return uPosFound;
373 }
374
375 #if defined(__WXMAC__) && !defined(__UNIX__)
376 void wxUnix2MacFilename (char *s) ;
377 void
378 wxUnix2MacFilename (char *s)
379 {
380 if (s)
381 {
382 if ( *s == '.' )
383 {
384 /* relative path , since it goes on with slash which is translated to a : */
385 memmove( s , s+1 ,strlen( s ) ) ;
386 }
387 else if ( *s == '/' )
388 {
389 /* absolute path -> on mac just start with the drive name */
390 memmove( s , s+1 ,strlen( s ) ) ;
391 }
392 else
393 {
394 /* wxASSERT_MSG( 1 , "unkown path beginning" ) ; */
395 }
396 while (*s)
397 {
398 if (*s == '/' || *s == '\\')
399 {
400 /* convert any back-directory situations */
401 if ( *(s+1) == '.' && *(s+2) == '.' && ( (*(s+3) == '/' || *(s+3) == '\\') ) )
402 {
403 *s = ':';
404 memmove( s+1 , s+3 ,strlen( s+3 ) + 1 ) ;
405 }
406 else
407 *s = ':';
408 }
409
410 s++ ;
411 }
412 }
413 }
414 extern char * wxBuffer ;
415 #endif
416
417 /*
418 Open a Zip file. path contain the full pathname (by example,
419 on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
420 "zlib/zlib109.zip".
421 If the zipfile cannot be opened (file don't exist or in not valid), the
422 return value is NULL.
423 Else, the return value is a unzFile Handle, usable with other function
424 of this unzip package.
425 */
426 extern unzFile ZEXPORT unzOpen (path)
427 const char *path;
428 {
429 unz_s us;
430 unz_s *s;
431 uLong central_pos,uL;
432 FILE * fin ;
433
434 uLong number_disk; /* number of the current dist, used for
435 spaning ZIP, unsupported, always 0*/
436 uLong number_disk_with_CD; /* number the the disk with central dir, used
437 for spaning ZIP, unsupported, always 0*/
438 uLong number_entry_CD; /* total number of entries in
439 the central dir
440 (same than number_entry on nospan) */
441
442 int err=UNZ_OK;
443
444 if (unz_copyright[0]!=' ')
445 return NULL;
446
447 #if defined(__WXMAC__) && !defined(__UNIX__)
448 strcpy( wxBuffer , path ) ;
449 wxUnix2MacFilename( wxBuffer ) ;
450 fin=fopen(wxBuffer,"rb");
451 #else
452 fin=fopen(path,"rb");
453 #endif
454 if (fin==NULL)
455 return NULL;
456
457 central_pos = unzlocal_SearchCentralDir(fin);
458 if (central_pos==0)
459 err=UNZ_ERRNO;
460
461 if (fseek(fin,central_pos,SEEK_SET)!=0)
462 err=UNZ_ERRNO;
463
464 /* the signature, already checked */
465 if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
466 err=UNZ_ERRNO;
467
468 /* number of this disk */
469 if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
470 err=UNZ_ERRNO;
471
472 /* number of the disk with the start of the central directory */
473 if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
474 err=UNZ_ERRNO;
475
476 /* total number of entries in the central dir on this disk */
477 if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
478 err=UNZ_ERRNO;
479
480 /* total number of entries in the central dir */
481 if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
482 err=UNZ_ERRNO;
483
484 if ((number_entry_CD!=us.gi.number_entry) ||
485 (number_disk_with_CD!=0) ||
486 (number_disk!=0))
487 err=UNZ_BADZIPFILE;
488
489 /* size of the central directory */
490 if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
491 err=UNZ_ERRNO;
492
493 /* offset of start of central directory with respect to the
494 starting disk number */
495 if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
496 err=UNZ_ERRNO;
497
498 /* zipfile comment length */
499 if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
500 err=UNZ_ERRNO;
501
502 if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
503 (err==UNZ_OK))
504 err=UNZ_BADZIPFILE;
505
506 if (err!=UNZ_OK)
507 {
508 fclose(fin);
509 return NULL;
510 }
511 us.file=fin;
512 us.byte_before_the_zipfile = central_pos -
513 (us.offset_central_dir+us.size_central_dir);
514 us.central_pos = central_pos;
515 us.pfile_in_zip_read = NULL;
516
517
518 s=(unz_s*)ALLOC(sizeof(unz_s));
519 *s=us;
520 unzGoToFirstFile((unzFile)s);
521 return (unzFile)s;
522 }
523
524
525 /*
526 Close a ZipFile opened with unzipOpen.
527 If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
528 these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
529 return UNZ_OK if there is no problem. */
530 extern int ZEXPORT unzClose (file)
531 unzFile file;
532 {
533 unz_s* s;
534 if (file==NULL)
535 return UNZ_PARAMERROR;
536 s=(unz_s*)file;
537
538 if (s->pfile_in_zip_read!=NULL)
539 unzCloseCurrentFile(file);
540
541 fclose(s->file);
542 TRYFREE(s);
543 return UNZ_OK;
544 }
545
546
547 /*
548 Write info about the ZipFile in the *pglobal_info structure.
549 No preparation of the structure is needed
550 return UNZ_OK if there is no problem. */
551 extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
552 unzFile file;
553 unz_global_info *pglobal_info;
554 {
555 unz_s* s;
556 if (file==NULL)
557 return UNZ_PARAMERROR;
558 s=(unz_s*)file;
559 *pglobal_info=s->gi;
560 return UNZ_OK;
561 }
562
563
564 /*
565 Translate date/time from Dos format to tm_unz (readable more easilty)
566 */
567 local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
568 uLong ulDosDate;
569 tm_unz* ptm;
570 {
571 uLong uDate;
572 uDate = (uLong)(ulDosDate>>16);
573 ptm->tm_mday = (uInt)(uDate&0x1f) ;
574 ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
575 ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
576
577 ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
578 ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
579 ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
580 }
581
582 /*
583 Get Info about the current file in the zipfile, with internal only info
584 */
585 local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
586 unz_file_info *pfile_info,
587 unz_file_info_internal
588 *pfile_info_internal,
589 char *szFileName,
590 uLong fileNameBufferSize,
591 void *extraField,
592 uLong extraFieldBufferSize,
593 char *szComment,
594 uLong commentBufferSize));
595
596 local int unzlocal_GetCurrentFileInfoInternal (file,
597 pfile_info,
598 pfile_info_internal,
599 szFileName, fileNameBufferSize,
600 extraField, extraFieldBufferSize,
601 szComment, commentBufferSize)
602 unzFile file;
603 unz_file_info *pfile_info;
604 unz_file_info_internal *pfile_info_internal;
605 char *szFileName;
606 uLong fileNameBufferSize;
607 void *extraField;
608 uLong extraFieldBufferSize;
609 char *szComment;
610 uLong commentBufferSize;
611 {
612 unz_s* s;
613 unz_file_info file_info;
614 unz_file_info_internal file_info_internal;
615 int err=UNZ_OK;
616 uLong uMagic;
617 long lSeek=0;
618
619 if (file==NULL)
620 return UNZ_PARAMERROR;
621 s=(unz_s*)file;
622 if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
623 err=UNZ_ERRNO;
624
625
626 /* we check the magic */
627 if (err==UNZ_OK)
628 {
629 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
630 err=UNZ_ERRNO;
631 else if (uMagic!=0x02014b50)
632 err=UNZ_BADZIPFILE;
633 }
634
635 if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
636 err=UNZ_ERRNO;
637
638 if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
639 err=UNZ_ERRNO;
640
641 if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
642 err=UNZ_ERRNO;
643
644 if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
645 err=UNZ_ERRNO;
646
647 if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
648 err=UNZ_ERRNO;
649
650 unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
651
652 if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
653 err=UNZ_ERRNO;
654
655 if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
656 err=UNZ_ERRNO;
657
658 if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
659 err=UNZ_ERRNO;
660
661 if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
662 err=UNZ_ERRNO;
663
664 if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
665 err=UNZ_ERRNO;
666
667 if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
668 err=UNZ_ERRNO;
669
670 if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
671 err=UNZ_ERRNO;
672
673 if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
674 err=UNZ_ERRNO;
675
676 if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
677 err=UNZ_ERRNO;
678
679 if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
680 err=UNZ_ERRNO;
681
682 lSeek+=file_info.size_filename;
683 if ((err==UNZ_OK) && (szFileName!=NULL))
684 {
685 uLong uSizeRead ;
686 if (file_info.size_filename<fileNameBufferSize)
687 {
688 *(szFileName+file_info.size_filename)='\0';
689 uSizeRead = file_info.size_filename;
690 }
691 else
692 uSizeRead = fileNameBufferSize;
693
694 if ((file_info.size_filename>0) && (fileNameBufferSize>0))
695 if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
696 err=UNZ_ERRNO;
697 lSeek -= uSizeRead;
698 }
699
700
701 if ((err==UNZ_OK) && (extraField!=NULL))
702 {
703 uLong uSizeRead ;
704 if (file_info.size_file_extra<extraFieldBufferSize)
705 uSizeRead = file_info.size_file_extra;
706 else
707 uSizeRead = extraFieldBufferSize;
708
709 if (lSeek!=0)
710 {
711 if (fseek(s->file,lSeek,SEEK_CUR)==0)
712 lSeek=0;
713 else
714 err=UNZ_ERRNO;
715 }
716
717 if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
718 if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
719 err=UNZ_ERRNO;
720 lSeek += file_info.size_file_extra - uSizeRead;
721 }
722 else
723 lSeek+=file_info.size_file_extra;
724
725
726 if ((err==UNZ_OK) && (szComment!=NULL))
727 {
728 uLong uSizeRead ;
729 if (file_info.size_file_comment<commentBufferSize)
730 {
731 *(szComment+file_info.size_file_comment)='\0';
732 uSizeRead = file_info.size_file_comment;
733 }
734 else
735 uSizeRead = commentBufferSize;
736
737 if (lSeek!=0)
738 {
739 if (fseek(s->file,lSeek,SEEK_CUR)==0)
740 lSeek=0;
741 else
742 err=UNZ_ERRNO;
743 }
744
745 if ((file_info.size_file_comment>0) && (commentBufferSize>0))
746 if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
747 err=UNZ_ERRNO;
748 lSeek+=file_info.size_file_comment - uSizeRead;
749 }
750 else
751 lSeek+=file_info.size_file_comment;
752
753 if ((err==UNZ_OK) && (pfile_info!=NULL))
754 *pfile_info=file_info;
755
756 if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
757 *pfile_info_internal=file_info_internal;
758
759 return err;
760 }
761
762
763
764 /*
765 Write info about the ZipFile in the *pglobal_info structure.
766 No preparation of the structure is needed
767 return UNZ_OK if there is no problem.
768 */
769 extern int ZEXPORT unzGetCurrentFileInfo (file,
770 pfile_info,
771 szFileName, fileNameBufferSize,
772 extraField, extraFieldBufferSize,
773 szComment, commentBufferSize)
774 unzFile file;
775 unz_file_info *pfile_info;
776 char *szFileName;
777 uLong fileNameBufferSize;
778 void *extraField;
779 uLong extraFieldBufferSize;
780 char *szComment;
781 uLong commentBufferSize;
782 {
783 return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
784 szFileName,fileNameBufferSize,
785 extraField,extraFieldBufferSize,
786 szComment,commentBufferSize);
787 }
788
789 /*
790 Set the current file of the zipfile to the first file.
791 return UNZ_OK if there is no problem
792 */
793 extern int ZEXPORT unzGoToFirstFile (file)
794 unzFile file;
795 {
796 int err=UNZ_OK;
797 unz_s* s;
798 if (file==NULL)
799 return UNZ_PARAMERROR;
800 s=(unz_s*)file;
801 s->pos_in_central_dir=s->offset_central_dir;
802 s->num_file=0;
803 err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
804 &s->cur_file_info_internal,
805 NULL,0,NULL,0,NULL,0);
806 s->current_file_ok = (err == UNZ_OK);
807 return err;
808 }
809
810
811 /*
812 Set the current file of the zipfile to the next file.
813 return UNZ_OK if there is no problem
814 return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
815 */
816 extern int ZEXPORT unzGoToNextFile (file)
817 unzFile file;
818 {
819 unz_s* s;
820 int err;
821
822 if (file==NULL)
823 return UNZ_PARAMERROR;
824 s=(unz_s*)file;
825 if (!s->current_file_ok)
826 return UNZ_END_OF_LIST_OF_FILE;
827 if (s->num_file+1==s->gi.number_entry)
828 return UNZ_END_OF_LIST_OF_FILE;
829
830 s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
831 s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
832 s->num_file++;
833 err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
834 &s->cur_file_info_internal,
835 NULL,0,NULL,0,NULL,0);
836 s->current_file_ok = (err == UNZ_OK);
837 return err;
838 }
839
840
841 /*
842 Try locate the file szFileName in the zipfile.
843 For the iCaseSensitivity signification, see unzipStringFileNameCompare
844
845 return value :
846 UNZ_OK if the file is found. It becomes the current file.
847 UNZ_END_OF_LIST_OF_FILE if the file is not found
848 */
849 extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
850 unzFile file;
851 const char *szFileName;
852 int iCaseSensitivity;
853 {
854 unz_s* s;
855 int err;
856 const char *c;
857 char *c2;
858 char szFileName2[UNZ_MAXFILENAMEINZIP+1];
859
860 uLong num_fileSaved;
861 uLong pos_in_central_dirSaved;
862
863 for (c = szFileName, c2 = szFileName2; *c != '\0'; c++, c2++)
864 if (*c == '\\') *c2 = '/';
865 else *c2 = *c;
866 *c2 = '\0';
867
868 if (file==NULL)
869 return UNZ_PARAMERROR;
870
871 if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
872 return UNZ_PARAMERROR;
873
874 s=(unz_s*)file;
875 if (!s->current_file_ok)
876 return UNZ_END_OF_LIST_OF_FILE;
877
878 num_fileSaved = s->num_file;
879 pos_in_central_dirSaved = s->pos_in_central_dir;
880
881 err = unzGoToFirstFile(file);
882
883 while (err == UNZ_OK)
884 {
885 char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
886 unzGetCurrentFileInfo(file,NULL,
887 szCurrentFileName,sizeof(szCurrentFileName)-1,
888 NULL,0,NULL,0);
889 for (c2 = szCurrentFileName; *c2 != '\0'; c2++) if (*c2 == '\\') *c2 = '/';
890 if (unzStringFileNameCompare(szCurrentFileName,
891 szFileName2,iCaseSensitivity)==0)
892 return UNZ_OK;
893 err = unzGoToNextFile(file);
894 }
895
896 s->num_file = num_fileSaved ;
897 s->pos_in_central_dir = pos_in_central_dirSaved ;
898 return err;
899 }
900
901
902 /*
903 Read the local header of the current zipfile
904 Check the coherency of the local header and info in the end of central
905 directory about this file
906 store in *piSizeVar the size of extra info in local header
907 (filename and size of extra field data)
908 */
909 local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
910 poffset_local_extrafield,
911 psize_local_extrafield)
912 unz_s* s;
913 uInt* piSizeVar;
914 uLong *poffset_local_extrafield;
915 uInt *psize_local_extrafield;
916 {
917 uLong uMagic,uData,uFlags;
918 uLong size_filename;
919 uLong size_extra_field;
920 int err=UNZ_OK;
921
922 *piSizeVar = 0;
923 *poffset_local_extrafield = 0;
924 *psize_local_extrafield = 0;
925
926 if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
927 s->byte_before_the_zipfile,SEEK_SET)!=0)
928 return UNZ_ERRNO;
929
930
931 if (err==UNZ_OK)
932 {
933 if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
934 err=UNZ_ERRNO;
935 else if (uMagic!=0x04034b50)
936 err=UNZ_BADZIPFILE;
937 }
938
939 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
940 err=UNZ_ERRNO;
941 /*
942 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
943 err=UNZ_BADZIPFILE;
944 */
945 if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
946 err=UNZ_ERRNO;
947
948 if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
949 err=UNZ_ERRNO;
950 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
951 err=UNZ_BADZIPFILE;
952
953 if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
954 (s->cur_file_info.compression_method!=Z_DEFLATED))
955 err=UNZ_BADZIPFILE;
956
957 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
958 err=UNZ_ERRNO;
959
960 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
961 err=UNZ_ERRNO;
962 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
963 ((uFlags & 8)==0))
964 err=UNZ_BADZIPFILE;
965
966 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
967 err=UNZ_ERRNO;
968 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
969 ((uFlags & 8)==0))
970 err=UNZ_BADZIPFILE;
971
972 if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
973 err=UNZ_ERRNO;
974 else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
975 ((uFlags & 8)==0))
976 err=UNZ_BADZIPFILE;
977
978
979 if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
980 err=UNZ_ERRNO;
981 else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
982 err=UNZ_BADZIPFILE;
983
984 *piSizeVar += (uInt)size_filename;
985
986 if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
987 err=UNZ_ERRNO;
988 *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
989 SIZEZIPLOCALHEADER + size_filename;
990 *psize_local_extrafield = (uInt)size_extra_field;
991
992 *piSizeVar += (uInt)size_extra_field;
993
994 return err;
995 }
996
997 /*
998 Open for reading data the current file in the zipfile.
999 If there is no error and the file is opened, the return value is UNZ_OK.
1000 */
1001 extern int ZEXPORT unzOpenCurrentFile (file)
1002 unzFile file;
1003 {
1004 int err=UNZ_OK;
1005 int Store;
1006 uInt iSizeVar;
1007 unz_s* s;
1008 file_in_zip_read_info_s* pfile_in_zip_read_info;
1009 uLong offset_local_extrafield; /* offset of the local extra field */
1010 uInt size_local_extrafield; /* size of the local extra field */
1011
1012 if (file==NULL)
1013 return UNZ_PARAMERROR;
1014 s=(unz_s*)file;
1015 if (!s->current_file_ok)
1016 return UNZ_PARAMERROR;
1017
1018 if (s->pfile_in_zip_read != NULL)
1019 unzCloseCurrentFile(file);
1020
1021 if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
1022 &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
1023 return UNZ_BADZIPFILE;
1024
1025 pfile_in_zip_read_info = (file_in_zip_read_info_s*)
1026 ALLOC(sizeof(file_in_zip_read_info_s));
1027 if (pfile_in_zip_read_info==NULL)
1028 return UNZ_INTERNALERROR;
1029
1030 pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
1031 pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1032 pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1033 pfile_in_zip_read_info->pos_local_extrafield=0;
1034
1035 if (pfile_in_zip_read_info->read_buffer==NULL)
1036 {
1037 TRYFREE(pfile_in_zip_read_info);
1038 return UNZ_INTERNALERROR;
1039 }
1040
1041 pfile_in_zip_read_info->stream_initialised=0;
1042
1043 if ((s->cur_file_info.compression_method!=0) &&
1044 (s->cur_file_info.compression_method!=Z_DEFLATED))
1045 err=UNZ_BADZIPFILE;
1046 Store = s->cur_file_info.compression_method==0;
1047
1048 pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
1049 pfile_in_zip_read_info->crc32=0;
1050 pfile_in_zip_read_info->compression_method =
1051 s->cur_file_info.compression_method;
1052 pfile_in_zip_read_info->file=s->file;
1053 pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
1054
1055 pfile_in_zip_read_info->stream.total_out = 0;
1056
1057 if (!Store)
1058 {
1059 pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
1060 pfile_in_zip_read_info->stream.zfree = (free_func)0;
1061 pfile_in_zip_read_info->stream.opaque = (voidpf)0;
1062
1063 err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
1064 if (err == Z_OK)
1065 pfile_in_zip_read_info->stream_initialised=1;
1066 /* windowBits is passed < 0 to tell that there is no zlib header.
1067 * Note that in this case inflate *requires* an extra "dummy" byte
1068 * after the compressed stream in order to complete decompression and
1069 * return Z_STREAM_END.
1070 * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1071 * size of both compressed and uncompressed data
1072 */
1073 }
1074 pfile_in_zip_read_info->rest_read_compressed =
1075 s->cur_file_info.compressed_size ;
1076 pfile_in_zip_read_info->rest_read_uncompressed =
1077 s->cur_file_info.uncompressed_size ;
1078
1079
1080 pfile_in_zip_read_info->pos_in_zipfile =
1081 s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
1082 iSizeVar;
1083
1084 pfile_in_zip_read_info->stream.avail_in = (uInt)0;
1085
1086
1087 s->pfile_in_zip_read = pfile_in_zip_read_info;
1088 return UNZ_OK;
1089 }
1090
1091
1092 /*
1093 Read bytes from the current file.
1094 buf contain buffer where data must be copied
1095 len the size of buf.
1096
1097 return the number of byte copied if somes bytes are copied
1098 return 0 if the end of file was reached
1099 return <0 with error code if there is an error
1100 (UNZ_ERRNO for IO error, or zLib error for uncompress error)
1101 */
1102 extern int ZEXPORT unzReadCurrentFile (file, buf, len)
1103 unzFile file;
1104 voidp buf;
1105 unsigned len;
1106 {
1107 int err=UNZ_OK;
1108 uInt iRead = 0;
1109 unz_s* s;
1110 file_in_zip_read_info_s* pfile_in_zip_read_info;
1111 if (file==NULL)
1112 return UNZ_PARAMERROR;
1113 s=(unz_s*)file;
1114 pfile_in_zip_read_info=s->pfile_in_zip_read;
1115
1116 if (pfile_in_zip_read_info==NULL)
1117 return UNZ_PARAMERROR;
1118
1119
1120 if ((pfile_in_zip_read_info->read_buffer == NULL))
1121 return UNZ_END_OF_LIST_OF_FILE;
1122 if (len==0)
1123 return 0;
1124
1125 pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
1126
1127 pfile_in_zip_read_info->stream.avail_out = (uInt)len;
1128
1129 if (len>pfile_in_zip_read_info->rest_read_uncompressed)
1130 pfile_in_zip_read_info->stream.avail_out =
1131 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
1132
1133 while (pfile_in_zip_read_info->stream.avail_out>0)
1134 {
1135 if ((pfile_in_zip_read_info->stream.avail_in==0) &&
1136 (pfile_in_zip_read_info->rest_read_compressed>0))
1137 {
1138 uInt uReadThis = UNZ_BUFSIZE;
1139 if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1140 uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
1141 if (uReadThis == 0)
1142 return UNZ_EOF;
1143 if (fseek(pfile_in_zip_read_info->file,
1144 pfile_in_zip_read_info->pos_in_zipfile +
1145 pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
1146 return UNZ_ERRNO;
1147 if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
1148 pfile_in_zip_read_info->file)!=1)
1149 return UNZ_ERRNO;
1150 pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1151
1152 pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
1153
1154 pfile_in_zip_read_info->stream.next_in =
1155 (Bytef*)pfile_in_zip_read_info->read_buffer;
1156 pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
1157 }
1158
1159 if (pfile_in_zip_read_info->compression_method==0)
1160 {
1161 uInt uDoCopy,i ;
1162 if (pfile_in_zip_read_info->stream.avail_out <
1163 pfile_in_zip_read_info->stream.avail_in)
1164 uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
1165 else
1166 uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
1167
1168 for (i=0;i<uDoCopy;i++)
1169 *(pfile_in_zip_read_info->stream.next_out+i) =
1170 *(pfile_in_zip_read_info->stream.next_in+i);
1171
1172 pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
1173 pfile_in_zip_read_info->stream.next_out,
1174 uDoCopy);
1175 pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
1176 pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1177 pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1178 pfile_in_zip_read_info->stream.next_out += uDoCopy;
1179 pfile_in_zip_read_info->stream.next_in += uDoCopy;
1180 pfile_in_zip_read_info->stream.total_out += uDoCopy;
1181 iRead += uDoCopy;
1182 }
1183 else
1184 {
1185 uLong uTotalOutBefore,uTotalOutAfter;
1186 const Bytef *bufBefore;
1187 uLong uOutThis;
1188 int flush=Z_SYNC_FLUSH;
1189
1190 uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1191 bufBefore = pfile_in_zip_read_info->stream.next_out;
1192
1193 /*
1194 if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1195 pfile_in_zip_read_info->stream.avail_out) &&
1196 (pfile_in_zip_read_info->rest_read_compressed == 0))
1197 flush = Z_FINISH;
1198 */
1199 err=inflate(&pfile_in_zip_read_info->stream,flush);
1200
1201 uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1202 uOutThis = uTotalOutAfter-uTotalOutBefore;
1203
1204 pfile_in_zip_read_info->crc32 =
1205 crc32(pfile_in_zip_read_info->crc32,bufBefore,
1206 (uInt)(uOutThis));
1207
1208 pfile_in_zip_read_info->rest_read_uncompressed -=
1209 uOutThis;
1210
1211 iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
1212
1213 if (err==Z_STREAM_END)
1214 return (iRead==0) ? UNZ_EOF : iRead;
1215 if (err!=Z_OK)
1216 break;
1217 }
1218 }
1219
1220 if (err==Z_OK)
1221 return iRead;
1222 return err;
1223 }
1224
1225
1226 /*
1227 Give the current position in uncompressed data
1228 */
1229 extern z_off_t ZEXPORT unztell (file)
1230 unzFile file;
1231 {
1232 unz_s* s;
1233 file_in_zip_read_info_s* pfile_in_zip_read_info;
1234 if (file==NULL)
1235 return UNZ_PARAMERROR;
1236 s=(unz_s*)file;
1237 pfile_in_zip_read_info=s->pfile_in_zip_read;
1238
1239 if (pfile_in_zip_read_info==NULL)
1240 return UNZ_PARAMERROR;
1241
1242 return (z_off_t)pfile_in_zip_read_info->stream.total_out;
1243 }
1244
1245
1246 /*
1247 return 1 if the end of file was reached, 0 elsewhere
1248 */
1249 extern int ZEXPORT unzeof (file)
1250 unzFile file;
1251 {
1252 unz_s* s;
1253 file_in_zip_read_info_s* pfile_in_zip_read_info;
1254 if (file==NULL)
1255 return UNZ_PARAMERROR;
1256 s=(unz_s*)file;
1257 pfile_in_zip_read_info=s->pfile_in_zip_read;
1258
1259 if (pfile_in_zip_read_info==NULL)
1260 return UNZ_PARAMERROR;
1261
1262 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1263 return 1;
1264 else
1265 return 0;
1266 }
1267
1268
1269
1270 /*
1271 Read extra field from the current file (opened by unzOpenCurrentFile)
1272 This is the local-header version of the extra field (sometimes, there is
1273 more info in the local-header version than in the central-header)
1274
1275 if buf==NULL, it return the size of the local extra field that can be read
1276
1277 if buf!=NULL, len is the size of the buffer, the extra header is copied in
1278 buf.
1279 the return value is the number of bytes copied in buf, or (if <0)
1280 the error code
1281 */
1282 extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
1283 unzFile file;
1284 voidp buf;
1285 unsigned len;
1286 {
1287 unz_s* s;
1288 file_in_zip_read_info_s* pfile_in_zip_read_info;
1289 uInt read_now;
1290 uLong size_to_read;
1291
1292 if (file==NULL)
1293 return UNZ_PARAMERROR;
1294 s=(unz_s*)file;
1295 pfile_in_zip_read_info=s->pfile_in_zip_read;
1296
1297 if (pfile_in_zip_read_info==NULL)
1298 return UNZ_PARAMERROR;
1299
1300 size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
1301 pfile_in_zip_read_info->pos_local_extrafield);
1302
1303 if (buf==NULL)
1304 return (int)size_to_read;
1305
1306 if (len>size_to_read)
1307 read_now = (uInt)size_to_read;
1308 else
1309 read_now = (uInt)len ;
1310
1311 if (read_now==0)
1312 return 0;
1313
1314 if (fseek(pfile_in_zip_read_info->file,
1315 pfile_in_zip_read_info->offset_local_extrafield +
1316 pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
1317 return UNZ_ERRNO;
1318
1319 if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
1320 return UNZ_ERRNO;
1321
1322 return (int)read_now;
1323 }
1324
1325 /*
1326 Close the file in zip opened with unzipOpenCurrentFile
1327 Return UNZ_CRCERROR if all the file was read but the CRC is not good
1328 */
1329 extern int ZEXPORT unzCloseCurrentFile (file)
1330 unzFile file;
1331 {
1332 int err=UNZ_OK;
1333
1334 unz_s* s;
1335 file_in_zip_read_info_s* pfile_in_zip_read_info;
1336 if (file==NULL)
1337 return UNZ_PARAMERROR;
1338 s=(unz_s*)file;
1339 pfile_in_zip_read_info=s->pfile_in_zip_read;
1340
1341 if (pfile_in_zip_read_info==NULL)
1342 return UNZ_PARAMERROR;
1343
1344
1345 if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
1346 {
1347 if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
1348 err=UNZ_CRCERROR;
1349 }
1350
1351
1352 TRYFREE(pfile_in_zip_read_info->read_buffer);
1353 pfile_in_zip_read_info->read_buffer = NULL;
1354 if (pfile_in_zip_read_info->stream_initialised)
1355 inflateEnd(&pfile_in_zip_read_info->stream);
1356
1357 pfile_in_zip_read_info->stream_initialised = 0;
1358 TRYFREE(pfile_in_zip_read_info);
1359
1360 s->pfile_in_zip_read=NULL;
1361
1362 return err;
1363 }
1364
1365
1366 /*
1367 Get the global comment string of the ZipFile, in the szComment buffer.
1368 uSizeBuf is the size of the szComment buffer.
1369 return the number of byte copied or an error code <0
1370 */
1371 extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
1372 unzFile file;
1373 char *szComment;
1374 uLong uSizeBuf;
1375 {
1376 unz_s* s;
1377 uLong uReadThis ;
1378 if (file==NULL)
1379 return UNZ_PARAMERROR;
1380 s=(unz_s*)file;
1381
1382 uReadThis = uSizeBuf;
1383 if (uReadThis>s->gi.size_comment)
1384 uReadThis = s->gi.size_comment;
1385
1386 if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
1387 return UNZ_ERRNO;
1388
1389 if (uReadThis>0)
1390 {
1391 *szComment='\0';
1392 if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
1393 return UNZ_ERRNO;
1394 }
1395
1396 if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
1397 *(szComment+s->gi.size_comment)='\0';
1398 return (int)uReadThis;
1399 }
1400
1401 #else
1402
1403 /* the file shouldn't be empty, som compilers don't like it */
1404 static const int dummyVariableInUnzip = 17;
1405
1406 #endif /* wxUSE_ZLIB && wxUSE_ZIPSTREAM */