~ubuntu-branches/ubuntu/wily/smplayer/wily

« back to all changes in this revision

Viewing changes to zlib-1.2.6/contrib/minizip/zip.c

  • Committer: Package Import Robot
  • Author(s): Maia Kozheva, Maia Kozheva, Alessio Treglia
  • Date: 2012-04-14 12:01:57 UTC
  • mfrom: (1.1.13)
  • mto: (20.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 23.
  • Revision ID: package-import@ubuntu.com-20120414120157-mndwobcslgisomso
[ Maia Kozheva ]
* New upstream release:
  - Changes since 0.7.1:
    + A toolbar editor has been added. Now it's possible to select the
      buttons and controls that want to appear in the toolbars.
    + New video filters: gradfun, blur and sharpen.
    + Now it's possible to change the GUI (default, mini, mpc) at runtime,
      no restart required.
    + sub files from opensubtitles should work again.
    + (Youtube) Recognize short urls (like this one:
      http://y2u.be/F5OcZBVPwOA)
    + Better support for chapters in video files.
    + Bug fix: remote m3u files work from the favorites menu or command line.
    + Internal changes in the single instance option (switch to 
      QtSingleApplication).
  - Fixes since 0.7.0:
    + SMPlayer took more than 10 seconds to show when running for the very
      first time.
    + The links to download subtitles from Opensubtitles were wrong.
    + SMPlayer crashed in the favorite editor when trying to select a file
      if the KDE open dialog was used.
  - Changes since 0.7.0:
    + By default the screenshots are saved in the user's pictures folder
      instead of the SMPlayer's config folder.
    + Now it's possible to change the opensubtitles server.
    + Youtube: seeking is slow with flv videos, so now flv videos have the
      lowest priority.
    + Youtube: now it's possible to search and download videos from youtube.
      This is provided by an external application (in linux you have to
      install an independent package: smtube).
* debian/copyright:
  - Rewrite according to DEP-5 specification.
* debian/control:
  - Depend on mplayer2 | mplayer. (Closes: #638279)
  - Update Standards-Version to 3.9.3.
* Remove debian/patches/handle_local_urls.diff, merged upstream.

[ Alessio Treglia ]
* Mention smplayer is also a front-end for MPlayer2.
* Fix small typo in the description.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* zip.c -- IO on .zip files using zlib
 
2
   Version 1.1, February 14h, 2010
 
3
   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
 
4
 
 
5
         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
 
6
 
 
7
         Modifications for Zip64 support
 
8
         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
 
9
 
 
10
         For more info read MiniZip_info.txt
 
11
 
 
12
         Changes
 
13
   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
 
14
   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
 
15
   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
 
16
   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
 
17
                                 It is used when recreting zip archive with RAW when deleting items from a zip.
 
18
                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
 
19
   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
 
20
   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
 
21
 
 
22
*/
 
23
 
 
24
 
 
25
#include <stdio.h>
 
26
#include <stdlib.h>
 
27
#include <string.h>
 
28
#include <time.h>
 
29
#include "zlib.h"
 
30
#include "zip.h"
 
31
 
 
32
#ifdef STDC
 
33
#  include <stddef.h>
 
34
#  include <string.h>
 
35
#  include <stdlib.h>
 
36
#endif
 
37
#ifdef NO_ERRNO_H
 
38
    extern int errno;
 
39
#else
 
40
#   include <errno.h>
 
41
#endif
 
42
 
 
43
 
 
44
#ifndef local
 
45
#  define local static
 
46
#endif
 
47
/* compile with -Dlocal if your debugger can't find static symbols */
 
48
 
 
49
#ifndef VERSIONMADEBY
 
50
# define VERSIONMADEBY   (0x0) /* platform depedent */
 
51
#endif
 
52
 
 
53
#ifndef Z_BUFSIZE
 
54
#define Z_BUFSIZE (64*1024) //(16384)
 
55
#endif
 
56
 
 
57
#ifndef Z_MAXFILENAMEINZIP
 
58
#define Z_MAXFILENAMEINZIP (256)
 
59
#endif
 
60
 
 
61
#ifndef ALLOC
 
62
# define ALLOC(size) (malloc(size))
 
63
#endif
 
64
#ifndef TRYFREE
 
65
# define TRYFREE(p) {if (p) free(p);}
 
66
#endif
 
67
 
 
68
/*
 
69
#define SIZECENTRALDIRITEM (0x2e)
 
70
#define SIZEZIPLOCALHEADER (0x1e)
 
71
*/
 
72
 
 
73
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
 
74
 
 
75
 
 
76
// NOT sure that this work on ALL platform
 
77
#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
 
78
 
 
79
#ifndef SEEK_CUR
 
80
#define SEEK_CUR    1
 
81
#endif
 
82
 
 
83
#ifndef SEEK_END
 
84
#define SEEK_END    2
 
85
#endif
 
86
 
 
87
#ifndef SEEK_SET
 
88
#define SEEK_SET    0
 
89
#endif
 
90
 
 
91
#ifndef DEF_MEM_LEVEL
 
92
#if MAX_MEM_LEVEL >= 8
 
93
#  define DEF_MEM_LEVEL 8
 
94
#else
 
95
#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
 
96
#endif
 
97
#endif
 
98
const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
 
99
 
 
100
 
 
101
#define SIZEDATA_INDATABLOCK (4096-(4*4))
 
102
 
 
103
#define LOCALHEADERMAGIC    (0x04034b50)
 
104
#define CENTRALHEADERMAGIC  (0x02014b50)
 
105
#define ENDHEADERMAGIC      (0x06054b50)
 
106
#define ZIP64ENDHEADERMAGIC      (0x6064b50)
 
107
#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
 
108
 
 
109
#define FLAG_LOCALHEADER_OFFSET (0x06)
 
110
#define CRC_LOCALHEADER_OFFSET  (0x0e)
 
111
 
 
112
#define SIZECENTRALHEADER (0x2e) /* 46 */
 
113
 
 
114
typedef struct linkedlist_datablock_internal_s
 
115
{
 
116
  struct linkedlist_datablock_internal_s* next_datablock;
 
117
  uLong  avail_in_this_block;
 
118
  uLong  filled_in_this_block;
 
119
  uLong  unused; /* for future use and alignement */
 
120
  unsigned char data[SIZEDATA_INDATABLOCK];
 
121
} linkedlist_datablock_internal;
 
122
 
 
123
typedef struct linkedlist_data_s
 
124
{
 
125
    linkedlist_datablock_internal* first_block;
 
126
    linkedlist_datablock_internal* last_block;
 
127
} linkedlist_data;
 
128
 
 
129
 
 
130
typedef struct
 
131
{
 
132
    z_stream stream;            /* zLib stream structure for inflate */
 
133
#ifdef HAVE_BZIP2
 
134
    bz_stream bstream;          /* bzLib stream structure for bziped */
 
135
#endif
 
136
 
 
137
    int  stream_initialised;    /* 1 is stream is initialised */
 
138
    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
 
139
 
 
140
    ZPOS64_T pos_local_header;     /* offset of the local header of the file
 
141
                                     currenty writing */
 
142
    char* central_header;       /* central header data for the current file */
 
143
    uLong size_centralExtra;
 
144
    uLong size_centralheader;   /* size of the central header for cur file */
 
145
    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
 
146
    uLong flag;                 /* flag of the file currently writing */
 
147
 
 
148
    int  method;                /* compression method of file currenty wr.*/
 
149
    int  raw;                   /* 1 for directly writing raw data */
 
150
    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
 
151
    uLong dosDate;
 
152
    uLong crc32;
 
153
    int  encrypt;
 
154
    int  zip64;               /* Add ZIP64 extened information in the extra field */
 
155
    ZPOS64_T pos_zip64extrainfo;
 
156
    ZPOS64_T totalCompressedData;
 
157
    ZPOS64_T totalUncompressedData;
 
158
#ifndef NOCRYPT
 
159
    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
 
160
    const unsigned long* pcrc_32_tab;
 
161
    int crypt_header_size;
 
162
#endif
 
163
} curfile64_info;
 
164
 
 
165
typedef struct
 
166
{
 
167
    zlib_filefunc64_32_def z_filefunc;
 
168
    voidpf filestream;        /* io structore of the zipfile */
 
169
    linkedlist_data central_dir;/* datablock with central dir in construction*/
 
170
    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
 
171
    curfile64_info ci;            /* info on the file curretly writing */
 
172
 
 
173
    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
 
174
    ZPOS64_T add_position_when_writting_offset;
 
175
    ZPOS64_T number_entry;
 
176
 
 
177
#ifndef NO_ADDFILEINEXISTINGZIP
 
178
    char *globalcomment;
 
179
#endif
 
180
 
 
181
} zip64_internal;
 
182
 
 
183
 
 
184
#ifndef NOCRYPT
 
185
#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
 
186
#include "crypt.h"
 
187
#endif
 
188
 
 
189
local linkedlist_datablock_internal* allocate_new_datablock()
 
190
{
 
191
    linkedlist_datablock_internal* ldi;
 
192
    ldi = (linkedlist_datablock_internal*)
 
193
                 ALLOC(sizeof(linkedlist_datablock_internal));
 
194
    if (ldi!=NULL)
 
195
    {
 
196
        ldi->next_datablock = NULL ;
 
197
        ldi->filled_in_this_block = 0 ;
 
198
        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
 
199
    }
 
200
    return ldi;
 
201
}
 
202
 
 
203
local void free_datablock(linkedlist_datablock_internal* ldi)
 
204
{
 
205
    while (ldi!=NULL)
 
206
    {
 
207
        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
 
208
        TRYFREE(ldi);
 
209
        ldi = ldinext;
 
210
    }
 
211
}
 
212
 
 
213
local void init_linkedlist(linkedlist_data* ll)
 
214
{
 
215
    ll->first_block = ll->last_block = NULL;
 
216
}
 
217
 
 
218
local void free_linkedlist(linkedlist_data* ll)
 
219
{
 
220
    free_datablock(ll->first_block);
 
221
    ll->first_block = ll->last_block = NULL;
 
222
}
 
223
 
 
224
 
 
225
local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
 
226
{
 
227
    linkedlist_datablock_internal* ldi;
 
228
    const unsigned char* from_copy;
 
229
 
 
230
    if (ll==NULL)
 
231
        return ZIP_INTERNALERROR;
 
232
 
 
233
    if (ll->last_block == NULL)
 
234
    {
 
235
        ll->first_block = ll->last_block = allocate_new_datablock();
 
236
        if (ll->first_block == NULL)
 
237
            return ZIP_INTERNALERROR;
 
238
    }
 
239
 
 
240
    ldi = ll->last_block;
 
241
    from_copy = (unsigned char*)buf;
 
242
 
 
243
    while (len>0)
 
244
    {
 
245
        uInt copy_this;
 
246
        uInt i;
 
247
        unsigned char* to_copy;
 
248
 
 
249
        if (ldi->avail_in_this_block==0)
 
250
        {
 
251
            ldi->next_datablock = allocate_new_datablock();
 
252
            if (ldi->next_datablock == NULL)
 
253
                return ZIP_INTERNALERROR;
 
254
            ldi = ldi->next_datablock ;
 
255
            ll->last_block = ldi;
 
256
        }
 
257
 
 
258
        if (ldi->avail_in_this_block < len)
 
259
            copy_this = (uInt)ldi->avail_in_this_block;
 
260
        else
 
261
            copy_this = (uInt)len;
 
262
 
 
263
        to_copy = &(ldi->data[ldi->filled_in_this_block]);
 
264
 
 
265
        for (i=0;i<copy_this;i++)
 
266
            *(to_copy+i)=*(from_copy+i);
 
267
 
 
268
        ldi->filled_in_this_block += copy_this;
 
269
        ldi->avail_in_this_block -= copy_this;
 
270
        from_copy += copy_this ;
 
271
        len -= copy_this;
 
272
    }
 
273
    return ZIP_OK;
 
274
}
 
275
 
 
276
 
 
277
 
 
278
/****************************************************************************/
 
279
 
 
280
#ifndef NO_ADDFILEINEXISTINGZIP
 
281
/* ===========================================================================
 
282
   Inputs a long in LSB order to the given file
 
283
   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
 
284
*/
 
285
 
 
286
local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
 
287
local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
 
288
{
 
289
    unsigned char buf[8];
 
290
    int n;
 
291
    for (n = 0; n < nbByte; n++)
 
292
    {
 
293
        buf[n] = (unsigned char)(x & 0xff);
 
294
        x >>= 8;
 
295
    }
 
296
    if (x != 0)
 
297
      {     /* data overflow - hack for ZIP64 (X Roche) */
 
298
      for (n = 0; n < nbByte; n++)
 
299
        {
 
300
          buf[n] = 0xff;
 
301
        }
 
302
      }
 
303
 
 
304
    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
 
305
        return ZIP_ERRNO;
 
306
    else
 
307
        return ZIP_OK;
 
308
}
 
309
 
 
310
local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
 
311
local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
 
312
{
 
313
    unsigned char* buf=(unsigned char*)dest;
 
314
    int n;
 
315
    for (n = 0; n < nbByte; n++) {
 
316
        buf[n] = (unsigned char)(x & 0xff);
 
317
        x >>= 8;
 
318
    }
 
319
 
 
320
    if (x != 0)
 
321
    {     /* data overflow - hack for ZIP64 */
 
322
       for (n = 0; n < nbByte; n++)
 
323
       {
 
324
          buf[n] = 0xff;
 
325
       }
 
326
    }
 
327
}
 
328
 
 
329
/****************************************************************************/
 
330
 
 
331
 
 
332
local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
 
333
{
 
334
    uLong year = (uLong)ptm->tm_year;
 
335
    if (year>=1980)
 
336
        year-=1980;
 
337
    else if (year>=80)
 
338
        year-=80;
 
339
    return
 
340
      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
 
341
        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
 
342
}
 
343
 
 
344
 
 
345
/****************************************************************************/
 
346
 
 
347
local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
 
348
 
 
349
local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
 
350
{
 
351
    unsigned char c;
 
352
    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
 
353
    if (err==1)
 
354
    {
 
355
        *pi = (int)c;
 
356
        return ZIP_OK;
 
357
    }
 
358
    else
 
359
    {
 
360
        if (ZERROR64(*pzlib_filefunc_def,filestream))
 
361
            return ZIP_ERRNO;
 
362
        else
 
363
            return ZIP_EOF;
 
364
    }
 
365
}
 
366
 
 
367
 
 
368
/* ===========================================================================
 
369
   Reads a long in LSB order from the given gz_stream. Sets
 
370
*/
 
371
local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
 
372
 
 
373
local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
 
374
{
 
375
    uLong x ;
 
376
    int i = 0;
 
377
    int err;
 
378
 
 
379
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
380
    x = (uLong)i;
 
381
 
 
382
    if (err==ZIP_OK)
 
383
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
384
    x += ((uLong)i)<<8;
 
385
 
 
386
    if (err==ZIP_OK)
 
387
        *pX = x;
 
388
    else
 
389
        *pX = 0;
 
390
    return err;
 
391
}
 
392
 
 
393
local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
 
394
 
 
395
local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
 
396
{
 
397
    uLong x ;
 
398
    int i = 0;
 
399
    int err;
 
400
 
 
401
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
402
    x = (uLong)i;
 
403
 
 
404
    if (err==ZIP_OK)
 
405
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
406
    x += ((uLong)i)<<8;
 
407
 
 
408
    if (err==ZIP_OK)
 
409
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
410
    x += ((uLong)i)<<16;
 
411
 
 
412
    if (err==ZIP_OK)
 
413
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
414
    x += ((uLong)i)<<24;
 
415
 
 
416
    if (err==ZIP_OK)
 
417
        *pX = x;
 
418
    else
 
419
        *pX = 0;
 
420
    return err;
 
421
}
 
422
 
 
423
local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
 
424
 
 
425
 
 
426
local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
 
427
{
 
428
  ZPOS64_T x;
 
429
  int i = 0;
 
430
  int err;
 
431
 
 
432
  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
433
  x = (ZPOS64_T)i;
 
434
 
 
435
  if (err==ZIP_OK)
 
436
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
437
  x += ((ZPOS64_T)i)<<8;
 
438
 
 
439
  if (err==ZIP_OK)
 
440
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
441
  x += ((ZPOS64_T)i)<<16;
 
442
 
 
443
  if (err==ZIP_OK)
 
444
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
445
  x += ((ZPOS64_T)i)<<24;
 
446
 
 
447
  if (err==ZIP_OK)
 
448
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
449
  x += ((ZPOS64_T)i)<<32;
 
450
 
 
451
  if (err==ZIP_OK)
 
452
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
453
  x += ((ZPOS64_T)i)<<40;
 
454
 
 
455
  if (err==ZIP_OK)
 
456
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
457
  x += ((ZPOS64_T)i)<<48;
 
458
 
 
459
  if (err==ZIP_OK)
 
460
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
 
461
  x += ((ZPOS64_T)i)<<56;
 
462
 
 
463
  if (err==ZIP_OK)
 
464
    *pX = x;
 
465
  else
 
466
    *pX = 0;
 
467
 
 
468
  return err;
 
469
}
 
470
 
 
471
#ifndef BUFREADCOMMENT
 
472
#define BUFREADCOMMENT (0x400)
 
473
#endif
 
474
/*
 
475
  Locate the Central directory of a zipfile (at the end, just before
 
476
    the global comment)
 
477
*/
 
478
local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
 
479
 
 
480
local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
 
481
{
 
482
  unsigned char* buf;
 
483
  ZPOS64_T uSizeFile;
 
484
  ZPOS64_T uBackRead;
 
485
  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
 
486
  ZPOS64_T uPosFound=0;
 
487
 
 
488
  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
 
489
    return 0;
 
490
 
 
491
 
 
492
  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
 
493
 
 
494
  if (uMaxBack>uSizeFile)
 
495
    uMaxBack = uSizeFile;
 
496
 
 
497
  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
 
498
  if (buf==NULL)
 
499
    return 0;
 
500
 
 
501
  uBackRead = 4;
 
502
  while (uBackRead<uMaxBack)
 
503
  {
 
504
    uLong uReadSize;
 
505
    ZPOS64_T uReadPos ;
 
506
    int i;
 
507
    if (uBackRead+BUFREADCOMMENT>uMaxBack)
 
508
      uBackRead = uMaxBack;
 
509
    else
 
510
      uBackRead+=BUFREADCOMMENT;
 
511
    uReadPos = uSizeFile-uBackRead ;
 
512
 
 
513
    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
 
514
      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
 
515
    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
516
      break;
 
517
 
 
518
    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
 
519
      break;
 
520
 
 
521
    for (i=(int)uReadSize-3; (i--)>0;)
 
522
      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
 
523
        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
 
524
      {
 
525
        uPosFound = uReadPos+i;
 
526
        break;
 
527
      }
 
528
 
 
529
      if (uPosFound!=0)
 
530
        break;
 
531
  }
 
532
  TRYFREE(buf);
 
533
  return uPosFound;
 
534
}
 
535
 
 
536
/*
 
537
Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
 
538
the global comment)
 
539
*/
 
540
local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
 
541
 
 
542
local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
 
543
{
 
544
  unsigned char* buf;
 
545
  ZPOS64_T uSizeFile;
 
546
  ZPOS64_T uBackRead;
 
547
  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
 
548
  ZPOS64_T uPosFound=0;
 
549
  uLong uL;
 
550
  ZPOS64_T relativeOffset;
 
551
 
 
552
  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
 
553
    return 0;
 
554
 
 
555
  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
 
556
 
 
557
  if (uMaxBack>uSizeFile)
 
558
    uMaxBack = uSizeFile;
 
559
 
 
560
  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
 
561
  if (buf==NULL)
 
562
    return 0;
 
563
 
 
564
  uBackRead = 4;
 
565
  while (uBackRead<uMaxBack)
 
566
  {
 
567
    uLong uReadSize;
 
568
    ZPOS64_T uReadPos;
 
569
    int i;
 
570
    if (uBackRead+BUFREADCOMMENT>uMaxBack)
 
571
      uBackRead = uMaxBack;
 
572
    else
 
573
      uBackRead+=BUFREADCOMMENT;
 
574
    uReadPos = uSizeFile-uBackRead ;
 
575
 
 
576
    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
 
577
      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
 
578
    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
579
      break;
 
580
 
 
581
    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
 
582
      break;
 
583
 
 
584
    for (i=(int)uReadSize-3; (i--)>0;)
 
585
    {
 
586
      // Signature "0x07064b50" Zip64 end of central directory locater
 
587
      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
 
588
      {
 
589
        uPosFound = uReadPos+i;
 
590
        break;
 
591
      }
 
592
    }
 
593
 
 
594
      if (uPosFound!=0)
 
595
        break;
 
596
  }
 
597
 
 
598
  TRYFREE(buf);
 
599
  if (uPosFound == 0)
 
600
    return 0;
 
601
 
 
602
  /* Zip64 end of central directory locator */
 
603
  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
604
    return 0;
 
605
 
 
606
  /* the signature, already checked */
 
607
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
 
608
    return 0;
 
609
 
 
610
  /* number of the disk with the start of the zip64 end of  central directory */
 
611
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
 
612
    return 0;
 
613
  if (uL != 0)
 
614
    return 0;
 
615
 
 
616
  /* relative offset of the zip64 end of central directory record */
 
617
  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
 
618
    return 0;
 
619
 
 
620
  /* total number of disks */
 
621
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
 
622
    return 0;
 
623
  if (uL != 1)
 
624
    return 0;
 
625
 
 
626
  /* Goto Zip64 end of central directory record */
 
627
  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
628
    return 0;
 
629
 
 
630
  /* the signature */
 
631
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
 
632
    return 0;
 
633
 
 
634
  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
 
635
    return 0;
 
636
 
 
637
  return relativeOffset;
 
638
}
 
639
 
 
640
int LoadCentralDirectoryRecord(zip64_internal* pziinit)
 
641
{
 
642
  int err=ZIP_OK;
 
643
  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
 
644
 
 
645
  ZPOS64_T size_central_dir;     /* size of the central directory  */
 
646
  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
 
647
  ZPOS64_T central_pos;
 
648
  uLong uL;
 
649
 
 
650
  uLong number_disk;          /* number of the current dist, used for
 
651
                              spaning ZIP, unsupported, always 0*/
 
652
  uLong number_disk_with_CD;  /* number the the disk with central dir, used
 
653
                              for spaning ZIP, unsupported, always 0*/
 
654
  ZPOS64_T number_entry;
 
655
  ZPOS64_T number_entry_CD;      /* total number of entries in
 
656
                                the central dir
 
657
                                (same than number_entry on nospan) */
 
658
  uLong VersionMadeBy;
 
659
  uLong VersionNeeded;
 
660
  uLong size_comment;
 
661
 
 
662
  int hasZIP64Record = 0;
 
663
 
 
664
  // check first if we find a ZIP64 record
 
665
  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
 
666
  if(central_pos > 0)
 
667
  {
 
668
    hasZIP64Record = 1;
 
669
  }
 
670
  else if(central_pos == 0)
 
671
  {
 
672
    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
 
673
  }
 
674
 
 
675
/* disable to allow appending to empty ZIP archive
 
676
        if (central_pos==0)
 
677
            err=ZIP_ERRNO;
 
678
*/
 
679
 
 
680
  if(hasZIP64Record)
 
681
  {
 
682
    ZPOS64_T sizeEndOfCentralDirectory;
 
683
    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
 
684
      err=ZIP_ERRNO;
 
685
 
 
686
    /* the signature, already checked */
 
687
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
 
688
      err=ZIP_ERRNO;
 
689
 
 
690
    /* size of zip64 end of central directory record */
 
691
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
 
692
      err=ZIP_ERRNO;
 
693
 
 
694
    /* version made by */
 
695
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
 
696
      err=ZIP_ERRNO;
 
697
 
 
698
    /* version needed to extract */
 
699
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
 
700
      err=ZIP_ERRNO;
 
701
 
 
702
    /* number of this disk */
 
703
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
 
704
      err=ZIP_ERRNO;
 
705
 
 
706
    /* number of the disk with the start of the central directory */
 
707
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
 
708
      err=ZIP_ERRNO;
 
709
 
 
710
    /* total number of entries in the central directory on this disk */
 
711
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
 
712
      err=ZIP_ERRNO;
 
713
 
 
714
    /* total number of entries in the central directory */
 
715
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
 
716
      err=ZIP_ERRNO;
 
717
 
 
718
    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
 
719
      err=ZIP_BADZIPFILE;
 
720
 
 
721
    /* size of the central directory */
 
722
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
 
723
      err=ZIP_ERRNO;
 
724
 
 
725
    /* offset of start of central directory with respect to the
 
726
    starting disk number */
 
727
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
 
728
      err=ZIP_ERRNO;
 
729
 
 
730
    // TODO..
 
731
    // read the comment from the standard central header.
 
732
    size_comment = 0;
 
733
  }
 
734
  else
 
735
  {
 
736
    // Read End of central Directory info
 
737
    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
738
      err=ZIP_ERRNO;
 
739
 
 
740
    /* the signature, already checked */
 
741
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
 
742
      err=ZIP_ERRNO;
 
743
 
 
744
    /* number of this disk */
 
745
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
 
746
      err=ZIP_ERRNO;
 
747
 
 
748
    /* number of the disk with the start of the central directory */
 
749
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
 
750
      err=ZIP_ERRNO;
 
751
 
 
752
    /* total number of entries in the central dir on this disk */
 
753
    number_entry = 0;
 
754
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
 
755
      err=ZIP_ERRNO;
 
756
    else
 
757
      number_entry = uL;
 
758
 
 
759
    /* total number of entries in the central dir */
 
760
    number_entry_CD = 0;
 
761
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
 
762
      err=ZIP_ERRNO;
 
763
    else
 
764
      number_entry_CD = uL;
 
765
 
 
766
    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
 
767
      err=ZIP_BADZIPFILE;
 
768
 
 
769
    /* size of the central directory */
 
770
    size_central_dir = 0;
 
771
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
 
772
      err=ZIP_ERRNO;
 
773
    else
 
774
      size_central_dir = uL;
 
775
 
 
776
    /* offset of start of central directory with respect to the starting disk number */
 
777
    offset_central_dir = 0;
 
778
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
 
779
      err=ZIP_ERRNO;
 
780
    else
 
781
      offset_central_dir = uL;
 
782
 
 
783
 
 
784
    /* zipfile global comment length */
 
785
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
 
786
      err=ZIP_ERRNO;
 
787
  }
 
788
 
 
789
  if ((central_pos<offset_central_dir+size_central_dir) &&
 
790
    (err==ZIP_OK))
 
791
    err=ZIP_BADZIPFILE;
 
792
 
 
793
  if (err!=ZIP_OK)
 
794
  {
 
795
    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
 
796
    return ZIP_ERRNO;
 
797
  }
 
798
 
 
799
  if (size_comment>0)
 
800
  {
 
801
    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
 
802
    if (pziinit->globalcomment)
 
803
    {
 
804
      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
 
805
      pziinit->globalcomment[size_comment]=0;
 
806
    }
 
807
  }
 
808
 
 
809
  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
 
810
  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
 
811
 
 
812
  {
 
813
    ZPOS64_T size_central_dir_to_read = size_central_dir;
 
814
    size_t buf_size = SIZEDATA_INDATABLOCK;
 
815
    void* buf_read = (void*)ALLOC(buf_size);
 
816
    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
 
817
      err=ZIP_ERRNO;
 
818
 
 
819
    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
 
820
    {
 
821
      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
 
822
      if (read_this > size_central_dir_to_read)
 
823
        read_this = size_central_dir_to_read;
 
824
 
 
825
      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
 
826
        err=ZIP_ERRNO;
 
827
 
 
828
      if (err==ZIP_OK)
 
829
        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
 
830
 
 
831
      size_central_dir_to_read-=read_this;
 
832
    }
 
833
    TRYFREE(buf_read);
 
834
  }
 
835
  pziinit->begin_pos = byte_before_the_zipfile;
 
836
  pziinit->number_entry = number_entry_CD;
 
837
 
 
838
  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
 
839
    err=ZIP_ERRNO;
 
840
 
 
841
  return err;
 
842
}
 
843
 
 
844
 
 
845
#endif /* !NO_ADDFILEINEXISTINGZIP*/
 
846
 
 
847
 
 
848
/************************************************************/
 
849
extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
 
850
{
 
851
    zip64_internal ziinit;
 
852
    zip64_internal* zi;
 
853
    int err=ZIP_OK;
 
854
 
 
855
    ziinit.z_filefunc.zseek32_file = NULL;
 
856
    ziinit.z_filefunc.ztell32_file = NULL;
 
857
    if (pzlib_filefunc64_32_def==NULL)
 
858
        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
 
859
    else
 
860
        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
 
861
 
 
862
    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
 
863
                  pathname,
 
864
                  (append == APPEND_STATUS_CREATE) ?
 
865
                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
 
866
                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
 
867
 
 
868
    if (ziinit.filestream == NULL)
 
869
        return NULL;
 
870
 
 
871
    if (append == APPEND_STATUS_CREATEAFTER)
 
872
        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
 
873
 
 
874
    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
 
875
    ziinit.in_opened_file_inzip = 0;
 
876
    ziinit.ci.stream_initialised = 0;
 
877
    ziinit.number_entry = 0;
 
878
    ziinit.add_position_when_writting_offset = 0;
 
879
    init_linkedlist(&(ziinit.central_dir));
 
880
 
 
881
 
 
882
 
 
883
    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
 
884
    if (zi==NULL)
 
885
    {
 
886
        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
 
887
        return NULL;
 
888
    }
 
889
 
 
890
    /* now we add file in a zipfile */
 
891
#    ifndef NO_ADDFILEINEXISTINGZIP
 
892
    ziinit.globalcomment = NULL;
 
893
    if (append == APPEND_STATUS_ADDINZIP)
 
894
    {
 
895
      // Read and Cache Central Directory Records
 
896
      err = LoadCentralDirectoryRecord(&ziinit);
 
897
    }
 
898
 
 
899
    if (globalcomment)
 
900
    {
 
901
      *globalcomment = ziinit.globalcomment;
 
902
    }
 
903
#    endif /* !NO_ADDFILEINEXISTINGZIP*/
 
904
 
 
905
    if (err != ZIP_OK)
 
906
    {
 
907
#    ifndef NO_ADDFILEINEXISTINGZIP
 
908
        TRYFREE(ziinit.globalcomment);
 
909
#    endif /* !NO_ADDFILEINEXISTINGZIP*/
 
910
        TRYFREE(zi);
 
911
        return NULL;
 
912
    }
 
913
    else
 
914
    {
 
915
        *zi = ziinit;
 
916
        return (zipFile)zi;
 
917
    }
 
918
}
 
919
 
 
920
extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
 
921
{
 
922
    if (pzlib_filefunc32_def != NULL)
 
923
    {
 
924
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
 
925
        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
 
926
        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
 
927
    }
 
928
    else
 
929
        return zipOpen3(pathname, append, globalcomment, NULL);
 
930
}
 
931
 
 
932
extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
 
933
{
 
934
    if (pzlib_filefunc_def != NULL)
 
935
    {
 
936
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
 
937
        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
 
938
        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
 
939
        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
 
940
        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
 
941
    }
 
942
    else
 
943
        return zipOpen3(pathname, append, globalcomment, NULL);
 
944
}
 
945
 
 
946
 
 
947
 
 
948
extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
 
949
{
 
950
    return zipOpen3((const void*)pathname,append,NULL,NULL);
 
951
}
 
952
 
 
953
extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
 
954
{
 
955
    return zipOpen3(pathname,append,NULL,NULL);
 
956
}
 
957
 
 
958
int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
 
959
{
 
960
  /* write the local header */
 
961
  int err;
 
962
  uInt size_filename = (uInt)strlen(filename);
 
963
  uInt size_extrafield = size_extrafield_local;
 
964
 
 
965
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
 
966
 
 
967
  if (err==ZIP_OK)
 
968
  {
 
969
    if(zi->ci.zip64)
 
970
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
 
971
    else
 
972
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
 
973
  }
 
974
 
 
975
  if (err==ZIP_OK)
 
976
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
 
977
 
 
978
  if (err==ZIP_OK)
 
979
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
 
980
 
 
981
  if (err==ZIP_OK)
 
982
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
 
983
 
 
984
  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
 
985
  if (err==ZIP_OK)
 
986
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
 
987
  if (err==ZIP_OK)
 
988
  {
 
989
    if(zi->ci.zip64)
 
990
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
 
991
    else
 
992
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
 
993
  }
 
994
  if (err==ZIP_OK)
 
995
  {
 
996
    if(zi->ci.zip64)
 
997
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
 
998
    else
 
999
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
 
1000
  }
 
1001
 
 
1002
  if (err==ZIP_OK)
 
1003
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
 
1004
 
 
1005
  if(zi->ci.zip64)
 
1006
  {
 
1007
    size_extrafield += 20;
 
1008
  }
 
1009
 
 
1010
  if (err==ZIP_OK)
 
1011
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
 
1012
 
 
1013
  if ((err==ZIP_OK) && (size_filename > 0))
 
1014
  {
 
1015
    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
 
1016
      err = ZIP_ERRNO;
 
1017
  }
 
1018
 
 
1019
  if ((err==ZIP_OK) && (size_extrafield_local > 0))
 
1020
  {
 
1021
    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
 
1022
      err = ZIP_ERRNO;
 
1023
  }
 
1024
 
 
1025
 
 
1026
  if ((err==ZIP_OK) && (zi->ci.zip64))
 
1027
  {
 
1028
      // write the Zip64 extended info
 
1029
      short HeaderID = 1;
 
1030
      short DataSize = 16;
 
1031
      ZPOS64_T CompressedSize = 0;
 
1032
      ZPOS64_T UncompressedSize = 0;
 
1033
 
 
1034
      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
 
1035
      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
 
1036
 
 
1037
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
 
1038
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
 
1039
 
 
1040
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
 
1041
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
 
1042
  }
 
1043
 
 
1044
  return err;
 
1045
}
 
1046
 
 
1047
/*
 
1048
 NOTE.
 
1049
 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
 
1050
 before calling this function it can be done with zipRemoveExtraInfoBlock
 
1051
 
 
1052
 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
 
1053
 unnecessary allocations.
 
1054
 */
 
1055
extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1056
                                         const void* extrafield_local, uInt size_extrafield_local,
 
1057
                                         const void* extrafield_global, uInt size_extrafield_global,
 
1058
                                         const char* comment, int method, int level, int raw,
 
1059
                                         int windowBits,int memLevel, int strategy,
 
1060
                                         const char* password, uLong crcForCrypting,
 
1061
                                         uLong versionMadeBy, uLong flagBase, int zip64)
 
1062
{
 
1063
    zip64_internal* zi;
 
1064
    uInt size_filename;
 
1065
    uInt size_comment;
 
1066
    uInt i;
 
1067
    int err = ZIP_OK;
 
1068
 
 
1069
#    ifdef NOCRYPT
 
1070
    (crcForCrypting);
 
1071
    if (password != NULL)
 
1072
        return ZIP_PARAMERROR;
 
1073
#    endif
 
1074
 
 
1075
    if (file == NULL)
 
1076
        return ZIP_PARAMERROR;
 
1077
 
 
1078
#ifdef HAVE_BZIP2
 
1079
    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
 
1080
      return ZIP_PARAMERROR;
 
1081
#else
 
1082
    if ((method!=0) && (method!=Z_DEFLATED))
 
1083
      return ZIP_PARAMERROR;
 
1084
#endif
 
1085
 
 
1086
    zi = (zip64_internal*)file;
 
1087
 
 
1088
    if (zi->in_opened_file_inzip == 1)
 
1089
    {
 
1090
        err = zipCloseFileInZip (file);
 
1091
        if (err != ZIP_OK)
 
1092
            return err;
 
1093
    }
 
1094
 
 
1095
    if (filename==NULL)
 
1096
        filename="-";
 
1097
 
 
1098
    if (comment==NULL)
 
1099
        size_comment = 0;
 
1100
    else
 
1101
        size_comment = (uInt)strlen(comment);
 
1102
 
 
1103
    size_filename = (uInt)strlen(filename);
 
1104
 
 
1105
    if (zipfi == NULL)
 
1106
        zi->ci.dosDate = 0;
 
1107
    else
 
1108
    {
 
1109
        if (zipfi->dosDate != 0)
 
1110
            zi->ci.dosDate = zipfi->dosDate;
 
1111
        else
 
1112
          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
 
1113
    }
 
1114
 
 
1115
    zi->ci.flag = flagBase;
 
1116
    if ((level==8) || (level==9))
 
1117
      zi->ci.flag |= 2;
 
1118
    if ((level==2))
 
1119
      zi->ci.flag |= 4;
 
1120
    if ((level==1))
 
1121
      zi->ci.flag |= 6;
 
1122
    if (password != NULL)
 
1123
      zi->ci.flag |= 1;
 
1124
 
 
1125
    zi->ci.crc32 = 0;
 
1126
    zi->ci.method = method;
 
1127
    zi->ci.encrypt = 0;
 
1128
    zi->ci.stream_initialised = 0;
 
1129
    zi->ci.pos_in_buffered_data = 0;
 
1130
    zi->ci.raw = raw;
 
1131
    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
 
1132
 
 
1133
    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
 
1134
    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
 
1135
 
 
1136
    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
 
1137
 
 
1138
    zi->ci.size_centralExtra = size_extrafield_global;
 
1139
    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
 
1140
    /* version info */
 
1141
    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
 
1142
    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
 
1143
    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
 
1144
    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
 
1145
    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
 
1146
    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
 
1147
    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
 
1148
    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
 
1149
    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
 
1150
    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
 
1151
    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
 
1152
    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
 
1153
 
 
1154
    if (zipfi==NULL)
 
1155
        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
 
1156
    else
 
1157
        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
 
1158
 
 
1159
    if (zipfi==NULL)
 
1160
        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
 
1161
    else
 
1162
        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
 
1163
 
 
1164
    if(zi->ci.pos_local_header >= 0xffffffff)
 
1165
      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
 
1166
    else
 
1167
      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
 
1168
 
 
1169
    for (i=0;i<size_filename;i++)
 
1170
        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
 
1171
 
 
1172
    for (i=0;i<size_extrafield_global;i++)
 
1173
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
 
1174
              *(((const char*)extrafield_global)+i);
 
1175
 
 
1176
    for (i=0;i<size_comment;i++)
 
1177
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
 
1178
              size_extrafield_global+i) = *(comment+i);
 
1179
    if (zi->ci.central_header == NULL)
 
1180
        return ZIP_INTERNALERROR;
 
1181
 
 
1182
    zi->ci.zip64 = zip64;
 
1183
    zi->ci.totalCompressedData = 0;
 
1184
    zi->ci.totalUncompressedData = 0;
 
1185
    zi->ci.pos_zip64extrainfo = 0;
 
1186
 
 
1187
    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
 
1188
 
 
1189
#ifdef HAVE_BZIP2
 
1190
    zi->ci.bstream.avail_in = (uInt)0;
 
1191
    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
 
1192
    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
 
1193
    zi->ci.bstream.total_in_hi32 = 0;
 
1194
    zi->ci.bstream.total_in_lo32 = 0;
 
1195
    zi->ci.bstream.total_out_hi32 = 0;
 
1196
    zi->ci.bstream.total_out_lo32 = 0;
 
1197
#endif
 
1198
 
 
1199
    zi->ci.stream.avail_in = (uInt)0;
 
1200
    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
1201
    zi->ci.stream.next_out = zi->ci.buffered_data;
 
1202
    zi->ci.stream.total_in = 0;
 
1203
    zi->ci.stream.total_out = 0;
 
1204
    zi->ci.stream.data_type = Z_BINARY;
 
1205
 
 
1206
#ifdef HAVE_BZIP2
 
1207
    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 
1208
#else
 
1209
    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1210
#endif
 
1211
    {
 
1212
        if(zi->ci.method == Z_DEFLATED)
 
1213
        {
 
1214
          zi->ci.stream.zalloc = (alloc_func)0;
 
1215
          zi->ci.stream.zfree = (free_func)0;
 
1216
          zi->ci.stream.opaque = (voidpf)0;
 
1217
 
 
1218
          if (windowBits>0)
 
1219
              windowBits = -windowBits;
 
1220
 
 
1221
          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
 
1222
 
 
1223
          if (err==Z_OK)
 
1224
              zi->ci.stream_initialised = Z_DEFLATED;
 
1225
        }
 
1226
        else if(zi->ci.method == Z_BZIP2ED)
 
1227
        {
 
1228
#ifdef HAVE_BZIP2
 
1229
            // Init BZip stuff here
 
1230
          zi->ci.bstream.bzalloc = 0;
 
1231
          zi->ci.bstream.bzfree = 0;
 
1232
          zi->ci.bstream.opaque = (voidpf)0;
 
1233
 
 
1234
          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
 
1235
          if(err == BZ_OK)
 
1236
            zi->ci.stream_initialised = Z_BZIP2ED;
 
1237
#endif
 
1238
        }
 
1239
 
 
1240
    }
 
1241
 
 
1242
#    ifndef NOCRYPT
 
1243
    zi->ci.crypt_header_size = 0;
 
1244
    if ((err==Z_OK) && (password != NULL))
 
1245
    {
 
1246
        unsigned char bufHead[RAND_HEAD_LEN];
 
1247
        unsigned int sizeHead;
 
1248
        zi->ci.encrypt = 1;
 
1249
        zi->ci.pcrc_32_tab = get_crc_table();
 
1250
        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
 
1251
 
 
1252
        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
 
1253
        zi->ci.crypt_header_size = sizeHead;
 
1254
 
 
1255
        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
 
1256
                err = ZIP_ERRNO;
 
1257
    }
 
1258
#    endif
 
1259
 
 
1260
    if (err==Z_OK)
 
1261
        zi->in_opened_file_inzip = 1;
 
1262
    return err;
 
1263
}
 
1264
 
 
1265
extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1266
                                         const void* extrafield_local, uInt size_extrafield_local,
 
1267
                                         const void* extrafield_global, uInt size_extrafield_global,
 
1268
                                         const char* comment, int method, int level, int raw,
 
1269
                                         int windowBits,int memLevel, int strategy,
 
1270
                                         const char* password, uLong crcForCrypting,
 
1271
                                         uLong versionMadeBy, uLong flagBase)
 
