~ubuntu-branches/debian/experimental/smplayer/experimental

« back to all changes in this revision

Viewing changes to src/findsubtitles/quazip/zip.c

  • Committer: Bazaar Package Importer
  • Author(s): Maia Kozheva
  • Date: 2009-01-03 17:08:06 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090103170806-eodntb2slv6g2pb6
Tags: 0.6.6-0ubuntu1
* The "just before FF" release.
* New upstream release.
* debian/control: Bumped Standards-Version to 3.8.0.
* debian/copyright: Changed (C) to © to fix Lintian warning.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* zip.c -- IO on .zip files using zlib
 
2
   Version 1.01e, February 12th, 2005
 
3
 
 
4
   27 Dec 2004 Rolf Kalbermatter
 
5
   Modification to zipOpen2 to support globalComment retrieval.
 
6
 
 
7
   Copyright (C) 1998-2005 Gilles Vollant
 
8
 
 
9
   Read zip.h for more info
 
10
*/
 
11
 
 
12
 
 
13
#include <stdio.h>
 
14
#include <stdlib.h>
 
15
#include <string.h>
 
16
#include <time.h>
 
17
#include "zlib.h"
 
18
#include "zip.h"
 
19
 
 
20
#ifdef STDC
 
21
#  include <stddef.h>
 
22
#  include <string.h>
 
23
#  include <stdlib.h>
 
24
#endif
 
25
#ifdef NO_ERRNO_H
 
26
    extern int errno;
 
27
#else
 
28
#   include <errno.h>
 
29
#endif
 
30
 
 
31
 
 
32
#ifndef local
 
33
#  define local static
 
34
#endif
 
35
/* compile with -Dlocal if your debugger can't find static symbols */
 
36
 
 
37
#ifndef VERSIONMADEBY
 
38
# define VERSIONMADEBY   (0x0) /* platform depedent */
 
39
#endif
 
40
 
 
41
#ifndef Z_BUFSIZE
 
42
#define Z_BUFSIZE (16384)
 
43
#endif
 
44
 
 
45
#ifndef Z_MAXFILENAMEINZIP
 
46
#define Z_MAXFILENAMEINZIP (256)
 
47
#endif
 
48
 
 
49
#ifndef ALLOC
 
50
# define ALLOC(size) (malloc(size))
 
51
#endif
 
52
#ifndef TRYFREE
 
53
# define TRYFREE(p) {if (p) free(p);}
 
54
#endif
 
55
 
 
56
/*
 
57
#define SIZECENTRALDIRITEM (0x2e)
 
58
#define SIZEZIPLOCALHEADER (0x1e)
 
59
*/
 
60
 
 
61
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
 
62
 
 
63
#ifndef SEEK_CUR
 
64
#define SEEK_CUR    1
 
65
#endif
 
66
 
 
67
#ifndef SEEK_END
 
68
#define SEEK_END    2
 
69
#endif
 
70
 
 
71
#ifndef SEEK_SET
 
72
#define SEEK_SET    0
 
73
#endif
 
74
 
 
75
#ifndef DEF_MEM_LEVEL
 
76
#if MAX_MEM_LEVEL >= 8
 
77
#  define DEF_MEM_LEVEL 8
 
78
#else
 
79
#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
 
80
#endif
 
81
#endif
 
82
const char zip_copyright[] =
 
83
   " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
 
84
 
 
85
 
 
86
#define SIZEDATA_INDATABLOCK (4096-(4*4))
 
87
 
 
88
#define LOCALHEADERMAGIC    (0x04034b50)
 
89
#define CENTRALHEADERMAGIC  (0x02014b50)
 
90
#define ENDHEADERMAGIC      (0x06054b50)
 
91
 
 
92
#define FLAG_LOCALHEADER_OFFSET (0x06)
 
93
#define CRC_LOCALHEADER_OFFSET  (0x0e)
 
94
 
 
95
#define SIZECENTRALHEADER (0x2e) /* 46 */
 
96
 
 
97
typedef struct linkedlist_datablock_internal_s
 
98
{
 
99
  struct linkedlist_datablock_internal_s* next_datablock;
 
100
  uLong  avail_in_this_block;
 
101
  uLong  filled_in_this_block;
 
102
  uLong  unused; /* for future use and alignement */
 
103
  unsigned char data[SIZEDATA_INDATABLOCK];
 
104
} linkedlist_datablock_internal;
 
105
 
 
106
typedef struct linkedlist_data_s
 
107
{
 
108
    linkedlist_datablock_internal* first_block;
 
109
    linkedlist_datablock_internal* last_block;
 
110
} linkedlist_data;
 
111
 
 
112
 
 
113
typedef struct
 
114
{
 
115
    z_stream stream;            /* zLib stream structure for inflate */
 
116
    int  stream_initialised;    /* 1 is stream is initialised */
 
117
    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
 
118
 
 
119
    uLong pos_local_header;     /* offset of the local header of the file
 
120
                                     currenty writing */
 
121
    char* central_header;       /* central header data for the current file */
 
122
    uLong size_centralheader;   /* size of the central header for cur file */
 
123
    uLong flag;                 /* flag of the file currently writing */
 
124
 
 
125
    int  method;                /* compression method of file currenty wr.*/
 
126
    int  raw;                   /* 1 for directly writing raw data */
 
127
    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
 
128
    uLong dosDate;
 
129
    uLong crc32;
 
130
    int  encrypt;
 
131
#ifndef NOCRYPT
 
132
    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
 
133
    const unsigned long* pcrc_32_tab;
 
134
    int crypt_header_size;
 
135
#endif
 
136
} curfile_info;
 
