packvfs

diff test/zipcat/src/minizip/zip.c @ 3:ef6c1472607f

jesus fucking christ that was easy... written a test prog "zipcat" to try out zlib's contrib library "minizip", to list and read files out of zip archives directly...
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 04 Nov 2013 06:46:17 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/test/zipcat/src/minizip/zip.c	Mon Nov 04 06:46:17 2013 +0200
     1.3 @@ -0,0 +1,2007 @@
     1.4 +/* zip.c -- IO on .zip files using zlib
     1.5 +   Version 1.1, February 14h, 2010
     1.6 +   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
     1.7 +
     1.8 +         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
     1.9 +
    1.10 +         Modifications for Zip64 support
    1.11 +         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
    1.12 +
    1.13 +         For more info read MiniZip_info.txt
    1.14 +
    1.15 +         Changes
    1.16 +   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
    1.17 +   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
    1.18 +   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
    1.19 +   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
    1.20 +                                 It is used when recreting zip archive with RAW when deleting items from a zip.
    1.21 +                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
    1.22 +   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
    1.23 +   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
    1.24 +
    1.25 +*/
    1.26 +
    1.27 +
    1.28 +#include <stdio.h>
    1.29 +#include <stdlib.h>
    1.30 +#include <string.h>
    1.31 +#include <time.h>
    1.32 +#include "zlib.h"
    1.33 +#include "zip.h"
    1.34 +
    1.35 +#ifdef STDC
    1.36 +#  include <stddef.h>
    1.37 +#  include <string.h>
    1.38 +#  include <stdlib.h>
    1.39 +#endif
    1.40 +#ifdef NO_ERRNO_H
    1.41 +    extern int errno;
    1.42 +#else
    1.43 +#   include <errno.h>
    1.44 +#endif
    1.45 +
    1.46 +
    1.47 +#ifndef local
    1.48 +#  define local static
    1.49 +#endif
    1.50 +/* compile with -Dlocal if your debugger can't find static symbols */
    1.51 +
    1.52 +#ifndef VERSIONMADEBY
    1.53 +# define VERSIONMADEBY   (0x0) /* platform depedent */
    1.54 +#endif
    1.55 +
    1.56 +#ifndef Z_BUFSIZE
    1.57 +#define Z_BUFSIZE (64*1024) //(16384)
    1.58 +#endif
    1.59 +
    1.60 +#ifndef Z_MAXFILENAMEINZIP
    1.61 +#define Z_MAXFILENAMEINZIP (256)
    1.62 +#endif
    1.63 +
    1.64 +#ifndef ALLOC
    1.65 +# define ALLOC(size) (malloc(size))
    1.66 +#endif
    1.67 +#ifndef TRYFREE
    1.68 +# define TRYFREE(p) {if (p) free(p);}
    1.69 +#endif
    1.70 +
    1.71 +/*
    1.72 +#define SIZECENTRALDIRITEM (0x2e)
    1.73 +#define SIZEZIPLOCALHEADER (0x1e)
    1.74 +*/
    1.75 +
    1.76 +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
    1.77 +
    1.78 +
    1.79 +// NOT sure that this work on ALL platform
    1.80 +#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
    1.81 +
    1.82 +#ifndef SEEK_CUR
    1.83 +#define SEEK_CUR    1
    1.84 +#endif
    1.85 +
    1.86 +#ifndef SEEK_END
    1.87 +#define SEEK_END    2
    1.88 +#endif
    1.89 +
    1.90 +#ifndef SEEK_SET
    1.91 +#define SEEK_SET    0
    1.92 +#endif
    1.93 +
    1.94 +#ifndef DEF_MEM_LEVEL
    1.95 +#if MAX_MEM_LEVEL >= 8
    1.96 +#  define DEF_MEM_LEVEL 8
    1.97 +#else
    1.98 +#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
    1.99 +#endif
   1.100 +#endif
   1.101 +const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
   1.102 +
   1.103 +
   1.104 +#define SIZEDATA_INDATABLOCK (4096-(4*4))
   1.105 +
   1.106 +#define LOCALHEADERMAGIC    (0x04034b50)
   1.107 +#define CENTRALHEADERMAGIC  (0x02014b50)
   1.108 +#define ENDHEADERMAGIC      (0x06054b50)
   1.109 +#define ZIP64ENDHEADERMAGIC      (0x6064b50)
   1.110 +#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
   1.111 +
   1.112 +#define FLAG_LOCALHEADER_OFFSET (0x06)
   1.113 +#define CRC_LOCALHEADER_OFFSET  (0x0e)
   1.114 +
   1.115 +#define SIZECENTRALHEADER (0x2e) /* 46 */
   1.116 +
   1.117 +typedef struct linkedlist_datablock_internal_s
   1.118 +{
   1.119 +  struct linkedlist_datablock_internal_s* next_datablock;
   1.120 +  uLong  avail_in_this_block;
   1.121 +  uLong  filled_in_this_block;
   1.122 +  uLong  unused; /* for future use and alignement */
   1.123 +  unsigned char data[SIZEDATA_INDATABLOCK];
   1.124 +} linkedlist_datablock_internal;
   1.125 +
   1.126 +typedef struct linkedlist_data_s
   1.127 +{
   1.128 +    linkedlist_datablock_internal* first_block;
   1.129 +    linkedlist_datablock_internal* last_block;
   1.130 +} linkedlist_data;
   1.131 +
   1.132 +
   1.133 +typedef struct
   1.134 +{
   1.135 +    z_stream stream;            /* zLib stream structure for inflate */
   1.136 +#ifdef HAVE_BZIP2
   1.137 +    bz_stream bstream;          /* bzLib stream structure for bziped */
   1.138 +#endif
   1.139 +
   1.140 +    int  stream_initialised;    /* 1 is stream is initialised */
   1.141 +    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
   1.142 +
   1.143 +    ZPOS64_T pos_local_header;     /* offset of the local header of the file
   1.144 +                                     currenty writing */
   1.145 +    char* central_header;       /* central header data for the current file */
   1.146 +    uLong size_centralExtra;
   1.147 +    uLong size_centralheader;   /* size of the central header for cur file */
   1.148 +    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
   1.149 +    uLong flag;                 /* flag of the file currently writing */
   1.150 +
   1.151 +    int  method;                /* compression method of file currenty wr.*/
   1.152 +    int  raw;                   /* 1 for directly writing raw data */
   1.153 +    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
   1.154 +    uLong dosDate;
   1.155 +    uLong crc32;
   1.156 +    int  encrypt;
   1.157 +    int  zip64;               /* Add ZIP64 extened information in the extra field */
   1.158 +    ZPOS64_T pos_zip64extrainfo;
   1.159 +    ZPOS64_T totalCompressedData;
   1.160 +    ZPOS64_T totalUncompressedData;
   1.161 +#ifndef NOCRYPT
   1.162 +    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
   1.163 +    const z_crc_t* pcrc_32_tab;
   1.164 +    int crypt_header_size;
   1.165 +#endif
   1.166 +} curfile64_info;
   1.167 +
   1.168 +typedef struct
   1.169 +{
   1.170 +    zlib_filefunc64_32_def z_filefunc;
   1.171 +    voidpf filestream;        /* io structore of the zipfile */
   1.172 +    linkedlist_data central_dir;/* datablock with central dir in construction*/
   1.173 +    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
   1.174 +    curfile64_info ci;            /* info on the file curretly writing */
   1.175 +
   1.176 +    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
   1.177 +    ZPOS64_T add_position_when_writting_offset;
   1.178 +    ZPOS64_T number_entry;
   1.179 +
   1.180 +#ifndef NO_ADDFILEINEXISTINGZIP
   1.181 +    char *globalcomment;
   1.182 +#endif
   1.183 +
   1.184 +} zip64_internal;
   1.185 +
   1.186 +
   1.187 +#ifndef NOCRYPT
   1.188 +#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
   1.189 +#include "crypt.h"
   1.190 +#endif
   1.191 +
   1.192 +local linkedlist_datablock_internal* allocate_new_datablock()
   1.193 +{
   1.194 +    linkedlist_datablock_internal* ldi;
   1.195 +    ldi = (linkedlist_datablock_internal*)
   1.196 +                 ALLOC(sizeof(linkedlist_datablock_internal));
   1.197 +    if (ldi!=NULL)
   1.198 +    {
   1.199 +        ldi->next_datablock = NULL ;
   1.200 +        ldi->filled_in_this_block = 0 ;
   1.201 +        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
   1.202 +    }
   1.203 +    return ldi;
   1.204 +}
   1.205 +
   1.206 +local void free_datablock(linkedlist_datablock_internal* ldi)
   1.207 +{
   1.208 +    while (ldi!=NULL)
   1.209 +    {
   1.210 +        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
   1.211 +        TRYFREE(ldi);
   1.212 +        ldi = ldinext;
   1.213 +    }
   1.214 +}
   1.215 +
   1.216 +local void init_linkedlist(linkedlist_data* ll)
   1.217 +{
   1.218 +    ll->first_block = ll->last_block = NULL;
   1.219 +}
   1.220 +
   1.221 +local void free_linkedlist(linkedlist_data* ll)
   1.222 +{
   1.223 +    free_datablock(ll->first_block);
   1.224 +    ll->first_block = ll->last_block = NULL;
   1.225 +}
   1.226 +
   1.227 +
   1.228 +local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
   1.229 +{
   1.230 +    linkedlist_datablock_internal* ldi;
   1.231 +    const unsigned char* from_copy;
   1.232 +
   1.233 +    if (ll==NULL)
   1.234 +        return ZIP_INTERNALERROR;
   1.235 +
   1.236 +    if (ll->last_block == NULL)
   1.237 +    {
   1.238 +        ll->first_block = ll->last_block = allocate_new_datablock();
   1.239 +        if (ll->first_block == NULL)
   1.240 +            return ZIP_INTERNALERROR;
   1.241 +    }
   1.242 +
   1.243 +    ldi = ll->last_block;
   1.244 +    from_copy = (unsigned char*)buf;
   1.245 +
   1.246 +    while (len>0)
   1.247 +    {
   1.248 +        uInt copy_this;
   1.249 +        uInt i;
   1.250 +        unsigned char* to_copy;
   1.251 +
   1.252 +        if (ldi->avail_in_this_block==0)
   1.253 +        {
   1.254 +            ldi->next_datablock = allocate_new_datablock();
   1.255 +            if (ldi->next_datablock == NULL)
   1.256 +                return ZIP_INTERNALERROR;
   1.257 +            ldi = ldi->next_datablock ;
   1.258 +            ll->last_block = ldi;
   1.259 +        }
   1.260 +
   1.261 +        if (ldi->avail_in_this_block < len)
   1.262 +            copy_this = (uInt)ldi->avail_in_this_block;
   1.263 +        else
   1.264 +            copy_this = (uInt)len;
   1.265 +
   1.266 +        to_copy = &(ldi->data[ldi->filled_in_this_block]);
   1.267 +
   1.268 +        for (i=0;i<copy_this;i++)
   1.269 +            *(to_copy+i)=*(from_copy+i);
   1.270 +
   1.271 +        ldi->filled_in_this_block += copy_this;
   1.272 +        ldi->avail_in_this_block -= copy_this;
   1.273 +        from_copy += copy_this ;
   1.274 +        len -= copy_this;
   1.275 +    }
   1.276 +    return ZIP_OK;
   1.277 +}
   1.278 +
   1.279 +
   1.280 +
   1.281 +/****************************************************************************/
   1.282 +
   1.283 +#ifndef NO_ADDFILEINEXISTINGZIP
   1.284 +/* ===========================================================================
   1.285 +   Inputs a long in LSB order to the given file
   1.286 +   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
   1.287 +*/
   1.288 +
   1.289 +local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
   1.290 +local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
   1.291 +{
   1.292 +    unsigned char buf[8];
   1.293 +    int n;
   1.294 +    for (n = 0; n < nbByte; n++)
   1.295 +    {
   1.296 +        buf[n] = (unsigned char)(x & 0xff);
   1.297 +        x >>= 8;
   1.298 +    }
   1.299 +    if (x != 0)
   1.300 +      {     /* data overflow - hack for ZIP64 (X Roche) */
   1.301 +      for (n = 0; n < nbByte; n++)
   1.302 +        {
   1.303 +          buf[n] = 0xff;
   1.304 +        }
   1.305 +      }
   1.306 +
   1.307 +    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
   1.308 +        return ZIP_ERRNO;
   1.309 +    else
   1.310 +        return ZIP_OK;
   1.311 +}
   1.312 +
   1.313 +local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
   1.314 +local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
   1.315 +{
   1.316 +    unsigned char* buf=(unsigned char*)dest;
   1.317 +    int n;
   1.318 +    for (n = 0; n < nbByte; n++) {
   1.319 +        buf[n] = (unsigned char)(x & 0xff);
   1.320 +        x >>= 8;
   1.321 +    }
   1.322 +
   1.323 +    if (x != 0)
   1.324 +    {     /* data overflow - hack for ZIP64 */
   1.325 +       for (n = 0; n < nbByte; n++)
   1.326 +       {
   1.327 +          buf[n] = 0xff;
   1.328 +       }
   1.329 +    }
   1.330 +}
   1.331 +
   1.332 +/****************************************************************************/
   1.333 +
   1.334 +
   1.335 +local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
   1.336 +{
   1.337 +    uLong year = (uLong)ptm->tm_year;
   1.338 +    if (year>=1980)
   1.339 +        year-=1980;
   1.340 +    else if (year>=80)
   1.341 +        year-=80;
   1.342 +    return
   1.343 +      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
   1.344 +        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
   1.345 +}
   1.346 +
   1.347 +
   1.348 +/****************************************************************************/
   1.349 +
   1.350 +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
   1.351 +
   1.352 +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
   1.353 +{
   1.354 +    unsigned char c;
   1.355 +    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
   1.356 +    if (err==1)
   1.357 +    {
   1.358 +        *pi = (int)c;
   1.359 +        return ZIP_OK;
   1.360 +    }
   1.361 +    else
   1.362 +    {
   1.363 +        if (ZERROR64(*pzlib_filefunc_def,filestream))
   1.364 +            return ZIP_ERRNO;
   1.365 +        else
   1.366 +            return ZIP_EOF;
   1.367 +    }
   1.368 +}
   1.369 +
   1.370 +
   1.371 +/* ===========================================================================
   1.372 +   Reads a long in LSB order from the given gz_stream. Sets
   1.373 +*/
   1.374 +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
   1.375 +
   1.376 +local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
   1.377 +{
   1.378 +    uLong x ;
   1.379 +    int i = 0;
   1.380 +    int err;
   1.381 +
   1.382 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.383 +    x = (uLong)i;
   1.384 +
   1.385 +    if (err==ZIP_OK)
   1.386 +        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.387 +    x += ((uLong)i)<<8;
   1.388 +
   1.389 +    if (err==ZIP_OK)
   1.390 +        *pX = x;
   1.391 +    else
   1.392 +        *pX = 0;
   1.393 +    return err;
   1.394 +}
   1.395 +
   1.396 +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
   1.397 +
   1.398 +local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
   1.399 +{
   1.400 +    uLong x ;
   1.401 +    int i = 0;
   1.402 +    int err;
   1.403 +
   1.404 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.405 +    x = (uLong)i;
   1.406 +
   1.407 +    if (err==ZIP_OK)
   1.408 +        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.409 +    x += ((uLong)i)<<8;
   1.410 +
   1.411 +    if (err==ZIP_OK)
   1.412 +        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.413 +    x += ((uLong)i)<<16;
   1.414 +
   1.415 +    if (err==ZIP_OK)
   1.416 +        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.417 +    x += ((uLong)i)<<24;
   1.418 +
   1.419 +    if (err==ZIP_OK)
   1.420 +        *pX = x;
   1.421 +    else
   1.422 +        *pX = 0;
   1.423 +    return err;
   1.424 +}
   1.425 +
   1.426 +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
   1.427 +
   1.428 +
   1.429 +local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
   1.430 +{
   1.431 +  ZPOS64_T x;
   1.432 +  int i = 0;
   1.433 +  int err;
   1.434 +
   1.435 +  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.436 +  x = (ZPOS64_T)i;
   1.437 +
   1.438 +  if (err==ZIP_OK)
   1.439 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.440 +  x += ((ZPOS64_T)i)<<8;
   1.441 +
   1.442 +  if (err==ZIP_OK)
   1.443 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.444 +  x += ((ZPOS64_T)i)<<16;
   1.445 +
   1.446 +  if (err==ZIP_OK)
   1.447 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.448 +  x += ((ZPOS64_T)i)<<24;
   1.449 +
   1.450 +  if (err==ZIP_OK)
   1.451 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.452 +  x += ((ZPOS64_T)i)<<32;
   1.453 +
   1.454 +  if (err==ZIP_OK)
   1.455 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.456 +  x += ((ZPOS64_T)i)<<40;
   1.457 +
   1.458 +  if (err==ZIP_OK)
   1.459 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.460 +  x += ((ZPOS64_T)i)<<48;
   1.461 +
   1.462 +  if (err==ZIP_OK)
   1.463 +    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
   1.464 +  x += ((ZPOS64_T)i)<<56;
   1.465 +
   1.466 +  if (err==ZIP_OK)
   1.467 +    *pX = x;
   1.468 +  else
   1.469 +    *pX = 0;
   1.470 +
   1.471 +  return err;
   1.472 +}
   1.473 +
   1.474 +#ifndef BUFREADCOMMENT
   1.475 +#define BUFREADCOMMENT (0x400)
   1.476 +#endif
   1.477 +/*
   1.478 +  Locate the Central directory of a zipfile (at the end, just before
   1.479 +    the global comment)
   1.480 +*/
   1.481 +local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
   1.482 +
   1.483 +local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
   1.484 +{
   1.485 +  unsigned char* buf;
   1.486 +  ZPOS64_T uSizeFile;
   1.487 +  ZPOS64_T uBackRead;
   1.488 +  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
   1.489 +  ZPOS64_T uPosFound=0;
   1.490 +
   1.491 +  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
   1.492 +    return 0;
   1.493 +
   1.494 +
   1.495 +  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
   1.496 +
   1.497 +  if (uMaxBack>uSizeFile)
   1.498 +    uMaxBack = uSizeFile;
   1.499 +
   1.500 +  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
   1.501 +  if (buf==NULL)
   1.502 +    return 0;
   1.503 +
   1.504 +  uBackRead = 4;
   1.505 +  while (uBackRead<uMaxBack)
   1.506 +  {
   1.507 +    uLong uReadSize;
   1.508 +    ZPOS64_T uReadPos ;
   1.509 +    int i;
   1.510 +    if (uBackRead+BUFREADCOMMENT>uMaxBack)
   1.511 +      uBackRead = uMaxBack;
   1.512 +    else
   1.513 +      uBackRead+=BUFREADCOMMENT;
   1.514 +    uReadPos = uSizeFile-uBackRead ;
   1.515 +
   1.516 +    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
   1.517 +      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
   1.518 +    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1.519 +      break;
   1.520 +
   1.521 +    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
   1.522 +      break;
   1.523 +
   1.524 +    for (i=(int)uReadSize-3; (i--)>0;)
   1.525 +      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
   1.526 +        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
   1.527 +      {
   1.528 +        uPosFound = uReadPos+i;
   1.529 +        break;
   1.530 +      }
   1.531 +
   1.532 +      if (uPosFound!=0)
   1.533 +        break;
   1.534 +  }
   1.535 +  TRYFREE(buf);
   1.536 +  return uPosFound;
   1.537 +}
   1.538 +
   1.539 +/*
   1.540 +Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
   1.541 +the global comment)
   1.542 +*/
   1.543 +local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
   1.544 +
   1.545 +local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
   1.546 +{
   1.547 +  unsigned char* buf;
   1.548 +  ZPOS64_T uSizeFile;
   1.549 +  ZPOS64_T uBackRead;
   1.550 +  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
   1.551 +  ZPOS64_T uPosFound=0;
   1.552 +  uLong uL;
   1.553 +  ZPOS64_T relativeOffset;
   1.554 +
   1.555 +  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
   1.556 +    return 0;
   1.557 +
   1.558 +  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
   1.559 +
   1.560 +  if (uMaxBack>uSizeFile)
   1.561 +    uMaxBack = uSizeFile;
   1.562 +
   1.563 +  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
   1.564 +  if (buf==NULL)
   1.565 +    return 0;
   1.566 +
   1.567 +  uBackRead = 4;
   1.568 +  while (uBackRead<uMaxBack)
   1.569 +  {
   1.570 +    uLong uReadSize;
   1.571 +    ZPOS64_T uReadPos;
   1.572 +    int i;
   1.573 +    if (uBackRead+BUFREADCOMMENT>uMaxBack)
   1.574 +      uBackRead = uMaxBack;
   1.575 +    else
   1.576 +      uBackRead+=BUFREADCOMMENT;
   1.577 +    uReadPos = uSizeFile-uBackRead ;
   1.578 +
   1.579 +    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
   1.580 +      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
   1.581 +    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1.582 +      break;
   1.583 +
   1.584 +    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
   1.585 +      break;
   1.586 +
   1.587 +    for (i=(int)uReadSize-3; (i--)>0;)
   1.588 +    {
   1.589 +      // Signature "0x07064b50" Zip64 end of central directory locater
   1.590 +      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
   1.591 +      {
   1.592 +        uPosFound = uReadPos+i;
   1.593 +        break;
   1.594 +      }
   1.595 +    }
   1.596 +
   1.597 +      if (uPosFound!=0)
   1.598 +        break;
   1.599 +  }
   1.600 +
   1.601 +  TRYFREE(buf);
   1.602 +  if (uPosFound == 0)
   1.603 +    return 0;
   1.604 +
   1.605 +  /* Zip64 end of central directory locator */
   1.606 +  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1.607 +    return 0;
   1.608 +
   1.609 +  /* the signature, already checked */
   1.610 +  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
   1.611 +    return 0;
   1.612 +
   1.613 +  /* number of the disk with the start of the zip64 end of  central directory */
   1.614 +  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
   1.615 +    return 0;
   1.616 +  if (uL != 0)
   1.617 +    return 0;
   1.618 +
   1.619 +  /* relative offset of the zip64 end of central directory record */
   1.620 +  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
   1.621 +    return 0;
   1.622 +
   1.623 +  /* total number of disks */
   1.624 +  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
   1.625 +    return 0;
   1.626 +  if (uL != 1)
   1.627 +    return 0;
   1.628 +
   1.629 +  /* Goto Zip64 end of central directory record */
   1.630 +  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1.631 +    return 0;
   1.632 +
   1.633 +  /* the signature */
   1.634 +  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
   1.635 +    return 0;
   1.636 +
   1.637 +  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
   1.638 +    return 0;
   1.639 +
   1.640 +  return relativeOffset;
   1.641 +}
   1.642 +
   1.643 +int LoadCentralDirectoryRecord(zip64_internal* pziinit)
   1.644 +{
   1.645 +  int err=ZIP_OK;
   1.646 +  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
   1.647 +
   1.648 +  ZPOS64_T size_central_dir;     /* size of the central directory  */
   1.649 +  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
   1.650 +  ZPOS64_T central_pos;
   1.651 +  uLong uL;
   1.652 +
   1.653 +  uLong number_disk;          /* number of the current dist, used for
   1.654 +                              spaning ZIP, unsupported, always 0*/
   1.655 +  uLong number_disk_with_CD;  /* number the the disk with central dir, used
   1.656 +                              for spaning ZIP, unsupported, always 0*/
   1.657 +  ZPOS64_T number_entry;
   1.658 +  ZPOS64_T number_entry_CD;      /* total number of entries in
   1.659 +                                the central dir
   1.660 +                                (same than number_entry on nospan) */
   1.661 +  uLong VersionMadeBy;
   1.662 +  uLong VersionNeeded;
   1.663 +  uLong size_comment;
   1.664 +
   1.665 +  int hasZIP64Record = 0;
   1.666 +
   1.667 +  // check first if we find a ZIP64 record
   1.668 +  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
   1.669 +  if(central_pos > 0)
   1.670 +  {
   1.671 +    hasZIP64Record = 1;
   1.672 +  }
   1.673 +  else if(central_pos == 0)
   1.674 +  {
   1.675 +    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
   1.676 +  }
   1.677 +
   1.678 +/* disable to allow appending to empty ZIP archive
   1.679 +        if (central_pos==0)
   1.680 +            err=ZIP_ERRNO;
   1.681 +*/
   1.682 +
   1.683 +  if(hasZIP64Record)
   1.684 +  {
   1.685 +    ZPOS64_T sizeEndOfCentralDirectory;
   1.686 +    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
   1.687 +      err=ZIP_ERRNO;
   1.688 +
   1.689 +    /* the signature, already checked */
   1.690 +    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
   1.691 +      err=ZIP_ERRNO;
   1.692 +
   1.693 +    /* size of zip64 end of central directory record */
   1.694 +    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
   1.695 +      err=ZIP_ERRNO;
   1.696 +
   1.697 +    /* version made by */
   1.698 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
   1.699 +      err=ZIP_ERRNO;
   1.700 +
   1.701 +    /* version needed to extract */
   1.702 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
   1.703 +      err=ZIP_ERRNO;
   1.704 +
   1.705 +    /* number of this disk */
   1.706 +    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
   1.707 +      err=ZIP_ERRNO;
   1.708 +
   1.709 +    /* number of the disk with the start of the central directory */
   1.710 +    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
   1.711 +      err=ZIP_ERRNO;
   1.712 +
   1.713 +    /* total number of entries in the central directory on this disk */
   1.714 +    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
   1.715 +      err=ZIP_ERRNO;
   1.716 +
   1.717 +    /* total number of entries in the central directory */
   1.718 +    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
   1.719 +      err=ZIP_ERRNO;
   1.720 +
   1.721 +    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
   1.722 +      err=ZIP_BADZIPFILE;
   1.723 +
   1.724 +    /* size of the central directory */
   1.725 +    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
   1.726 +      err=ZIP_ERRNO;
   1.727 +
   1.728 +    /* offset of start of central directory with respect to the
   1.729 +    starting disk number */
   1.730 +    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
   1.731 +      err=ZIP_ERRNO;
   1.732 +
   1.733 +    // TODO..
   1.734 +    // read the comment from the standard central header.
   1.735 +    size_comment = 0;
   1.736 +  }
   1.737 +  else
   1.738 +  {
   1.739 +    // Read End of central Directory info
   1.740 +    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
   1.741 +      err=ZIP_ERRNO;
   1.742 +
   1.743 +    /* the signature, already checked */
   1.744 +    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
   1.745 +      err=ZIP_ERRNO;
   1.746 +
   1.747 +    /* number of this disk */
   1.748 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
   1.749 +      err=ZIP_ERRNO;
   1.750 +
   1.751 +    /* number of the disk with the start of the central directory */
   1.752 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
   1.753 +      err=ZIP_ERRNO;
   1.754 +
   1.755 +    /* total number of entries in the central dir on this disk */
   1.756 +    number_entry = 0;
   1.757 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
   1.758 +      err=ZIP_ERRNO;
   1.759 +    else
   1.760 +      number_entry = uL;
   1.761 +
   1.762 +    /* total number of entries in the central dir */
   1.763 +    number_entry_CD = 0;
   1.764 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
   1.765 +      err=ZIP_ERRNO;
   1.766 +    else
   1.767 +      number_entry_CD = uL;
   1.768 +
   1.769 +    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
   1.770 +      err=ZIP_BADZIPFILE;
   1.771 +
   1.772 +    /* size of the central directory */
   1.773 +    size_central_dir = 0;
   1.774 +    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
   1.775 +      err=ZIP_ERRNO;
   1.776 +    else
   1.777 +      size_central_dir = uL;
   1.778 +
   1.779 +    /* offset of start of central directory with respect to the starting disk number */
   1.780 +    offset_central_dir = 0;
   1.781 +    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
   1.782 +      err=ZIP_ERRNO;
   1.783 +    else
   1.784 +      offset_central_dir = uL;
   1.785 +
   1.786 +
   1.787 +    /* zipfile global comment length */
   1.788 +    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
   1.789 +      err=ZIP_ERRNO;
   1.790 +  }
   1.791 +
   1.792 +  if ((central_pos<offset_central_dir+size_central_dir) &&
   1.793 +    (err==ZIP_OK))
   1.794 +    err=ZIP_BADZIPFILE;
   1.795 +
   1.796 +  if (err!=ZIP_OK)
   1.797 +  {
   1.798 +    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
   1.799 +    return ZIP_ERRNO;
   1.800 +  }
   1.801 +
   1.802 +  if (size_comment>0)
   1.803 +  {
   1.804 +    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
   1.805 +    if (pziinit->globalcomment)
   1.806 +    {
   1.807 +      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
   1.808 +      pziinit->globalcomment[size_comment]=0;
   1.809 +    }
   1.810 +  }
   1.811 +
   1.812 +  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
   1.813 +  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
   1.814 +
   1.815 +  {
   1.816 +    ZPOS64_T size_central_dir_to_read = size_central_dir;
   1.817 +    size_t buf_size = SIZEDATA_INDATABLOCK;
   1.818 +    void* buf_read = (void*)ALLOC(buf_size);
   1.819 +    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
   1.820 +      err=ZIP_ERRNO;
   1.821 +
   1.822 +    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
   1.823 +    {
   1.824 +      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
   1.825 +      if (read_this > size_central_dir_to_read)
   1.826 +        read_this = size_central_dir_to_read;
   1.827 +
   1.828 +      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
   1.829 +        err=ZIP_ERRNO;
   1.830 +
   1.831 +      if (err==ZIP_OK)
   1.832 +        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
   1.833 +
   1.834 +      size_central_dir_to_read-=read_this;
   1.835 +    }
   1.836 +    TRYFREE(buf_read);
   1.837 +  }
   1.838 +  pziinit->begin_pos = byte_before_the_zipfile;
   1.839 +  pziinit->number_entry = number_entry_CD;
   1.840 +
   1.841 +  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
   1.842 +    err=ZIP_ERRNO;
   1.843 +
   1.844 +  return err;
   1.845 +}
   1.846 +
   1.847 +
   1.848 +#endif /* !NO_ADDFILEINEXISTINGZIP*/
   1.849 +
   1.850 +
   1.851 +/************************************************************/
   1.852 +extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
   1.853 +{
   1.854 +    zip64_internal ziinit;
   1.855 +    zip64_internal* zi;
   1.856 +    int err=ZIP_OK;
   1.857 +
   1.858 +    ziinit.z_filefunc.zseek32_file = NULL;
   1.859 +    ziinit.z_filefunc.ztell32_file = NULL;
   1.860 +    if (pzlib_filefunc64_32_def==NULL)
   1.861 +        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
   1.862 +    else
   1.863 +        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
   1.864 +
   1.865 +    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
   1.866 +                  pathname,
   1.867 +                  (append == APPEND_STATUS_CREATE) ?
   1.868 +                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
   1.869 +                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
   1.870 +
   1.871 +    if (ziinit.filestream == NULL)
   1.872 +        return NULL;
   1.873 +
   1.874 +    if (append == APPEND_STATUS_CREATEAFTER)
   1.875 +        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
   1.876 +
   1.877 +    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
   1.878 +    ziinit.in_opened_file_inzip = 0;
   1.879 +    ziinit.ci.stream_initialised = 0;
   1.880 +    ziinit.number_entry = 0;
   1.881 +    ziinit.add_position_when_writting_offset = 0;
   1.882 +    init_linkedlist(&(ziinit.central_dir));
   1.883 +
   1.884 +
   1.885 +
   1.886 +    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
   1.887 +    if (zi==NULL)
   1.888 +    {
   1.889 +        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
   1.890 +        return NULL;
   1.891 +    }
   1.892 +
   1.893 +    /* now we add file in a zipfile */
   1.894 +#    ifndef NO_ADDFILEINEXISTINGZIP
   1.895 +    ziinit.globalcomment = NULL;
   1.896 +    if (append == APPEND_STATUS_ADDINZIP)
   1.897 +    {
   1.898 +      // Read and Cache Central Directory Records
   1.899 +      err = LoadCentralDirectoryRecord(&ziinit);
   1.900 +    }
   1.901 +
   1.902 +    if (globalcomment)
   1.903 +    {
   1.904 +      *globalcomment = ziinit.globalcomment;
   1.905 +    }
   1.906 +#    endif /* !NO_ADDFILEINEXISTINGZIP*/
   1.907 +
   1.908 +    if (err != ZIP_OK)
   1.909 +    {
   1.910 +#    ifndef NO_ADDFILEINEXISTINGZIP
   1.911 +        TRYFREE(ziinit.globalcomment);
   1.912 +#    endif /* !NO_ADDFILEINEXISTINGZIP*/
   1.913 +        TRYFREE(zi);
   1.914 +        return NULL;
   1.915 +    }
   1.916 +    else
   1.917 +    {
   1.918 +        *zi = ziinit;
   1.919 +        return (zipFile)zi;
   1.920 +    }
   1.921 +}
   1.922 +
   1.923 +extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
   1.924 +{
   1.925 +    if (pzlib_filefunc32_def != NULL)
   1.926 +    {
   1.927 +        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
   1.928 +        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
   1.929 +        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
   1.930 +    }
   1.931 +    else
   1.932 +        return zipOpen3(pathname, append, globalcomment, NULL);
   1.933 +}
   1.934 +
   1.935 +extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
   1.936 +{
   1.937 +    if (pzlib_filefunc_def != NULL)
   1.938 +    {
   1.939 +        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
   1.940 +        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
   1.941 +        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
   1.942 +        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
   1.943 +        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
   1.944 +    }
   1.945 +    else
   1.946 +        return zipOpen3(pathname, append, globalcomment, NULL);
   1.947 +}
   1.948 +
   1.949 +
   1.950 +
   1.951 +extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
   1.952 +{
   1.953 +    return zipOpen3((const void*)pathname,append,NULL,NULL);
   1.954 +}
   1.955 +
   1.956 +extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
   1.957 +{
   1.958 +    return zipOpen3(pathname,append,NULL,NULL);
   1.959 +}
   1.960 +
   1.961 +int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
   1.962 +{
   1.963 +  /* write the local header */
   1.964 +  int err;
   1.965 +  uInt size_filename = (uInt)strlen(filename);
   1.966 +  uInt size_extrafield = size_extrafield_local;
   1.967 +
   1.968 +  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
   1.969 +
   1.970 +  if (err==ZIP_OK)
   1.971 +  {
   1.972 +    if(zi->ci.zip64)
   1.973 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
   1.974 +    else
   1.975 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
   1.976 +  }
   1.977 +
   1.978 +  if (err==ZIP_OK)
   1.979 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
   1.980 +
   1.981 +  if (err==ZIP_OK)
   1.982 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
   1.983 +
   1.984 +  if (err==ZIP_OK)
   1.985 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
   1.986 +
   1.987 +  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
   1.988 +  if (err==ZIP_OK)
   1.989 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
   1.990 +  if (err==ZIP_OK)
   1.991 +  {
   1.992 +    if(zi->ci.zip64)
   1.993 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
   1.994 +    else
   1.995 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
   1.996 +  }
   1.997 +  if (err==ZIP_OK)
   1.998 +  {
   1.999 +    if(zi->ci.zip64)
  1.1000 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
  1.1001 +    else
  1.1002 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
  1.1003 +  }
  1.1004 +
  1.1005 +  if (err==ZIP_OK)
  1.1006 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
  1.1007 +
  1.1008 +  if(zi->ci.zip64)
  1.1009 +  {
  1.1010 +    size_extrafield += 20;
  1.1011 +  }
  1.1012 +
  1.1013 +  if (err==ZIP_OK)
  1.1014 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
  1.1015 +
  1.1016 +  if ((err==ZIP_OK) && (size_filename > 0))
  1.1017 +  {
  1.1018 +    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
  1.1019 +      err = ZIP_ERRNO;
  1.1020 +  }
  1.1021 +
  1.1022 +  if ((err==ZIP_OK) && (size_extrafield_local > 0))
  1.1023 +  {
  1.1024 +    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
  1.1025 +      err = ZIP_ERRNO;
  1.1026 +  }
  1.1027 +
  1.1028 +
  1.1029 +  if ((err==ZIP_OK) && (zi->ci.zip64))
  1.1030 +  {
  1.1031 +      // write the Zip64 extended info
  1.1032 +      short HeaderID = 1;
  1.1033 +      short DataSize = 16;
  1.1034 +      ZPOS64_T CompressedSize = 0;
  1.1035 +      ZPOS64_T UncompressedSize = 0;
  1.1036 +
  1.1037 +      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
  1.1038 +      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
  1.1039 +
  1.1040 +      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
  1.1041 +      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
  1.1042 +
  1.1043 +      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
  1.1044 +      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
  1.1045 +  }
  1.1046 +
  1.1047 +  return err;
  1.1048 +}
  1.1049 +
  1.1050 +/*
  1.1051 + NOTE.
  1.1052 + When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
  1.1053 + before calling this function it can be done with zipRemoveExtraInfoBlock
  1.1054 +
  1.1055 + It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
  1.1056 + unnecessary allocations.
  1.1057 + */
  1.1058 +extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1059 +                                         const void* extrafield_local, uInt size_extrafield_local,
  1.1060 +                                         const void* extrafield_global, uInt size_extrafield_global,
  1.1061 +                                         const char* comment, int method, int level, int raw,
  1.1062 +                                         int windowBits,int memLevel, int strategy,
  1.1063 +                                         const char* password, uLong crcForCrypting,
  1.1064 +                                         uLong versionMadeBy, uLong flagBase, int zip64)
  1.1065 +{
  1.1066 +    zip64_internal* zi;
  1.1067 +    uInt size_filename;
  1.1068 +    uInt size_comment;
  1.1069 +    uInt i;
  1.1070 +    int err = ZIP_OK;
  1.1071 +
  1.1072 +#    ifdef NOCRYPT
  1.1073 +    (crcForCrypting);
  1.1074 +    if (password != NULL)
  1.1075 +        return ZIP_PARAMERROR;
  1.1076 +#    endif
  1.1077 +
  1.1078 +    if (file == NULL)
  1.1079 +        return ZIP_PARAMERROR;
  1.1080 +
  1.1081 +#ifdef HAVE_BZIP2
  1.1082 +    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
  1.1083 +      return ZIP_PARAMERROR;
  1.1084 +#else
  1.1085 +    if ((method!=0) && (method!=Z_DEFLATED))
  1.1086 +      return ZIP_PARAMERROR;
  1.1087 +#endif
  1.1088 +
  1.1089 +    zi = (zip64_internal*)file;
  1.1090 +
  1.1091 +    if (zi->in_opened_file_inzip == 1)
  1.1092 +    {
  1.1093 +        err = zipCloseFileInZip (file);
  1.1094 +        if (err != ZIP_OK)
  1.1095 +            return err;
  1.1096 +    }
  1.1097 +
  1.1098 +    if (filename==NULL)
  1.1099 +        filename="-";
  1.1100 +
  1.1101 +    if (comment==NULL)
  1.1102 +        size_comment = 0;
  1.1103 +    else
  1.1104 +        size_comment = (uInt)strlen(comment);
  1.1105 +
  1.1106 +    size_filename = (uInt)strlen(filename);
  1.1107 +
  1.1108 +    if (zipfi == NULL)
  1.1109 +        zi->ci.dosDate = 0;
  1.1110 +    else
  1.1111 +    {
  1.1112 +        if (zipfi->dosDate != 0)
  1.1113 +            zi->ci.dosDate = zipfi->dosDate;
  1.1114 +        else
  1.1115 +          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
  1.1116 +    }
  1.1117 +
  1.1118 +    zi->ci.flag = flagBase;
  1.1119 +    if ((level==8) || (level==9))
  1.1120 +      zi->ci.flag |= 2;
  1.1121 +    if (level==2)
  1.1122 +      zi->ci.flag |= 4;
  1.1123 +    if (level==1)
  1.1124 +      zi->ci.flag |= 6;
  1.1125 +    if (password != NULL)
  1.1126 +      zi->ci.flag |= 1;
  1.1127 +
  1.1128 +    zi->ci.crc32 = 0;
  1.1129 +    zi->ci.method = method;
  1.1130 +    zi->ci.encrypt = 0;
  1.1131 +    zi->ci.stream_initialised = 0;
  1.1132 +    zi->ci.pos_in_buffered_data = 0;
  1.1133 +    zi->ci.raw = raw;
  1.1134 +    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
  1.1135 +
  1.1136 +    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
  1.1137 +    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
  1.1138 +
  1.1139 +    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
  1.1140 +
  1.1141 +    zi->ci.size_centralExtra = size_extrafield_global;
  1.1142 +    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
  1.1143 +    /* version info */
  1.1144 +    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
  1.1145 +    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
  1.1146 +    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
  1.1147 +    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
  1.1148 +    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
  1.1149 +    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
  1.1150 +    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
  1.1151 +    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
  1.1152 +    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
  1.1153 +    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
  1.1154 +    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
  1.1155 +    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
  1.1156 +
  1.1157 +    if (zipfi==NULL)
  1.1158 +        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
  1.1159 +    else
  1.1160 +        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
  1.1161 +
  1.1162 +    if (zipfi==NULL)
  1.1163 +        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
  1.1164 +    else
  1.1165 +        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
  1.1166 +
  1.1167 +    if(zi->ci.pos_local_header >= 0xffffffff)
  1.1168 +      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
  1.1169 +    else
  1.1170 +      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
  1.1171 +
  1.1172 +    for (i=0;i<size_filename;i++)
  1.1173 +        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
  1.1174 +
  1.1175 +    for (i=0;i<size_extrafield_global;i++)
  1.1176 +        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
  1.1177 +              *(((const char*)extrafield_global)+i);
  1.1178 +
  1.1179 +    for (i=0;i<size_comment;i++)
  1.1180 +        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
  1.1181 +              size_extrafield_global+i) = *(comment+i);
  1.1182 +    if (zi->ci.central_header == NULL)
  1.1183 +        return ZIP_INTERNALERROR;
  1.1184 +
  1.1185 +    zi->ci.zip64 = zip64;
  1.1186 +    zi->ci.totalCompressedData = 0;
  1.1187 +    zi->ci.totalUncompressedData = 0;
  1.1188 +    zi->ci.pos_zip64extrainfo = 0;
  1.1189 +
  1.1190 +    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
  1.1191 +
  1.1192 +#ifdef HAVE_BZIP2
  1.1193 +    zi->ci.bstream.avail_in = (uInt)0;
  1.1194 +    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  1.1195 +    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
  1.1196 +    zi->ci.bstream.total_in_hi32 = 0;
  1.1197 +    zi->ci.bstream.total_in_lo32 = 0;
  1.1198 +    zi->ci.bstream.total_out_hi32 = 0;
  1.1199 +    zi->ci.bstream.total_out_lo32 = 0;
  1.1200 +#endif
  1.1201 +
  1.1202 +    zi->ci.stream.avail_in = (uInt)0;
  1.1203 +    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1.1204 +    zi->ci.stream.next_out = zi->ci.buffered_data;
  1.1205 +    zi->ci.stream.total_in = 0;
  1.1206 +    zi->ci.stream.total_out = 0;
  1.1207 +    zi->ci.stream.data_type = Z_BINARY;
  1.1208 +
  1.1209 +#ifdef HAVE_BZIP2
  1.1210 +    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  1.1211 +#else
  1.1212 +    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  1.1213 +#endif
  1.1214 +    {
  1.1215 +        if(zi->ci.method == Z_DEFLATED)
  1.1216 +        {
  1.1217 +          zi->ci.stream.zalloc = (alloc_func)0;
  1.1218 +          zi->ci.stream.zfree = (free_func)0;
  1.1219 +          zi->ci.stream.opaque = (voidpf)0;
  1.1220 +
  1.1221 +          if (windowBits>0)
  1.1222 +              windowBits = -windowBits;
  1.1223 +
  1.1224 +          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
  1.1225 +
  1.1226 +          if (err==Z_OK)
  1.1227 +              zi->ci.stream_initialised = Z_DEFLATED;
  1.1228 +        }
  1.1229 +        else if(zi->ci.method == Z_BZIP2ED)
  1.1230 +        {
  1.1231 +#ifdef HAVE_BZIP2
  1.1232 +            // Init BZip stuff here
  1.1233 +          zi->ci.bstream.bzalloc = 0;
  1.1234 +          zi->ci.bstream.bzfree = 0;
  1.1235 +          zi->ci.bstream.opaque = (voidpf)0;
  1.1236 +
  1.1237 +          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
  1.1238 +          if(err == BZ_OK)
  1.1239 +            zi->ci.stream_initialised = Z_BZIP2ED;
  1.1240 +#endif
  1.1241 +        }
  1.1242 +
  1.1243 +    }
  1.1244 +
  1.1245 +#    ifndef NOCRYPT
  1.1246 +    zi->ci.crypt_header_size = 0;
  1.1247 +    if ((err==Z_OK) && (password != NULL))
  1.1248 +    {
  1.1249 +        unsigned char bufHead[RAND_HEAD_LEN];
  1.1250 +        unsigned int sizeHead;
  1.1251 +        zi->ci.encrypt = 1;
  1.1252 +        zi->ci.pcrc_32_tab = get_crc_table();
  1.1253 +        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
  1.1254 +
  1.1255 +        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
  1.1256 +        zi->ci.crypt_header_size = sizeHead;
  1.1257 +
  1.1258 +        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
  1.1259 +                err = ZIP_ERRNO;
  1.1260 +    }
  1.1261 +#    endif
  1.1262 +
  1.1263 +    if (err==Z_OK)
  1.1264 +        zi->in_opened_file_inzip = 1;
  1.1265 +    return err;
  1.1266 +}
  1.1267 +
  1.1268 +extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1269 +                                         const void* extrafield_local, uInt size_extrafield_local,
  1.1270 +                                         const void* extrafield_global, uInt size_extrafield_global,
  1.1271 +                                         const char* comment, int method, int level, int raw,
  1.1272 +                                         int windowBits,int memLevel, int strategy,
  1.1273 +                                         const char* password, uLong crcForCrypting,
  1.1274 +                                         uLong versionMadeBy, uLong flagBase)
  1.1275 +{
  1.1276 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1277 +                                 extrafield_local, size_extrafield_local,
  1.1278 +                                 extrafield_global, size_extrafield_global,
  1.1279 +                                 comment, method, level, raw,
  1.1280 +                                 windowBits, memLevel, strategy,
  1.1281 +                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
  1.1282 +}
  1.1283 +
  1.1284 +extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1285 +                                         const void* extrafield_local, uInt size_extrafield_local,
  1.1286 +                                         const void* extrafield_global, uInt size_extrafield_global,
  1.1287 +                                         const char* comment, int method, int level, int raw,
  1.1288 +                                         int windowBits,int memLevel, int strategy,
  1.1289 +                                         const char* password, uLong crcForCrypting)
  1.1290 +{
  1.1291 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1292 +                                 extrafield_local, size_extrafield_local,
  1.1293 +                                 extrafield_global, size_extrafield_global,
  1.1294 +                                 comment, method, level, raw,
  1.1295 +                                 windowBits, memLevel, strategy,
  1.1296 +                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
  1.1297 +}
  1.1298 +
  1.1299 +extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1300 +                                         const void* extrafield_local, uInt size_extrafield_local,
  1.1301 +                                         const void* extrafield_global, uInt size_extrafield_global,
  1.1302 +                                         const char* comment, int method, int level, int raw,
  1.1303 +                                         int windowBits,int memLevel, int strategy,
  1.1304 +                                         const char* password, uLong crcForCrypting, int zip64)
  1.1305 +{
  1.1306 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1307 +                                 extrafield_local, size_extrafield_local,
  1.1308 +                                 extrafield_global, size_extrafield_global,
  1.1309 +                                 comment, method, level, raw,
  1.1310 +                                 windowBits, memLevel, strategy,
  1.1311 +                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
  1.1312 +}
  1.1313 +
  1.1314 +extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1315 +                                        const void* extrafield_local, uInt size_extrafield_local,
  1.1316 +                                        const void* extrafield_global, uInt size_extrafield_global,
  1.1317 +                                        const char* comment, int method, int level, int raw)
  1.1318 +{
  1.1319 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1320 +                                 extrafield_local, size_extrafield_local,
  1.1321 +                                 extrafield_global, size_extrafield_global,
  1.1322 +                                 comment, method, level, raw,
  1.1323 +                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  1.1324 +                                 NULL, 0, VERSIONMADEBY, 0, 0);
  1.1325 +}
  1.1326 +
  1.1327 +extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1328 +                                        const void* extrafield_local, uInt size_extrafield_local,
  1.1329 +                                        const void* extrafield_global, uInt size_extrafield_global,
  1.1330 +                                        const char* comment, int method, int level, int raw, int zip64)
  1.1331 +{
  1.1332 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1333 +                                 extrafield_local, size_extrafield_local,
  1.1334 +                                 extrafield_global, size_extrafield_global,
  1.1335 +                                 comment, method, level, raw,
  1.1336 +                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  1.1337 +                                 NULL, 0, VERSIONMADEBY, 0, zip64);
  1.1338 +}
  1.1339 +
  1.1340 +extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1341 +                                        const void* extrafield_local, uInt size_extrafield_local,
  1.1342 +                                        const void*extrafield_global, uInt size_extrafield_global,
  1.1343 +                                        const char* comment, int method, int level, int zip64)
  1.1344 +{
  1.1345 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1346 +                                 extrafield_local, size_extrafield_local,
  1.1347 +                                 extrafield_global, size_extrafield_global,
  1.1348 +                                 comment, method, level, 0,
  1.1349 +                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  1.1350 +                                 NULL, 0, VERSIONMADEBY, 0, zip64);
  1.1351 +}
  1.1352 +
  1.1353 +extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
  1.1354 +                                        const void* extrafield_local, uInt size_extrafield_local,
  1.1355 +                                        const void*extrafield_global, uInt size_extrafield_global,
  1.1356 +                                        const char* comment, int method, int level)
  1.1357 +{
  1.1358 +    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
  1.1359 +                                 extrafield_local, size_extrafield_local,
  1.1360 +                                 extrafield_global, size_extrafield_global,
  1.1361 +                                 comment, method, level, 0,
  1.1362 +                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
  1.1363 +                                 NULL, 0, VERSIONMADEBY, 0, 0);
  1.1364 +}
  1.1365 +
  1.1366 +local int zip64FlushWriteBuffer(zip64_internal* zi)
  1.1367 +{
  1.1368 +    int err=ZIP_OK;
  1.1369 +
  1.1370 +    if (zi->ci.encrypt != 0)
  1.1371 +    {
  1.1372 +#ifndef NOCRYPT
  1.1373 +        uInt i;
  1.1374 +        int t;
  1.1375 +        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
  1.1376 +            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
  1.1377 +#endif
  1.1378 +    }
  1.1379 +
  1.1380 +    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
  1.1381 +      err = ZIP_ERRNO;
  1.1382 +
  1.1383 +    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
  1.1384 +
  1.1385 +#ifdef HAVE_BZIP2
  1.1386 +    if(zi->ci.method == Z_BZIP2ED)
  1.1387 +    {
  1.1388 +      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
  1.1389 +      zi->ci.bstream.total_in_lo32 = 0;
  1.1390 +      zi->ci.bstream.total_in_hi32 = 0;
  1.1391 +    }
  1.1392 +    else
  1.1393 +#endif
  1.1394 +    {
  1.1395 +      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
  1.1396 +      zi->ci.stream.total_in = 0;
  1.1397 +    }
  1.1398 +
  1.1399 +
  1.1400 +    zi->ci.pos_in_buffered_data = 0;
  1.1401 +
  1.1402 +    return err;
  1.1403 +}
  1.1404 +
  1.1405 +extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
  1.1406 +{
  1.1407 +    zip64_internal* zi;
  1.1408 +    int err=ZIP_OK;
  1.1409 +
  1.1410 +    if (file == NULL)
  1.1411 +        return ZIP_PARAMERROR;
  1.1412 +    zi = (zip64_internal*)file;
  1.1413 +
  1.1414 +    if (zi->in_opened_file_inzip == 0)
  1.1415 +        return ZIP_PARAMERROR;
  1.1416 +
  1.1417 +    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
  1.1418 +
  1.1419 +#ifdef HAVE_BZIP2
  1.1420 +    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
  1.1421 +    {
  1.1422 +      zi->ci.bstream.next_in = (void*)buf;
  1.1423 +      zi->ci.bstream.avail_in = len;
  1.1424 +      err = BZ_RUN_OK;
  1.1425 +
  1.1426 +      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
  1.1427 +      {
  1.1428 +        if (zi->ci.bstream.avail_out == 0)
  1.1429 +        {
  1.1430 +          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1.1431 +            err = ZIP_ERRNO;
  1.1432 +          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  1.1433 +          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
  1.1434 +        }
  1.1435 +
  1.1436 +
  1.1437 +        if(err != BZ_RUN_OK)
  1.1438 +          break;
  1.1439 +
  1.1440 +        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  1.1441 +        {
  1.1442 +          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
  1.1443 +//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
  1.1444 +          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
  1.1445 +
  1.1446 +          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
  1.1447 +        }
  1.1448 +      }
  1.1449 +
  1.1450 +      if(err == BZ_RUN_OK)
  1.1451 +        err = ZIP_OK;
  1.1452 +    }
  1.1453 +    else
  1.1454 +#endif
  1.1455 +    {
  1.1456 +      zi->ci.stream.next_in = (Bytef*)buf;
  1.1457 +      zi->ci.stream.avail_in = len;
  1.1458 +
  1.1459 +      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
  1.1460 +      {
  1.1461 +          if (zi->ci.stream.avail_out == 0)
  1.1462 +          {
  1.1463 +              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1.1464 +                  err = ZIP_ERRNO;
  1.1465 +              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1.1466 +              zi->ci.stream.next_out = zi->ci.buffered_data;
  1.1467 +          }
  1.1468 +
  1.1469 +
  1.1470 +          if(err != ZIP_OK)
  1.1471 +              break;
  1.1472 +
  1.1473 +          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  1.1474 +          {
  1.1475 +              uLong uTotalOutBefore = zi->ci.stream.total_out;
  1.1476 +              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
  1.1477 +              if(uTotalOutBefore > zi->ci.stream.total_out)
  1.1478 +              {
  1.1479 +                int bBreak = 0;
  1.1480 +                bBreak++;
  1.1481 +              }
  1.1482 +
  1.1483 +              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  1.1484 +          }
  1.1485 +          else
  1.1486 +          {
  1.1487 +              uInt copy_this,i;
  1.1488 +              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
  1.1489 +                  copy_this = zi->ci.stream.avail_in;
  1.1490 +              else
  1.1491 +                  copy_this = zi->ci.stream.avail_out;
  1.1492 +
  1.1493 +              for (i = 0; i < copy_this; i++)
  1.1494 +                  *(((char*)zi->ci.stream.next_out)+i) =
  1.1495 +                      *(((const char*)zi->ci.stream.next_in)+i);
  1.1496 +              {
  1.1497 +                  zi->ci.stream.avail_in -= copy_this;
  1.1498 +                  zi->ci.stream.avail_out-= copy_this;
  1.1499 +                  zi->ci.stream.next_in+= copy_this;
  1.1500 +                  zi->ci.stream.next_out+= copy_this;
  1.1501 +                  zi->ci.stream.total_in+= copy_this;
  1.1502 +                  zi->ci.stream.total_out+= copy_this;
  1.1503 +                  zi->ci.pos_in_buffered_data += copy_this;
  1.1504 +              }
  1.1505 +          }
  1.1506 +      }// while(...)
  1.1507 +    }
  1.1508 +
  1.1509 +    return err;
  1.1510 +}
  1.1511 +
  1.1512 +extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
  1.1513 +{
  1.1514 +    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
  1.1515 +}
  1.1516 +
  1.1517 +extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
  1.1518 +{
  1.1519 +    zip64_internal* zi;
  1.1520 +    ZPOS64_T compressed_size;
  1.1521 +    uLong invalidValue = 0xffffffff;
  1.1522 +    short datasize = 0;
  1.1523 +    int err=ZIP_OK;
  1.1524 +
  1.1525 +    if (file == NULL)
  1.1526 +        return ZIP_PARAMERROR;
  1.1527 +    zi = (zip64_internal*)file;
  1.1528 +
  1.1529 +    if (zi->in_opened_file_inzip == 0)
  1.1530 +        return ZIP_PARAMERROR;
  1.1531 +    zi->ci.stream.avail_in = 0;
  1.1532 +
  1.1533 +    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  1.1534 +                {
  1.1535 +                        while (err==ZIP_OK)
  1.1536 +                        {
  1.1537 +                                uLong uTotalOutBefore;
  1.1538 +                                if (zi->ci.stream.avail_out == 0)
  1.1539 +                                {
  1.1540 +                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1.1541 +                                                err = ZIP_ERRNO;
  1.1542 +                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
  1.1543 +                                        zi->ci.stream.next_out = zi->ci.buffered_data;
  1.1544 +                                }
  1.1545 +                                uTotalOutBefore = zi->ci.stream.total_out;
  1.1546 +                                err=deflate(&zi->ci.stream,  Z_FINISH);
  1.1547 +                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
  1.1548 +                        }
  1.1549 +                }
  1.1550 +    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  1.1551 +    {
  1.1552 +#ifdef HAVE_BZIP2
  1.1553 +      err = BZ_FINISH_OK;
  1.1554 +      while (err==BZ_FINISH_OK)
  1.1555 +      {
  1.1556 +        uLong uTotalOutBefore;
  1.1557 +        if (zi->ci.bstream.avail_out == 0)
  1.1558 +        {
  1.1559 +          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
  1.1560 +            err = ZIP_ERRNO;
  1.1561 +          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
  1.1562 +          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
  1.1563 +        }
  1.1564 +        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
  1.1565 +        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
  1.1566 +        if(err == BZ_STREAM_END)
  1.1567 +          err = Z_STREAM_END;
  1.1568 +
  1.1569 +        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
  1.1570 +      }
  1.1571 +
  1.1572 +      if(err == BZ_FINISH_OK)
  1.1573 +        err = ZIP_OK;
  1.1574 +#endif
  1.1575 +    }
  1.1576 +
  1.1577 +    if (err==Z_STREAM_END)
  1.1578 +        err=ZIP_OK; /* this is normal */
  1.1579 +
  1.1580 +    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
  1.1581 +                {
  1.1582 +        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
  1.1583 +            err = ZIP_ERRNO;
  1.1584 +                }
  1.1585 +
  1.1586 +    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
  1.1587 +    {
  1.1588 +        int tmp_err = deflateEnd(&zi->ci.stream);
  1.1589 +        if (err == ZIP_OK)
  1.1590 +            err = tmp_err;
  1.1591 +        zi->ci.stream_initialised = 0;
  1.1592 +    }
  1.1593 +#ifdef HAVE_BZIP2
  1.1594 +    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
  1.1595 +    {
  1.1596 +      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
  1.1597 +                        if (err==ZIP_OK)
  1.1598 +                                err = tmperr;
  1.1599 +                        zi->ci.stream_initialised = 0;
  1.1600 +    }
  1.1601 +#endif
  1.1602 +
  1.1603 +    if (!zi->ci.raw)
  1.1604 +    {
  1.1605 +        crc32 = (uLong)zi->ci.crc32;
  1.1606 +        uncompressed_size = zi->ci.totalUncompressedData;
  1.1607 +    }
  1.1608 +    compressed_size = zi->ci.totalCompressedData;
  1.1609 +
  1.1610 +#    ifndef NOCRYPT
  1.1611 +    compressed_size += zi->ci.crypt_header_size;
  1.1612 +#    endif
  1.1613 +
  1.1614 +    // update Current Item crc and sizes,
  1.1615 +    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
  1.1616 +    {
  1.1617 +      /*version Made by*/
  1.1618 +      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
  1.1619 +      /*version needed*/
  1.1620 +      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
  1.1621 +
  1.1622 +    }
  1.1623 +
  1.1624 +    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
  1.1625 +
  1.1626 +
  1.1627 +    if(compressed_size >= 0xffffffff)
  1.1628 +      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
  1.1629 +    else
  1.1630 +      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
  1.1631 +
  1.1632 +    /// set internal file attributes field
  1.1633 +    if (zi->ci.stream.data_type == Z_ASCII)
  1.1634 +        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
  1.1635 +
  1.1636 +    if(uncompressed_size >= 0xffffffff)
  1.1637 +      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
  1.1638 +    else
  1.1639 +      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
  1.1640 +
  1.1641 +    // Add ZIP64 extra info field for uncompressed size
  1.1642 +    if(uncompressed_size >= 0xffffffff)
  1.1643 +      datasize += 8;
  1.1644 +
  1.1645 +    // Add ZIP64 extra info field for compressed size
  1.1646 +    if(compressed_size >= 0xffffffff)
  1.1647 +      datasize += 8;
  1.1648 +
  1.1649 +    // Add ZIP64 extra info field for relative offset to local file header of current file
  1.1650 +    if(zi->ci.pos_local_header >= 0xffffffff)
  1.1651 +      datasize += 8;
  1.1652 +
  1.1653 +    if(datasize > 0)
  1.1654 +    {
  1.1655 +      char* p = NULL;
  1.1656 +
  1.1657 +      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
  1.1658 +      {
  1.1659 +        // we can not write more data to the buffer that we have room for.
  1.1660 +        return ZIP_BADZIPFILE;
  1.1661 +      }
  1.1662 +
  1.1663 +      p = zi->ci.central_header + zi->ci.size_centralheader;
  1.1664 +
  1.1665 +      // Add Extra Information Header for 'ZIP64 information'
  1.1666 +      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
  1.1667 +      p += 2;
  1.1668 +      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
  1.1669 +      p += 2;
  1.1670 +
  1.1671 +      if(uncompressed_size >= 0xffffffff)
  1.1672 +      {
  1.1673 +        zip64local_putValue_inmemory(p, uncompressed_size, 8);
  1.1674 +        p += 8;
  1.1675 +      }
  1.1676 +
  1.1677 +      if(compressed_size >= 0xffffffff)
  1.1678 +      {
  1.1679 +        zip64local_putValue_inmemory(p, compressed_size, 8);
  1.1680 +        p += 8;
  1.1681 +      }
  1.1682 +
  1.1683 +      if(zi->ci.pos_local_header >= 0xffffffff)
  1.1684 +      {
  1.1685 +        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
  1.1686 +        p += 8;
  1.1687 +      }
  1.1688 +
  1.1689 +      // Update how much extra free space we got in the memory buffer
  1.1690 +      // and increase the centralheader size so the new ZIP64 fields are included
  1.1691 +      // ( 4 below is the size of HeaderID and DataSize field )
  1.1692 +      zi->ci.size_centralExtraFree -= datasize + 4;
  1.1693 +      zi->ci.size_centralheader += datasize + 4;
  1.1694 +
  1.1695 +      // Update the extra info size field
  1.1696 +      zi->ci.size_centralExtra += datasize + 4;
  1.1697 +      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
  1.1698 +    }
  1.1699 +
  1.1700 +    if (err==ZIP_OK)
  1.1701 +        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
  1.1702 +
  1.1703 +    free(zi->ci.central_header);
  1.1704 +
  1.1705 +    if (err==ZIP_OK)
  1.1706 +    {
  1.1707 +        // Update the LocalFileHeader with the new values.
  1.1708 +
  1.1709 +        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
  1.1710 +
  1.1711 +        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
  1.1712 +            err = ZIP_ERRNO;
  1.1713 +
  1.1714 +        if (err==ZIP_OK)
  1.1715 +            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
  1.1716 +
  1.1717 +        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
  1.1718 +        {
  1.1719 +          if(zi->ci.pos_zip64extrainfo > 0)
  1.1720 +          {
  1.1721 +            // Update the size in the ZIP64 extended field.
  1.1722 +            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
  1.1723 +              err = ZIP_ERRNO;
  1.1724 +
  1.1725 +            if (err==ZIP_OK) /* compressed size, unknown */
  1.1726 +              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
  1.1727 +
  1.1728 +            if (err==ZIP_OK) /* uncompressed size, unknown */
  1.1729 +              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
  1.1730 +          }
  1.1731 +          else
  1.1732 +              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
  1.1733 +        }
  1.1734 +        else
  1.1735 +        {
  1.1736 +          if (err==ZIP_OK) /* compressed size, unknown */
  1.1737 +              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
  1.1738 +
  1.1739 +          if (err==ZIP_OK) /* uncompressed size, unknown */
  1.1740 +              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
  1.1741 +        }
  1.1742 +
  1.1743 +        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
  1.1744 +            err = ZIP_ERRNO;
  1.1745 +    }
  1.1746 +
  1.1747 +    zi->number_entry ++;
  1.1748 +    zi->in_opened_file_inzip = 0;
  1.1749 +
  1.1750 +    return err;
  1.1751 +}
  1.1752 +
  1.1753 +extern int ZEXPORT zipCloseFileInZip (zipFile file)
  1.1754 +{
  1.1755 +    return zipCloseFileInZipRaw (file,0,0);
  1.1756 +}
  1.1757 +
  1.1758 +int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
  1.1759 +{
  1.1760 +  int err = ZIP_OK;
  1.1761 +  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
  1.1762 +
  1.1763 +  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
  1.1764 +
  1.1765 +  /*num disks*/
  1.1766 +    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  1.1767 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
  1.1768 +
  1.1769 +  /*relative offset*/
  1.1770 +    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
  1.1771 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
  1.1772 +
  1.1773 +  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
  1.1774 +    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  1.1775 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
  1.1776 +
  1.1777 +    return err;
  1.1778 +}
  1.1779 +
  1.1780 +int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
  1.1781 +{
  1.1782 +  int err = ZIP_OK;
  1.1783 +
  1.1784 +  uLong Zip64DataSize = 44;
  1.1785 +
  1.1786 +  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
  1.1787 +
  1.1788 +  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
  1.1789 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
  1.1790 +
  1.1791 +  if (err==ZIP_OK) /* version made by */
  1.1792 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
  1.1793 +
  1.1794 +  if (err==ZIP_OK) /* version needed */
  1.1795 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
  1.1796 +
  1.1797 +  if (err==ZIP_OK) /* number of this disk */
  1.1798 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
  1.1799 +
  1.1800 +  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  1.1801 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
  1.1802 +
  1.1803 +  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
  1.1804 +    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
  1.1805 +
  1.1806 +  if (err==ZIP_OK) /* total number of entries in the central dir */
  1.1807 +    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
  1.1808 +
  1.1809 +  if (err==ZIP_OK) /* size of the central directory */
  1.1810 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
  1.1811 +
  1.1812 +  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
  1.1813 +  {
  1.1814 +    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  1.1815 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
  1.1816 +  }
  1.1817 +  return err;
  1.1818 +}
  1.1819 +int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
  1.1820 +{
  1.1821 +  int err = ZIP_OK;
  1.1822 +
  1.1823 +  /*signature*/
  1.1824 +  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
  1.1825 +
  1.1826 +  if (err==ZIP_OK) /* number of this disk */
  1.1827 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  1.1828 +
  1.1829 +  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
  1.1830 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
  1.1831 +
  1.1832 +  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
  1.1833 +  {
  1.1834 +    {
  1.1835 +      if(zi->number_entry >= 0xFFFF)
  1.1836 +        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
  1.1837 +      else
  1.1838 +        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  1.1839 +    }
  1.1840 +  }
  1.1841 +
  1.1842 +  if (err==ZIP_OK) /* total number of entries in the central dir */
  1.1843 +  {
  1.1844 +    if(zi->number_entry >= 0xFFFF)
  1.1845 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
  1.1846 +    else
  1.1847 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
  1.1848 +  }
  1.1849 +
  1.1850 +  if (err==ZIP_OK) /* size of the central directory */
  1.1851 +    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
  1.1852 +
  1.1853 +  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
  1.1854 +  {
  1.1855 +    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  1.1856 +    if(pos >= 0xffffffff)
  1.1857 +    {
  1.1858 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
  1.1859 +    }
  1.1860 +    else
  1.1861 +      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
  1.1862 +  }
  1.1863 +
  1.1864 +   return err;
  1.1865 +}
  1.1866 +
  1.1867 +int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
  1.1868 +{
  1.1869 +  int err = ZIP_OK;
  1.1870 +  uInt size_global_comment = 0;
  1.1871 +
  1.1872 +  if(global_comment != NULL)
  1.1873 +    size_global_comment = (uInt)strlen(global_comment);
  1.1874 +
  1.1875 +  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
  1.1876 +
  1.1877 +  if (err == ZIP_OK && size_global_comment > 0)
  1.1878 +  {
  1.1879 +    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
  1.1880 +      err = ZIP_ERRNO;
  1.1881 +  }
  1.1882 +  return err;
  1.1883 +}
  1.1884 +
  1.1885 +extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
  1.1886 +{
  1.1887 +    zip64_internal* zi;
  1.1888 +    int err = 0;
  1.1889 +    uLong size_centraldir = 0;
  1.1890 +    ZPOS64_T centraldir_pos_inzip;
  1.1891 +    ZPOS64_T pos;
  1.1892 +
  1.1893 +    if (file == NULL)
  1.1894 +        return ZIP_PARAMERROR;
  1.1895 +
  1.1896 +    zi = (zip64_internal*)file;
  1.1897 +
  1.1898 +    if (zi->in_opened_file_inzip == 1)
  1.1899 +    {
  1.1900 +        err = zipCloseFileInZip (file);
  1.1901 +    }
  1.1902 +
  1.1903 +#ifndef NO_ADDFILEINEXISTINGZIP
  1.1904 +    if (global_comment==NULL)
  1.1905 +        global_comment = zi->globalcomment;
  1.1906 +#endif
  1.1907 +
  1.1908 +    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
  1.1909 +
  1.1910 +    if (err==ZIP_OK)
  1.1911 +    {
  1.1912 +        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
  1.1913 +        while (ldi!=NULL)
  1.1914 +        {
  1.1915 +            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
  1.1916 +            {
  1.1917 +                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
  1.1918 +                    err = ZIP_ERRNO;
  1.1919 +            }
  1.1920 +
  1.1921 +            size_centraldir += ldi->filled_in_this_block;
  1.1922 +            ldi = ldi->next_datablock;
  1.1923 +        }
  1.1924 +    }
  1.1925 +    free_linkedlist(&(zi->central_dir));
  1.1926 +
  1.1927 +    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
  1.1928 +    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
  1.1929 +    {
  1.1930 +      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
  1.1931 +      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
  1.1932 +
  1.1933 +      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
  1.1934 +    }
  1.1935 +
  1.1936 +    if (err==ZIP_OK)
  1.1937 +      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
  1.1938 +
  1.1939 +    if(err == ZIP_OK)
  1.1940 +      err = Write_GlobalComment(zi, global_comment);
  1.1941 +
  1.1942 +    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
  1.1943 +        if (err == ZIP_OK)
  1.1944 +            err = ZIP_ERRNO;
  1.1945 +
  1.1946 +#ifndef NO_ADDFILEINEXISTINGZIP
  1.1947 +    TRYFREE(zi->globalcomment);
  1.1948 +#endif
  1.1949 +    TRYFREE(zi);
  1.1950 +
  1.1951 +    return err;
  1.1952 +}
  1.1953 +
  1.1954 +extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
  1.1955 +{
  1.1956 +  char* p = pData;
  1.1957 +  int size = 0;
  1.1958 +  char* pNewHeader;
  1.1959 +  char* pTmp;
  1.1960 +  short header;
  1.1961 +  short dataSize;
  1.1962 +
  1.1963 +  int retVal = ZIP_OK;
  1.1964 +
  1.1965 +  if(pData == NULL || *dataLen < 4)
  1.1966 +    return ZIP_PARAMERROR;
  1.1967 +
  1.1968 +  pNewHeader = (char*)ALLOC(*dataLen);
  1.1969 +  pTmp = pNewHeader;
  1.1970 +
  1.1971 +  while(p < (pData + *dataLen))
  1.1972 +  {
  1.1973 +    header = *(short*)p;
  1.1974 +    dataSize = *(((short*)p)+1);
  1.1975 +
  1.1976 +    if( header == sHeader ) // Header found.
  1.1977 +    {
  1.1978 +      p += dataSize + 4; // skip it. do not copy to temp buffer
  1.1979 +    }
  1.1980 +    else
  1.1981 +    {
  1.1982 +      // Extra Info block should not be removed, So copy it to the temp buffer.
  1.1983 +      memcpy(pTmp, p, dataSize + 4);
  1.1984 +      p += dataSize + 4;
  1.1985 +      size += dataSize + 4;
  1.1986 +    }
  1.1987 +
  1.1988 +  }
  1.1989 +
  1.1990 +  if(size < *dataLen)
  1.1991 +  {
  1.1992 +    // clean old extra info block.
  1.1993 +    memset(pData,0, *dataLen);
  1.1994 +
  1.1995 +    // copy the new extra info block over the old
  1.1996 +    if(size > 0)
  1.1997 +      memcpy(pData, pNewHeader, size);
  1.1998 +
  1.1999 +    // set the new extra info size
  1.2000 +    *dataLen = size;
  1.2001 +
  1.2002 +    retVal = ZIP_OK;
  1.2003 +  }
  1.2004 +  else
  1.2005 +    retVal = ZIP_ERRNO;
  1.2006 +
  1.2007 +  TRYFREE(pNewHeader);
  1.2008 +
  1.2009 +  return retVal;
  1.2010 +}