kusano fc6ab3
/* zip.c -- IO on .zip files using zlib
kusano fc6ab3
   Version 1.1, February 14h, 2010
kusano fc6ab3
   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
kusano fc6ab3
kusano fc6ab3
         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
kusano fc6ab3
kusano fc6ab3
         Modifications for Zip64 support
kusano fc6ab3
         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
kusano fc6ab3
kusano fc6ab3
         For more info read MiniZip_info.txt
kusano fc6ab3
kusano fc6ab3
         Changes
kusano fc6ab3
   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
kusano fc6ab3
   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
kusano fc6ab3
   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
kusano fc6ab3
   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
kusano fc6ab3
                                 It is used when recreting zip archive with RAW when deleting items from a zip.
kusano fc6ab3
                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
kusano fc6ab3
   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
kusano fc6ab3
   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
kusano fc6ab3
kusano fc6ab3
*/
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
#include <stdio.h></stdio.h>
kusano fc6ab3
#include <stdlib.h></stdlib.h>
kusano fc6ab3
#include <string.h></string.h>
kusano fc6ab3
#include <time.h></time.h>
kusano fc6ab3
#include "zlib.h"
kusano fc6ab3
#include "zip.h"
kusano fc6ab3
kusano fc6ab3
#ifdef STDC
kusano fc6ab3
#  include <stddef.h></stddef.h>
kusano fc6ab3
#  include <string.h></string.h>
kusano fc6ab3
#  include <stdlib.h></stdlib.h>
kusano fc6ab3
#endif
kusano fc6ab3
#ifdef NO_ERRNO_H
kusano fc6ab3
    extern int errno;