137
 
 
138
typedef struct
 
139
{
 
140
    zlib_filefunc_def z_filefunc;
 
141
    voidpf filestream;        /* io structore of the zipfile */
 
142
    linkedlist_data central_dir;/* datablock with central dir in construction*/
 
143
    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
 
144
    curfile_info ci;            /* info on the file curretly writing */
 
145
 
 
146
    uLong begin_pos;            /* position of the beginning of the zipfile */
 
147
    uLong add_position_when_writting_offset;
 
148
    uLong number_entry;
 
149
#ifndef NO_ADDFILEINEXISTINGZIP
 
150
    char *globalcomment;
 
151
#endif
 
152
} zip_internal;
 
153
 
 
154
 
 
155
 
 
156
#ifndef NOCRYPT
 
157
#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
 
158
#include "crypt.h"
 
159
#endif
 
160
 
 
161
local linkedlist_datablock_internal* allocate_new_datablock()
 
162
{
 
163
    linkedlist_datablock_internal* ldi;
 
164
    ldi = (linkedlist_datablock_internal*)
 
165
                 ALLOC(sizeof(linkedlist_datablock_internal));
 
166
    if (ldi!=NULL)
 
167
    {
 
168
        ldi->next_datablock = NULL ;
 
169
        ldi->filled_in_this_block = 0 ;
 
170
        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
 
171
    }
 
172
    return ldi;
 
173
}
 
174
 
 
175
local void free_datablock(ldi)
 
176
    linkedlist_datablock_internal* ldi;
 
177
{
 
178
    while (ldi!=NULL)
 
179
    {
 
180
        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
 
181
        TRYFREE(ldi);
 
182
        ldi = ldinext;
 
183
    }
 
184
}
 
185
 
 
186
local void init_linkedlist(ll)
 
187
    linkedlist_data* ll;
 
188
{
 
189
    ll->first_block = ll->last_block = NULL;
 
190
}
 
191
 
 
192
#if 0 // unused
 
193
local void free_linkedlist(ll)
 
194
    linkedlist_data* ll;
 
195
{
 
196
    free_datablock(ll->first_block);
 
197
    ll->first_block = ll->last_block = NULL;
 
198
}
 
199
#endif
 
200
 
 
201
local int add_data_in_datablock(ll,buf,len)
 
202
    linkedlist_data* ll;
 
203
    const void* buf;
 
204
    uLong len;
 
205
{
 
206
    linkedlist_datablock_internal* ldi;
 
207
    const unsigned char* from_copy;
 
208
 
 
209
    if (ll==NULL)
 
210
        return ZIP_INTERNALERROR;
 
211
 
 
212
    if (ll->last_block == NULL)
 
213
    {
 
214
        ll->first_block = ll->last_block = allocate_new_datablock();
 
215
        if (ll->first_block == NULL)
 
216
            return ZIP_INTERNALERROR;
 
217
    }
 
218
 
 
219
    ldi = ll->last_block;
 
220
    from_copy = (unsigned char*)buf;
 
221
 
 
222
    while (len>0)
 
223
    {
 
224
        uInt copy_this;
 
225
        uInt i;
 
226
        unsigned char* to_copy;
 
227
 
 
228
        if (ldi->avail_in_this_block==0)
 
229
        {
 
230
            ldi->next_datablock = allocate_new_datablock();
 
231
            if (ldi->next_datablock == NULL)
 
232
                return ZIP_INTERNALERROR;
 
233
            ldi = ldi->next_datablock ;
 
234
            ll->last_block = ldi;
 
235
        }
 
236
 
 
237
        if (ldi->avail_in_this_block < len)
 
238
            copy_this = (uInt)ldi->avail_in_this_block;
 
239
        else
 
240
            copy_this = (uInt)len;
 
241
 
 
242
        to_copy = &(ldi->data[ldi->filled_in_this_block]);
 
243
 
 
244
        for (i=0;i<copy_this;i++)
 
245
            *(to_copy+i)=*(from_copy+i);
 
246
 
 
247
        ldi->filled_in_this_block += copy_this;
 
248
        ldi->avail_in_this_block -= copy_this;
 
249
        from_copy += copy_this ;
 
250
        len -= copy_this;
 
251
    }
 
252
    return ZIP_OK;
 
253
}
 
254
 
 
255
 
 
256
 
 
257
/****************************************************************************/
 
258
 
 
259
#ifndef NO_ADDFILEINEXISTINGZIP
 
260
/* ===========================================================================
 
261
   Inputs a long in LSB order to the given file
 
262
   nbByte == 1, 2 or 4 (byte, short or long)
 
263
*/
 
264
 
 
265
local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
 
266
                                voidpf filestream, uLong x, int nbByte));
 
267
local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
 
268
    const zlib_filefunc_def* pzlib_filefunc_def;
 
269
    voidpf filestream;
 
270
    uLong x;
 
271
    int nbByte;
 
272
{
 
273
    unsigned char buf[4];
 
274
    int n;
 
275
    for (n = 0; n < nbByte; n++)
 
276
    {
 
277
        buf[n] = (unsigned char)(x & 0xff);
 
278
        x >>= 8;
 
279
    }
 
280
    if (x != 0)
 
281
      {     /* data overflow - hack for ZIP64 (X Roche) */
 
282
      for (n = 0; n < nbByte; n++)
 
283
        {
 
284
          buf[n] = 0xff;
 
285
        }
 
286
      }
 
287
 
 
288
    if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
 
289
        return ZIP_ERRNO;
 
290
    else
 
291
        return ZIP_OK;
 
292
}
 
