19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* zip.c -- IO on .zip files using zlib
2381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Version 1.1, February 14h, 2010
3381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
5381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
7381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes         Modifications for Zip64 support
8381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
9381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
10381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes         For more info read MiniZip_info.txt
11381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
12381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes         Changes
13381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
14381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
15381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
16381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
17381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 It is used when recreting zip archive with RAW when deleting items from a zip.
18381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
19381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
20381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h>
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdlib.h>
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <string.h>
289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <time.h>
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zlib.h"
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zip.h"
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef STDC
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <stddef.h>
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <string.h>
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  include <stdlib.h>
369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef NO_ERRNO_H
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    extern int errno;
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#   include <errno.h>
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef local
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define local static
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* compile with -Dlocal if your debugger can't find static symbols */
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef VERSIONMADEBY
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define VERSIONMADEBY   (0x0) /* platform depedent */
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef Z_BUFSIZE
54381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#define Z_BUFSIZE (64*1024) //(16384)
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef Z_MAXFILENAMEINZIP
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define Z_MAXFILENAMEINZIP (256)
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef ALLOC
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define ALLOC(size) (malloc(size))
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef TRYFREE
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define TRYFREE(p) {if (p) free(p);}
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SIZECENTRALDIRITEM (0x2e)
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SIZEZIPLOCALHEADER (0x1e)
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
75381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
76381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes// NOT sure that this work on ALL platform
77381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
78381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef SEEK_CUR
809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SEEK_CUR    1
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef SEEK_END
849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SEEK_END    2
859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef SEEK_SET
889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SEEK_SET    0
899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef DEF_MEM_LEVEL
929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#if MAX_MEM_LEVEL >= 8
939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define DEF_MEM_LEVEL 8
949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else
959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
98381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesconst char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SIZEDATA_INDATABLOCK (4096-(4*4))
1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define LOCALHEADERMAGIC    (0x04034b50)
1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define CENTRALHEADERMAGIC  (0x02014b50)
1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define ENDHEADERMAGIC      (0x06054b50)
106381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#define ZIP64ENDHEADERMAGIC      (0x6064b50)
107381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define FLAG_LOCALHEADER_OFFSET (0x06)
1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define CRC_LOCALHEADER_OFFSET  (0x0e)
1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SIZECENTRALHEADER (0x2e) /* 46 */
1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projecttypedef struct linkedlist_datablock_internal_s
1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  struct linkedlist_datablock_internal_s* next_datablock;
1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  uLong  avail_in_this_block;
1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  uLong  filled_in_this_block;
1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  uLong  unused; /* for future use and alignement */
1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  unsigned char data[SIZEDATA_INDATABLOCK];
1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} linkedlist_datablock_internal;
1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projecttypedef struct linkedlist_data_s
1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    linkedlist_datablock_internal* first_block;
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    linkedlist_datablock_internal* last_block;
1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} linkedlist_data;
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projecttypedef struct
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    z_stream stream;            /* zLib stream structure for inflate */
133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    bz_stream bstream;          /* bzLib stream structure for bziped */
135381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int  stream_initialised;    /* 1 is stream is initialised */
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
140381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T pos_local_header;     /* offset of the local header of the file
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                     currenty writing */
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char* central_header;       /* central header data for the current file */
143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong size_centralExtra;
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong size_centralheader;   /* size of the central header for cur file */
145381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong flag;                 /* flag of the file currently writing */
1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int  method;                /* compression method of file currenty wr.*/
1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int  raw;                   /* 1 for directly writing raw data */
1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong dosDate;
1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong crc32;
1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int  encrypt;
154381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int  zip64;               /* Add ZIP64 extened information in the extra field */
155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T pos_zip64extrainfo;
156381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T totalCompressedData;
157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T totalUncompressedData;
1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NOCRYPT
1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
16004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes    const z_crc_t* pcrc_32_tab;
1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int crypt_header_size;
1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
163381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} curfile64_info;
1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projecttypedef struct
1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
167381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zlib_filefunc64_32_def z_filefunc;
1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    voidpf filestream;        /* io structore of the zipfile */
1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    linkedlist_data central_dir;/* datablock with central dir in construction*/
1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
171381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    curfile64_info ci;            /* info on the file curretly writing */
172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T add_position_when_writting_offset;
175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T number_entry;
1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NO_ADDFILEINEXISTINGZIP
1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char *globalcomment;
1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
181381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} zip64_internal;
1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NOCRYPT
1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "crypt.h"
1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal linkedlist_datablock_internal* allocate_new_datablock()
1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    linkedlist_datablock_internal* ldi;
1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ldi = (linkedlist_datablock_internal*)
1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                 ALLOC(sizeof(linkedlist_datablock_internal));
1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (ldi!=NULL)
1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ldi->next_datablock = NULL ;
1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ldi->filled_in_this_block = 0 ;
1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return ldi;
2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
203381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void free_datablock(linkedlist_datablock_internal* ldi)
2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (ldi!=NULL)
2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        TRYFREE(ldi);
2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ldi = ldinext;
2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void init_linkedlist(linkedlist_data* ll)
2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ll->first_block = ll->last_block = NULL;
2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
218381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void free_linkedlist(linkedlist_data* ll)
2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    free_datablock(ll->first_block);
2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ll->first_block = ll->last_block = NULL;
2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
225381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    linkedlist_datablock_internal* ldi;
2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    const unsigned char* from_copy;
2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (ll==NULL)
2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_INTERNALERROR;
2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (ll->last_block == NULL)
2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ll->first_block = ll->last_block = allocate_new_datablock();
2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (ll->first_block == NULL)
2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return ZIP_INTERNALERROR;
2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ldi = ll->last_block;
2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    from_copy = (unsigned char*)buf;
2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    while (len>0)
2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        uInt copy_this;
2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        uInt i;
2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        unsigned char* to_copy;
2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (ldi->avail_in_this_block==0)
2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            ldi->next_datablock = allocate_new_datablock();
2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (ldi->next_datablock == NULL)
2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                return ZIP_INTERNALERROR;
2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            ldi = ldi->next_datablock ;
2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            ll->last_block = ldi;
2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (ldi->avail_in_this_block < len)
2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            copy_this = (uInt)ldi->avail_in_this_block;
2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        else
2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            copy_this = (uInt)len;
2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        to_copy = &(ldi->data[ldi->filled_in_this_block]);
2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        for (i=0;i<copy_this;i++)
2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            *(to_copy+i)=*(from_copy+i);
2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ldi->filled_in_this_block += copy_this;
2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ldi->avail_in_this_block -= copy_this;
2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        from_copy += copy_this ;
2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        len -= copy_this;
2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return ZIP_OK;
2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/****************************************************************************/
2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NO_ADDFILEINEXISTINGZIP
2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   Inputs a long in LSB order to the given file
283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/
2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
289381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    unsigned char buf[8];
2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int n;
2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (n = 0; n < nbByte; n++)
2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        buf[n] = (unsigned char)(x & 0xff);
2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        x >>= 8;
2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (x != 0)
2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      {     /* data overflow - hack for ZIP64 (X Roche) */
2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      for (n = 0; n < nbByte; n++)
2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          buf[n] = 0xff;
3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      }
3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
304381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_ERRNO;
3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_OK;
3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
310381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
311381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned char* buf=(unsigned char*)dest;
3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int n;
3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (n = 0; n < nbByte; n++) {
3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        buf[n] = (unsigned char)(x & 0xff);
3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        x >>= 8;
3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (x != 0)
3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {     /* data overflow - hack for ZIP64 */
3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       for (n = 0; n < nbByte; n++)
3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       {
3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project          buf[n] = 0xff;
3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project       }
3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/****************************************************************************/
3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
332381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong year = (uLong)ptm->tm_year;
335381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (year>=1980)
3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        year-=1980;
337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else if (year>=80)
3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        year-=80;
3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return
3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/****************************************************************************/
3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    unsigned char c;
352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==1)
3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *pi = (int)c;
3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_OK;
3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (ZERROR64(*pzlib_filefunc_def,filestream))
3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return ZIP_ERRNO;
3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        else
3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return ZIP_EOF;
3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* ===========================================================================
3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project   Reads a long in LSB order from the given gz_stream. Sets
3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/
371381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
372381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
373381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong x ;
376381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int i = 0;
3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
379381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    x = (uLong)i;
3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
383381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    x += ((uLong)i)<<8;
3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *pX = x;
3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *pX = 0;
3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
393381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong x ;
398381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int i = 0;
3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err;
4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
401381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    x = (uLong)i;
4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
405381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    x += ((uLong)i)<<8;
4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    x += ((uLong)i)<<16;
4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
413381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    x += ((uLong)i)<<24;
4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *pX = x;
4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *pX = 0;
4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
426381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T x;
429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int i = 0;
430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err;
431381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
432381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
433381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x = (ZPOS64_T)i;
434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<8;
438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<16;
442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
444381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
445381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<24;
446381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<32;
450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<40;
454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<48;
458381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  x += ((ZPOS64_T)i)<<56;
462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    *pX = x;
465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  else
466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    *pX = 0;
467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return err;
469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
4719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef BUFREADCOMMENT
4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BUFREADCOMMENT (0x400)
4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
4759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  Locate the Central directory of a zipfile (at the end, just before
4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    the global comment)
4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project*/
478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  unsigned char* buf;
483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uSizeFile;
484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uBackRead;
485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uPosFound=0;
487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
4939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (uMaxBack>uSizeFile)
495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uMaxBack = uSizeFile;
4969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (buf==NULL)
499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
5009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uBackRead = 4;
502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  while (uBackRead<uMaxBack)
503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong uReadSize;
505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T uReadPos ;
506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int i;
507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (uBackRead+BUFREADCOMMENT>uMaxBack)
508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      uBackRead = uMaxBack;
509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      uBackRead+=BUFREADCOMMENT;
511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uReadPos = uSizeFile-uBackRead ;
512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
515381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      break;
517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      break;
520381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
521381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    for (i=(int)uReadSize-3; (i--)>0;)
522381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
523381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        uPosFound = uReadPos+i;
526381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        break;
527381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (uPosFound!=0)
530381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        break;
531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  TRYFREE(buf);
533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return uPosFound;
534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/*
537381716e9396b55b1adb8235b020c37344f60ab07Elliott HughesLocate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesthe global comment)
539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes*/
540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
542381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  unsigned char* buf;
545381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uSizeFile;
546381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uBackRead;
547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
548381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T uPosFound=0;
549381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong uL;
550381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T relativeOffset;
551381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
552381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
553381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
554381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
555381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
557381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (uMaxBack>uSizeFile)
558381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uMaxBack = uSizeFile;
559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
560381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
561381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (buf==NULL)
562381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
564381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uBackRead = 4;
565381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  while (uBackRead<uMaxBack)
566381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
567381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong uReadSize;
568381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T uReadPos;
569381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    int i;
570381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (uBackRead+BUFREADCOMMENT>uMaxBack)
571381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      uBackRead = uMaxBack;
572381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
573381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      uBackRead+=BUFREADCOMMENT;
574381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uReadPos = uSizeFile-uBackRead ;
575381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
576381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
577381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
578381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
579381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      break;
580381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
581381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
582381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      break;
583381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
584381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    for (i=(int)uReadSize-3; (i--)>0;)
5859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
586381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Signature "0x07064b50" Zip64 end of central directory locater
587381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
588381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
589381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        uPosFound = uReadPos+i;
590381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        break;
591381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
592381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
594381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (uPosFound!=0)
595381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        break;
596381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
5979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
598381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  TRYFREE(buf);
599381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (uPosFound == 0)
600381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
602381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* Zip64 end of central directory locator */
603381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
604381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
605381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
606381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* the signature, already checked */
607381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
608381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
609381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
610381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* number of the disk with the start of the zip64 end of  central directory */
611381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
612381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
613381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (uL != 0)
614381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
615381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
616381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* relative offset of the zip64 end of central directory record */
617381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
618381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
619381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
620381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* total number of disks */
621381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
622381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
623381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (uL != 1)
624381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
6259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
626381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* Goto Zip64 end of central directory record */
627381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
628381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
629381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
630381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* the signature */
631381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
632381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
633381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
634381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
635381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return 0;
636381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
637381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return relativeOffset;
638381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
639381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
640381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint LoadCentralDirectoryRecord(zip64_internal* pziinit)
641381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
642381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err=ZIP_OK;
643381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
644381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
645381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T size_central_dir;     /* size of the central directory  */
646381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
647381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T central_pos;
648381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong uL;
649381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
650381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong number_disk;          /* number of the current dist, used for
651381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                              spaning ZIP, unsupported, always 0*/
652381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong number_disk_with_CD;  /* number the the disk with central dir, used
653381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                              for spaning ZIP, unsupported, always 0*/
654381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T number_entry;
655381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T number_entry_CD;      /* total number of entries in
656381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                the central dir
657381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                (same than number_entry on nospan) */
658381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong VersionMadeBy;
659381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong VersionNeeded;
660381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong size_comment;
661381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
662381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int hasZIP64Record = 0;
663381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
664381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  // check first if we find a ZIP64 record
665381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
666381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if(central_pos > 0)
667381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
668381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    hasZIP64Record = 1;
669381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
670381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  else if(central_pos == 0)
671381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
672381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
673381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
674381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
675381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/* disable to allow appending to empty ZIP archive
676381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (central_pos==0)
677381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            err=ZIP_ERRNO;
678381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes*/
679381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
680381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if(hasZIP64Record)
681381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
682381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T sizeEndOfCentralDirectory;
683381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
684381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
685381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
686381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* the signature, already checked */
687381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
688381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
689381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
690381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* size of zip64 end of central directory record */
691381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
692381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
693381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
694381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* version made by */
695381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
696381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
697381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
698381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* version needed to extract */
699381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
700381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
701381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
702381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* number of this disk */
703381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
704381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
705381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
706381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* number of the disk with the start of the central directory */
707381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
708381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
709381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
710381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* total number of entries in the central directory on this disk */
711381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
712381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
713381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
714381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* total number of entries in the central directory */
715381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
716381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
717381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
718381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
719381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_BADZIPFILE;
720381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
721381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* size of the central directory */
722381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
723381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
724381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
725381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* offset of start of central directory with respect to the
726381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    starting disk number */
727381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
728381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
729381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
730381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // TODO..
731381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // read the comment from the standard central header.
732381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size_comment = 0;
733381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
734381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  else
735381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
736381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // Read End of central Directory info
737381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
738381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
739381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
740381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* the signature, already checked */
741381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
742381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
743381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
744381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* number of this disk */
745381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
746381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
747381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
748381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* number of the disk with the start of the central directory */
749381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
750381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
751381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
752381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* total number of entries in the central dir on this disk */
753381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    number_entry = 0;
754381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
755381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
756381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
757381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      number_entry = uL;
758381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
759381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* total number of entries in the central dir */
760381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    number_entry_CD = 0;
761381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
762381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
763381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
764381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      number_entry_CD = uL;
765381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
766381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
767381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_BADZIPFILE;
768381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
769381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* size of the central directory */
770381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size_central_dir = 0;
771381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
772381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
773381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
774381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      size_central_dir = uL;
775381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
776381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* offset of start of central directory with respect to the starting disk number */
777381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    offset_central_dir = 0;
778381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
779381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
780381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
781381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      offset_central_dir = uL;
782381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
783381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
784381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /* zipfile global comment length */
785381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
786381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
787381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
788381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
789381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if ((central_pos<offset_central_dir+size_central_dir) &&
790381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    (err==ZIP_OK))
791381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err=ZIP_BADZIPFILE;
792381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
793381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err!=ZIP_OK)
794381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
795381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
796381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return ZIP_ERRNO;
797381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
798381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
799381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (size_comment>0)
800381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
801381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
802381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (pziinit->globalcomment)
803381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
804381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
805381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      pziinit->globalcomment[size_comment]=0;
8069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
807381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
808381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
809381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
810381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
811381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
812381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
813381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T size_central_dir_to_read = size_central_dir;
814381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size_t buf_size = SIZEDATA_INDATABLOCK;
815381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    void* buf_read = (void*)ALLOC(buf_size);
816381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
817381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err=ZIP_ERRNO;
818381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
819381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
820381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
821381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
822381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (read_this > size_central_dir_to_read)
823381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        read_this = size_central_dir_to_read;
824381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
825381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
826381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err=ZIP_ERRNO;
827381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
828381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if (err==ZIP_OK)
829381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
830381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
831381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      size_central_dir_to_read-=read_this;
832381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
833381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    TRYFREE(buf_read);
834381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
835381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  pziinit->begin_pos = byte_before_the_zipfile;
836381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  pziinit->number_entry = number_entry_CD;
837381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
838381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
839381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err=ZIP_ERRNO;
840381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
841381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return err;
8429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
843381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
844381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
8459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* !NO_ADDFILEINEXISTINGZIP*/
8469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
847381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
8489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/************************************************************/
849381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
8509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
851381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64_internal ziinit;
852381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64_internal* zi;
8539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err=ZIP_OK;
8549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
855381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ziinit.z_filefunc.zseek32_file = NULL;
856381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ziinit.z_filefunc.ztell32_file = NULL;
857381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (pzlib_filefunc64_32_def==NULL)
858381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
8599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
860381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
8619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
862381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
8639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  pathname,
8649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  (append == APPEND_STATUS_CREATE) ?
8659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
8669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
8679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
8689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (ziinit.filestream == NULL)
8699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return NULL;
870381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
871381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (append == APPEND_STATUS_CREATEAFTER)
872381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
873381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
874381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
8759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ziinit.in_opened_file_inzip = 0;
8769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ziinit.ci.stream_initialised = 0;
8779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ziinit.number_entry = 0;
8789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ziinit.add_position_when_writting_offset = 0;
8799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    init_linkedlist(&(ziinit.central_dir));
8809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
8819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
882381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
883381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
8849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi==NULL)
8859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
886381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
8879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return NULL;
8889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
8899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
8909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* now we add file in a zipfile */
8919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    ifndef NO_ADDFILEINEXISTINGZIP
8929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    ziinit.globalcomment = NULL;
8939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (append == APPEND_STATUS_ADDINZIP)
8949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
895381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Read and Cache Central Directory Records
896381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = LoadCentralDirectoryRecord(&ziinit);
8979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
8989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
8999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (globalcomment)
9009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
9019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      *globalcomment = ziinit.globalcomment;
9029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
9039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    endif /* !NO_ADDFILEINEXISTINGZIP*/
9049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
9059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err != ZIP_OK)
9069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
9079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    ifndef NO_ADDFILEINEXISTINGZIP
9089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        TRYFREE(ziinit.globalcomment);
9099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    endif /* !NO_ADDFILEINEXISTINGZIP*/
9109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        TRYFREE(zi);
9119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return NULL;
9129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
9139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
9149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
9159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *zi = ziinit;
9169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return (zipFile)zi;
9179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
9189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
9199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
920381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
9219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
922381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (pzlib_filefunc32_def != NULL)
923381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
924381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
925381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
926381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
927381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
928381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
929381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return zipOpen3(pathname, append, globalcomment, NULL);
9309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
9319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
932381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
933381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
934381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (pzlib_filefunc_def != NULL)
935381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
936381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
937381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
938381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
939381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
940381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
941381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
942381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
943381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return zipOpen3(pathname, append, globalcomment, NULL);
944381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
945381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
946381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
947381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
948381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern zipFile ZEXPORT zipOpen (const char* pathname, int append)
9499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
950381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpen3((const void*)pathname,append,NULL,NULL);
951381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
952381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
953381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
954381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
955381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpen3(pathname,append,NULL,NULL);
956381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
957381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
958381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
959381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
960381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /* write the local header */
961381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err;
962381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uInt size_filename = (uInt)strlen(filename);
963381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uInt size_extrafield = size_extrafield_local;
964381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
965381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
966381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
967381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
968381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
969381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.zip64)
970381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
971381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
972381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
973381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
974381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
975381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
976381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
977381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
978381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
979381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
980381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
981381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
982381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
983381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
984381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
985381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
986381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
987381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
988381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
989381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.zip64)
990381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
991381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
992381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
993381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
994381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
995381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
996381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.zip64)
997381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
998381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
999381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
1000381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1001381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1002381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
1003381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
1004381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1005381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if(zi->ci.zip64)
1006381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1007381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size_extrafield += 20;
1008381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1009381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1010381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK)
1011381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
1012381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1013381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if ((err==ZIP_OK) && (size_filename > 0))
1014381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1015381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
1016381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = ZIP_ERRNO;
1017381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1018381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1019381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if ((err==ZIP_OK) && (size_extrafield_local > 0))
1020381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1021381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
1022381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = ZIP_ERRNO;
1023381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1024381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1025381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1026381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if ((err==ZIP_OK) && (zi->ci.zip64))
1027381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1028381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // write the Zip64 extended info
1029381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      short HeaderID = 1;
1030381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      short DataSize = 16;
1031381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      ZPOS64_T CompressedSize = 0;
1032381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      ZPOS64_T UncompressedSize = 0;
1033381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1034381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
1035381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
1036381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1037381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
1038381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
1039381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1040381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
1041381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
1042381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1043381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1044381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return err;
1045381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1046381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1047381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes/*
1048381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NOTE.
1049381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
1050381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes before calling this function it can be done with zipRemoveExtraInfoBlock
1051381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1052381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
1053381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes unnecessary allocations.
1054381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes */
1055381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1056381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_local, uInt size_extrafield_local,
1057381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_global, uInt size_extrafield_global,
1058381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* comment, int method, int level, int raw,
1059381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         int windowBits,int memLevel, int strategy,
1060381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* password, uLong crcForCrypting,
1061381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         uLong versionMadeBy, uLong flagBase, int zip64)
1062381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1063381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64_internal* zi;
10649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uInt size_filename;
10659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uInt size_comment;
10669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uInt i;
10679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err = ZIP_OK;
10689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
10699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    ifdef NOCRYPT
1070ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    (crcForCrypting);
10719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (password != NULL)
10729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
10739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    endif
10749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
10759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (file == NULL)
10769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
1077381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1078381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1079381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
1080381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      return ZIP_PARAMERROR;
1081381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else
10829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((method!=0) && (method!=Z_DEFLATED))
1083381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      return ZIP_PARAMERROR;
1084381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
10859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1086381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi = (zip64_internal*)file;
10879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
10889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->in_opened_file_inzip == 1)
10899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
10909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        err = zipCloseFileInZip (file);
10919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (err != ZIP_OK)
10929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            return err;
10939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
10949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
10959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (filename==NULL)
10969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        filename="-";
10979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
10989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (comment==NULL)
10999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        size_comment = 0;
11009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
11019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        size_comment = (uInt)strlen(comment);
11029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    size_filename = (uInt)strlen(filename);
11049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zipfi == NULL)
11069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        zi->ci.dosDate = 0;
11079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
11089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
11099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (zipfi->dosDate != 0)
11109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            zi->ci.dosDate = zipfi->dosDate;
1111381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        else
1112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
11139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
11149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1115381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.flag = flagBase;
11169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((level==8) || (level==9))
11179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      zi->ci.flag |= 2;
111809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    if (level==2)
11199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      zi->ci.flag |= 4;
112009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes    if (level==1)
11219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      zi->ci.flag |= 6;
11229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (password != NULL)
11239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      zi->ci.flag |= 1;
11249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.crc32 = 0;
11269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.method = method;
11279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.encrypt = 0;
11289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream_initialised = 0;
11299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.pos_in_buffered_data = 0;
11309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.raw = raw;
1131381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
1132381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
1134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
11359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
1137381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1138381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.size_centralExtra = size_extrafield_global;
1139381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
11409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /* version info */
1141381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
1142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
1143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
1144381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
1145381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
1146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
1147381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
1148381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
1149381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
1150381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
1151381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
1152381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
11539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zipfi==NULL)
1155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
11569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
1157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
11589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zipfi==NULL)
1160381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
11619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
1162381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
11639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1164381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.pos_local_header >= 0xffffffff)
1165381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
1166381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1167381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
11689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (i=0;i<size_filename;i++)
11709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
11719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (i=0;i<size_extrafield_global;i++)
11739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
11749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              *(((const char*)extrafield_global)+i);
11759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    for (i=0;i<size_comment;i++)
11779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
11789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project              size_extrafield_global+i) = *(comment+i);
11799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->ci.central_header == NULL)
11809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_INTERNALERROR;
11819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1182381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.zip64 = zip64;
1183381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.totalCompressedData = 0;
1184381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.totalUncompressedData = 0;
1185381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.pos_zip64extrainfo = 0;
1186381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1187381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
1188381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1189381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1190381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.avail_in = (uInt)0;
1191381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1192381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
1193381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.total_in_hi32 = 0;
1194381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.total_in_lo32 = 0;
1195381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.total_out_hi32 = 0;
1196381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.bstream.total_out_lo32 = 0;
1197381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
11989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
11999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream.avail_in = (uInt)0;
12009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
12019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream.next_out = zi->ci.buffered_data;
12029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream.total_in = 0;
12039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream.total_out = 0;
1204381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.stream.data_type = Z_BINARY;
12059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1206381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1207381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1208381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else
12099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1210381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
12119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1212381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if(zi->ci.method == Z_DEFLATED)
1213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        {
1214381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.stream.zalloc = (alloc_func)0;
1215381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.stream.zfree = (free_func)0;
1216381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.stream.opaque = (voidpf)0;
12179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1218381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (windowBits>0)
1219381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              windowBits = -windowBits;
12209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1221381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
1222381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1223381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (err==Z_OK)
1224381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              zi->ci.stream_initialised = Z_DEFLATED;
1225381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
1226381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        else if(zi->ci.method == Z_BZIP2ED)
1227381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        {
1228381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1229381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            // Init BZip stuff here
1230381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.bzalloc = 0;
1231381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.bzfree = 0;
1232381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.opaque = (voidpf)0;
1233381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1234381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
1235381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if(err == BZ_OK)
1236381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            zi->ci.stream_initialised = Z_BZIP2ED;
1237381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
1238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
12399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
12409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
12429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    ifndef NOCRYPT
12439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.crypt_header_size = 0;
12449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((err==Z_OK) && (password != NULL))
12459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
12469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        unsigned char bufHead[RAND_HEAD_LEN];
12479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        unsigned int sizeHead;
12489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        zi->ci.encrypt = 1;
12499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        zi->ci.pcrc_32_tab = get_crc_table();
12509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
12519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
12529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
12539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        zi->ci.crypt_header_size = sizeHead;
12549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1255381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
12569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                err = ZIP_ERRNO;
12579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
12589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    endif
12599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
12609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==Z_OK)
12619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        zi->in_opened_file_inzip = 1;
12629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
12639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
12649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1265381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1266381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_local, uInt size_extrafield_local,
1267381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_global, uInt size_extrafield_global,
1268381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* comment, int method, int level, int raw,
1269381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         int windowBits,int memLevel, int strategy,
1270381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* password, uLong crcForCrypting,
1271381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         uLong versionMadeBy, uLong flagBase)
1272381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1273381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1274381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_local, size_extrafield_local,
1275381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_global, size_extrafield_global,
1276381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 comment, method, level, raw,
1277381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 windowBits, memLevel, strategy,
1278381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
1279381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1280381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1281381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1282381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_local, uInt size_extrafield_local,
1283381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_global, uInt size_extrafield_global,
1284381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* comment, int method, int level, int raw,
1285381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         int windowBits,int memLevel, int strategy,
1286381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* password, uLong crcForCrypting)
1287381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1288381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1289381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_local, size_extrafield_local,
1290381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_global, size_extrafield_global,
1291381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 comment, method, level, raw,
1292381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 windowBits, memLevel, strategy,
1293381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
1294381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1295381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1296381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1297381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_local, uInt size_extrafield_local,
1298381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const void* extrafield_global, uInt size_extrafield_global,
1299381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* comment, int method, int level, int raw,
1300381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         int windowBits,int memLevel, int strategy,
1301381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                         const char* password, uLong crcForCrypting, int zip64)
1302381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1303381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1304381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_local, size_extrafield_local,
1305381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_global, size_extrafield_global,
1306381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 comment, method, level, raw,
1307381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 windowBits, memLevel, strategy,
1308381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
1309381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1310381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1311381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1312381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void* extrafield_local, uInt size_extrafield_local,
1313381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void* extrafield_global, uInt size_extrafield_global,
1314381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const char* comment, int method, int level, int raw)
13159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1316381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
13179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                 extrafield_local, size_extrafield_local,
13189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                 extrafield_global, size_extrafield_global,
13199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                 comment, method, level, raw,
13209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1321381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 NULL, 0, VERSIONMADEBY, 0, 0);
13229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
13239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1324381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
1325381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void* extrafield_local, uInt size_extrafield_local,
1326381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void* extrafield_global, uInt size_extrafield_global,
1327381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const char* comment, int method, int level, int raw, int zip64)
13289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1329381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
13309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                 extrafield_local, size_extrafield_local,
13319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                                 extrafield_global, size_extrafield_global,
1332381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 comment, method, level, raw,
1333381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1334381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 NULL, 0, VERSIONMADEBY, 0, zip64);
13359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
13369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1337381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1338381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void* extrafield_local, uInt size_extrafield_local,
1339381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void*extrafield_global, uInt size_extrafield_global,
1340381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const char* comment, int method, int level, int zip64)
1341381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1342381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1343381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_local, size_extrafield_local,
1344381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_global, size_extrafield_global,
1345381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 comment, method, level, 0,
1346381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1347381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 NULL, 0, VERSIONMADEBY, 0, zip64);
1348381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1349381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1350381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
1351381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void* extrafield_local, uInt size_extrafield_local,
1352381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const void*extrafield_global, uInt size_extrafield_global,
1353381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        const char* comment, int method, int level)
1354381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1355381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
1356381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_local, size_extrafield_local,
1357381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 extrafield_global, size_extrafield_global,
1358381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 comment, method, level, 0,
1359381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
1360381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                 NULL, 0, VERSIONMADEBY, 0, 0);
1361381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1362381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1363381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslocal int zip64FlushWriteBuffer(zip64_internal* zi)
13649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
13659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err=ZIP_OK;
13669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
13679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->ci.encrypt != 0)
13689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
13699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NOCRYPT
13709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        uInt i;
13719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        int t;
13729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
1373381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
13749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
13759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1376381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1377381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
13789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      err = ZIP_ERRNO;
1379381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1380381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
1381381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1382381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1383381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.method == Z_BZIP2ED)
1384381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
1386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.bstream.total_in_lo32 = 0;
1387381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.bstream.total_in_hi32 = 0;
1388381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
1391381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1392381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
1393381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.stream.total_in = 0;
1394381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1396381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
13979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.pos_in_buffered_data = 0;
1398381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
13999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
14009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
14019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1402381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
14039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1404381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64_internal* zi;
14059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err=ZIP_OK;
14069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
14079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (file == NULL)
14089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
1409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi = (zip64_internal*)file;
14109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
14119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->in_opened_file_inzip == 0)
14129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
14139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1414381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
14159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
14189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1419381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.bstream.next_in = (void*)buf;
1420381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.bstream.avail_in = len;
1421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = BZ_RUN_OK;
1422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1423381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
1424381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
1425381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (zi->ci.bstream.avail_out == 0)
14269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1427381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1428381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            err = ZIP_ERRNO;
1429381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1430381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
14319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
14329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
14339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if(err != BZ_RUN_OK)
1435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          break;
14369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
14389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
1440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
1441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
14429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
14449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1445381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
1446381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1447381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if(err == BZ_RUN_OK)
1448381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = ZIP_OK;
1449381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1450381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1451381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
1452381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1453381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.stream.next_in = (Bytef*)buf;
1454381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.stream.avail_in = len;
1455381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1456381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
1457381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
1458381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (zi->ci.stream.avail_out == 0)
1459381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          {
1460381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1461381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  err = ZIP_ERRNO;
1462381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1463381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              zi->ci.stream.next_out = zi->ci.buffered_data;
1464381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          }
1465381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1466381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1467381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if(err != ZIP_OK)
1468381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              break;
1469381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          {
1472381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              uLong uTotalOutBefore = zi->ci.stream.total_out;
1473381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
1474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              if(uTotalOutBefore > zi->ci.stream.total_out)
1475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              {
1476381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                int bBreak = 0;
1477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                bBreak++;
1478381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              }
1479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1480381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1481381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          }
1482381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          else
1483381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          {
1484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              uInt copy_this,i;
1485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  copy_this = zi->ci.stream.avail_in;
1487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              else
1488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  copy_this = zi->ci.stream.avail_out;
1489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              for (i = 0; i < copy_this; i++)
1491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  *(((char*)zi->ci.stream.next_out)+i) =
1492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                      *(((const char*)zi->ci.stream.next_in)+i);
1493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              {
1494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.stream.avail_in -= copy_this;
1495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.stream.avail_out-= copy_this;
1496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.stream.next_in+= copy_this;
1497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.stream.next_out+= copy_this;
1498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.stream.total_in+= copy_this;
1499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.stream.total_out+= copy_this;
1500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                  zi->ci.pos_in_buffered_data += copy_this;
1501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              }
1502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          }
1503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }// while(...)
15049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
15059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
15079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
15089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
1510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
1512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1513381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
15159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1516381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64_internal* zi;
1517381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T compressed_size;
1518381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    uLong invalidValue = 0xffffffff;
1519381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    short datasize = 0;
15209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err=ZIP_OK;
15219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (file == NULL)
15239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
1524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi = (zip64_internal*)file;
15259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->in_opened_file_inzip == 0)
15279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
15289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->ci.stream.avail_in = 0;
15299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                {
1532381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        while (err==ZIP_OK)
1533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        {
1534381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                uLong uTotalOutBefore;
1535381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                if (zi->ci.stream.avail_out == 0)
1536381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                {
1537381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                                err = ZIP_ERRNO;
1539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1540381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                        zi->ci.stream.next_out = zi->ci.buffered_data;
1541381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                }
1542381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                uTotalOutBefore = zi->ci.stream.total_out;
1543381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                err=deflate(&zi->ci.stream,  Z_FINISH);
1544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1545381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        }
1546381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                }
1547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
15489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1549381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1550381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = BZ_FINISH_OK;
1551381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      while (err==BZ_FINISH_OK)
1552381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
15539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        uLong uTotalOutBefore;
1554381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (zi->ci.bstream.avail_out == 0)
15559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1556381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
1557381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            err = ZIP_ERRNO;
1558381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
1559381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
15609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1561381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
1562381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
1563381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if(err == BZ_STREAM_END)
1564381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          err = Z_STREAM_END;
1565381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1566381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
1567381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
1568381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1569381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if(err == BZ_FINISH_OK)
1570381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = ZIP_OK;
1571381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
15729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
15739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==Z_STREAM_END)
15759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        err=ZIP_OK; /* this is normal */
15769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1578381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                {
1579381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
15809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            err = ZIP_ERRNO;
1581381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                }
15829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
15839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
15849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1585381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        int tmp_err = deflateEnd(&zi->ci.stream);
1586381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (err == ZIP_OK)
1587381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            err = tmp_err;
15889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        zi->ci.stream_initialised = 0;
15899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1590381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef HAVE_BZIP2
1591381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
1592381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1593381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
1594381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        if (err==ZIP_OK)
1595381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                                err = tmperr;
1596381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                        zi->ci.stream_initialised = 0;
1597381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1598381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif
15999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
16009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (!zi->ci.raw)
16019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
16029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        crc32 = (uLong)zi->ci.crc32;
1603381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        uncompressed_size = zi->ci.totalUncompressedData;
16049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1605381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    compressed_size = zi->ci.totalCompressedData;
1606381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
16079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    ifndef NOCRYPT
16089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    compressed_size += zi->ci.crypt_header_size;
16099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#    endif
16109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1611381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // update Current Item crc and sizes,
1612381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
1613381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1614381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      /*version Made by*/
1615381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
1616381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      /*version needed*/
1617381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
1618381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1619381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1620381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1621381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1622381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1623381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1624381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(compressed_size >= 0xffffffff)
1625381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
1626381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1627381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
1628381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1629381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    /// set internal file attributes field
16309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->ci.stream.data_type == Z_ASCII)
1631381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1632381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1633381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(uncompressed_size >= 0xffffffff)
1634381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
1635381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1636381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
1637381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1638381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // Add ZIP64 extra info field for uncompressed size
1639381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(uncompressed_size >= 0xffffffff)
1640381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      datasize += 8;
1641381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1642381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // Add ZIP64 extra info field for compressed size
1643381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(compressed_size >= 0xffffffff)
1644381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      datasize += 8;
1645381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1646381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // Add ZIP64 extra info field for relative offset to local file header of current file
1647381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->ci.pos_local_header >= 0xffffffff)
1648381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      datasize += 8;
1649381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1650381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(datasize > 0)
1651381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1652381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      char* p = NULL;
1653381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1654381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
1655381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
1656381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        // we can not write more data to the buffer that we have room for.
1657381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        return ZIP_BADZIPFILE;
1658381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
1659381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1660381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      p = zi->ci.central_header + zi->ci.size_centralheader;
1661381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1662381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Add Extra Information Header for 'ZIP64 information'
1663381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
1664381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      p += 2;
1665381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
1666381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      p += 2;
1667381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1668381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if(uncompressed_size >= 0xffffffff)
1669381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
1670381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(p, uncompressed_size, 8);
1671381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        p += 8;
1672381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
1673381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1674381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if(compressed_size >= 0xffffffff)
1675381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
1676381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(p, compressed_size, 8);
1677381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        p += 8;
1678381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
1679381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1680381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if(zi->ci.pos_local_header >= 0xffffffff)
1681381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      {
1682381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
1683381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        p += 8;
1684381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      }
1685381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1686381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Update how much extra free space we got in the memory buffer
1687381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // and increase the centralheader size so the new ZIP64 fields are included
1688381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // ( 4 below is the size of HeaderID and DataSize field )
1689381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.size_centralExtraFree -= datasize + 4;
1690381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.size_centralheader += datasize + 4;
1691381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1692381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Update the extra info size field
1693381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zi->ci.size_centralExtra += datasize + 4;
1694381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
1695381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
16969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
16979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
1698381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
1699381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
17009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    free(zi->ci.central_header);
17019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
17029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
17039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1704381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        // Update the LocalFileHeader with the new values.
1705381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1706381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1707381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1708381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
17099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            err = ZIP_ERRNO;
17109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
17119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (err==ZIP_OK)
1712381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
17139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1714ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
1715381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        {
1716381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if(zi->ci.pos_zip64extrainfo > 0)
1717381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          {
1718381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            // Update the size in the ZIP64 extended field.
1719381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
1720381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              err = ZIP_ERRNO;
1721381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1722381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (err==ZIP_OK) /* compressed size, unknown */
1723381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
1724381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1725381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            if (err==ZIP_OK) /* uncompressed size, unknown */
1726381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
1727381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          }
1728ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes          else
1729ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
1730381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
1731381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        else
1732381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        {
1733381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (err==ZIP_OK) /* compressed size, unknown */
1734381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
17359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1736381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes          if (err==ZIP_OK) /* uncompressed size, unknown */
1737381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1738381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        }
17399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1740381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
17419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            err = ZIP_ERRNO;
17429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
17439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
17449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->number_entry ++;
17459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    zi->in_opened_file_inzip = 0;
17469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
17479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
17489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
17499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1750381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipCloseFileInZip (zipFile file)
17519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
17529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return zipCloseFileInZipRaw (file,0,0);
17539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
17549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1755381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
17569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1757381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err = ZIP_OK;
1758381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
1759381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1760381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
1761381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1762381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /*num disks*/
1763381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1764381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1765381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1766381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /*relative offset*/
1767381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
1768381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
1769381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1770381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
1771381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1772381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
1773381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1774381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return err;
1775381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1776381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1777381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
1778381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1779381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err = ZIP_OK;
1780381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1781381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uLong Zip64DataSize = 44;
1782381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1783381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
1784381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1785381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
1786381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
1787381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1788381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* version made by */
1789381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
1790381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1791381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* version needed */
1792381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
1793381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1794381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* number of this disk */
1795381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1796381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1797381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1798381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
1799381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1800381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1801381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1802381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1803381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* total number of entries in the central dir */
1804381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
1805381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1806381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* size of the central directory */
1807381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
1808381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1809381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
1810381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1811381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1812381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
1813381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1814381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return err;
1815381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1816381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
1817381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1818381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err = ZIP_OK;
1819381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1820381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  /*signature*/
1821381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1822381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1823381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* number of this disk */
1824381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1825381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1826381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1827381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1828381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1829381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1830381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1831381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1832381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      if(zi->number_entry >= 0xFFFF)
1833381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
1834381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      else
1835381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1836381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1837381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1838381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1839381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* total number of entries in the central dir */
1840381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1841381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(zi->number_entry >= 0xFFFF)
1842381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
1843381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1844381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1845381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1846381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1847381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* size of the central directory */
1848381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1849381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1850381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
1851381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1852381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1853381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(pos >= 0xffffffff)
1854381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1855381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
1856381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1857381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1858ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1859381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1860381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1861381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes   return err;
1862381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1863381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1864381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint Write_GlobalComment(zip64_internal* zi, const char* global_comment)
1865381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1866381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int err = ZIP_OK;
1867381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  uInt size_global_comment = 0;
1868381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1869381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if(global_comment != NULL)
1870381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    size_global_comment = (uInt)strlen(global_comment);
1871381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1872381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1873381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1874381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if (err == ZIP_OK && size_global_comment > 0)
1875381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1876381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
1877381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = ZIP_ERRNO;
1878381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1879381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return err;
1880381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
1881381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1882381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipClose (zipFile file, const char* global_comment)
1883381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1884381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zip64_internal* zi;
18859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int err = 0;
18869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    uLong size_centraldir = 0;
1887381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T centraldir_pos_inzip;
1888381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    ZPOS64_T pos;
1889381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
18909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (file == NULL)
18919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return ZIP_PARAMERROR;
1892381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1893381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    zi = (zip64_internal*)file;
18949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
18959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (zi->in_opened_file_inzip == 1)
18969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
18979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        err = zipCloseFileInZip (file);
18989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
18999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
19009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NO_ADDFILEINEXISTINGZIP
19019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (global_comment==NULL)
19029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        global_comment = zi->globalcomment;
19039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
19049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1905381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
1906381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
19079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (err==ZIP_OK)
19089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1909381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
19109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        while (ldi!=NULL)
19119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
19129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1913381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            {
1914381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
19159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                    err = ZIP_ERRNO;
1916381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes            }
19179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
19189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            size_centraldir += ldi->filled_in_this_block;
19199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            ldi = ldi->next_datablock;
19209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
19219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1922381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    free_linkedlist(&(zi->central_dir));
19239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1924381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
1925ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
1926381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1927381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
1928381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
19299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1930381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
1931381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
19329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1933381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (err==ZIP_OK)
1934381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
19359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1936381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(err == ZIP_OK)
1937381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      err = Write_GlobalComment(zi, global_comment);
19389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1939381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
19409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        if (err == ZIP_OK)
19419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            err = ZIP_ERRNO;
19429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
19439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef NO_ADDFILEINEXISTINGZIP
19449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    TRYFREE(zi->globalcomment);
19459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif
19469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    TRYFREE(zi);
19479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
19489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return err;
19499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1950381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1951381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesextern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
1952381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{
1953381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  char* p = pData;
1954381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int size = 0;
1955381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  char* pNewHeader;
1956381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  char* pTmp;
1957381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  short header;
1958381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  short dataSize;
1959381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1960381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  int retVal = ZIP_OK;
1961381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1962381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if(pData == NULL || *dataLen < 4)
1963381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    return ZIP_PARAMERROR;
1964381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1965381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  pNewHeader = (char*)ALLOC(*dataLen);
1966381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  pTmp = pNewHeader;
1967381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1968381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  while(p < (pData + *dataLen))
1969381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1970381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    header = *(short*)p;
1971381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    dataSize = *(((short*)p)+1);
1972381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1973381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if( header == sHeader ) // Header found.
1974381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1975381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      p += dataSize + 4; // skip it. do not copy to temp buffer
1976381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1977381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    else
1978381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    {
1979381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      // Extra Info block should not be removed, So copy it to the temp buffer.
1980381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      memcpy(pTmp, p, dataSize + 4);
1981381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      p += dataSize + 4;
1982381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      size += dataSize + 4;
1983381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    }
1984381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1985381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
1986381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1987381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  if(size < *dataLen)
1988381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  {
1989381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // clean old extra info block.
1990381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    memset(pData,0, *dataLen);
1991381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1992381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // copy the new extra info block over the old
1993381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    if(size > 0)
1994381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes      memcpy(pData, pNewHeader, size);
1995381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1996381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    // set the new extra info size
1997381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    *dataLen = size;
1998381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
1999381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    retVal = ZIP_OK;
2000381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  }
2001381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  else
2002381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    retVal = ZIP_ERRNO;
2003381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
2004381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  TRYFREE(pNewHeader);
2005381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes
2006381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes  return retVal;
2007381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes}
2008