1272
{
 
1273
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1274
                                 extrafield_local, size_extrafield_local,
 
1275
                                 extrafield_global, size_extrafield_global,
 
1276
                                 comment, method, level, raw,
 
1277
                                 windowBits, memLevel, strategy,
 
1278
                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
 
1279
}
 
1280
 
 
1281
extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1282
                                         const void* extrafield_local, uInt size_extrafield_local,
 
1283
                                         const void* extrafield_global, uInt size_extrafield_global,
 
1284
                                         const char* comment, int method, int level, int raw,
 
1285
                                         int windowBits,int memLevel, int strategy,
 
1286
                                         const char* password, uLong crcForCrypting)
 
1287
{
 
1288
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1289
                                 extrafield_local, size_extrafield_local,
 
1290
                                 extrafield_global, size_extrafield_global,
 
1291
                                 comment, method, level, raw,
 
1292
                                 windowBits, memLevel, strategy,
 
1293
                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
 
1294
}
 
1295
 
 
1296
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1297
                                         const void* extrafield_local, uInt size_extrafield_local,
 
1298
                                         const void* extrafield_global, uInt size_extrafield_global,
 
1299
                                         const char* comment, int method, int level, int raw,
 
1300
                                         int windowBits,int memLevel, int strategy,
 
1301
                                         const char* password, uLong crcForCrypting, int zip64)
 
