1
/* zip.c -- IO on .zip files using zlib
2
Version 1.01e, February 12th, 2005
4
27 Dec 2004 Rolf Kalbermatter
5
Modification to zipOpen2 to support globalComment retrieval.
7
Copyright (C) 1998-2005 Gilles Vollant
9
Read zip.h for more info
35
/* compile with -Dlocal if your debugger can't find static symbols */
38
# define VERSIONMADEBY (0x0) /* platform depedent */
42
#define Z_BUFSIZE (16384)
45
#ifndef Z_MAXFILENAMEINZIP
46
#define Z_MAXFILENAMEINZIP (256)
50
# define ALLOC(size) (malloc(size))
53
# define TRYFREE(p) {if (p) free(p);}
57
#define SIZECENTRALDIRITEM (0x2e)
58
#define SIZEZIPLOCALHEADER (0x1e)
61
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
76
#if MAX_MEM_LEVEL >= 8
77
# define DEF_MEM_LEVEL 8
79
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
82
const char zip_copyright[] =
83
" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
86
#define SIZEDATA_INDATABLOCK (4096-(4*4))
88
#define LOCALHEADERMAGIC (0x04034b50)
89
#define CENTRALHEADERMAGIC (0x02014b50)
90
#define ENDHEADERMAGIC (0x06054b50)
92
#define FLAG_LOCALHEADER_OFFSET (0x06)
93
#define CRC_LOCALHEADER_OFFSET (0x0e)
95
#define SIZECENTRALHEADER (0x2e) /* 46 */
97
typedef struct linkedlist_datablock_internal_s
99
struct linkedlist_datablock_internal_s* next_datablock;
100
uLong avail_in_this_block;
101
uLong filled_in_this_block;
102
uLong unused; /* for future use and alignement */
103
unsigned char data[SIZEDATA_INDATABLOCK];
104
} linkedlist_datablock_internal;
106
typedef struct linkedlist_data_s
108
linkedlist_datablock_internal* first_block;
109
linkedlist_datablock_internal* last_block;
115
z_stream stream; /* zLib stream structure for inflate */
116
int stream_initialised; /* 1 is stream is initialised */
117
uInt pos_in_buffered_data; /* last written byte in buffered_data */
119
uLong pos_local_header; /* offset of the local header of the file
121
char* central_header; /* central header data for the current file */
122
uLong size_centralheader; /* size of the central header for cur file */
123
uLong flag; /* flag of the file currently writing */
125
int method; /* compression method of file currenty wr.*/
126
int raw; /* 1 for directly writing raw data */
127
Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
132
unsigned long keys[3]; /* keys defining the pseudo-random sequence */
133
const unsigned long* pcrc_32_tab;
134
int crypt_header_size;
140
zlib_filefunc_def z_filefunc;
141
voidpf filestream; /* io structore of the zipfile */
142
linkedlist_data central_dir;/* datablock with central dir in construction*/
143
int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/
144
curfile_info ci; /* info on the file curretly writing */
146
uLong begin_pos; /* position of the beginning of the zipfile */
147
uLong add_position_when_writting_offset;
149
#ifndef NO_ADDFILEINEXISTINGZIP
157
#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
161
local linkedlist_datablock_internal* allocate_new_datablock()
163
linkedlist_datablock_internal* ldi;
164
ldi = (linkedlist_datablock_internal*)
165
ALLOC(sizeof(linkedlist_datablock_internal));
168
ldi->next_datablock = NULL ;
169
ldi->filled_in_this_block = 0 ;
170
ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
175
local void free_datablock(ldi)
176
linkedlist_datablock_internal* ldi;
180
linkedlist_datablock_internal* ldinext = ldi->next_datablock;
186
local void init_linkedlist(ll)
189
ll->first_block = ll->last_block = NULL;
193
local void free_linkedlist(ll)
196
free_datablock(ll->first_block);
197
ll->first_block = ll->last_block = NULL;
201
local int add_data_in_datablock(ll,buf,len)
206
linkedlist_datablock_internal* ldi;
207
const unsigned char* from_copy;
210
return ZIP_INTERNALERROR;
212
if (ll->last_block == NULL)
214
ll->first_block = ll->last_block = allocate_new_datablock();
215
if (ll->first_block == NULL)
216
return ZIP_INTERNALERROR;
219
ldi = ll->last_block;
220
from_copy = (unsigned char*)buf;
226
unsigned char* to_copy;
228
if (ldi->avail_in_this_block==0)
230
ldi->next_datablock = allocate_new_datablock();
231
if (ldi->next_datablock == NULL)
232
return ZIP_INTERNALERROR;
233
ldi = ldi->next_datablock ;
234
ll->last_block = ldi;
237
if (ldi->avail_in_this_block < len)
238
copy_this = (uInt)ldi->avail_in_this_block;
240
copy_this = (uInt)len;
242
to_copy = &(ldi->data[ldi->filled_in_this_block]);
244
for (i=0;i<copy_this;i++)
245
*(to_copy+i)=*(from_copy+i);
247
ldi->filled_in_this_block += copy_this;
248
ldi->avail_in_this_block -= copy_this;
249
from_copy += copy_this ;
257
/****************************************************************************/
259
#ifndef NO_ADDFILEINEXISTINGZIP
260
/* ===========================================================================
261
Inputs a long in LSB order to the given file
262
nbByte == 1, 2 or 4 (byte, short or long)
265
local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
266
voidpf filestream, uLong x, int nbByte));
267
local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
268
const zlib_filefunc_def* pzlib_filefunc_def;
273
unsigned char buf[4];
275
for (n = 0; n < nbByte; n++)
277
buf[n] = (unsigned char)(x & 0xff);
281
{ /* data overflow - hack for ZIP64 (X Roche) */
282
for (n = 0; n < nbByte; n++)
288
if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
294
local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
295
local void ziplocal_putValue_inmemory (dest, x, nbByte)
300
unsigned char* buf=(unsigned char*)dest;
302
for (n = 0; n < nbByte; n++) {
303
buf[n] = (unsigned char)(x & 0xff);
308
{ /* data overflow - hack for ZIP64 */
309
for (n = 0; n < nbByte; n++)
316
/****************************************************************************/
319
local uLong ziplocal_TmzDateToDosDate(ptm,dosDate)
323
(void) dosDate; /* avoid "unused parameter" warning */
324
uLong year = (uLong)ptm->tm_year;
330
(uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
331
((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
335
/****************************************************************************/
337
local int ziplocal_getByte OF((
338
const zlib_filefunc_def* pzlib_filefunc_def,
342
local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
343
const zlib_filefunc_def* pzlib_filefunc_def;
348
int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
356
if (ZERROR(*pzlib_filefunc_def,filestream))
364
/* ===========================================================================
365
Reads a long in LSB order from the given gz_stream. Sets
367
local int ziplocal_getShort OF((
368
const zlib_filefunc_def* pzlib_filefunc_def,
372
local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
373
const zlib_filefunc_def* pzlib_filefunc_def;
381
err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
385
err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
395
local int ziplocal_getLong OF((
396
const zlib_filefunc_def* pzlib_filefunc_def,
400
local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
401
const zlib_filefunc_def* pzlib_filefunc_def;
409
err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
413
err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
417
err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
421
err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
431
#ifndef BUFREADCOMMENT
432
#define BUFREADCOMMENT (0x400)
435
Locate the Central directory of a zipfile (at the end, just before
438
local uLong ziplocal_SearchCentralDir OF((
439
const zlib_filefunc_def* pzlib_filefunc_def,
442
local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
443
const zlib_filefunc_def* pzlib_filefunc_def;
449
uLong uMaxBack=0xffff; /* maximum size of global comment */
452
if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
456
uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
458
if (uMaxBack>uSizeFile)
459
uMaxBack = uSizeFile;
461
buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
466
while (uBackRead<uMaxBack)
468
uLong uReadSize,uReadPos ;
470
if (uBackRead+BUFREADCOMMENT>uMaxBack)
471
uBackRead = uMaxBack;
473
uBackRead+=BUFREADCOMMENT;
474
uReadPos = uSizeFile-uBackRead ;
476
uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
477
(BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
478
if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
481
if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
484
for (i=(int)uReadSize-3; (i--)>0;)
485
if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
486
((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
488
uPosFound = uReadPos+i;
498
#endif /* !NO_ADDFILEINEXISTINGZIP*/
500
/************************************************************/
501
extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
502
const char *pathname;
504
zipcharpc* globalcomment;
505
zlib_filefunc_def* pzlib_filefunc_def;
512
if (pzlib_filefunc_def==NULL)
513
fill_fopen_filefunc(&ziinit.z_filefunc);
515
ziinit.z_filefunc = *pzlib_filefunc_def;
517
ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
518
(ziinit.z_filefunc.opaque,
520
(append == APPEND_STATUS_CREATE) ?
521
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
522
(ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
524
if (ziinit.filestream == NULL)
526
ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
527
ziinit.in_opened_file_inzip = 0;
528
ziinit.ci.stream_initialised = 0;
529
ziinit.number_entry = 0;
530
ziinit.add_position_when_writting_offset = 0;
531
init_linkedlist(&(ziinit.central_dir));
534
zi = (zip_internal*)ALLOC(sizeof(zip_internal));
537
ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
541
/* now we add file in a zipfile */
542
# ifndef NO_ADDFILEINEXISTINGZIP
543
ziinit.globalcomment = NULL;
544
if (append == APPEND_STATUS_ADDINZIP)
546
uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
548
uLong size_central_dir; /* size of the central directory */
549
uLong offset_central_dir; /* offset of start of central directory */
550
uLong central_pos,uL;
552
uLong number_disk; /* number of the current dist, used for
553
spaning ZIP, unsupported, always 0*/
554
uLong number_disk_with_CD; /* number the the disk with central dir, used
555
for spaning ZIP, unsupported, always 0*/
557
uLong number_entry_CD; /* total number of entries in
559
(same than number_entry on nospan) */
562
central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
566
if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
567
central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
570
/* the signature, already checked */
571
if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
574
/* number of this disk */
575
if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
578
/* number of the disk with the start of the central directory */
579
if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
582
/* total number of entries in the central dir on this disk */
583
if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
586
/* total number of entries in the central dir */
587
if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
590
if ((number_entry_CD!=number_entry) ||
591
(number_disk_with_CD!=0) ||
595
/* size of the central directory */
596
if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
599
/* offset of start of central directory with respect to the
600
starting disk number */
601
if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
604
/* zipfile global comment length */
605
if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
608
if ((central_pos<offset_central_dir+size_central_dir) &&
614
ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
620
ziinit.globalcomment = ALLOC(size_comment+1);
621
if (ziinit.globalcomment)
623
size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
624
ziinit.globalcomment[size_comment]=0;
628
byte_before_the_zipfile = central_pos -
629
(offset_central_dir+size_central_dir);
630
ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
633
uLong size_central_dir_to_read = size_central_dir;
634
size_t buf_size = SIZEDATA_INDATABLOCK;
635
void* buf_read = (void*)ALLOC(buf_size);
636
if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
637
offset_central_dir + byte_before_the_zipfile,
638
ZLIB_FILEFUNC_SEEK_SET) != 0)
641
while ((size_central_dir_to_read>0) && (err==ZIP_OK))
643
uLong read_this = SIZEDATA_INDATABLOCK;
644
if (read_this > size_central_dir_to_read)
645
read_this = size_central_dir_to_read;
646
if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
650
err = add_data_in_datablock(&ziinit.central_dir,buf_read,
652
size_central_dir_to_read-=read_this;
656
ziinit.begin_pos = byte_before_the_zipfile;
657
ziinit.number_entry = number_entry_CD;
659
if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
660
offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
666
*globalcomment = ziinit.globalcomment;
668
# endif /* !NO_ADDFILEINEXISTINGZIP*/
672
# ifndef NO_ADDFILEINEXISTINGZIP
673
TRYFREE(ziinit.globalcomment);
674
# endif /* !NO_ADDFILEINEXISTINGZIP*/
685
extern zipFile ZEXPORT zipOpen (pathname, append)
686
const char *pathname;
689
return zipOpen2(pathname,append,NULL,NULL);
692
extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
693
extrafield_local, size_extrafield_local,
694
extrafield_global, size_extrafield_global,
695
comment, method, level, raw,
696
windowBits, memLevel, strategy,
697
password, crcForCrypting)
699
const char* filename;
700
const zip_fileinfo* zipfi;
701
const void* extrafield_local;
702
uInt size_extrafield_local;
703
const void* extrafield_global;
704
uInt size_extrafield_global;
712
const char* password;
713
uLong crcForCrypting;
722
if (password != NULL)
723
return ZIP_PARAMERROR;
727
return ZIP_PARAMERROR;
728
if ((method!=0) && (method!=Z_DEFLATED))
729
return ZIP_PARAMERROR;
731
zi = (zip_internal*)file;
733
if (zi->in_opened_file_inzip == 1)
735
err = zipCloseFileInZip (file);
747
size_comment = (uInt)strlen(comment);
749
size_filename = (uInt)strlen(filename);
755
if (zipfi->dosDate != 0)
756
zi->ci.dosDate = zipfi->dosDate;
757
else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
761
if ((level==8) || (level==9))
767
if (password != NULL)
771
zi->ci.method = method;
773
zi->ci.stream_initialised = 0;
774
zi->ci.pos_in_buffered_data = 0;
776
zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
777
zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
778
size_extrafield_global + size_comment;
779
zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
781
ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
783
ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
784
ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
785
ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
786
ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
787
ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
788
ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
789
ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
790
ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
791
ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
792
ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
793
ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
794
ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
797
ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
799
ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
802
ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
804
ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
806
ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
808
for (i=0;i<size_filename;i++)
809
*(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
811
for (i=0;i<size_extrafield_global;i++)
812
*(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
813
*(((const char*)extrafield_global)+i);
815
for (i=0;i<size_comment;i++)
816
*(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
817
size_extrafield_global+i) = *(comment+i);
818
if (zi->ci.central_header == NULL)
819
return ZIP_INTERNALERROR;
821
/* write the local header */
822
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
825
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
827
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
830
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
833
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
836
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
838
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
840
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
843
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
846
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
848
if ((err==ZIP_OK) && (size_filename>0))
849
if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
852
if ((err==ZIP_OK) && (size_extrafield_local>0))
853
if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
854
!=size_extrafield_local)
857
zi->ci.stream.avail_in = (uInt)0;
858
zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
859
zi->ci.stream.next_out = zi->ci.buffered_data;
860
zi->ci.stream.total_in = 0;
861
zi->ci.stream.total_out = 0;
863
if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
865
zi->ci.stream.zalloc = (alloc_func)0;
866
zi->ci.stream.zfree = (free_func)0;
867
zi->ci.stream.opaque = (voidpf)0;
870
windowBits = -windowBits;
872
err = deflateInit2(&zi->ci.stream, level,
873
Z_DEFLATED, windowBits, memLevel, strategy);
876
zi->ci.stream_initialised = 1;
879
zi->ci.crypt_header_size = 0;
880
if ((err==Z_OK) && (password != NULL))
882
unsigned char bufHead[RAND_HEAD_LEN];
883
unsigned int sizeHead;
885
zi->ci.pcrc_32_tab = get_crc_table();
886
/*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
888
sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
889
zi->ci.crypt_header_size = sizeHead;
891
if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
897
zi->in_opened_file_inzip = 1;
901
extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
902
extrafield_local, size_extrafield_local,
903
extrafield_global, size_extrafield_global,
904
comment, method, level, raw)
906
const char* filename;
907
const zip_fileinfo* zipfi;
908
const void* extrafield_local;
909
uInt size_extrafield_local;
910
const void* extrafield_global;
911
uInt size_extrafield_global;
917
return zipOpenNewFileInZip3 (file, filename, zipfi,
918
extrafield_local, size_extrafield_local,
919
extrafield_global, size_extrafield_global,
920
comment, method, level, raw,
921
-MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
925
extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
926
extrafield_local, size_extrafield_local,
927
extrafield_global, size_extrafield_global,
928
comment, method, level)
930
const char* filename;
931
const zip_fileinfo* zipfi;
932
const void* extrafield_local;
933
uInt size_extrafield_local;
934
const void* extrafield_global;
935
uInt size_extrafield_global;
940
return zipOpenNewFileInZip2 (file, filename, zipfi,
941
extrafield_local, size_extrafield_local,
942
extrafield_global, size_extrafield_global,
943
comment, method, level, 0);
946
local int zipFlushWriteBuffer(zi)
951
if (zi->ci.encrypt != 0)
956
for (i=0;i<zi->ci.pos_in_buffered_data;i++)
957
zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
958
zi->ci.buffered_data[i],t);
961
if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
962
!=zi->ci.pos_in_buffered_data)
964
zi->ci.pos_in_buffered_data = 0;
968
extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
977
return ZIP_PARAMERROR;
978
zi = (zip_internal*)file;
980
if (zi->in_opened_file_inzip == 0)
981
return ZIP_PARAMERROR;
983
zi->ci.stream.next_in = (void*)buf;
984
zi->ci.stream.avail_in = len;
985
zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
987
while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
989
if (zi->ci.stream.avail_out == 0)
991
if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
993
zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
994
zi->ci.stream.next_out = zi->ci.buffered_data;
1001
if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1003
uLong uTotalOutBefore = zi->ci.stream.total_out;
1004
err=deflate(&zi->ci.stream, Z_NO_FLUSH);
1005
zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1011
if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1012
copy_this = zi->ci.stream.avail_in;
1014
copy_this = zi->ci.stream.avail_out;
1015
for (i=0;i<copy_this;i++)
1016
*(((char*)zi->ci.stream.next_out)+i) =
1017
*(((const char*)zi->ci.stream.next_in)+i);
1019
zi->ci.stream.avail_in -= copy_this;
1020
zi->ci.stream.avail_out-= copy_this;
1021
zi->ci.stream.next_in+= copy_this;
1022
zi->ci.stream.next_out+= copy_this;
1023
zi->ci.stream.total_in+= copy_this;
1024
zi->ci.stream.total_out+= copy_this;
1025
zi->ci.pos_in_buffered_data += copy_this;
1033
extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
1035
uLong uncompressed_size;
1039
uLong compressed_size;
1043
return ZIP_PARAMERROR;
1044
zi = (zip_internal*)file;
1046
if (zi->in_opened_file_inzip == 0)
1047
return ZIP_PARAMERROR;
1048
zi->ci.stream.avail_in = 0;
1050
if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1053
uLong uTotalOutBefore;
1054
if (zi->ci.stream.avail_out == 0)
1056
if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
1058
zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1059
zi->ci.stream.next_out = zi->ci.buffered_data;
1061
uTotalOutBefore = zi->ci.stream.total_out;
1062
err=deflate(&zi->ci.stream, Z_FINISH);
1063
zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1066
if (err==Z_STREAM_END)
1067
err=ZIP_OK; /* this is normal */
1069
if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1070
if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
1073
if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1075
err=deflateEnd(&zi->ci.stream);
1076
zi->ci.stream_initialised = 0;
1081
crc32 = (uLong)zi->ci.crc32;
1082
uncompressed_size = (uLong)zi->ci.stream.total_in;
1084
compressed_size = (uLong)zi->ci.stream.total_out;
1086
compressed_size += zi->ci.crypt_header_size;
1089
ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1090
ziplocal_putValue_inmemory(zi->ci.central_header+20,
1091
compressed_size,4); /*compr size*/
1092
if (zi->ci.stream.data_type == Z_ASCII)
1093
ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1094
ziplocal_putValue_inmemory(zi->ci.central_header+24,
1095
uncompressed_size,4); /*uncompr size*/
1098
err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
1099
(uLong)zi->ci.size_centralheader);
1100
free(zi->ci.central_header);
1104
long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1105
if (ZSEEK(zi->z_filefunc,zi->filestream,
1106
zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1110
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1112
if (err==ZIP_OK) /* compressed size, unknown */
1113
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1115
if (err==ZIP_OK) /* uncompressed size, unknown */
1116
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1118
if (ZSEEK(zi->z_filefunc,zi->filestream,
1119
cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1123
zi->number_entry ++;
1124
zi->in_opened_file_inzip = 0;
1129
extern int ZEXPORT zipCloseFileInZip (file)
1132
return zipCloseFileInZipRaw (file,0,0);
1135
extern int ZEXPORT zipClose (file, global_comment)
1137
const char* global_comment;
1141
uLong size_centraldir = 0;
1142
uLong centraldir_pos_inzip;
1143
uInt size_global_comment;
1145
return ZIP_PARAMERROR;
1146
zi = (zip_internal*)file;
1148
if (zi->in_opened_file_inzip == 1)
1150
err = zipCloseFileInZip (file);
1153
#ifndef NO_ADDFILEINEXISTINGZIP
1154
if (global_comment==NULL)
1155
global_comment = zi->globalcomment;
1157
if (global_comment==NULL)
1158
size_global_comment = 0;
1160
size_global_comment = (uInt)strlen(global_comment);
1162
centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1165
linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
1168
if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1169
if (ZWRITE(zi->z_filefunc,zi->filestream,
1170
ldi->data,ldi->filled_in_this_block)
1171
!=ldi->filled_in_this_block )
1174
size_centraldir += ldi->filled_in_this_block;
1175
ldi = ldi->next_datablock;
1178
free_datablock(zi->central_dir.first_block);
1180
if (err==ZIP_OK) /* Magic End */
1181
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1183
if (err==ZIP_OK) /* number of this disk */
1184
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1186
if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1187
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1189
if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1190
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1192
if (err==ZIP_OK) /* total number of entries in the central dir */
1193
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1195
if (err==ZIP_OK) /* size of the central directory */
1196
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1198
if (err==ZIP_OK) /* offset of start of central directory with respect to the
1199
starting disk number */
1200
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
1201
(uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1203
if (err==ZIP_OK) /* zipfile comment length */
1204
err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1206
if ((err==ZIP_OK) && (size_global_comment>0))
1207
if (ZWRITE(zi->z_filefunc,zi->filestream,
1208
global_comment,size_global_comment) != size_global_comment)
1211
if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
1215
#ifndef NO_ADDFILEINEXISTINGZIP
1216
TRYFREE(zi->globalcomment);