293
 
 
294
local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
 
295
local void ziplocal_putValue_inmemory (dest, x, nbByte)
 
296
    void* dest;
 
297
    uLong x;
 
298
    int nbByte;
 
299
{
 
300
    unsigned char* buf=(unsigned char*)dest;
 
301
    int n;
 
302
    for (n = 0; n < nbByte; n++) {
 
303
        buf[n] = (unsigned char)(x & 0xff);
 
304
        x >>= 8;
 
305
    }
 
306
 
 
307
    if (x != 0)
 
308
    {     /* data overflow - hack for ZIP64 */
 
309
       for (n = 0; n < nbByte; n++)
 
310
       {
 
311
          buf[n] = 0xff;
 
312
       }
 
313
    }
 
314
}
 
315
 
 
316
/****************************************************************************/
 
317
 
 
318
 
 
319
local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
 
320
    const tm_zip* ptm;
 
321
    uLong dosDate;
 
322
{
 
323
    (void) dosDate; /* avoid "unused parameter" warning */
 
324
    uLong year = (uLong)ptm->tm_year;
 
325
    if (year>1980)
 
326
        year-=1980;
 
327
    else if (year>80)
 
328
        year-=80;
 
329
    return
 
330
      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
 
331
        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
 
332
}
 
333
 
 
334
 
 
335
/****************************************************************************/
 
336
 
 
337
local int ziplocal_getByte OF((
 
338
    const zlib_filefunc_def* pzlib_filefunc_def,
 
339
    voidpf filestream,
 
340
    int *pi));
 
341
 
 
342
local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
 
343
    const zlib_filefunc_def* pzlib_filefunc_def;
 
344
    voidpf filestream;
 
345
    int *pi;
 
346
{
 
347
    unsigned char c;
 
348
    int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
 
349
    if (err==1)
 
350
    {
 
351
        *pi = (int)c;
 
352
        return ZIP_OK;
 
353
    }
 
354
    else
 
355
    {
 
356
        if (ZERROR(*pzlib_filefunc_def,filestream))
 
357
            return ZIP_ERRNO;
 
358
        else
 
359
            return ZIP_EOF;
 
360
    }
 
361
}
 
362
 
 
363
 
 
364
/* ===========================================================================
 
365
   Reads a long in LSB order from the given gz_stream. Sets
 
366
*/
 
367
local int ziplocal_getShort OF((
 
368
    const zlib_filefunc_def* pzlib_filefunc_def,
 
369
    voidpf filestream,
 
370
    uLong *pX));
 
371
 
 
372
local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
 
373
    const zlib_filefunc_def* pzlib_filefunc_def;
 
374
    voidpf filestream;
 
375
    uLong *pX;
 
376
{
 
377
    uLong x ;
 
378
    int i;
 
379
    int err;
 
380
 
 
381
    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
 
382
    x = (uLong)i;
 
383
 
 
384
    if (err==ZIP_OK)
 
385
        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
 
386
    x += ((uLong)i)<<8;
 
387
 
 
388
    if (err==ZIP_OK)
 
389
        *pX = x;
 
390
    else
 
391
        *pX = 0;
 
392
    return err;
 
393
}
 
394
 
 
395
local int ziplocal_getLong OF((
 
396
    const zlib_filefunc_def* pzlib_filefunc_def,
 
397
    voidpf filestream,
 
398
    uLong *pX));
 
399
 
 
400
local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
 
401
    const zlib_filefunc_def* pzlib_filefunc_def;
 
402
    voidpf filestream;
 
403
    uLong *pX;
 
404
{
 
405
    uLong x ;
 
406
    int i;
 
407
    int err;
 
408
 
 
409
    err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
 
410
    x = (uLong)i;
 
411
 
 
412
    if (err==ZIP_OK)
 
413
        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
 
414
    x += ((uLong)i)<<8;
 
415
 
 
416
    if (err==ZIP_OK)
 
417
        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
 
418
    x += ((uLong)i)<<16;
 
419
 
 
420
    if (err==ZIP_OK)
 
421
        err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
 
422
    x += ((uLong)i)<<24;
 
423
 
 
424
    if (err==ZIP_OK)
 
425
        *pX = x;
 
426
    else
 
427
        *pX = 0;
 
428
    return err;
 
429
}
 
430
 
 
431
#ifndef BUFREADCOMMENT
 
432
#define BUFREADCOMMENT (0x400)
 
433
#endif
 
434
/*
 
435
  Locate the Central directory of a zipfile (at the end, just before
 
436
    the global comment)
 
437
*/
 
438
local uLong ziplocal_SearchCentralDir OF((
 
439
    const zlib_filefunc_def* pzlib_filefunc_def,
 
440
    voidpf filestream));
 
441
 
 
442
local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
 
443
    const zlib_filefunc_def* pzlib_filefunc_def;
 
444
    voidpf filestream;
 