1302
{
 
1303
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1304
                                 extrafield_local, size_extrafield_local,
 
1305
                                 extrafield_global, size_extrafield_global,
 
1306
                                 comment, method, level, raw,
 
1307
                                 windowBits, memLevel, strategy,
 
1308
                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
 
1309
}
 
1310
 
 
1311
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1312
                                        const void* extrafield_local, uInt size_extrafield_local,
 
1313
                                        const void* extrafield_global, uInt size_extrafield_global,
 
1314
                                        const char* comment, int method, int level, int raw)
 
1315
{
 
1316
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1317
                                 extrafield_local, size_extrafield_local,
 
1318
                                 extrafield_global, size_extrafield_global,
 
1319
                                 comment, method, level, raw,
 
1320
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 
1321
                                 NULL, 0, VERSIONMADEBY, 0, 0);
 
1322
}
 
1323
 
 
1324
extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1325
                                        const void* extrafield_local, uInt size_extrafield_local,
 
1326
                                        const void* extrafield_global, uInt size_extrafield_global,
 
1327
                                        const char* comment, int method, int level, int raw, int zip64)
 
1328
{
 
1329
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1330
                                 extrafield_local, size_extrafield_local,
 
1331
                                 extrafield_global, size_extrafield_global,
 
1332
                                 comment, method, level, raw,
 
1333
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 
1334
                                 NULL, 0, VERSIONMADEBY, 0, zip64);
 