kusano fc6ab3
#else
kusano fc6ab3
#   include <errno.h></errno.h>
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
#ifndef local
kusano fc6ab3
#  define local static
kusano fc6ab3
#endif
kusano fc6ab3
/* compile with -Dlocal if your debugger can't find static symbols */
kusano fc6ab3
kusano fc6ab3
#ifndef VERSIONMADEBY
kusano fc6ab3
# define VERSIONMADEBY   (0x0) /* platform depedent */
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
#ifndef Z_BUFSIZE
kusano fc6ab3
#define Z_BUFSIZE (64*1024) //(16384)
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
#ifndef Z_MAXFILENAMEINZIP
kusano fc6ab3
#define Z_MAXFILENAMEINZIP (256)
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
#ifndef ALLOC
kusano fc6ab3
# define ALLOC(size) (malloc(size))
kusano fc6ab3
#endif
kusano fc6ab3
#ifndef TRYFREE
kusano fc6ab3
# define TRYFREE(p) {if (p) free(p);}
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
#define SIZECENTRALDIRITEM (0x2e)
kusano fc6ab3
#define SIZEZIPLOCALHEADER (0x1e)
kusano fc6ab3
*/
kusano fc6ab3
kusano fc6ab3
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
// NOT sure that this work on ALL platform
kusano fc6ab3
#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
kusano fc6ab3
kusano fc6ab3
#ifndef SEEK_CUR
kusano fc6ab3
#define SEEK_CUR    1
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
#ifndef SEEK_END
kusano fc6ab3
#define SEEK_END    2
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
#ifndef SEEK_SET
kusano fc6ab3
#define SEEK_SET    0
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
#ifndef DEF_MEM_LEVEL
kusano fc6ab3
#if MAX_MEM_LEVEL >= 8
kusano fc6ab3
#  define DEF_MEM_LEVEL 8
kusano fc6ab3
#else
kusano fc6ab3
#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
kusano fc6ab3
#endif
kusano fc6ab3
#endif
kusano fc6ab3
const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
#define SIZEDATA_INDATABLOCK (4096-(4*4))
kusano fc6ab3
kusano fc6ab3
#define LOCALHEADERMAGIC    (0x04034b50)
kusano fc6ab3
#define CENTRALHEADERMAGIC  (0x02014b50)
kusano fc6ab3
#define ENDHEADERMAGIC      (0x06054b50)
kusano fc6ab3
#define ZIP64ENDHEADERMAGIC      (0x6064b50)
kusano fc6ab3
#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
kusano fc6ab3
kusano fc6ab3
#define FLAG_LOCALHEADER_OFFSET (0x06)
kusano fc6ab3
#define CRC_LOCALHEADER_OFFSET  (0x0e)
kusano fc6ab3
kusano fc6ab3
#define SIZECENTRALHEADER (0x2e) /* 46 */
kusano fc6ab3
kusano fc6ab3
typedef struct linkedlist_datablock_internal_s
kusano fc6ab3
{
kusano fc6ab3
  struct linkedlist_datablock_internal_s* next_datablock;
kusano fc6ab3
  uLong  avail_in_this_block;
kusano fc6ab3
  uLong  filled_in_this_block;
kusano fc6ab3
  uLong  unused; /* for future use and alignement */
kusano fc6ab3
  unsigned char data[SIZEDATA_INDATABLOCK];
kusano fc6ab3
} linkedlist_datablock_internal;
kusano fc6ab3
kusano fc6ab3
typedef struct linkedlist_data_s
kusano fc6ab3
{
kusano fc6ab3
    linkedlist_datablock_internal* first_block;
kusano fc6ab3
    linkedlist_datablock_internal* last_block;
kusano fc6ab3
} linkedlist_data;
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
typedef struct
kusano fc6ab3
{
kusano fc6ab3
    z_stream stream;            /* zLib stream structure for inflate */
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    bz_stream bstream;          /* bzLib stream structure for bziped */
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
    int  stream_initialised;    /* 1 is stream is initialised */
kusano fc6ab3
    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
kusano fc6ab3
kusano fc6ab3
    ZPOS64_T pos_local_header;     /* offset of the local header of the file
kusano fc6ab3
                                     currenty writing */
kusano fc6ab3
    char* central_header;       /* central header data for the current file */
kusano fc6ab3
    uLong size_centralExtra;
kusano fc6ab3
    uLong size_centralheader;   /* size of the central header for cur file */
kusano fc6ab3
    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
kusano fc6ab3
    uLong flag;                 /* flag of the file currently writing */
kusano fc6ab3
kusano fc6ab3
    int  method;                /* compression method of file currenty wr.*/
kusano fc6ab3
    int  raw;                   /* 1 for directly writing raw data */
kusano fc6ab3
    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
kusano fc6ab3
    uLong dosDate;
kusano fc6ab3
    uLong crc32;
kusano fc6ab3
    int  encrypt;
kusano fc6ab3
    int  zip64;               /* Add ZIP64 extened information in the extra field */
kusano fc6ab3
    ZPOS64_T pos_zip64extrainfo;
kusano fc6ab3
    ZPOS64_T totalCompressedData;
kusano fc6ab3
    ZPOS64_T totalUncompressedData;
kusano fc6ab3
#ifndef NOCRYPT
kusano fc6ab3
    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
kusano fc6ab3
    const z_crc_t* pcrc_32_tab;
kusano fc6ab3
    int crypt_header_size;
kusano fc6ab3
#endif
kusano fc6ab3
} curfile64_info;
kusano fc6ab3
kusano fc6ab3
typedef struct
kusano fc6ab3
{
kusano fc6ab3
    zlib_filefunc64_32_def z_filefunc;
kusano fc6ab3
    voidpf filestream;        /* io structore of the zipfile */
kusano fc6ab3
    linkedlist_data central_dir;/* datablock with central dir in construction*/
kusano fc6ab3
    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
kusano fc6ab3
    curfile64_info ci;            /* info on the file curretly writing */
kusano fc6ab3
kusano fc6ab3
    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
kusano fc6ab3
    ZPOS64_T add_position_when_writting_offset;
kusano fc6ab3
    ZPOS64_T number_entry;
kusano fc6ab3
kusano fc6ab3
#ifndef NO_ADDFILEINEXISTINGZIP
kusano fc6ab3
    char *globalcomment;
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
} zip64_internal;
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
#ifndef NOCRYPT
kusano fc6ab3
#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
kusano fc6ab3
#include "crypt.h"
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
local linkedlist_datablock_internal* allocate_new_datablock()
kusano fc6ab3
{
kusano fc6ab3
    linkedlist_datablock_internal* ldi;
kusano fc6ab3
    ldi = (linkedlist_datablock_internal*)
kusano fc6ab3
                 ALLOC(sizeof(linkedlist_datablock_internal));
kusano fc6ab3
    if (ldi!=NULL)
kusano fc6ab3
    {
kusano fc6ab3
        ldi->next_datablock = NULL ;
kusano fc6ab3
        ldi->filled_in_this_block = 0 ;
kusano fc6ab3
        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
kusano fc6ab3
    }
kusano fc6ab3
    return ldi;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local void free_datablock(linkedlist_datablock_internal* ldi)
kusano fc6ab3
{
kusano fc6ab3
    while (ldi!=NULL)
kusano fc6ab3
    {
kusano fc6ab3
        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
kusano fc6ab3
        TRYFREE(ldi);
kusano fc6ab3
        ldi = ldinext;
kusano fc6ab3
    }
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local void init_linkedlist(linkedlist_data* ll)
kusano fc6ab3
{
kusano fc6ab3
    ll->first_block = ll->last_block = NULL;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local void free_linkedlist(linkedlist_data* ll)
kusano fc6ab3
{
kusano fc6ab3
    free_datablock(ll->first_block);
kusano fc6ab3
    ll->first_block = ll->last_block = NULL;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
kusano fc6ab3
{
kusano fc6ab3
    linkedlist_datablock_internal* ldi;
kusano fc6ab3
    const unsigned char* from_copy;
kusano fc6ab3
kusano fc6ab3
    if (ll==NULL)
kusano fc6ab3
        return ZIP_INTERNALERROR;
kusano fc6ab3
kusano fc6ab3
    if (ll->last_block == NULL)
kusano fc6ab3
    {
kusano fc6ab3
        ll->first_block = ll->last_block = allocate_new_datablock();
kusano fc6ab3
        if (ll->first_block == NULL)
kusano fc6ab3
            return ZIP_INTERNALERROR;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    ldi = ll->last_block;
kusano fc6ab3
    from_copy = (unsigned char*)buf;
kusano fc6ab3
kusano fc6ab3
    while (len>0)
kusano fc6ab3
    {
kusano fc6ab3
        uInt copy_this;
kusano fc6ab3
        uInt i;
kusano fc6ab3
        unsigned char* to_copy;
kusano fc6ab3
kusano fc6ab3
        if (ldi->avail_in_this_block==0)
kusano fc6ab3
        {
kusano fc6ab3
            ldi->next_datablock = allocate_new_datablock();
kusano fc6ab3
            if (ldi->next_datablock == NULL)
kusano fc6ab3
                return ZIP_INTERNALERROR;
kusano fc6ab3
            ldi = ldi->next_datablock ;
kusano fc6ab3
            ll->last_block = ldi;
kusano fc6ab3
        }
kusano fc6ab3
kusano fc6ab3
        if (ldi->avail_in_this_block < len)
kusano fc6ab3
            copy_this = (uInt)ldi->avail_in_this_block;
kusano fc6ab3
        else
kusano fc6ab3
            copy_this = (uInt)len;
kusano fc6ab3
kusano fc6ab3
        to_copy = &(ldi->data[ldi->filled_in_this_block]);
kusano fc6ab3
kusano fc6ab3
        for (i=0;i
kusano fc6ab3
            *(to_copy+i)=*(from_copy+i);
kusano fc6ab3
kusano fc6ab3
        ldi->filled_in_this_block += copy_this;
kusano fc6ab3
        ldi->avail_in_this_block -= copy_this;
kusano fc6ab3
        from_copy += copy_this ;
kusano fc6ab3
        len -= copy_this;
kusano fc6ab3
    }
kusano fc6ab3
    return ZIP_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
/****************************************************************************/
kusano fc6ab3
kusano fc6ab3
#ifndef NO_ADDFILEINEXISTINGZIP
kusano fc6ab3
/* ===========================================================================
kusano fc6ab3
   Inputs a long in LSB order to the given file
kusano fc6ab3
   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
kusano fc6ab3
*/
kusano fc6ab3
kusano fc6ab3
local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
kusano fc6ab3
local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
kusano fc6ab3
{
kusano fc6ab3
    unsigned char buf[8];
kusano fc6ab3
    int n;
kusano fc6ab3
    for (n = 0; n < nbByte; n++)
kusano fc6ab3
    {
kusano fc6ab3
        buf[n] = (unsigned char)(x & 0xff);
kusano fc6ab3
        x >>= 8;
kusano fc6ab3
    }
kusano fc6ab3
    if (x != 0)
kusano fc6ab3
      {     /* data overflow - hack for ZIP64 (X Roche) */
kusano fc6ab3
      for (n = 0; n < nbByte; n++)
kusano fc6ab3
        {
kusano fc6ab3
          buf[n] = 0xff;
kusano fc6ab3
        }
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
kusano fc6ab3
        return ZIP_ERRNO;
kusano fc6ab3
    else
kusano fc6ab3
        return ZIP_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
kusano fc6ab3
local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
kusano fc6ab3
{
kusano fc6ab3
    unsigned char* buf=(unsigned char*)dest;
kusano fc6ab3
    int n;
kusano fc6ab3
    for (n = 0; n < nbByte; n++) {
kusano fc6ab3
        buf[n] = (unsigned char)(x & 0xff);
kusano fc6ab3
        x >>= 8;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (x != 0)
kusano fc6ab3
    {     /* data overflow - hack for ZIP64 */
kusano fc6ab3
       for (n = 0; n < nbByte; n++)
kusano fc6ab3
       {
kusano fc6ab3
          buf[n] = 0xff;
kusano fc6ab3
       }
kusano fc6ab3
    }
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/****************************************************************************/
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
kusano fc6ab3
{
kusano fc6ab3
    uLong year = (uLong)ptm->tm_year;
kusano fc6ab3
    if (year>=1980)
kusano fc6ab3
        year-=1980;
kusano fc6ab3
    else if (year>=80)
kusano fc6ab3
        year-=80;
kusano fc6ab3
    return
kusano fc6ab3
      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
kusano fc6ab3
        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
/****************************************************************************/
kusano fc6ab3
kusano fc6ab3
local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
kusano fc6ab3
kusano fc6ab3
local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
kusano fc6ab3
{
kusano fc6ab3
    unsigned char c;
kusano fc6ab3
    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
kusano fc6ab3
    if (err==1)
kusano fc6ab3
    {
kusano fc6ab3
        *pi = (int)c;
kusano fc6ab3
        return ZIP_OK;
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
    {
kusano fc6ab3
        if (ZERROR64(*pzlib_filefunc_def,filestream))
kusano fc6ab3
            return ZIP_ERRNO;
kusano fc6ab3
        else
kusano fc6ab3
            return ZIP_EOF;
kusano fc6ab3
    }
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
/* ===========================================================================
kusano fc6ab3
   Reads a long in LSB order from the given gz_stream. Sets
kusano fc6ab3
*/
kusano fc6ab3
local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
kusano fc6ab3
kusano fc6ab3
local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
kusano fc6ab3
{
kusano fc6ab3
    uLong x ;
kusano fc6ab3
    int i = 0;
kusano fc6ab3
    int err;
kusano fc6ab3
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
    x = (uLong)i;
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
    x += ((uLong)i)<<8;
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        *pX = x;
kusano fc6ab3
    else
kusano fc6ab3
        *pX = 0;
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
kusano fc6ab3
kusano fc6ab3
local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
kusano fc6ab3
{
kusano fc6ab3
    uLong x ;
kusano fc6ab3
    int i = 0;
kusano fc6ab3
    int err;
kusano fc6ab3
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
    x = (uLong)i;
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
    x += ((uLong)i)<<8;
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
    x += ((uLong)i)<<16;
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
    x += ((uLong)i)<<24;
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        *pX = x;
kusano fc6ab3
    else
kusano fc6ab3
        *pX = 0;
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
kusano fc6ab3
{
kusano fc6ab3
  ZPOS64_T x;
kusano fc6ab3
  int i = 0;
kusano fc6ab3
  int err;
kusano fc6ab3
kusano fc6ab3
  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x = (ZPOS64_T)i;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<8;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<16;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<24;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<32;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<40;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<48;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
kusano fc6ab3
  x += ((ZPOS64_T)i)<<56;
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    *pX = x;
kusano fc6ab3
  else
kusano fc6ab3
    *pX = 0;
kusano fc6ab3
kusano fc6ab3
  return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
#ifndef BUFREADCOMMENT
kusano fc6ab3
#define BUFREADCOMMENT (0x400)
kusano fc6ab3
#endif
kusano fc6ab3
/*
kusano fc6ab3
  Locate the Central directory of a zipfile (at the end, just before
kusano fc6ab3
    the global comment)
kusano fc6ab3
*/
kusano fc6ab3
local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
kusano fc6ab3
kusano fc6ab3
local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
kusano fc6ab3
{
kusano fc6ab3
  unsigned char* buf;
kusano fc6ab3
  ZPOS64_T uSizeFile;
kusano fc6ab3
  ZPOS64_T uBackRead;
kusano fc6ab3
  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
kusano fc6ab3
  ZPOS64_T uPosFound=0;
kusano fc6ab3
kusano fc6ab3
  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
kusano fc6ab3
kusano fc6ab3
  if (uMaxBack>uSizeFile)
kusano fc6ab3
    uMaxBack = uSizeFile;
kusano fc6ab3
kusano fc6ab3
  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
kusano fc6ab3
  if (buf==NULL)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  uBackRead = 4;
kusano fc6ab3
  while (uBackRead
kusano fc6ab3
  {
kusano fc6ab3
    uLong uReadSize;
kusano fc6ab3
    ZPOS64_T uReadPos ;
kusano fc6ab3
    int i;
kusano fc6ab3
    if (uBackRead+BUFREADCOMMENT>uMaxBack)
kusano fc6ab3
      uBackRead = uMaxBack;
kusano fc6ab3
    else
kusano fc6ab3
      uBackRead+=BUFREADCOMMENT;
kusano fc6ab3
    uReadPos = uSizeFile-uBackRead ;
kusano fc6ab3
kusano fc6ab3
    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
kusano fc6ab3
      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
kusano fc6ab3
    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
      break;
kusano fc6ab3
kusano fc6ab3
    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
kusano fc6ab3
      break;
kusano fc6ab3
kusano fc6ab3
    for (i=(int)uReadSize-3; (i--)>0;)
kusano fc6ab3
      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
kusano fc6ab3
        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
kusano fc6ab3
      {
kusano fc6ab3
        uPosFound = uReadPos+i;
kusano fc6ab3
        break;
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      if (uPosFound!=0)
kusano fc6ab3
        break;
kusano fc6ab3
  }
kusano fc6ab3
  TRYFREE(buf);
kusano fc6ab3
  return uPosFound;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
kusano fc6ab3
the global comment)
kusano fc6ab3
*/
kusano fc6ab3
local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
kusano fc6ab3
kusano fc6ab3
local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
kusano fc6ab3
{
kusano fc6ab3
  unsigned char* buf;
kusano fc6ab3
  ZPOS64_T uSizeFile;
kusano fc6ab3
  ZPOS64_T uBackRead;
kusano fc6ab3
  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
kusano fc6ab3
  ZPOS64_T uPosFound=0;
kusano fc6ab3
  uLong uL;
kusano fc6ab3
  ZPOS64_T relativeOffset;
kusano fc6ab3
kusano fc6ab3
  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
kusano fc6ab3
kusano fc6ab3
  if (uMaxBack>uSizeFile)
kusano fc6ab3
    uMaxBack = uSizeFile;
kusano fc6ab3
kusano fc6ab3
  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
kusano fc6ab3
  if (buf==NULL)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  uBackRead = 4;
kusano fc6ab3
  while (uBackRead
kusano fc6ab3
  {
kusano fc6ab3
    uLong uReadSize;
kusano fc6ab3
    ZPOS64_T uReadPos;
kusano fc6ab3
    int i;
kusano fc6ab3
    if (uBackRead+BUFREADCOMMENT>uMaxBack)
kusano fc6ab3
      uBackRead = uMaxBack;
kusano fc6ab3
    else
kusano fc6ab3
      uBackRead+=BUFREADCOMMENT;
kusano fc6ab3
    uReadPos = uSizeFile-uBackRead ;
kusano fc6ab3
kusano fc6ab3
    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
kusano fc6ab3
      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
kusano fc6ab3
    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
      break;
kusano fc6ab3
kusano fc6ab3
    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
kusano fc6ab3
      break;
kusano fc6ab3
kusano fc6ab3
    for (i=(int)uReadSize-3; (i--)>0;)
kusano fc6ab3
    {
kusano fc6ab3
      // Signature "0x07064b50" Zip64 end of central directory locater
kusano fc6ab3
      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
kusano fc6ab3
      {
kusano fc6ab3
        uPosFound = uReadPos+i;
kusano fc6ab3
        break;
kusano fc6ab3
      }
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
      if (uPosFound!=0)
kusano fc6ab3
        break;
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  TRYFREE(buf);
kusano fc6ab3
  if (uPosFound == 0)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* Zip64 end of central directory locator */
kusano fc6ab3
  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* the signature, already checked */
kusano fc6ab3
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* number of the disk with the start of the zip64 end of  central directory */
kusano fc6ab3
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
kusano fc6ab3
    return 0;
kusano fc6ab3
  if (uL != 0)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* relative offset of the zip64 end of central directory record */
kusano fc6ab3
  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* total number of disks */
kusano fc6ab3
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
kusano fc6ab3
    return 0;
kusano fc6ab3
  if (uL != 1)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* Goto Zip64 end of central directory record */
kusano fc6ab3
  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  /* the signature */
kusano fc6ab3
  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
kusano fc6ab3
    return 0;
kusano fc6ab3
kusano fc6ab3
  return relativeOffset;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int LoadCentralDirectoryRecord(zip64_internal* pziinit)
kusano fc6ab3
{
kusano fc6ab3
  int err=ZIP_OK;
kusano fc6ab3
  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
kusano fc6ab3
kusano fc6ab3
  ZPOS64_T size_central_dir;     /* size of the central directory  */
kusano fc6ab3
  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
kusano fc6ab3
  ZPOS64_T central_pos;
kusano fc6ab3
  uLong uL;
kusano fc6ab3
kusano fc6ab3
  uLong number_disk;          /* number of the current dist, used for
kusano fc6ab3
                              spaning ZIP, unsupported, always 0*/
kusano fc6ab3
  uLong number_disk_with_CD;  /* number the the disk with central dir, used
kusano fc6ab3
                              for spaning ZIP, unsupported, always 0*/
kusano fc6ab3
  ZPOS64_T number_entry;
kusano fc6ab3
  ZPOS64_T number_entry_CD;      /* total number of entries in
kusano fc6ab3
                                the central dir
kusano fc6ab3
                                (same than number_entry on nospan) */
kusano fc6ab3
  uLong VersionMadeBy;
kusano fc6ab3
  uLong VersionNeeded;
kusano fc6ab3
  uLong size_comment;
kusano fc6ab3
kusano fc6ab3
  int hasZIP64Record = 0;
kusano fc6ab3
kusano fc6ab3
  // check first if we find a ZIP64 record
kusano fc6ab3
  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
kusano fc6ab3
  if(central_pos > 0)
kusano fc6ab3
  {
kusano fc6ab3
    hasZIP64Record = 1;
kusano fc6ab3
  }
kusano fc6ab3
  else if(central_pos == 0)
kusano fc6ab3
  {
kusano fc6ab3
    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
/* disable to allow appending to empty ZIP archive
kusano fc6ab3
        if (central_pos==0)
kusano fc6ab3
            err=ZIP_ERRNO;
kusano fc6ab3
*/
kusano fc6ab3
kusano fc6ab3
  if(hasZIP64Record)
kusano fc6ab3
  {
kusano fc6ab3
    ZPOS64_T sizeEndOfCentralDirectory;
kusano fc6ab3
    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* the signature, already checked */
kusano fc6ab3
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* size of zip64 end of central directory record */
kusano fc6ab3
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* version made by */
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* version needed to extract */
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* number of this disk */
kusano fc6ab3
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* number of the disk with the start of the central directory */
kusano fc6ab3
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* total number of entries in the central directory on this disk */
kusano fc6ab3
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* total number of entries in the central directory */
kusano fc6ab3
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
kusano fc6ab3
      err=ZIP_BADZIPFILE;
kusano fc6ab3
kusano fc6ab3
    /* size of the central directory */
kusano fc6ab3
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* offset of start of central directory with respect to the
kusano fc6ab3
    starting disk number */
kusano fc6ab3
    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    // TODO..
kusano fc6ab3
    // read the comment from the standard central header.
kusano fc6ab3
    size_comment = 0;
kusano fc6ab3
  }
kusano fc6ab3
  else
kusano fc6ab3
  {
kusano fc6ab3
    // Read End of central Directory info
kusano fc6ab3
    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* the signature, already checked */
kusano fc6ab3
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* number of this disk */
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* number of the disk with the start of the central directory */
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    /* total number of entries in the central dir on this disk */
kusano fc6ab3
    number_entry = 0;
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
    else
kusano fc6ab3
      number_entry = uL;
kusano fc6ab3
kusano fc6ab3
    /* total number of entries in the central dir */
kusano fc6ab3
    number_entry_CD = 0;
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
    else
kusano fc6ab3
      number_entry_CD = uL;
kusano fc6ab3
kusano fc6ab3
    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
kusano fc6ab3
      err=ZIP_BADZIPFILE;
kusano fc6ab3
kusano fc6ab3
    /* size of the central directory */
kusano fc6ab3
    size_central_dir = 0;
kusano fc6ab3
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
    else
kusano fc6ab3
      size_central_dir = uL;
kusano fc6ab3
kusano fc6ab3
    /* offset of start of central directory with respect to the starting disk number */
kusano fc6ab3
    offset_central_dir = 0;
kusano fc6ab3
    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
    else
kusano fc6ab3
      offset_central_dir = uL;
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
    /* zipfile global comment length */
kusano fc6ab3
    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if ((central_pos
kusano fc6ab3
    (err==ZIP_OK))
kusano fc6ab3
    err=ZIP_BADZIPFILE;
kusano fc6ab3
kusano fc6ab3
  if (err!=ZIP_OK)
kusano fc6ab3
  {
kusano fc6ab3
    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
kusano fc6ab3
    return ZIP_ERRNO;
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if (size_comment>0)
kusano fc6ab3
  {
kusano fc6ab3
    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
kusano fc6ab3
    if (pziinit->globalcomment)
kusano fc6ab3
    {
kusano fc6ab3
      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
kusano fc6ab3
      pziinit->globalcomment[size_comment]=0;
kusano fc6ab3
    }
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
kusano fc6ab3
  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
kusano fc6ab3
kusano fc6ab3
  {
kusano fc6ab3
    ZPOS64_T size_central_dir_to_read = size_central_dir;
kusano fc6ab3
    size_t buf_size = SIZEDATA_INDATABLOCK;
kusano fc6ab3
    void* buf_read = (void*)ALLOC(buf_size);
kusano fc6ab3
    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
kusano fc6ab3
      err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
kusano fc6ab3
    {
kusano fc6ab3
      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
kusano fc6ab3
      if (read_this > size_central_dir_to_read)
kusano fc6ab3
        read_this = size_central_dir_to_read;
kusano fc6ab3
kusano fc6ab3
      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
kusano fc6ab3
        err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
      if (err==ZIP_OK)
kusano fc6ab3
        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
kusano fc6ab3
kusano fc6ab3
      size_central_dir_to_read-=read_this;
kusano fc6ab3
    }
kusano fc6ab3
    TRYFREE(buf_read);
kusano fc6ab3
  }
kusano fc6ab3
  pziinit->begin_pos = byte_before_the_zipfile;
kusano fc6ab3
  pziinit->number_entry = number_entry_CD;
kusano fc6ab3
kusano fc6ab3
  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
kusano fc6ab3
    err=ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
  return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
#endif /* !NO_ADDFILEINEXISTINGZIP*/
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
/************************************************************/
kusano fc6ab3
extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
kusano fc6ab3
{
kusano fc6ab3
    zip64_internal ziinit;
kusano fc6ab3
    zip64_internal* zi;
kusano fc6ab3
    int err=ZIP_OK;
kusano fc6ab3
kusano fc6ab3
    ziinit.z_filefunc.zseek32_file = NULL;
kusano fc6ab3
    ziinit.z_filefunc.ztell32_file = NULL;
kusano fc6ab3
    if (pzlib_filefunc64_32_def==NULL)
kusano fc6ab3
        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
kusano fc6ab3
    else
kusano fc6ab3
        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
kusano fc6ab3
kusano fc6ab3
    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
kusano fc6ab3
                  pathname,
kusano fc6ab3
                  (append == APPEND_STATUS_CREATE) ?
kusano fc6ab3
                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
kusano fc6ab3
                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
kusano fc6ab3
kusano fc6ab3
    if (ziinit.filestream == NULL)
kusano fc6ab3
        return NULL;
kusano fc6ab3
kusano fc6ab3
    if (append == APPEND_STATUS_CREATEAFTER)
kusano fc6ab3
        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
kusano fc6ab3
kusano fc6ab3
    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
kusano fc6ab3
    ziinit.in_opened_file_inzip = 0;
kusano fc6ab3
    ziinit.ci.stream_initialised = 0;
kusano fc6ab3
    ziinit.number_entry = 0;
kusano fc6ab3
    ziinit.add_position_when_writting_offset = 0;
kusano fc6ab3
    init_linkedlist(&(ziinit.central_dir));
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
kusano fc6ab3
    if (zi==NULL)
kusano fc6ab3
    {
kusano fc6ab3
        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
kusano fc6ab3
        return NULL;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* now we add file in a zipfile */
kusano fc6ab3
#    ifndef NO_ADDFILEINEXISTINGZIP
kusano fc6ab3
    ziinit.globalcomment = NULL;
kusano fc6ab3
    if (append == APPEND_STATUS_ADDINZIP)
kusano fc6ab3
    {
kusano fc6ab3
      // Read and Cache Central Directory Records
kusano fc6ab3
      err = LoadCentralDirectoryRecord(&ziinit);
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (globalcomment)
kusano fc6ab3
    {
kusano fc6ab3
      *globalcomment = ziinit.globalcomment;
kusano fc6ab3
    }
kusano fc6ab3
#    endif /* !NO_ADDFILEINEXISTINGZIP*/
kusano fc6ab3
kusano fc6ab3
    if (err != ZIP_OK)
kusano fc6ab3
    {
kusano fc6ab3
#    ifndef NO_ADDFILEINEXISTINGZIP
kusano fc6ab3
        TRYFREE(ziinit.globalcomment);
kusano fc6ab3
#    endif /* !NO_ADDFILEINEXISTINGZIP*/
kusano fc6ab3
        TRYFREE(zi);
kusano fc6ab3
        return NULL;
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
    {
kusano fc6ab3
        *zi = ziinit;
kusano fc6ab3
        return (zipFile)zi;
kusano fc6ab3
    }
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
kusano fc6ab3
{
kusano fc6ab3
    if (pzlib_filefunc32_def != NULL)
kusano fc6ab3
    {
kusano fc6ab3
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
kusano fc6ab3
        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
kusano fc6ab3
        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
        return zipOpen3(pathname, append, globalcomment, NULL);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
kusano fc6ab3
{
kusano fc6ab3
    if (pzlib_filefunc_def != NULL)
kusano fc6ab3
    {
kusano fc6ab3
        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
kusano fc6ab3
        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
kusano fc6ab3
        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
kusano fc6ab3
        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
kusano fc6ab3
        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
        return zipOpen3(pathname, append, globalcomment, NULL);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpen3((const void*)pathname,append,NULL,NULL);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpen3(pathname,append,NULL,NULL);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
kusano fc6ab3
{
kusano fc6ab3
  /* write the local header */
kusano fc6ab3
  int err;
kusano fc6ab3
  uInt size_filename = (uInt)strlen(filename);
kusano fc6ab3
  uInt size_extrafield = size_extrafield_local;
kusano fc6ab3
kusano fc6ab3
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
  {
kusano fc6ab3
    if(zi->ci.zip64)
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
kusano fc6ab3
    else
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
kusano fc6ab3
kusano fc6ab3
  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
  {
kusano fc6ab3
    if(zi->ci.zip64)
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
kusano fc6ab3
    else
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
kusano fc6ab3
  }
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
  {
kusano fc6ab3
    if(zi->ci.zip64)
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
kusano fc6ab3
    else
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
kusano fc6ab3
kusano fc6ab3
  if(zi->ci.zip64)
kusano fc6ab3
  {
kusano fc6ab3
    size_extrafield += 20;
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK)
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
kusano fc6ab3
kusano fc6ab3
  if ((err==ZIP_OK) && (size_filename > 0))
kusano fc6ab3
  {
kusano fc6ab3
    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
kusano fc6ab3
      err = ZIP_ERRNO;
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if ((err==ZIP_OK) && (size_extrafield_local > 0))
kusano fc6ab3
  {
kusano fc6ab3
    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
kusano fc6ab3
      err = ZIP_ERRNO;
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
  if ((err==ZIP_OK) && (zi->ci.zip64))
kusano fc6ab3
  {
kusano fc6ab3
      // write the Zip64 extended info
kusano fc6ab3
      short HeaderID = 1;
kusano fc6ab3
      short DataSize = 16;
kusano fc6ab3
      ZPOS64_T CompressedSize = 0;
kusano fc6ab3
      ZPOS64_T UncompressedSize = 0;
kusano fc6ab3
kusano fc6ab3
      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
kusano fc6ab3
      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
kusano fc6ab3
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
kusano fc6ab3
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
 NOTE.
kusano fc6ab3
 When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
kusano fc6ab3
 before calling this function it can be done with zipRemoveExtraInfoBlock
kusano fc6ab3
kusano fc6ab3
 It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
kusano fc6ab3
 unnecessary allocations.
kusano fc6ab3
 */
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                         const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                         const void* extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                         const char* comment, int method, int level, int raw,
kusano fc6ab3
                                         int windowBits,int memLevel, int strategy,
kusano fc6ab3
                                         const char* password, uLong crcForCrypting,
kusano fc6ab3
                                         uLong versionMadeBy, uLong flagBase, int zip64)
kusano fc6ab3
{
kusano fc6ab3
    zip64_internal* zi;
kusano fc6ab3
    uInt size_filename;
kusano fc6ab3
    uInt size_comment;
kusano fc6ab3
    uInt i;
kusano fc6ab3
    int err = ZIP_OK;
kusano fc6ab3
kusano fc6ab3
#    ifdef NOCRYPT
kusano fc6ab3
    (crcForCrypting);
kusano fc6ab3
    if (password != NULL)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
#    endif
kusano fc6ab3
kusano fc6ab3
    if (file == NULL)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
kusano fc6ab3
      return ZIP_PARAMERROR;
kusano fc6ab3
#else
kusano fc6ab3
    if ((method!=0) && (method!=Z_DEFLATED))
kusano fc6ab3
      return ZIP_PARAMERROR;
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
    zi = (zip64_internal*)file;
kusano fc6ab3
kusano fc6ab3
    if (zi->in_opened_file_inzip == 1)
kusano fc6ab3
    {
kusano fc6ab3
        err = zipCloseFileInZip (file);
kusano fc6ab3
        if (err != ZIP_OK)
kusano fc6ab3
            return err;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (filename==NULL)
kusano fc6ab3
        filename="-";
kusano fc6ab3
kusano fc6ab3
    if (comment==NULL)
kusano fc6ab3
        size_comment = 0;
kusano fc6ab3
    else
kusano fc6ab3
        size_comment = (uInt)strlen(comment);
kusano fc6ab3
kusano fc6ab3
    size_filename = (uInt)strlen(filename);
kusano fc6ab3
kusano fc6ab3
    if (zipfi == NULL)
kusano fc6ab3
        zi->ci.dosDate = 0;
kusano fc6ab3
    else
kusano fc6ab3
    {
kusano fc6ab3
        if (zipfi->dosDate != 0)
kusano fc6ab3
            zi->ci.dosDate = zipfi->dosDate;
kusano fc6ab3
        else
kusano fc6ab3
          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    zi->ci.flag = flagBase;
kusano fc6ab3
    if ((level==8) || (level==9))
kusano fc6ab3
      zi->ci.flag |= 2;
kusano fc6ab3
    if (level==2)
kusano fc6ab3
      zi->ci.flag |= 4;
kusano fc6ab3
    if (level==1)
kusano fc6ab3
      zi->ci.flag |= 6;
kusano fc6ab3
    if (password != NULL)
kusano fc6ab3
      zi->ci.flag |= 1;
kusano fc6ab3
kusano fc6ab3
    zi->ci.crc32 = 0;
kusano fc6ab3
    zi->ci.method = method;
kusano fc6ab3
    zi->ci.encrypt = 0;
kusano fc6ab3
    zi->ci.stream_initialised = 0;
kusano fc6ab3
    zi->ci.pos_in_buffered_data = 0;
kusano fc6ab3
    zi->ci.raw = raw;
kusano fc6ab3
    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
kusano fc6ab3
kusano fc6ab3
    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
kusano fc6ab3
    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
kusano fc6ab3
kusano fc6ab3
    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
kusano fc6ab3
kusano fc6ab3
    zi->ci.size_centralExtra = size_extrafield_global;
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
kusano fc6ab3
    /* version info */
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
kusano fc6ab3
kusano fc6ab3
    if (zipfi==NULL)
kusano fc6ab3
        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
kusano fc6ab3
    else
kusano fc6ab3
        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
kusano fc6ab3
kusano fc6ab3
    if (zipfi==NULL)
kusano fc6ab3
        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
kusano fc6ab3
    else
kusano fc6ab3
        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
kusano fc6ab3
kusano fc6ab3
    if(zi->ci.pos_local_header >= 0xffffffff)
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
kusano fc6ab3
    else
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
kusano fc6ab3
kusano fc6ab3
    for (i=0;i
kusano fc6ab3
        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
kusano fc6ab3
kusano fc6ab3
    for (i=0;i
kusano fc6ab3
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
kusano fc6ab3
              *(((const char*)extrafield_global)+i);
kusano fc6ab3
kusano fc6ab3
    for (i=0;i
kusano fc6ab3
        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
kusano fc6ab3
              size_extrafield_global+i) = *(comment+i);
kusano fc6ab3
    if (zi->ci.central_header == NULL)
kusano fc6ab3
        return ZIP_INTERNALERROR;
kusano fc6ab3
kusano fc6ab3
    zi->ci.zip64 = zip64;
kusano fc6ab3
    zi->ci.totalCompressedData = 0;
kusano fc6ab3
    zi->ci.totalUncompressedData = 0;
kusano fc6ab3
    zi->ci.pos_zip64extrainfo = 0;
kusano fc6ab3
kusano fc6ab3
    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
kusano fc6ab3
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    zi->ci.bstream.avail_in = (uInt)0;
kusano fc6ab3
    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
kusano fc6ab3
    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
kusano fc6ab3
    zi->ci.bstream.total_in_hi32 = 0;
kusano fc6ab3
    zi->ci.bstream.total_in_lo32 = 0;
kusano fc6ab3
    zi->ci.bstream.total_out_hi32 = 0;
kusano fc6ab3
    zi->ci.bstream.total_out_lo32 = 0;
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
    zi->ci.stream.avail_in = (uInt)0;
kusano fc6ab3
    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
kusano fc6ab3
    zi->ci.stream.next_out = zi->ci.buffered_data;
kusano fc6ab3
    zi->ci.stream.total_in = 0;
kusano fc6ab3
    zi->ci.stream.total_out = 0;
kusano fc6ab3
    zi->ci.stream.data_type = Z_BINARY;
kusano fc6ab3
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
kusano fc6ab3
#else
kusano fc6ab3
    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
kusano fc6ab3
#endif
kusano fc6ab3
    {
kusano fc6ab3
        if(zi->ci.method == Z_DEFLATED)
kusano fc6ab3
        {
kusano fc6ab3
          zi->ci.stream.zalloc = (alloc_func)0;
kusano fc6ab3
          zi->ci.stream.zfree = (free_func)0;
kusano fc6ab3
          zi->ci.stream.opaque = (voidpf)0;
kusano fc6ab3
kusano fc6ab3
          if (windowBits>0)
kusano fc6ab3
              windowBits = -windowBits;
kusano fc6ab3
kusano fc6ab3
          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
kusano fc6ab3
kusano fc6ab3
          if (err==Z_OK)
kusano fc6ab3
              zi->ci.stream_initialised = Z_DEFLATED;
kusano fc6ab3
        }
kusano fc6ab3
        else if(zi->ci.method == Z_BZIP2ED)
kusano fc6ab3
        {
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
            // Init BZip stuff here
kusano fc6ab3
          zi->ci.bstream.bzalloc = 0;
kusano fc6ab3
          zi->ci.bstream.bzfree = 0;
kusano fc6ab3
          zi->ci.bstream.opaque = (voidpf)0;
kusano fc6ab3
kusano fc6ab3
          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
kusano fc6ab3
          if(err == BZ_OK)
kusano fc6ab3
            zi->ci.stream_initialised = Z_BZIP2ED;
kusano fc6ab3
#endif
kusano fc6ab3
        }
kusano fc6ab3
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
#    ifndef NOCRYPT
kusano fc6ab3
    zi->ci.crypt_header_size = 0;
kusano fc6ab3
    if ((err==Z_OK) && (password != NULL))
kusano fc6ab3
    {
kusano fc6ab3
        unsigned char bufHead[RAND_HEAD_LEN];
kusano fc6ab3
        unsigned int sizeHead;
kusano fc6ab3
        zi->ci.encrypt = 1;
kusano fc6ab3
        zi->ci.pcrc_32_tab = get_crc_table();
kusano fc6ab3
        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
kusano fc6ab3
kusano fc6ab3
        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
kusano fc6ab3
        zi->ci.crypt_header_size = sizeHead;
kusano fc6ab3
kusano fc6ab3
        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
kusano fc6ab3
                err = ZIP_ERRNO;
kusano fc6ab3
    }
kusano fc6ab3
#    endif
kusano fc6ab3
kusano fc6ab3
    if (err==Z_OK)
kusano fc6ab3
        zi->in_opened_file_inzip = 1;
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                         const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                         const void* extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                         const char* comment, int method, int level, int raw,
kusano fc6ab3
                                         int windowBits,int memLevel, int strategy,
kusano fc6ab3
                                         const char* password, uLong crcForCrypting,
kusano fc6ab3
                                         uLong versionMadeBy, uLong flagBase)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, raw,
kusano fc6ab3
                                 windowBits, memLevel, strategy,
kusano fc6ab3
                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                         const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                         const void* extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                         const char* comment, int method, int level, int raw,
kusano fc6ab3
                                         int windowBits,int memLevel, int strategy,
kusano fc6ab3
                                         const char* password, uLong crcForCrypting)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, raw,
kusano fc6ab3
                                 windowBits, memLevel, strategy,
kusano fc6ab3
                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                         const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                         const void* extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                         const char* comment, int method, int level, int raw,
kusano fc6ab3
                                         int windowBits,int memLevel, int strategy,
kusano fc6ab3
                                         const char* password, uLong crcForCrypting, int zip64)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, raw,
kusano fc6ab3
                                 windowBits, memLevel, strategy,
kusano fc6ab3
                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                        const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                        const void* extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                        const char* comment, int method, int level, int raw)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, raw,
kusano fc6ab3
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
kusano fc6ab3
                                 NULL, 0, VERSIONMADEBY, 0, 0);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                        const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                        const void* extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                        const char* comment, int method, int level, int raw, int zip64)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, raw,
kusano fc6ab3
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
kusano fc6ab3
                                 NULL, 0, VERSIONMADEBY, 0, zip64);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                        const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                        const void*extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                        const char* comment, int method, int level, int zip64)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, 0,
kusano fc6ab3
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
kusano fc6ab3
                                 NULL, 0, VERSIONMADEBY, 0, zip64);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
kusano fc6ab3
                                        const void* extrafield_local, uInt size_extrafield_local,
kusano fc6ab3
                                        const void*extrafield_global, uInt size_extrafield_global,
kusano fc6ab3
                                        const char* comment, int method, int level)
kusano fc6ab3
{
kusano fc6ab3
    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
kusano fc6ab3
                                 extrafield_local, size_extrafield_local,
kusano fc6ab3
                                 extrafield_global, size_extrafield_global,
kusano fc6ab3
                                 comment, method, level, 0,
kusano fc6ab3
                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
kusano fc6ab3
                                 NULL, 0, VERSIONMADEBY, 0, 0);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
local int zip64FlushWriteBuffer(zip64_internal* zi)
kusano fc6ab3
{
kusano fc6ab3
    int err=ZIP_OK;
kusano fc6ab3
kusano fc6ab3
    if (zi->ci.encrypt != 0)
kusano fc6ab3
    {
kusano fc6ab3
#ifndef NOCRYPT
kusano fc6ab3
        uInt i;
kusano fc6ab3
        int t;
kusano fc6ab3
        for (i=0;i<zi->ci.pos_in_buffered_data;i++)</zi->
kusano fc6ab3
            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
kusano fc6ab3
#endif
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
kusano fc6ab3
      err = ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
kusano fc6ab3
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    if(zi->ci.method == Z_BZIP2ED)
kusano fc6ab3
    {
kusano fc6ab3
      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
kusano fc6ab3
      zi->ci.bstream.total_in_lo32 = 0;
kusano fc6ab3
      zi->ci.bstream.total_in_hi32 = 0;
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
#endif
kusano fc6ab3
    {
kusano fc6ab3
      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
kusano fc6ab3
      zi->ci.stream.total_in = 0;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
    zi->ci.pos_in_buffered_data = 0;
kusano fc6ab3
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
kusano fc6ab3
{
kusano fc6ab3
    zip64_internal* zi;
kusano fc6ab3
    int err=ZIP_OK;
kusano fc6ab3
kusano fc6ab3
    if (file == NULL)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
    zi = (zip64_internal*)file;
kusano fc6ab3
kusano fc6ab3
    if (zi->in_opened_file_inzip == 0)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
kusano fc6ab3
    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
kusano fc6ab3
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
kusano fc6ab3
    {
kusano fc6ab3
      zi->ci.bstream.next_in = (void*)buf;
kusano fc6ab3
      zi->ci.bstream.avail_in = len;
kusano fc6ab3
      err = BZ_RUN_OK;
kusano fc6ab3
kusano fc6ab3
      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
kusano fc6ab3
      {
kusano fc6ab3
        if (zi->ci.bstream.avail_out == 0)
kusano fc6ab3
        {
kusano fc6ab3
          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
kusano fc6ab3
            err = ZIP_ERRNO;
kusano fc6ab3
          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
kusano fc6ab3
          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
kusano fc6ab3
        }
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
        if(err != BZ_RUN_OK)
kusano fc6ab3
          break;
kusano fc6ab3
kusano fc6ab3
        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
kusano fc6ab3
        {
kusano fc6ab3
          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
kusano fc6ab3
//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
kusano fc6ab3
          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
kusano fc6ab3
kusano fc6ab3
          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
kusano fc6ab3
        }
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      if(err == BZ_RUN_OK)
kusano fc6ab3
        err = ZIP_OK;
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
#endif
kusano fc6ab3
    {
kusano fc6ab3
      zi->ci.stream.next_in = (Bytef*)buf;
kusano fc6ab3
      zi->ci.stream.avail_in = len;
kusano fc6ab3
kusano fc6ab3
      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
kusano fc6ab3
      {
kusano fc6ab3
          if (zi->ci.stream.avail_out == 0)
kusano fc6ab3
          {
kusano fc6ab3
              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
kusano fc6ab3
                  err = ZIP_ERRNO;
kusano fc6ab3
              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
kusano fc6ab3
              zi->ci.stream.next_out = zi->ci.buffered_data;
kusano fc6ab3
          }
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
          if(err != ZIP_OK)
kusano fc6ab3
              break;
kusano fc6ab3
kusano fc6ab3
          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
kusano fc6ab3
          {
kusano fc6ab3
              uLong uTotalOutBefore = zi->ci.stream.total_out;
kusano fc6ab3
              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
kusano fc6ab3
              if(uTotalOutBefore > zi->ci.stream.total_out)
kusano fc6ab3
              {
kusano fc6ab3
                int bBreak = 0;
kusano fc6ab3
                bBreak++;
kusano fc6ab3
              }
kusano fc6ab3
kusano fc6ab3
              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
kusano fc6ab3
          }
kusano fc6ab3
          else
kusano fc6ab3
          {
kusano fc6ab3
              uInt copy_this,i;
kusano fc6ab3
              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
kusano fc6ab3
                  copy_this = zi->ci.stream.avail_in;
kusano fc6ab3
              else
kusano fc6ab3
                  copy_this = zi->ci.stream.avail_out;
kusano fc6ab3
kusano fc6ab3
              for (i = 0; i < copy_this; i++)
kusano fc6ab3
                  *(((char*)zi->ci.stream.next_out)+i) =
kusano fc6ab3
                      *(((const char*)zi->ci.stream.next_in)+i);
kusano fc6ab3
              {
kusano fc6ab3
                  zi->ci.stream.avail_in -= copy_this;
kusano fc6ab3
                  zi->ci.stream.avail_out-= copy_this;
kusano fc6ab3
                  zi->ci.stream.next_in+= copy_this;
kusano fc6ab3
                  zi->ci.stream.next_out+= copy_this;
kusano fc6ab3
                  zi->ci.stream.total_in+= copy_this;
kusano fc6ab3
                  zi->ci.stream.total_out+= copy_this;
kusano fc6ab3
                  zi->ci.pos_in_buffered_data += copy_this;
kusano fc6ab3
              }
kusano fc6ab3
          }
kusano fc6ab3
      }// while(...)
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
kusano fc6ab3
{
kusano fc6ab3
    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
kusano fc6ab3
{
kusano fc6ab3
    zip64_internal* zi;
kusano fc6ab3
    ZPOS64_T compressed_size;
kusano fc6ab3
    uLong invalidValue = 0xffffffff;
kusano fc6ab3
    short datasize = 0;
kusano fc6ab3
    int err=ZIP_OK;
kusano fc6ab3
kusano fc6ab3
    if (file == NULL)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
    zi = (zip64_internal*)file;
kusano fc6ab3
kusano fc6ab3
    if (zi->in_opened_file_inzip == 0)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
    zi->ci.stream.avail_in = 0;
kusano fc6ab3
kusano fc6ab3
    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
kusano fc6ab3
                {
kusano fc6ab3
                        while (err==ZIP_OK)
kusano fc6ab3
                        {
kusano fc6ab3
                                uLong uTotalOutBefore;
kusano fc6ab3
                                if (zi->ci.stream.avail_out == 0)
kusano fc6ab3
                                {
kusano fc6ab3
                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
kusano fc6ab3
                                                err = ZIP_ERRNO;
kusano fc6ab3
                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
kusano fc6ab3
                                        zi->ci.stream.next_out = zi->ci.buffered_data;
kusano fc6ab3
                                }
kusano fc6ab3
                                uTotalOutBefore = zi->ci.stream.total_out;
kusano fc6ab3
                                err=deflate(&zi->ci.stream,  Z_FINISH);
kusano fc6ab3
                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
kusano fc6ab3
                        }
kusano fc6ab3
                }
kusano fc6ab3
    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
kusano fc6ab3
    {
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
      err = BZ_FINISH_OK;
kusano fc6ab3
      while (err==BZ_FINISH_OK)
kusano fc6ab3
      {
kusano fc6ab3
        uLong uTotalOutBefore;
kusano fc6ab3
        if (zi->ci.bstream.avail_out == 0)
kusano fc6ab3
        {
kusano fc6ab3
          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
kusano fc6ab3
            err = ZIP_ERRNO;
kusano fc6ab3
          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
kusano fc6ab3
          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
kusano fc6ab3
        }
kusano fc6ab3
        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
kusano fc6ab3
        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
kusano fc6ab3
        if(err == BZ_STREAM_END)
kusano fc6ab3
          err = Z_STREAM_END;
kusano fc6ab3
kusano fc6ab3
        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      if(err == BZ_FINISH_OK)
kusano fc6ab3
        err = ZIP_OK;
kusano fc6ab3
#endif
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (err==Z_STREAM_END)
kusano fc6ab3
        err=ZIP_OK; /* this is normal */
kusano fc6ab3
kusano fc6ab3
    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
kusano fc6ab3
                {
kusano fc6ab3
        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
kusano fc6ab3
            err = ZIP_ERRNO;
kusano fc6ab3
                }
kusano fc6ab3
kusano fc6ab3
    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
kusano fc6ab3
    {
kusano fc6ab3
        int tmp_err = deflateEnd(&zi->ci.stream);
kusano fc6ab3
        if (err == ZIP_OK)
kusano fc6ab3
            err = tmp_err;
kusano fc6ab3
        zi->ci.stream_initialised = 0;
kusano fc6ab3
    }
kusano fc6ab3
#ifdef HAVE_BZIP2
kusano fc6ab3
    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
kusano fc6ab3
    {
kusano fc6ab3
      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
kusano fc6ab3
                        if (err==ZIP_OK)
kusano fc6ab3
                                err = tmperr;
kusano fc6ab3
                        zi->ci.stream_initialised = 0;
kusano fc6ab3
    }
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
    if (!zi->ci.raw)
kusano fc6ab3
    {
kusano fc6ab3
        crc32 = (uLong)zi->ci.crc32;
kusano fc6ab3
        uncompressed_size = zi->ci.totalUncompressedData;
kusano fc6ab3
    }
kusano fc6ab3
    compressed_size = zi->ci.totalCompressedData;
kusano fc6ab3
kusano fc6ab3
#    ifndef NOCRYPT
kusano fc6ab3
    compressed_size += zi->ci.crypt_header_size;
kusano fc6ab3
#    endif
kusano fc6ab3
kusano fc6ab3
    // update Current Item crc and sizes,
kusano fc6ab3
    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
kusano fc6ab3
    {
kusano fc6ab3
      /*version Made by*/
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
kusano fc6ab3
      /*version needed*/
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
kusano fc6ab3
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
kusano fc6ab3
kusano fc6ab3
kusano fc6ab3
    if(compressed_size >= 0xffffffff)
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
kusano fc6ab3
    else
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
kusano fc6ab3
kusano fc6ab3
    /// set internal file attributes field
kusano fc6ab3
    if (zi->ci.stream.data_type == Z_ASCII)
kusano fc6ab3
        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
kusano fc6ab3
kusano fc6ab3
    if(uncompressed_size >= 0xffffffff)
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
kusano fc6ab3
    else
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
kusano fc6ab3
kusano fc6ab3
    // Add ZIP64 extra info field for uncompressed size
kusano fc6ab3
    if(uncompressed_size >= 0xffffffff)
kusano fc6ab3
      datasize += 8;
kusano fc6ab3
kusano fc6ab3
    // Add ZIP64 extra info field for compressed size
kusano fc6ab3
    if(compressed_size >= 0xffffffff)
kusano fc6ab3
      datasize += 8;
kusano fc6ab3
kusano fc6ab3
    // Add ZIP64 extra info field for relative offset to local file header of current file
kusano fc6ab3
    if(zi->ci.pos_local_header >= 0xffffffff)
kusano fc6ab3
      datasize += 8;
kusano fc6ab3
kusano fc6ab3
    if(datasize > 0)
kusano fc6ab3
    {
kusano fc6ab3
      char* p = NULL;
kusano fc6ab3
kusano fc6ab3
      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
kusano fc6ab3
      {
kusano fc6ab3
        // we can not write more data to the buffer that we have room for.
kusano fc6ab3
        return ZIP_BADZIPFILE;
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      p = zi->ci.central_header + zi->ci.size_centralheader;
kusano fc6ab3
kusano fc6ab3
      // Add Extra Information Header for 'ZIP64 information'
kusano fc6ab3
      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
kusano fc6ab3
      p += 2;
kusano fc6ab3
      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
kusano fc6ab3
      p += 2;
kusano fc6ab3
kusano fc6ab3
      if(uncompressed_size >= 0xffffffff)
kusano fc6ab3
      {
kusano fc6ab3
        zip64local_putValue_inmemory(p, uncompressed_size, 8);
kusano fc6ab3
        p += 8;
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      if(compressed_size >= 0xffffffff)
kusano fc6ab3
      {
kusano fc6ab3
        zip64local_putValue_inmemory(p, compressed_size, 8);
kusano fc6ab3
        p += 8;
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      if(zi->ci.pos_local_header >= 0xffffffff)
kusano fc6ab3
      {
kusano fc6ab3
        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
kusano fc6ab3
        p += 8;
kusano fc6ab3
      }
kusano fc6ab3
kusano fc6ab3
      // Update how much extra free space we got in the memory buffer
kusano fc6ab3
      // and increase the centralheader size so the new ZIP64 fields are included
kusano fc6ab3
      // ( 4 below is the size of HeaderID and DataSize field )
kusano fc6ab3
      zi->ci.size_centralExtraFree -= datasize + 4;
kusano fc6ab3
      zi->ci.size_centralheader += datasize + 4;
kusano fc6ab3
kusano fc6ab3
      // Update the extra info size field
kusano fc6ab3
      zi->ci.size_centralExtra += datasize + 4;
kusano fc6ab3
      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
kusano fc6ab3
kusano fc6ab3
    free(zi->ci.central_header);
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
    {
kusano fc6ab3
        // Update the LocalFileHeader with the new values.
kusano fc6ab3
kusano fc6ab3
        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
kusano fc6ab3
kusano fc6ab3
        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
            err = ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
        if (err==ZIP_OK)
kusano fc6ab3
            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
kusano fc6ab3
kusano fc6ab3
        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
kusano fc6ab3
        {
kusano fc6ab3
          if(zi->ci.pos_zip64extrainfo > 0)
kusano fc6ab3
          {
kusano fc6ab3
            // Update the size in the ZIP64 extended field.
kusano fc6ab3
            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
              err = ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
            if (err==ZIP_OK) /* compressed size, unknown */
kusano fc6ab3
              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
kusano fc6ab3
kusano fc6ab3
            if (err==ZIP_OK) /* uncompressed size, unknown */
kusano fc6ab3
              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
kusano fc6ab3
          }
kusano fc6ab3
          else
kusano fc6ab3
              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
kusano fc6ab3
        }
kusano fc6ab3
        else
kusano fc6ab3
        {
kusano fc6ab3
          if (err==ZIP_OK) /* compressed size, unknown */
kusano fc6ab3
              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
kusano fc6ab3
kusano fc6ab3
          if (err==ZIP_OK) /* uncompressed size, unknown */
kusano fc6ab3
              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
kusano fc6ab3
        }
kusano fc6ab3
kusano fc6ab3
        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
kusano fc6ab3
            err = ZIP_ERRNO;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    zi->number_entry ++;
kusano fc6ab3
    zi->in_opened_file_inzip = 0;
kusano fc6ab3
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipCloseFileInZip (zipFile file)
kusano fc6ab3
{
kusano fc6ab3
    return zipCloseFileInZipRaw (file,0,0);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
kusano fc6ab3
{
kusano fc6ab3
  int err = ZIP_OK;
kusano fc6ab3
  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
kusano fc6ab3
kusano fc6ab3
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
kusano fc6ab3
kusano fc6ab3
  /*num disks*/
kusano fc6ab3
    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
kusano fc6ab3
kusano fc6ab3
  /*relative offset*/
kusano fc6ab3
    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
kusano fc6ab3
kusano fc6ab3
  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
kusano fc6ab3
    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
kusano fc6ab3
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
kusano fc6ab3
{
kusano fc6ab3
  int err = ZIP_OK;
kusano fc6ab3
kusano fc6ab3
  uLong Zip64DataSize = 44;
kusano fc6ab3
kusano fc6ab3
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* version made by */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* version needed */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* number of this disk */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* total number of entries in the central dir */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* size of the central directory */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
kusano fc6ab3
  {
kusano fc6ab3
    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
kusano fc6ab3
  }
kusano fc6ab3
  return err;
kusano fc6ab3
}
kusano fc6ab3
int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
kusano fc6ab3
{
kusano fc6ab3
  int err = ZIP_OK;
kusano fc6ab3
kusano fc6ab3
  /*signature*/
kusano fc6ab3
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* number of this disk */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
kusano fc6ab3
  {
kusano fc6ab3
    {
kusano fc6ab3
      if(zi->number_entry >= 0xFFFF)
kusano fc6ab3
        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
kusano fc6ab3
      else
kusano fc6ab3
        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
kusano fc6ab3
    }
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* total number of entries in the central dir */
kusano fc6ab3
  {
kusano fc6ab3
    if(zi->number_entry >= 0xFFFF)
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
kusano fc6ab3
    else
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* size of the central directory */
kusano fc6ab3
    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
kusano fc6ab3
kusano fc6ab3
  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
kusano fc6ab3
  {
kusano fc6ab3
    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
kusano fc6ab3
    if(pos >= 0xffffffff)
kusano fc6ab3
    {
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
   return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
kusano fc6ab3
{
kusano fc6ab3
  int err = ZIP_OK;
kusano fc6ab3
  uInt size_global_comment = 0;
kusano fc6ab3
kusano fc6ab3
  if(global_comment != NULL)
kusano fc6ab3
    size_global_comment = (uInt)strlen(global_comment);
kusano fc6ab3
kusano fc6ab3
  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
kusano fc6ab3
kusano fc6ab3
  if (err == ZIP_OK && size_global_comment > 0)
kusano fc6ab3
  {
kusano fc6ab3
    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
kusano fc6ab3
      err = ZIP_ERRNO;
kusano fc6ab3
  }
kusano fc6ab3
  return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
kusano fc6ab3
{
kusano fc6ab3
    zip64_internal* zi;
kusano fc6ab3
    int err = 0;
kusano fc6ab3
    uLong size_centraldir = 0;
kusano fc6ab3
    ZPOS64_T centraldir_pos_inzip;
kusano fc6ab3
    ZPOS64_T pos;
kusano fc6ab3
kusano fc6ab3
    if (file == NULL)
kusano fc6ab3
        return ZIP_PARAMERROR;
kusano fc6ab3
kusano fc6ab3
    zi = (zip64_internal*)file;
kusano fc6ab3
kusano fc6ab3
    if (zi->in_opened_file_inzip == 1)
kusano fc6ab3
    {
kusano fc6ab3
        err = zipCloseFileInZip (file);
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
#ifndef NO_ADDFILEINEXISTINGZIP
kusano fc6ab3
    if (global_comment==NULL)
kusano fc6ab3
        global_comment = zi->globalcomment;
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
    {
kusano fc6ab3
        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
kusano fc6ab3
        while (ldi!=NULL)
kusano fc6ab3
        {
kusano fc6ab3
            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
kusano fc6ab3
            {
kusano fc6ab3
                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
kusano fc6ab3
                    err = ZIP_ERRNO;
kusano fc6ab3
            }
kusano fc6ab3
kusano fc6ab3
            size_centraldir += ldi->filled_in_this_block;
kusano fc6ab3
            ldi = ldi->next_datablock;
kusano fc6ab3
        }
kusano fc6ab3
    }
kusano fc6ab3
    free_linkedlist(&(zi->central_dir));
kusano fc6ab3
kusano fc6ab3
    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
kusano fc6ab3
    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
kusano fc6ab3
    {
kusano fc6ab3
      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
kusano fc6ab3
      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
kusano fc6ab3
kusano fc6ab3
      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    if (err==ZIP_OK)
kusano fc6ab3
      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
kusano fc6ab3
kusano fc6ab3
    if(err == ZIP_OK)
kusano fc6ab3
      err = Write_GlobalComment(zi, global_comment);
kusano fc6ab3
kusano fc6ab3
    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
kusano fc6ab3
        if (err == ZIP_OK)
kusano fc6ab3
            err = ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
#ifndef NO_ADDFILEINEXISTINGZIP
kusano fc6ab3
    TRYFREE(zi->globalcomment);
kusano fc6ab3
#endif
kusano fc6ab3
    TRYFREE(zi);
kusano fc6ab3
kusano fc6ab3
    return err;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
kusano fc6ab3
{
kusano fc6ab3
  char* p = pData;
kusano fc6ab3
  int size = 0;
kusano fc6ab3
  char* pNewHeader;
kusano fc6ab3
  char* pTmp;
kusano fc6ab3
  short header;
kusano fc6ab3
  short dataSize;
kusano fc6ab3
kusano fc6ab3
  int retVal = ZIP_OK;
kusano fc6ab3
kusano fc6ab3
  if(pData == NULL || *dataLen < 4)
kusano fc6ab3
    return ZIP_PARAMERROR;
kusano fc6ab3
kusano fc6ab3
  pNewHeader = (char*)ALLOC(*dataLen);
kusano fc6ab3
  pTmp = pNewHeader;
kusano fc6ab3
kusano fc6ab3
  while(p < (pData + *dataLen))
kusano fc6ab3
  {
kusano fc6ab3
    header = *(short*)p;
kusano fc6ab3
    dataSize = *(((short*)p)+1);
kusano fc6ab3
kusano fc6ab3
    if( header == sHeader ) // Header found.
kusano fc6ab3
    {
kusano fc6ab3
      p += dataSize + 4; // skip it. do not copy to temp buffer
kusano fc6ab3
    }
kusano fc6ab3
    else
kusano fc6ab3
    {
kusano fc6ab3
      // Extra Info block should not be removed, So copy it to the temp buffer.
kusano fc6ab3
      memcpy(pTmp, p, dataSize + 4);
kusano fc6ab3
      p += dataSize + 4;
kusano fc6ab3
      size += dataSize + 4;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
  }
kusano fc6ab3
kusano fc6ab3
  if(size < *dataLen)
kusano fc6ab3
  {
kusano fc6ab3
    // clean old extra info block.
kusano fc6ab3
    memset(pData,0, *dataLen);
kusano fc6ab3
kusano fc6ab3
    // copy the new extra info block over the old
kusano fc6ab3
    if(size > 0)
kusano fc6ab3
      memcpy(pData, pNewHeader, size);
kusano fc6ab3
kusano fc6ab3
    // set the new extra info size
kusano fc6ab3
    *dataLen = size;
kusano fc6ab3
kusano fc6ab3
    retVal = ZIP_OK;
kusano fc6ab3
  }
kusano fc6ab3
  else
kusano fc6ab3
    retVal = ZIP_ERRNO;
kusano fc6ab3
kusano fc6ab3
  TRYFREE(pNewHeader);
kusano fc6ab3
kusano fc6ab3
  return retVal;
kusano fc6ab3
}