445
{
 
446
    unsigned char* buf;
 
447
    uLong uSizeFile;
 
448
    uLong uBackRead;
 
449
    uLong uMaxBack=0xffff; /* maximum size of global comment */
 
450
    uLong uPosFound=0;
 
451
 
 
452
    if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
 
453
        return 0;
 
454
 
 
455
 
 
456
    uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
 
457
 
 
458
    if (uMaxBack>uSizeFile)
 
459
        uMaxBack = uSizeFile;
 
460
 
 
461
    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
 
462
    if (buf==NULL)
 
463
        return 0;
 
464
 
 
465
    uBackRead = 4;
 
466
    while (uBackRead<uMaxBack)
 
467
    {
 
468
        uLong uReadSize,uReadPos ;
 
469
        int i;
 
470
        if (uBackRead+BUFREADCOMMENT>uMaxBack)
 
471
            uBackRead = uMaxBack;
 
472
        else
 
473
            uBackRead+=BUFREADCOMMENT;
 
474
        uReadPos = uSizeFile-uBackRead ;
 
475
 
 
476
        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
 
477
                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
 
478
        if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
479
            break;
 
480
 
 
481
        if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
 
482
            break;
 
483
 
 
484
        for (i=(int)uReadSize-3; (i--)>0;)
 
485
            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
 
486
                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
 
487
            {
 
488
                uPosFound = uReadPos+i;
 
489
                break;
 
490
            }
 
491
 
 
492
        if (uPosFound!=0)
 
493
            break;
 
494
    }
 
495
    TRYFREE(buf);
 
496
    return uPosFound;
 
497
}
 
498
#endif /* !NO_ADDFILEINEXISTINGZIP*/
 
499
 
 
500
/************************************************************/
 
501
extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
 
502
    const char *pathname;
 
503
    int append;
 
504
    zipcharpc* globalcomment;
 
505
    zlib_filefunc_def* pzlib_filefunc_def;
 
506
{
 
507
    zip_internal ziinit;
 
508
    zip_internal* zi;
 
509
    int err=ZIP_OK;
 
510
 
 
511
 
 
512
    if (pzlib_filefunc_def==NULL)
 
513
        fill_fopen_filefunc(&ziinit.z_filefunc);
 
514
    else
 
515
        ziinit.z_filefunc = *pzlib_filefunc_def;
 
516
 
 
517
    ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
 
518
                 (ziinit.z_filefunc.opaque,
 
519
                  pathname,
 
520
                  (append == APPEND_STATUS_CREATE) ?
 
521
                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
 
522
                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
 
523
 
 
524
    if (ziinit.filestream == NULL)
 
525
        return NULL;
 
526
    ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
 
527
    ziinit.in_opened_file_inzip = 0;
 
528
    ziinit.ci.stream_initialised = 0;
 
529
    ziinit.number_entry = 0;
 
530
    ziinit.add_position_when_writting_offset = 0;
 
531
    init_linkedlist(&(ziinit.central_dir));
 
532
 
 
533
 
 
534
    zi = (zip_internal*)ALLOC(sizeof(zip_internal));
 
535
    if (zi==NULL)
 
536
    {
 
537
        ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
 
538
        return NULL;
 
539
    }
 
540
 
 
541
    /* now we add file in a zipfile */
 
542
#    ifndef NO_ADDFILEINEXISTINGZIP
 
543
    ziinit.globalcomment = NULL;
 
544
    if (append == APPEND_STATUS_ADDINZIP)
 
545
    {
 
546
        uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
 
547
 
 
548
        uLong size_central_dir;     /* size of the central directory  */
 
549
        uLong offset_central_dir;   /* offset of start of central directory */
 
550
        uLong central_pos,uL;
 
551
 
 
552
        uLong number_disk;          /* number of the current dist, used for
 
553
                                    spaning ZIP, unsupported, always 0*/
 
554
        uLong number_disk_with_CD;  /* number the the disk with central dir, used
 
555
                                    for spaning ZIP, unsupported, always 0*/
 
556
        uLong number_entry;
 
557
        uLong number_entry_CD;      /* total number of entries in
 
558
                                    the central dir
 
559
                                    (same than number_entry on nospan) */
 
560
        uLong size_comment;
 
561
 
 
562
        central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
 
563
        if (central_pos==0)
 
564
            err=ZIP_ERRNO;
 
565
 
 
566
        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
 
567
                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
568
            err=ZIP_ERRNO;
 
569
 
 
570
        /* the signature, already checked */
 
571
        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
 
572
            err=ZIP_ERRNO;
 
573
 
 
574
        /* number of this disk */
 
575
        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
 
576
            err=ZIP_ERRNO;
 
577
 
 
578
        /* number of the disk with the start of the central directory */
 
579
        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
 
580
            err=ZIP_ERRNO;
 
581
 
 
582
        /* total number of entries in the central dir on this disk */
 
583
        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
 
584
            err=ZIP_ERRNO;
 
585
 
 
586
        /* total number of entries in the central dir */
 
587
        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
 
588
            err=ZIP_ERRNO;
 
589
 
 
590
        if ((number_entry_CD!=number_entry) ||
 
591
            (number_disk_with_CD!=0) ||
 
592
            (number_disk!=0))
 
593
            err=ZIP_BADZIPFILE;
 
594
 
 
595
        /* size of the central directory */
 
596
        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
 
597
            err=ZIP_ERRNO;
 
598
 
 
599
        /* offset of start of central directory with respect to the
 
600
            starting disk number */
 
601
        if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
 
602
            err=ZIP_ERRNO;
 
603
 
 
604
        /* zipfile global comment length */
 
605
        if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
 
606
            err=ZIP_ERRNO;
 
607
 
 
608
        if ((central_pos<offset_central_dir+size_central_dir) &&
 
609
            (err==ZIP_OK))
 
610
            err=ZIP_BADZIPFILE;
 
611
 
 
612
        if (err!=ZIP_OK)
 
613
        {
 
614
            ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
 
615
            return NULL;
 
616
        }
 
617
 
 
618
        if (size_comment>0)
 
619
        {
 
620
            ziinit.globalcomment = ALLOC(size_comment+1);
 
621
            if (ziinit.globalcomment)
 
622
            {
 
623
               size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
 
624
               ziinit.globalcomment[size_comment]=0;
 
625
            }
 
626
        }
 
627
 
 
628
        byte_before_the_zipfile = central_pos -
 
629
                                (offset_central_dir+size_central_dir);
 
630
        ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
 
631
 
 
632
        {
 
633
            uLong size_central_dir_to_read = size_central_dir;
 
634
            size_t buf_size = SIZEDATA_INDATABLOCK;
 
635
            void* buf_read = (void*)ALLOC(buf_size);
 
636
            if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
 
637
                  offset_central_dir + byte_before_the_zipfile,
 
638
                  ZLIB_FILEFUNC_SEEK_SET) != 0)
 
639
                  err=ZIP_ERRNO;
 
640
 
 
641
            while ((size_central_dir_to_read>0) && (err==ZIP_OK))
 
642
            {
 
643
                uLong read_this = SIZEDATA_INDATABLOCK;
 
644
                if (read_this > size_central_dir_to_read)
 
645
                    read_this = size_central_dir_to_read;
 
646
                if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
 
647
                    err=ZIP_ERRNO;
 
648
 
 
649
                if (err==ZIP_OK)
 
650
                    err = add_data_in_datablock(&ziinit.central_dir,buf_read,
 
651
                                                (uLong)read_this);
 
652
                size_central_dir_to_read-=read_this;
 
653
            }
 
654
            TRYFREE(buf_read);
 
655
        }
 
656
        ziinit.begin_pos = byte_before_the_zipfile;
 
657
        ziinit.number_entry = number_entry_CD;
 
658
 
 
659
        if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
 
660
                  offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
661
            err=ZIP_ERRNO;
 
662
    }
 