1335
}
 
1336
 
 
1337
extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1338
                                        const void* extrafield_local, uInt size_extrafield_local,
 
1339
                                        const void*extrafield_global, uInt size_extrafield_global,
 
1340
                                        const char* comment, int method, int level, int zip64)
 
1341
{
 
1342
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1343
                                 extrafield_local, size_extrafield_local,
 
1344
                                 extrafield_global, size_extrafield_global,
 
1345
                                 comment, method, level, 0,
 
1346
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 
1347
                                 NULL, 0, VERSIONMADEBY, 0, zip64);
 
1348
}
 
1349
 
 
1350
extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
 
1351
                                        const void* extrafield_local, uInt size_extrafield_local,
 
1352
                                        const void*extrafield_global, uInt size_extrafield_global,
 
1353
                                        const char* comment, int method, int level)
 
1354
{
 
1355
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
 
1356
                                 extrafield_local, size_extrafield_local,
 
1357
                                 extrafield_global, size_extrafield_global,
 
1358
                                 comment, method, level, 0,
 
1359
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
 
1360
                                 NULL, 0, VERSIONMADEBY, 0, 0);
 
1361
}
 
1362
 
 
1363
local int zip64FlushWriteBuffer(zip64_internal* zi)
 
1364
{
 
1365
    int err=ZIP_OK;
 
1366
 
 
1367
    if (zi->ci.encrypt != 0)
 
1368
    {
 
1369
#ifndef NOCRYPT
 
1370
        uInt i;
 
1371
        int t;
 
1372
        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
 
1373
            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
 
1374
#endif
 
1375
    }
 
1376
 
 
1377
    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
 
1378
      err = ZIP_ERRNO;
 
1379
 
 
1380
    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
 
1381
 
 
1382
#ifdef HAVE_BZIP2
 
1383
    if(zi->ci.method == Z_BZIP2ED)
 
1384
    {
 
1385
      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
 
1386
      zi->ci.bstream.total_in_lo32 = 0;
 
1387
      zi->ci.bstream.total_in_hi32 = 0;
 
1388
    }
 
1389
    else
 
1390
#endif
 
1391
    {
 
1392
      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
 
1393
      zi->ci.stream.total_in = 0;
 
1394
    }
 
1395
 
 
1396
 
 
1397
    zi->ci.pos_in_buffered_data = 0;
 
1398
 
 
1399
    return err;
 
1400
}
 
