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(void)
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(linkedlist_datablock_internal *ldi)
179 linkedlist_datablock_internal* ldinext = ldi->next_datablock;
185 local void init_linkedlist(linkedlist_data *ll)
187 ll->first_block = ll->last_block = NULL;
191 local void free_linkedlist(linkedlist_data *ll)
193 free_datablock(ll->first_block);
194 ll->first_block = ll->last_block = NULL;
198 local int add_data_in_datablock(linkedlist_data *ll, const void *buf, uLong len)
200 linkedlist_datablock_internal* ldi;
201 const unsigned char* from_copy;
204 return ZIP_INTERNALERROR;
206 if (ll->last_block == NULL)
208 ll->first_block = ll->last_block = allocate_new_datablock();
209 if (ll->first_block == NULL)
210 return ZIP_INTERNALERROR;
213 ldi = ll->last_block;
214 from_copy = (unsigned char*)buf;
220 unsigned char* to_copy;
222 if (ldi->avail_in_this_block==0)
224 ldi->next_datablock = allocate_new_datablock();
225 if (ldi->next_datablock == NULL)
226 return ZIP_INTERNALERROR;
227 ldi = ldi->next_datablock ;
228 ll->last_block = ldi;
231 if (ldi->avail_in_this_block < len)
232 copy_this = (uInt)ldi->avail_in_this_block;
234 copy_this = (uInt)len;
236 to_copy = &(ldi->data[ldi->filled_in_this_block]);
238 for (i=0;i<copy_this;i++)
239 *(to_copy+i)=*(from_copy+i);
241 ldi->filled_in_this_block += copy_this;
242 ldi->avail_in_this_block -= copy_this;
243 from_copy += copy_this ;
251 /****************************************************************************/
253 #ifndef NO_ADDFILEINEXISTINGZIP
254 /* ===========================================================================
255 Inputs a long in LSB order to the given file
256 nbByte == 1, 2 or 4 (byte, short or long)
259 local int ziplocal_putValue OF((const zlib_filefunc_def* pzlib_filefunc_def,
260 voidpf filestream, uLong x, int nbByte));
261 local int ziplocal_putValue (pzlib_filefunc_def, filestream, x, nbByte)
262 const zlib_filefunc_def* pzlib_filefunc_def;
267 unsigned char buf[4];
269 for (n = 0; n < nbByte; n++)
271 buf[n] = (unsigned char)(x & 0xff);
275 { /* data overflow - hack for ZIP64 (X Roche) */
276 for (n = 0; n < nbByte; n++)
282 if (ZWRITE(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
288 local void ziplocal_putValue_inmemory OF((void* dest, uLong x, int nbByte));
289 local void ziplocal_putValue_inmemory (dest, x, nbByte)
294 unsigned char* buf=(unsigned char*)dest;
296 for (n = 0; n < nbByte; n++) {
297 buf[n] = (unsigned char)(x & 0xff);
302 { /* data overflow - hack for ZIP64 */
303 for (n = 0; n < nbByte; n++)
310 /****************************************************************************/
313 local uLong ziplocal_TmzDateToDosDate(const tm_zip *ptm, uLong dosDate)
315 uLong year = (uLong)ptm->tm_year;
321 (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
322 ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
326 /****************************************************************************/
328 local int ziplocal_getByte OF((
329 const zlib_filefunc_def* pzlib_filefunc_def,
333 local int ziplocal_getByte(pzlib_filefunc_def,filestream,pi)
334 const zlib_filefunc_def* pzlib_filefunc_def;
339 int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
347 if (ZERROR(*pzlib_filefunc_def,filestream))
355 /* ===========================================================================
356 Reads a long in LSB order from the given gz_stream. Sets
358 local int ziplocal_getShort OF((
359 const zlib_filefunc_def* pzlib_filefunc_def,
363 local int ziplocal_getShort (pzlib_filefunc_def,filestream,pX)
364 const zlib_filefunc_def* pzlib_filefunc_def;
372 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
376 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
386 local int ziplocal_getLong OF((
387 const zlib_filefunc_def* pzlib_filefunc_def,
391 local int ziplocal_getLong (pzlib_filefunc_def,filestream,pX)
392 const zlib_filefunc_def* pzlib_filefunc_def;
400 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
404 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
408 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
412 err = ziplocal_getByte(pzlib_filefunc_def,filestream,&i);
422 #ifndef BUFREADCOMMENT
423 #define BUFREADCOMMENT (0x400)
426 Locate the Central directory of a zipfile (at the end, just before
429 local uLong ziplocal_SearchCentralDir OF((
430 const zlib_filefunc_def* pzlib_filefunc_def,
433 local uLong ziplocal_SearchCentralDir(pzlib_filefunc_def,filestream)
434 const zlib_filefunc_def* pzlib_filefunc_def;
440 uLong uMaxBack=0xffff; /* maximum size of global comment */
443 if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
447 uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
449 if (uMaxBack>uSizeFile)
450 uMaxBack = uSizeFile;
452 buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
457 while (uBackRead<uMaxBack)
459 uLong uReadSize,uReadPos ;
461 if (uBackRead+BUFREADCOMMENT>uMaxBack)
462 uBackRead = uMaxBack;
464 uBackRead+=BUFREADCOMMENT;
465 uReadPos = uSizeFile-uBackRead ;
467 uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
468 (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
469 if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
472 if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
475 for (i=(int)uReadSize-3; (i--)>0;)
476 if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
477 ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
479 uPosFound = uReadPos+i;
489 #endif /* !NO_ADDFILEINEXISTINGZIP*/
491 /************************************************************/
492 extern zipFile ZEXPORT zipOpen2 (pathname, append, globalcomment, pzlib_filefunc_def)
493 const char *pathname;
495 zipcharpc* globalcomment;
496 zlib_filefunc_def* pzlib_filefunc_def;
503 if (pzlib_filefunc_def==NULL)
504 fill_fopen_filefunc(&ziinit.z_filefunc);
506 ziinit.z_filefunc = *pzlib_filefunc_def;
508 ziinit.filestream = (*(ziinit.z_filefunc.zopen_file))
509 (ziinit.z_filefunc.opaque,
511 (append == APPEND_STATUS_CREATE) ?
512 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
513 (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
515 if (ziinit.filestream == NULL)
517 ziinit.begin_pos = ZTELL(ziinit.z_filefunc,ziinit.filestream);
518 ziinit.in_opened_file_inzip = 0;
519 ziinit.ci.stream_initialised = 0;
520 ziinit.number_entry = 0;
521 ziinit.add_position_when_writting_offset = 0;
522 init_linkedlist(&(ziinit.central_dir));
525 zi = (zip_internal*)ALLOC(sizeof(zip_internal));
528 ZCLOSE(ziinit.z_filefunc,ziinit.filestream);
532 /* now we add file in a zipfile */
533 # ifndef NO_ADDFILEINEXISTINGZIP
534 ziinit.globalcomment = NULL;
535 if (append == APPEND_STATUS_ADDINZIP)
537 uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
539 uLong size_central_dir; /* size of the central directory */
540 uLong offset_central_dir; /* offset of start of central directory */
541 uLong central_pos,uL;
543 uLong number_disk; /* number of the current dist, used for
544 spaning ZIP, unsupported, always 0*/
545 uLong number_disk_with_CD; /* number the the disk with central dir, used
546 for spaning ZIP, unsupported, always 0*/
548 uLong number_entry_CD; /* total number of entries in
550 (same than number_entry on nospan) */
553 central_pos = ziplocal_SearchCentralDir(&ziinit.z_filefunc,ziinit.filestream);
557 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
558 central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
561 /* the signature, already checked */
562 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&uL)!=ZIP_OK)
565 /* number of this disk */
566 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk)!=ZIP_OK)
569 /* number of the disk with the start of the central directory */
570 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_disk_with_CD)!=ZIP_OK)
573 /* total number of entries in the central dir on this disk */
574 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry)!=ZIP_OK)
577 /* total number of entries in the central dir */
578 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&number_entry_CD)!=ZIP_OK)
581 if ((number_entry_CD!=number_entry) ||
582 (number_disk_with_CD!=0) ||
586 /* size of the central directory */
587 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&size_central_dir)!=ZIP_OK)
590 /* offset of start of central directory with respect to the
591 starting disk number */
592 if (ziplocal_getLong(&ziinit.z_filefunc, ziinit.filestream,&offset_central_dir)!=ZIP_OK)
595 /* zipfile global comment length */
596 if (ziplocal_getShort(&ziinit.z_filefunc, ziinit.filestream,&size_comment)!=ZIP_OK)
599 if ((central_pos<offset_central_dir+size_central_dir) &&
605 ZCLOSE(ziinit.z_filefunc, ziinit.filestream);
611 ziinit.globalcomment = ALLOC(size_comment+1);
612 if (ziinit.globalcomment)
614 size_comment = ZREAD(ziinit.z_filefunc, ziinit.filestream,ziinit.globalcomment,size_comment);
615 ziinit.globalcomment[size_comment]=0;
619 byte_before_the_zipfile = central_pos -
620 (offset_central_dir+size_central_dir);
621 ziinit.add_position_when_writting_offset = byte_before_the_zipfile;
624 uLong size_central_dir_to_read = size_central_dir;
625 size_t buf_size = SIZEDATA_INDATABLOCK;
626 void* buf_read = (void*)ALLOC(buf_size);
627 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
628 offset_central_dir + byte_before_the_zipfile,
629 ZLIB_FILEFUNC_SEEK_SET) != 0)
632 while ((size_central_dir_to_read>0) && (err==ZIP_OK))
634 uLong read_this = SIZEDATA_INDATABLOCK;
635 if (read_this > size_central_dir_to_read)
636 read_this = size_central_dir_to_read;
637 if (ZREAD(ziinit.z_filefunc, ziinit.filestream,buf_read,read_this) != read_this)
641 err = add_data_in_datablock(&ziinit.central_dir,buf_read,
643 size_central_dir_to_read-=read_this;
647 ziinit.begin_pos = byte_before_the_zipfile;
648 ziinit.number_entry = number_entry_CD;
650 if (ZSEEK(ziinit.z_filefunc, ziinit.filestream,
651 offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
657 *globalcomment = ziinit.globalcomment;
659 # endif /* !NO_ADDFILEINEXISTINGZIP*/
663 # ifndef NO_ADDFILEINEXISTINGZIP
664 TRYFREE(ziinit.globalcomment);
665 # endif /* !NO_ADDFILEINEXISTINGZIP*/
676 extern zipFile ZEXPORT zipOpen (pathname, append)
677 const char *pathname;
680 return zipOpen2(pathname,append,NULL,NULL);
683 extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
684 extrafield_local, size_extrafield_local,
685 extrafield_global, size_extrafield_global,
686 comment, method, level, raw,
687 windowBits, memLevel, strategy,
688 password, crcForCrypting)
690 const char* filename;
691 const zip_fileinfo* zipfi;
692 const void* extrafield_local;
693 uInt size_extrafield_local;
694 const void* extrafield_global;
695 uInt size_extrafield_global;
703 const char* password;
704 uLong crcForCrypting;
713 if (password != NULL)
714 return ZIP_PARAMERROR;
718 return ZIP_PARAMERROR;
719 if ((method!=0) && (method!=Z_DEFLATED))
720 return ZIP_PARAMERROR;
722 zi = (zip_internal*)file;
724 if (zi->in_opened_file_inzip == 1)
726 err = zipCloseFileInZip (file);
738 size_comment = (uInt)strlen(comment);
740 size_filename = (uInt)strlen(filename);
746 if (zipfi->dosDate != 0)
747 zi->ci.dosDate = zipfi->dosDate;
748 else zi->ci.dosDate = ziplocal_TmzDateToDosDate(&zipfi->tmz_date,zipfi->dosDate);
752 if ((level==8) || (level==9))
758 if (password != NULL)
762 zi->ci.method = method;
764 zi->ci.stream_initialised = 0;
765 zi->ci.pos_in_buffered_data = 0;
767 zi->ci.pos_local_header = ZTELL(zi->z_filefunc,zi->filestream) ;
768 zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename +
769 size_extrafield_global + size_comment;
770 zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader);
772 ziplocal_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
774 ziplocal_putValue_inmemory(zi->ci.central_header+4,(uLong)VERSIONMADEBY,2);
775 ziplocal_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
776 ziplocal_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
777 ziplocal_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
778 ziplocal_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
779 ziplocal_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
780 ziplocal_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
781 ziplocal_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
782 ziplocal_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
783 ziplocal_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
784 ziplocal_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
785 ziplocal_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
788 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
790 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
793 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
795 ziplocal_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
797 ziplocal_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header- zi->add_position_when_writting_offset,4);
799 for (i=0;i<size_filename;i++)
800 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
802 for (i=0;i<size_extrafield_global;i++)
803 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
804 *(((const char*)extrafield_global)+i);
806 for (i=0;i<size_comment;i++)
807 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
808 size_extrafield_global+i) = *(comment+i);
809 if (zi->ci.central_header == NULL)
810 return ZIP_INTERNALERROR;
812 /* write the local header */
813 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC,4);
816 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
818 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
821 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
824 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
827 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
829 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
831 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
834 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
837 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield_local,2);
839 if ((err==ZIP_OK) && (size_filename>0))
840 if (ZWRITE(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
843 if ((err==ZIP_OK) && (size_extrafield_local>0))
844 if (ZWRITE(zi->z_filefunc,zi->filestream,extrafield_local,size_extrafield_local)
845 !=size_extrafield_local)
848 zi->ci.stream.avail_in = (uInt)0;
849 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
850 zi->ci.stream.next_out = zi->ci.buffered_data;
851 zi->ci.stream.total_in = 0;
852 zi->ci.stream.total_out = 0;
854 if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
856 zi->ci.stream.zalloc = (alloc_func)0;
857 zi->ci.stream.zfree = (free_func)0;
858 zi->ci.stream.opaque = (voidpf)0;
861 windowBits = -windowBits;
863 err = deflateInit2(&zi->ci.stream, level,
864 Z_DEFLATED, windowBits, memLevel, strategy);
867 zi->ci.stream_initialised = 1;
870 zi->ci.crypt_header_size = 0;
871 if ((err==Z_OK) && (password != NULL))
873 unsigned char bufHead[RAND_HEAD_LEN];
874 unsigned int sizeHead;
876 zi->ci.pcrc_32_tab = get_crc_table();
877 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
879 sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
880 zi->ci.crypt_header_size = sizeHead;
882 if (ZWRITE(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
888 zi->in_opened_file_inzip = 1;
892 extern int ZEXPORT zipOpenNewFileInZip2(file, filename, zipfi,
893 extrafield_local, size_extrafield_local,
894 extrafield_global, size_extrafield_global,
895 comment, method, level, raw)
897 const char* filename;
898 const zip_fileinfo* zipfi;
899 const void* extrafield_local;
900 uInt size_extrafield_local;
901 const void* extrafield_global;
902 uInt size_extrafield_global;
908 return zipOpenNewFileInZip3 (file, filename, zipfi,
909 extrafield_local, size_extrafield_local,
910 extrafield_global, size_extrafield_global,
911 comment, method, level, raw,
912 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
916 extern int ZEXPORT zipOpenNewFileInZip (file, filename, zipfi,
917 extrafield_local, size_extrafield_local,
918 extrafield_global, size_extrafield_global,
919 comment, method, level)
921 const char* filename;
922 const zip_fileinfo* zipfi;
923 const void* extrafield_local;
924 uInt size_extrafield_local;
925 const void* extrafield_global;
926 uInt size_extrafield_global;
931 return zipOpenNewFileInZip2 (file, filename, zipfi,
932 extrafield_local, size_extrafield_local,
933 extrafield_global, size_extrafield_global,
934 comment, method, level, 0);
937 local int zipFlushWriteBuffer(zip_internal *zi)
941 if (zi->ci.encrypt != 0)
946 for (i=0;i<zi->ci.pos_in_buffered_data;i++)
947 zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab,
948 zi->ci.buffered_data[i],t);
951 if (ZWRITE(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data)
952 !=zi->ci.pos_in_buffered_data)
954 zi->ci.pos_in_buffered_data = 0;
958 extern int ZEXPORT zipWriteInFileInZip (file, buf, len)
967 return ZIP_PARAMERROR;
968 zi = (zip_internal*)file;
970 if (zi->in_opened_file_inzip == 0)
971 return ZIP_PARAMERROR;
973 zi->ci.stream.next_in = (void*)buf;
974 zi->ci.stream.avail_in = len;
975 zi->ci.crc32 = crc32(zi->ci.crc32,buf,len);
977 while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
979 if (zi->ci.stream.avail_out == 0)
981 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
983 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
984 zi->ci.stream.next_out = zi->ci.buffered_data;
991 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
993 uLong uTotalOutBefore = zi->ci.stream.total_out;
994 err=deflate(&zi->ci.stream, Z_NO_FLUSH);
995 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1001 if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
1002 copy_this = zi->ci.stream.avail_in;
1004 copy_this = zi->ci.stream.avail_out;
1005 for (i=0;i<copy_this;i++)
1006 *(((char*)zi->ci.stream.next_out)+i) =
1007 *(((const char*)zi->ci.stream.next_in)+i);
1009 zi->ci.stream.avail_in -= copy_this;
1010 zi->ci.stream.avail_out-= copy_this;
1011 zi->ci.stream.next_in+= copy_this;
1012 zi->ci.stream.next_out+= copy_this;
1013 zi->ci.stream.total_in+= copy_this;
1014 zi->ci.stream.total_out+= copy_this;
1015 zi->ci.pos_in_buffered_data += copy_this;
1023 extern int ZEXPORT zipCloseFileInZipRaw (file, uncompressed_size, crc32)
1025 uLong uncompressed_size;
1029 uLong compressed_size;
1033 return ZIP_PARAMERROR;
1034 zi = (zip_internal*)file;
1036 if (zi->in_opened_file_inzip == 0)
1037 return ZIP_PARAMERROR;
1038 zi->ci.stream.avail_in = 0;
1040 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1043 uLong uTotalOutBefore;
1044 if (zi->ci.stream.avail_out == 0)
1046 if (zipFlushWriteBuffer(zi) == ZIP_ERRNO)
1048 zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
1049 zi->ci.stream.next_out = zi->ci.buffered_data;
1051 uTotalOutBefore = zi->ci.stream.total_out;
1052 err=deflate(&zi->ci.stream, Z_FINISH);
1053 zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
1056 if (err==Z_STREAM_END)
1057 err=ZIP_OK; /* this is normal */
1059 if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
1060 if (zipFlushWriteBuffer(zi)==ZIP_ERRNO)
1063 if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
1065 err=deflateEnd(&zi->ci.stream);
1066 zi->ci.stream_initialised = 0;
1071 crc32 = (uLong)zi->ci.crc32;
1072 uncompressed_size = (uLong)zi->ci.stream.total_in;
1074 compressed_size = (uLong)zi->ci.stream.total_out;
1076 compressed_size += zi->ci.crypt_header_size;
1079 ziplocal_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
1080 ziplocal_putValue_inmemory(zi->ci.central_header+20,
1081 compressed_size,4); /*compr size*/
1082 if (zi->ci.stream.data_type == Z_ASCII)
1083 ziplocal_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
1084 ziplocal_putValue_inmemory(zi->ci.central_header+24,
1085 uncompressed_size,4); /*uncompr size*/
1088 err = add_data_in_datablock(&zi->central_dir,zi->ci.central_header,
1089 (uLong)zi->ci.size_centralheader);
1090 free(zi->ci.central_header);
1094 long cur_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1095 if (ZSEEK(zi->z_filefunc,zi->filestream,
1096 zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
1100 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
1102 if (err==ZIP_OK) /* compressed size, unknown */
1103 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
1105 if (err==ZIP_OK) /* uncompressed size, unknown */
1106 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
1108 if (ZSEEK(zi->z_filefunc,zi->filestream,
1109 cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
1113 zi->number_entry ++;
1114 zi->in_opened_file_inzip = 0;
1119 extern int ZEXPORT zipCloseFileInZip (file)
1122 return zipCloseFileInZipRaw (file,0,0);
1125 extern int ZEXPORT zipClose (file, global_comment)
1127 const char* global_comment;
1131 uLong size_centraldir = 0;
1132 uLong centraldir_pos_inzip;
1133 uInt size_global_comment;
1135 return ZIP_PARAMERROR;
1136 zi = (zip_internal*)file;
1138 if (zi->in_opened_file_inzip == 1)
1140 err = zipCloseFileInZip (file);
1143 #ifndef NO_ADDFILEINEXISTINGZIP
1144 if (global_comment==NULL)
1145 global_comment = zi->globalcomment;
1147 if (global_comment==NULL)
1148 size_global_comment = 0;
1150 size_global_comment = (uInt)strlen(global_comment);
1152 centraldir_pos_inzip = ZTELL(zi->z_filefunc,zi->filestream);
1155 linkedlist_datablock_internal* ldi = zi->central_dir.first_block ;
1158 if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
1159 if (ZWRITE(zi->z_filefunc,zi->filestream,
1160 ldi->data,ldi->filled_in_this_block)
1161 !=ldi->filled_in_this_block )
1164 size_centraldir += ldi->filled_in_this_block;
1165 ldi = ldi->next_datablock;
1168 free_datablock(zi->central_dir.first_block);
1170 if (err==ZIP_OK) /* Magic End */
1171 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
1173 if (err==ZIP_OK) /* number of this disk */
1174 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1176 if (err==ZIP_OK) /* number of the disk with the start of the central directory */
1177 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
1179 if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
1180 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1182 if (err==ZIP_OK) /* total number of entries in the central dir */
1183 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
1185 if (err==ZIP_OK) /* size of the central directory */
1186 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
1188 if (err==ZIP_OK) /* offset of start of central directory with respect to the
1189 starting disk number */
1190 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,
1191 (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
1193 if (err==ZIP_OK) /* zipfile comment length */
1194 err = ziplocal_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
1196 if ((err==ZIP_OK) && (size_global_comment>0))
1197 if (ZWRITE(zi->z_filefunc,zi->filestream,
1198 global_comment,size_global_comment) != size_global_comment)
1201 if (ZCLOSE(zi->z_filefunc,zi->filestream) != 0)
1205 #ifndef NO_ADDFILEINEXISTINGZIP
1206 TRYFREE(zi->globalcomment);