663
 
 
664
    if (globalcomment)
 
665
    {
 
666
      *globalcomment = ziinit.globalcomment;
 
667
    }
 
668
#    endif /* !NO_ADDFILEINEXISTINGZIP*/
 
669
 
 
670
    if (err != ZIP_OK)
 
671
    {
 
672
#    ifndef NO_ADDFILEINEXISTINGZIP
 
673
        TRYFREE(ziinit.globalcomment);
 
674
#    endif /* !NO_ADDFILEINEXISTINGZIP*/
 
675
        TRYFREE(zi);
 
676
        return NULL;
 
677
    }
 
678
    else
 
679
    {
 
680
        *zi = ziinit;
 
681
        return (zipFile)zi;
 
682
    }
 
683
}
 
684
 
 
685
extern zipFile ZEXPORT zipOpen (pathname, append)
 
686
    const char *pathname;
 
687
    int append;
 
688
{
 
689
    return zipOpen2(pathname,append,NULL,NULL);
 
690
}
 
691
 
 
692
extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
 
693
                                         extrafield_local, size_extrafield_local,
 
694
                                         extrafield_global, size_extrafield_global,
 
695
                                         comment, method, level, raw,
 
696
                                         windowBits, memLevel, strategy,
 
697
                                         password, crcForCrypting)
 
698
    zipFile file;
 
699
    const char* filename;
 
700
    const zip_fileinfo* zipfi;
 
701
    const void* extrafield_local;
 
702
    uInt size_extrafield_local;
 
703
    const void* extrafield_global;
 
704
    uInt size_extrafield_global;
 
705
    const char* comment;
 
706
    int method;
 
707
    int level;
 
708
    int raw;
 
709
    int windowBits;
 
710
    int memLevel;
 
711
    int strategy;
 
712
    const char* password;
 
713
    uLong crcForCrypting;
 
714
{
 
715
    zip_internal* zi;
 
716
    uInt size_filename;
 
717
    uInt size_comment;
 
718
    uInt i;
 
719
    int err = ZIP_OK;
 
720
 
 
721
#    ifdef NOCRYPT
 
722
    if (password != NULL)
 
723
        return ZIP_PARAMERROR;
 
724
#    endif
 
725
 
 
726
    if (file == NULL)
 
727
        return ZIP_PARAMERROR;
 
728
    if ((method!=0) && (method!=Z_DEFLATED))
 
729
        return ZIP_PARAMERROR;
 
730
 
 
731
    zi = (zip_internal*)file;
 
732
 
 
733
    if (zi->in_opened_file_inzip == 1)
 
734
    {
 
735
        err = zipCloseFileInZip (file);
 
736
        if (err != ZIP_OK)
 
737
            return err;
 
738
    }
 
739
 
 
740
 
 
741
    if (filename==NULL)
 
742
        filename="-";
 
743
 
 
744
    if (comment==NULL)
 
745
        size_comment = 0;
 
746
    else
 
747
        size_comment = (uInt)strlen(comment);
 
748
 
 
749
    size_filename = (uInt)strlen(filename);
 
750
 
 
751
    if (zipfi == NULL)
 
752
        zi->ci.dosDate = 0;
 
753
    else
 
754
    {
 
755
        if (zipfi->dosDate != 0)
 
756
            zi->ci.dosDate = zipfi->dosDate;
 
757
        else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
 
758
    }
 
759
 
 
760
    zi->ci.flag = 0;
 
761
    if ((level==8) || (level==9))
 
762
      zi->ci.flag |= 2;
 
763
    if ((level==2))
 
764
      zi->ci.flag |= 4;
 
765
    if ((level==1))
 
766
      zi->ci.flag |= 6;
 
767
    if (password != NULL)
 
768
      zi->ci.flag |= 1;
 
769
 
 
770
    zi->ci.crc32 = 0;
 
771
    zi->ci.method = method;
 
772
    zi->ci.encrypt = 0;
 
773
    zi->ci.stream_initialised = 0;
 
774
    zi->ci.pos_in_buffered_data = 0;
 
775
    zi->ci.raw = raw;
 
776
    zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
 
777
    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
 
778
                                      size_extrafield_global + size_comment;
 
779
    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
 
780
 
 
781
    ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
 
782
    /* version info */
 
783
    ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
 
784
    ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
 
785
    ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
 
786
    ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
 
787
    ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
 
788
    ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
 
789
    ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
 
790
    ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
 
791
    ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
 
792
    ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
 
793
    ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
 
794
    ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
 
795
 
 
796
    if (zipfi==NULL)
 
797
        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
 
798
    else
 
799
        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
 
800
 
 
801
    if (zipfi==NULL)
 
802
        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
 
803
    else
 
804
        ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
 
805
 
 
806
    ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
 
807
 
 
808
    for (i=0;i<size_filename;i++)
 
809
        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
 
810
 
 
811
    for (i=0;i<size_extrafield_global;i++)
 
812
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
 
813
              *(((const char*)extrafield_global)+i);
 
814
 
 
815
    for (i=0;i<size_comment;i++)
 
816
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
 
817
              size_extrafield_global+i) = *(comment+i);
 