1401
 
 
1402
extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
 
1403
{
 
1404
    zip64_internal* zi;
 
1405
    int err=ZIP_OK;
 
1406
 
 
1407
    if (file == NULL)
 
1408
        return ZIP_PARAMERROR;
 
1409
    zi = (zip64_internal*)file;
 
1410
 
 
1411
    if (zi->in_opened_file_inzip == 0)
 
1412
        return ZIP_PARAMERROR;
 
1413
 
 
1414
    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
 
1415
 
 
1416
#ifdef HAVE_BZIP2
 
1417
    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
 
1418
    {
 
1419
      zi->ci.bstream.next_in = (void*)buf;
 
1420
      zi->ci.bstream.avail_in = len;
 
1421
      err = BZ_RUN_OK;
 
1422
 
 
1423
      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
 
1424
      {
 
1425
        if (zi->ci.bstream.avail_out == 0)
 
1426
        {
 
1427
          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 
1428
            err = ZIP_ERRNO;
 
1429
          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
 
1430
          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
 
1431
        }
 
1432
 
 
1433
 
 
1434
        if(err != BZ_RUN_OK)
 
1435
          break;
 
1436
 
 
1437
        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 
1438
        {
 
1439
          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
 
1440
//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
 
1441
          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
 
1442
 
 
1443
          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
 
1444
        }
 
1445
      }
 
1446
 
 
1447
      if(err == BZ_RUN_OK)
 
1448
        err = ZIP_OK;
 
1449
    }
 
1450
    else
 
1451
#endif
 
1452
    {
 
1453
      zi->ci.stream.next_in = (Bytef*)buf;
 
1454
      zi->ci.stream.avail_in = len;
 
1455
 
 
1456
      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
 
1457
      {
 
1458
          if (zi->ci.stream.avail_out == 0)
 
1459
          {
 
1460
              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 
1461
                  err = ZIP_ERRNO;
 
1462
              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
1463
              zi->ci.stream.next_out = zi->ci.buffered_data;
 
1464
          }
 
1465
 
 
1466
 
 
1467
          if(err != ZIP_OK)
 
1468
              break;
 
1469
 
 
1470
          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1471
          {
 
1472
              uLong uTotalOutBefore = zi->ci.stream.total_out;
 
1473
              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
 
1474
              if(uTotalOutBefore > zi->ci.stream.total_out)
 
1475
              {
 
1476
                int bBreak = 0;
 
1477
                bBreak++;
 
1478
              }
 
1479
 
 
1480
              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 
1481
          }
 
1482
          else
 
1483
          {
 
1484
              uInt copy_this,i;
 
1485
              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
 
1486
                  copy_this = zi->ci.stream.avail_in;
 
1487
              else
 
1488
                  copy_this = zi->ci.stream.avail_out;
 
1489
 
 
1490
              for (i = 0; i < copy_this; i++)
 
1491
                  *(((char*)zi->ci.stream.next_out)+i) =
 
1492
                      *(((const char*)zi->ci.stream.next_in)+i);
 
1493
              {
 
1494
                  zi->ci.stream.avail_in -= copy_this;
 
1495
                  zi->ci.stream.avail_out-= copy_this;
 
1496
                  zi->ci.stream.next_in+= copy_this;
 
1497
                  zi->ci.stream.next_out+= copy_this;
 
1498
                  zi->ci.stream.total_in+= copy_this;
 
1499
                  zi->ci.stream.total_out+= copy_this;
 
1500
                  zi->ci.pos_in_buffered_data += copy_this;
 
1501
              }
 
1502
          }
 
1503
      }// while(...)
 
1504
    }
 
1505
 
 
1506
    return err;
 
1507
}
 
