annotate src/zlib-1.2.7/contrib/minizip/zip.c @ 83:ae30d91d2ffe

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