818
    if (zi->ci.central_header == NULL)
 
819
        return ZIP_INTERNALERROR;
 
820
 
 
821
    /* write the local header */
 
822
    err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
 
823
 
 
824
    if (err==ZIP_OK)
 
825
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
 
826
    if (err==ZIP_OK)
 
827
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
 
828
 
 
829
    if (err==ZIP_OK)
 
830
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
 
831
 
 
832
    if (err==ZIP_OK)
 
833
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
 
834
 
 
835
    if (err==ZIP_OK)
 
836
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
 
837
    if (err==ZIP_OK)
 
838
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
 
839
    if (err==ZIP_OK)
 
840
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
 
841
 
 
842
    if (err==ZIP_OK)
 
843
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
 
844
 
 
845
    if (err==ZIP_OK)
 
846
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
 
847
 
 
848
    if ((err==ZIP_OK) && (size_filename>0))
 
849
        if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
 
850
                err = ZIP_ERRNO;
 
851
 
 
852
    if ((err==ZIP_OK) && (size_extrafield_local>0))
 
853
        if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
 
854
                                                                           !=size_extrafield_local)
 
855
                err = ZIP_ERRNO;
 
856
 
 
857
    zi->ci.stream.avail_in = (uInt)0;
 
858
    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
859
    zi->ci.stream.next_out = zi->ci.buffered_data;
 
860
    zi->ci.stream.total_in = 0;
 
861
    zi->ci.stream.total_out = 0;
 
862
 
 
863
    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
864
    {
 
865
        zi->ci.stream.zalloc = (alloc_func)0;
 
866
        zi->ci.stream.zfree = (free_func)0;
 
867
        zi->ci.stream.opaque = (voidpf)0;
 
868
 
 
869
        if (windowBits>0)
 
870
            windowBits = -windowBits;
 
871
 
 
872
        err = deflateInit2(&zi->ci.stream, level,
 
873
               Z_DEFLATED, windowBits, memLevel, strategy);
 
874
 
 
875
        if (err==Z_OK)
 
876
            zi->ci.stream_initialised = 1;
 
877
    }
 
878
#    ifndef NOCRYPT
 
879
    zi->ci.crypt_header_size = 0;
 
880
    if ((err==Z_OK) && (password != NULL))
 
881
    {
 
882
        unsigned char bufHead[RAND_HEAD_LEN];
 
883
        unsigned int sizeHead;
 
884
        zi->ci.encrypt = 1;
 
885
        zi->ci.pcrc_32_tab = get_crc_table();
 
886
        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
 
887
 
 
888
        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
 
889
        zi->ci.crypt_header_size = sizeHead;
 
890
 
 
891
        if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
 
892
                err = ZIP_ERRNO;
 
893
    }
 
894
#    endif
 
895
 
 
896
    if (err==Z_OK)
 
897
        zi->in_opened_file_inzip = 1;
 
898
    return err;
 
899
}
 
900
 
 
901
extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
 
902
                                        extrafield_local, size_extrafield_local,
 
903
                                        extrafield_global, size_extrafield_global,
 
904
                                        comment, method, level, raw)
 
905
    zipFile file;
 
906
    const char* filename;
 
907
    const zip_fileinfo* zipfi;
 
908
    const void* extrafield_local;
 
909
    uInt size_extrafield_local;
 
910
    const void* extrafield_global;
 
911
    uInt size_extrafield_global;
 
912
    const char* comment;
 
913
    int method;
 
914
    int level;
 
915
    int raw;
 
916
{
 
917
    return zipOpenNewFileInZip3 (file, filename, zipfi,
 
918
                                 extrafield_local, size_extrafield_local,
 
919
                                 extrafield_global, size_extrafield_global,
 
920
                                 comment, method, level, raw,
 
921
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 
922
                                 NULL, 0);
 
923
}
 
924
 
 
925
extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
 
926
                                        extrafield_local, size_extrafield_local,
 
927
                                        extrafield_global, size_extrafield_global,
 
928
                                        comment, method, level)
 
929
    zipFile file;
 