1508
 
 
1509
extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
 
1510
{
 
1511
    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
 
1512
}
 
1513
 
 
1514
extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
 
1515
{
 
1516
    zip64_internal* zi;
 
1517
    ZPOS64_T compressed_size;
 
1518
    uLong invalidValue = 0xffffffff;
 
1519
    short datasize = 0;
 
1520
    int err=ZIP_OK;
 
1521
 
 
1522
    if (file == NULL)
 
1523
        return ZIP_PARAMERROR;
 
1524
    zi = (zip64_internal*)file;
 
1525
 
 
1526
    if (zi->in_opened_file_inzip == 0)
 
1527
        return ZIP_PARAMERROR;
 
1528
    zi->ci.stream.avail_in = 0;
 
1529
 
 
1530
    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1531
                {
 
1532
                        while (err==ZIP_OK)
 
1533
                        {
 
1534
                                uLong uTotalOutBefore;
 
1535
                                if (zi->ci.stream.avail_out == 0)
 
1536
                                {
 
1537
                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 
1538
                                                err = ZIP_ERRNO;
 
1539
                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
 
1540
                                        zi->ci.stream.next_out = zi->ci.buffered_data;
 
1541
                                }
 
1542
                                uTotalOutBefore = zi->ci.stream.total_out;
 
1543
                                err=deflate(&zi->ci.stream,  Z_FINISH);
 
1544
                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
 
1545
                        }
 
1546
                }
 
1547
    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 
1548
    {
 
1549
#ifdef HAVE_BZIP2
 
1550
      err = BZ_FINISH_OK;
 
1551
      while (err==BZ_FINISH_OK)
 
1552
      {
 
1553
        uLong uTotalOutBefore;
 
1554
        if (zi->ci.bstream.avail_out == 0)
 
1555
        {
 
1556
          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
 
1557
            err = ZIP_ERRNO;
 
1558
          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
 
1559
          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
 
1560
        }
 
1561
        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
 
1562
        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
 
1563
        if(err == BZ_STREAM_END)
 
1564
          err = Z_STREAM_END;
 
1565
 
 
1566
        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
 
1567
      }
 
1568
 
 
1569
      if(err == BZ_FINISH_OK)
 
1570
        err = ZIP_OK;
 
1571
#endif
 
1572
    }
 
1573
 
 
1574
    if (err==Z_STREAM_END)
 
1575
        err=ZIP_OK; /* this is normal */
 
1576
 
 
1577
    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
 
1578
                {
 
1579
        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
 
1580
            err = ZIP_ERRNO;
 
1581
                }
 
1582
 
 
1583
    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
 
1584
    {
 
1585
        int tmp_err = deflateEnd(&zi->ci.stream);
 
1586
        if (err == ZIP_OK)
 
1587
            err = tmp_err;
 
1588
        zi->ci.stream_initialised = 0;
 
1589
    }
 
1590
#ifdef HAVE_BZIP2
 
1591
    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
 
1592
    {
 
1593
      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
 
1594
                        if (err==ZIP_OK)
 
1595
                                err = tmperr;
 
1596
                        zi->ci.stream_initialised = 0;
 
1597
    }
 
1598
#endif
 
1599
 
 
1600
    if (!zi->ci.raw)
 
1601
    {
 
1602
        crc32 = (uLong)zi->ci.crc32;
 
1603
        uncompressed_size = zi->ci.totalUncompressedData;
 
1604
    }
 
1605
    compressed_size = zi->ci.totalCompressedData;
 
1606
 
 
1607
#    ifndef NOCRYPT
 
1608
    compressed_size += zi->ci.crypt_header_size;
 
1609
#    endif
 
1610
 
 
1611
    // update Current Item crc and sizes,
 
1612
    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
 
1613
    {
 
1614
      /*version Made by*/
 
1615
      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
 
1616
      /*version needed*/
 
1617
      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
 
1618
 
 
1619
    }
 
1620
 
 
1621
    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
 
1622
 
 
1623
 
 
1624
    if(compressed_size >= 0xffffffff)
 
1625
      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
 
1626
    else
 
1627
      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
 
1628
 
 
1629
    /// set internal file attributes field
 
1630
    if (zi->ci.stream.data_type == Z_ASCII)
 
1631
        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
 
1632
 
 
1633
    if(uncompressed_size >= 0xffffffff)
 
1634
      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
 
1635
    else
 
1636
      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
 
1637
 
 
1638
    // Add ZIP64 extra info field for uncompressed size
 
1639
    if(uncompressed_size >= 0xffffffff)
 
1640
      datasize += 8;
 
1641
 
 
1642
    // Add ZIP64 extra info field for compressed size
 
1643
    if(compressed_size >= 0xffffffff)
 
1644
      datasize += 8;
 
1645
 
 
1646
    // Add ZIP64 extra info field for relative offset to local file header of current file
 
1647
    if(zi->ci.pos_local_header >= 0xffffffff)
 
1648
      datasize += 8;
 
1649
 
 
1650
    if(datasize > 0)
 
1651
    {
 
1652
      char* p = NULL;
 
1653
 
 
1654
      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
 
1655
      {
 
1656
        // we can not write more data to the buffer that we have room for.
 
1657
        return ZIP_BADZIPFILE;
 
1658
      }
 
1659
 
 
1660
      p = zi->ci.central_header + zi->ci.size_centralheader;
 
1661
 
 
1662
      // Add Extra Information Header for 'ZIP64 information'
 
1663
      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
 
1664
      p += 2;
 
1665
      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
 
1666
      p += 2;
 
1667
 
 
1668
      if(uncompressed_size >= 0xffffffff)
 
1669
      {
 
1670
        zip64local_putValue_inmemory(p, uncompressed_size, 8);
 
1671
        p += 8;
 
1672
      }
 
1673
 
 
1674
      if(compressed_size >= 0xffffffff)
 
1675
      {
 
1676
        zip64local_putValue_inmemory(p, compressed_size, 8);
 
1677
        p += 8;
 
1678
      }
 
1679
 
 
1680
      if(zi->ci.pos_local_header >= 0xffffffff)
 
1681
      {
 
1682
        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
 
1683
        p += 8;
 
1684
      }
 
1685
 
 
1686
      // Update how much extra free space we got in the memory buffer
 
1687
      // and increase the centralheader size so the new ZIP64 fields are included
 
1688
      // ( 4 below is the size of HeaderID and DataSize field )
 
1689
      zi->ci.size_centralExtraFree -= datasize + 4;
 
1690
      zi->ci.size_centralheader += datasize + 4;
 
1691
 
 
1692
      // Update the extra info size field
 
1693
      zi->ci.size_centralExtra += datasize + 4;
 
1694
      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
 
1695
    }
 
1696
 
 
1697
    if (err==ZIP_OK)
 
1698
        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
 
1699
 
 
1700
    free(zi->ci.central_header);
 
1701
 
 
1702
    if (err==ZIP_OK)
 
1703
    {
 
1704
        // Update the LocalFileHeader with the new values.
 
1705
 
 
1706
        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
 
1707
 
 
1708
        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
1709
            err = ZIP_ERRNO;
 
1710
 
 
1711
        if (err==ZIP_OK)
 
1712
            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
 
1713
 
 
1714
        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
 
1715
        {
 
1716
          if(zi->ci.pos_zip64extrainfo > 0)
 
1717
          {
 
1718
            // Update the size in the ZIP64 extended field.
 
1719
            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
1720
              err = ZIP_ERRNO;
 
1721
 
 
1722
            if (err==ZIP_OK) /* compressed size, unknown */
 
1723
              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
 
1724
 
 
1725
            if (err==ZIP_OK) /* uncompressed size, unknown */
 
1726
              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
 
1727
          }
 
1728
          else
 
1729
              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
 
1730
        }
 
1731
        else
 
1732
        {
 
1733
          if (err==ZIP_OK) /* compressed size, unknown */
 
1734
              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
 
1735
 
 
1736
          if (err==ZIP_OK) /* uncompressed size, unknown */
 
1737
              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
 
1738
        }
 
1739
 
 
1740
        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
 
1741
            err = ZIP_ERRNO;
 
1742
    }
 
1743
 
 
1744
    zi->number_entry ++;
 
1745
    zi->in_opened_file_inzip = 0;
 
1746
 
 
1747
    return err;
 
1748
}
 
