~ubuntu-branches/ubuntu/edgy/psi/edgy

« back to all changes in this revision

Viewing changes to cutestuff/zip/minizip/unzip.c

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2004-06-15 00:10:41 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040615001041-enywb6pcpe4sjsw6
Tags: 0.9.2-1
* New upstream release
* Set KDEDIR for ./configure so kde specific files get installed
* Don't install libpsiwidgets.so. It got installed in /usr/share
  where it doesn't belong. May be included (at a better location)
  later.

Show diffs side-by-side

added added

removed removed

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