930
    const char* filename;
 
931
    const zip_fileinfo* zipfi;
 
932
    const void* extrafield_local;
 
933
    uInt size_extrafield_local;
 
934
    const void* extrafield_global;
 
935
    uInt size_extrafield_global;
 
936
    const char* comment;
 
937
    int method;
 
938
    int level;
 
939
{
 
940
    return zipOpenNewFileInZip2 (file, filename, zipfi,
 
941
                                 extrafield_local, size_extrafield_local,
 
942
                                 extrafield_global, size_extrafield_global,
 
943
                                 comment, method, level, 0);
 
944
}
 
945
 
 
946
local int zipFlushWriteBuffer(zi)
 
947
  zip_internal* zi;
 
948
{
 
949
    int err=ZIP_OK;
 
950
 
 
951
    if (zi->ci.encrypt != 0)
 
952
    {
 
953
#ifndef NOCRYPT
 
954
        uInt i;
 
955
        int t;
 
956
        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
 
957
            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
 
958
                                       zi->ci.buffered_data[i],t);
 
959
#endif
 
960
    }
 
961
    if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
 
962
                                                                    !=zi->ci.pos_in_buffered_data)
 
963
      err = ZIP_ERRNO;
 
964
    zi->ci.pos_in_buffered_data = 0;
 
965
    return err;
 
966
}
 
967
 
 
968
extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
 
969
    zipFile file;
 
970
    const void* buf;
 
971
    unsigned len;
 
972
{
 
973
    zip_internal* zi;
 
974
    int err=ZIP_OK;
 
975
 
 
976
    if (file == NULL)
 
977
        return ZIP_PARAMERROR;
 
978
    zi = (zip_internal*)file;
 
979
 
 
980
    if (zi->in_opened_file_inzip == 0)
 
981
        return ZIP_PARAMERROR;
 
982
 
 
983
    zi->ci.stream.next_in = (void*)buf;
 
984
    zi->ci.stream.avail_in = len;
 
985
    zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
 
986
 
 
987
    while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
 
988
    {
 
989
        if (zi->ci.stream.avail_out == 0)
 
990
        {
 
991
            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
 
992
                err = ZIP_ERRNO;
 
993
            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
994
            zi->ci.stream.next_out = zi->ci.buffered_data;
 
995
        }
 
996
 
 
997
 
 
998
        if(err != ZIP_OK)
 
999
            break;
 
1000
 
 
1001
        if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1002
        {
 
1003
            uLong uTotalOutBefore = zi->ci.stream.total_out;
 
1004
            err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
 
1005
            zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 
1006
 
 
1007
        }
 
1008
        else
 
1009
        {
 
1010
            uInt copy_this,i;
 
1011
            if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
 
1012
                copy_this = zi->ci.stream.avail_in;
 
1013
            else
 
1014
                copy_this = zi->ci.stream.avail_out;
 
1015
            for (i=0;i<copy_this;i++)
 
1016
                *(((char*)zi->ci.stream.next_out)+i) =
 
1017
                    *(((const char*)zi->ci.stream.next_in)+i);
 
1018
            {
 
1019
                zi->ci.stream.avail_in -= copy_this;
 
1020
                zi->ci.stream.avail_out-= copy_this;
 
1021
                zi->ci.stream.next_in+= copy_this;
 
1022
                zi->ci.stream.next_out+= copy_this;
 
1023
                zi->ci.stream.total_in+= copy_this;
 
1024
                zi->ci.stream.total_out+= copy_this;
 
1025
                zi->ci.pos_in_buffered_data += copy_this;
 
1026
            }
 
1027
        }
 
1028
    }
 
1029
 
 
1030
    return err;
 
1031
}
 
1032
 
 
1033
extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
 
1034
    zipFile file;
 
1035
    uLong uncompressed_size;
 
1036
    uLong crc32;
 
1037
{
 
1038
    zip_internal* zi;
 
1039
    uLong compressed_size;
 
1040
    int err=ZIP_OK;
 
1041
 
 
1042
    if (file == NULL)
 
1043
        return ZIP_PARAMERROR;
 
1044
    zi = (zip_internal*)file;
 
1045
 
 
1046
    if (zi->in_opened_file_inzip == 0)
 
1047
        return ZIP_PARAMERROR;
 
1048
    zi->ci.stream.avail_in = 0;
 
1049
 
 
1050
    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1051
        while (err==ZIP_OK)
 
1052
    {
 
1053
        uLong uTotalOutBefore;
 
1054
        if (zi->ci.stream.avail_out == 0)
 
1055
        {
 
1056
            if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
 
1057
                err = ZIP_ERRNO;
 
1058
            zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
1059
            zi->ci.stream.next_out = zi->ci.buffered_data;
 
1060
        }
 
1061
        uTotalOutBefore = zi->ci.stream.total_out;
 
1062
        err=deflate(&zi->ci.stream,  Z_FINISH);
 
1063
        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 
1064
    }
 
1065
 
 
1066
    if (err==Z_STREAM_END)
 
1067
        err=ZIP_OK; /* this is normal */
 
1068
 
 
1069
    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
 
1070
        if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
 
1071
            err = ZIP_ERRNO;
 
1072
 
 
1073
    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1074
    {
 
1075
        err=deflateEnd(&zi->ci.stream);
 
1076
        zi->ci.stream_initialised = 0;
 
1077
    }
 
1078
 
 
1079
    if (!zi->ci.raw)
 
1080
    {
 
1081
        crc32 = (uLong)zi->ci.crc32;
 
1082
        uncompressed_size = (uLong)zi->ci.stream.total_in;
 
1083
    }
 
1084
    compressed_size = (uLong)zi->ci.stream.total_out;
 
1085
#    ifndef NOCRYPT
 
1086
    compressed_size += zi->ci.crypt_header_size;
 
1087
#    endif
 
1088
 
 
1089
    ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
 
1090
    ziplocal_putValue_inmemory(zi->ci.central_header+20,
 
1091
                                compressed_size,4); /*compr size*/
 
1092
    if (zi->ci.stream.data_type == Z_ASCII)
 
1093
        ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
 
1094
    ziplocal_putValue_inmemory(zi->ci.central_header+24,
 
1095
                                uncompressed_size,4); /*uncompr size*/
 
1096
 
 
1097
    if (err==ZIP_OK)
 
1098
        err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
 
1099
                                       (uLong)zi->ci.size_centralheader);
 