1749
 
 
1750
extern int ZEXPORT zipCloseFileInZip (zipFile file)
 
1751
{
 
1752
    return zipCloseFileInZipRaw (file,0,0);
 
1753
}
 
1754
 
 
1755
int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
 
1756
{
 
1757
  int err = ZIP_OK;
 
1758
  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
 
1759
 
 
1760
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
 
1761
 
 
1762
  /*num disks*/
 
1763
    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 
1764
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
 
1765
 
 
1766
  /*relative offset*/
 
1767
    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
 
1768
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
 
1769
 
 
1770
  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
 
1771
    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 
1772
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
 
1773
 
 
1774
    return err;
 
1775
}
 
1776
 
 
1777
int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
 
1778
{
 
1779
  int err = ZIP_OK;
 
1780
 
 
1781
  uLong Zip64DataSize = 44;
 
1782
 
 
1783
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
 
1784
 
 
1785
  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
 
1786
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
 
1787
 
 
1788
  if (err==ZIP_OK) /* version made by */
 
1789
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
 
1790
 
 
1791
  if (err==ZIP_OK) /* version needed */
 
1792
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
 
1793
 
 
1794
  if (err==ZIP_OK) /* number of this disk */
 
1795
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
 
1796
 
 
1797
  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 
1798
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
 
1799
 
 
1800
  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
 
1801
    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
 
1802
 
 
1803
  if (err==ZIP_OK) /* total number of entries in the central dir */
 
1804
    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
 
1805
 
 
1806
  if (err==ZIP_OK) /* size of the central directory */
 
1807
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
 
1808
 
 
1809
  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
 
1810
  {
 
1811
    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
 
1812
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
 
1813
  }
 
1814
  return err;
 
1815
}
 