1100
    free(zi->ci.central_header);
 
1101
 
 
1102
    if (err==ZIP_OK)
 
1103
    {
 
1104
        long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
 
1105
        if (ZSEEK(zi->z_filefunc,zi->filestream,
 
1106
                  zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
1107
            err = ZIP_ERRNO;
 
1108
 
 
1109
        if (err==ZIP_OK)
 
1110
            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
 
1111
 
 
1112
        if (err==ZIP_OK) /* compressed size, unknown */
 
1113
            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
 
1114
 
 
1115
        if (err==ZIP_OK) /* uncompressed size, unknown */
 
1116
            err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
 
1117
 
 
1118
        if (ZSEEK(zi->z_filefunc,zi->filestream,
 
1119
                  cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
1120
            err = ZIP_ERRNO;
 
1121
    }
 
1122
 
 
1123
    zi->number_entry ++;
 
1124
    zi->in_opened_file_inzip = 0;
 
1125
 
 
1126
    return err;
 
1127
}
 
1128
 
 
1129
extern int ZEXPORT zipCloseFileInZip (file)
 
1130
    zipFile file;
 
1131
{
 
1132
    return zipCloseFileInZipRaw (file,0,0);
 
1133
}
 
1134
 
 
1135
extern int ZEXPORT zipClose (file, global_comment)
 
1136
    zipFile file;
 
1137
    const char* global_comment;
 
1138
{
 
1139
    zip_internal* zi;
 
1140
    int err = 0;
 
1141
    uLong size_centraldir = 0;
 
1142
    uLong centraldir_pos_inzip;
 
1143
    uInt size_global_comment;
 
1144
    if (file == NULL)
 
1145
        return ZIP_PARAMERROR;
 
1146
    zi = (zip_internal*)file;
 
1147
 
 
1148
    if (zi->in_opened_file_inzip == 1)
 
1149
    {
 
1150
        err = zipCloseFileInZip (file);
 
1151
    }
 
1152
 
 
1153
#ifndef NO_ADDFILEINEXISTINGZIP
 
1154
    if (global_comment==NULL)
 
1155
        global_comment = zi->globalcomment;
 
1156
#endif
 
1157
    if (global_comment==NULL)
 
1158
        size_global_comment = 0;
 
1159
    else
 
1160
        size_global_comment = (uInt)strlen(global_comment);
 
1161
 
 
1162
    centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
 
1163
    if (err==ZIP_OK)
 
1164
    {
 
1165
        linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
 
1166
        while (ldi!=NULL)
 
1167
        {
 
1168
            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
 
1169
                if (ZWRITE(zi->z_filefunc,zi->filestream,
 
1170
                           ldi->data,ldi->filled_in_this_block)
 
1171
                              !=ldi->filled_in_this_block )
 
1172
                    err = ZIP_ERRNO;
 
1173
 
 
1174
            size_centraldir += ldi->filled_in_this_block;
 
1175
            ldi = ldi->next_datablock;
 
1176
        }
 
1177
    }
 
1178
    free_datablock(zi->central_dir.first_block);
 
1179
 
 
1180
    if (err==ZIP_OK) /* Magic End */
 
1181
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
 
1182
 
 
1183
    if (err==ZIP_OK) /* number of this disk */
 
1184
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
 
1185
 
 
1186
    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 
1187
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
 
1188
 
 
1189
    if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
 
1190
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
 
1191
 
 
1192
    if (err==ZIP_OK) /* total number of entries in the central dir */
 
1193
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
 
1194
 
 
1195
    if (err==ZIP_OK) /* size of the central directory */
 
1196
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
 
1197
 
 
1198
    if (err==ZIP_OK) /* offset of start of central directory with respect to the
 
1199
                            starting disk number */
 
1200
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
 
1201
                                (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
 
1202
 
 
1203
    if (err==ZIP_OK) /* zipfile comment length */
 
1204
        err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
 
1205
 
 
1206
    if ((err==ZIP_OK) && (size_global_comment>0))
 
1207
        if (ZWRITE(zi->z_filefunc,zi->filestream,
 
1208
                   global_comment,size_global_comment) != size_global_comment)
 
1209
                err = ZIP_ERRNO;
 
1210
 
 
1211
    if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
 
1212
        if (err == ZIP_OK)
 
1213
            err = ZIP_ERRNO;
 
1214
 
 
1215
#ifndef NO_ADDFILEINEXISTINGZIP
 
1216
    TRYFREE(zi->globalcomment);
 
1217
#endif
 
1218
    TRYFREE(zi);
 
1219
 
 
1220
    return err;
 
1221
}