1816
int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
 
1817
{
 
1818
  int err = ZIP_OK;
 
1819
 
 
1820
  /*signature*/
 
1821
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
 
1822
 
 
1823
  if (err==ZIP_OK) /* number of this disk */
 
1824
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
 
1825
 
 
1826
  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
 
1827
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
 
1828
 
 
1829
  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
 
1830
  {
 
1831
    {
 
1832
      if(zi->number_entry >= 0xFFFF)
 
1833
        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
 
1834
      else
 
1835
        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
 
1836
    }
 
1837
  }
 
1838
 
 
1839
  if (err==ZIP_OK) /* total number of entries in the central dir */
 
1840
  {
 
1841
    if(zi->number_entry >= 0xFFFF)
 
1842
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
 
1843
    else
 
1844
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
 
1845
  }
 
1846
 
 
1847
  if (err==ZIP_OK) /* size of the central directory */
 
1848
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
 
1849
 
 
1850
  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
 
1851
  {
 
1852
    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
 
1853
    if(pos >= 0xffffffff)
 
1854
    {
 
1855
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
 
1856
    }
 
1857
    else
 
1858
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
 
1859
  }
 
1860
 
 
1861
   return err;
 
1862
}
 
1863
 
 
1864
int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
 
1865
{
 
1866
  int err = ZIP_OK;
 
1867
  uInt size_global_comment = 0;
 
1868
 
 
1869
  if(global_comment != NULL)
 
1870
    size_global_comment = (uInt)strlen(global_comment);
 
1871
 
 
1872
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
 
1873
 
 
1874
  if (err == ZIP_OK && size_global_comment > 0)
 
1875
  {
 
1876
    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
 
1877
      err = ZIP_ERRNO;
 
1878
  }
 
1879
  return err;
 
1880
}
 
1881
 
 
1882
extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
 
1883
{
 
1884
    zip64_internal* zi;
 
1885
    int err = 0;
 
1886
    uLong size_centraldir = 0;
 
1887
    ZPOS64_T centraldir_pos_inzip;
 
1888
    ZPOS64_T pos;
 
1889
 
 
1890
    if (file == NULL)
 
1891
        return ZIP_PARAMERROR;
 
1892
 
 
1893
    zi = (zip64_internal*)file;
 
1894
 
 
1895
    if (zi->in_opened_file_inzip == 1)
 
1896
    {
 
1897
        err = zipCloseFileInZip (file);
 
1898
    }
 
1899
 
 
1900
#ifndef NO_ADDFILEINEXISTINGZIP
 
1901
    if (global_comment==NULL)
 
1902
        global_comment = zi->globalcomment;
 
1903
#endif
 
1904
 
 
1905
    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
 
1906
 
 
1907
    if (err==ZIP_OK)
 
1908
    {
 
1909
        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
 
1910
        while (ldi!=NULL)
 
1911
        {
 
1912
            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
 
1913
            {
 
1914
                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
 
1915
                    err = ZIP_ERRNO;
 
1916
            }
 
1917
 
 
1918
            size_centraldir += ldi->filled_in_this_block;
 
1919
            ldi = ldi->next_datablock;
 
1920
        }
 
1921
    }
 
1922
    free_linkedlist(&(zi->central_dir));
 
1923
 
 
1924
    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
 
1925
    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
 
1926
    {
 
1927
      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
 
1928
      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
 
1929
 
 
1930
      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
 
1931
    }
 
1932
 
 
1933
    if (err==ZIP_OK)
 
1934
      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
 
1935
 
 
1936
    if(err == ZIP_OK)
 
1937
      err = Write_GlobalComment(zi, global_comment);
 
1938
 
 
1939
    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
 
1940
        if (err == ZIP_OK)
 
1941
            err = ZIP_ERRNO;
 
1942
 
 
1943
#ifndef NO_ADDFILEINEXISTINGZIP
 
1944
    TRYFREE(zi->globalcomment);
 
1945
#endif
 
1946
    TRYFREE(zi);
 
1947
 
 
1948
    return err;
 
1949
}
 
1950
 
 
1951
extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
 
1952
{
 
1953
  char* p = pData;
 
1954
  int size = 0;
 
1955
  char* pNewHeader;
 
1956
  char* pTmp;
 
1957
  short header;
 
1958
  short dataSize;
 
1959
 
 
1960
  int retVal = ZIP_OK;
 
1961
 
 
1962
  if(pData == NULL || *dataLen < 4)
 
1963
    return ZIP_PARAMERROR;
 
1964
 
 
1965
  pNewHeader = (char*)ALLOC(*dataLen);
 
1966
  pTmp = pNewHeader;
 
1967
 
 
1968
  while(p < (pData + *dataLen))
 
1969
  {
 
1970
    header = *(short*)p;
 
1971
    dataSize = *(((short*)p)+1);
 
1972
 
 
1973
    if( header == sHeader ) // Header found.
 
1974
    {
 
1975
      p += dataSize + 4; // skip it. do not copy to temp buffer
 
1976
    }
 
1977
    else
 
1978
    {
 
1979
      // Extra Info block should not be removed, So copy it to the temp buffer.
 
1980
      memcpy(pTmp, p, dataSize + 4);
 
1981
      p += dataSize + 4;
 
1982
      size += dataSize + 4;
 
1983
    }
 
1984
 
 
1985
  }
 
1986
 
 
1987
  if(size < *dataLen)
 
1988
  {
 
1989
    // clean old extra info block.
 
1990
    memset(pData,0, *dataLen);
 
1991
 
 
1992
    // copy the new extra info block over the old
 
1993
    if(size > 0)
 
1994
      memcpy(pData, pNewHeader, size);
 
1995
 
 
1996
    // set the new extra info size
 
1997
    *dataLen = size;
 
1998
 
 
1999
    retVal = ZIP_OK;
 
2000
  }
 
2001
  else
 
2002
    retVal = ZIP_ERRNO;
 
2003
 
 
2004
  TRYFREE(pNewHeader);
 
2005
 
 
2006
  return retVal;
 
2007
}