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
;
192 local
void free_linkedlist(ll
)
195 free_datablock(ll
->first_block
);
196 ll
->first_block
= ll
->last_block
= NULL
;
200 local
int add_data_in_datablock(ll
,buf
,len
)
205 linkedlist_datablock_internal
* ldi
;
206 const unsigned char* from_copy
;
209 return ZIP_INTERNALERROR
;
211 if (ll
->last_block
== NULL
)
213 ll
->first_block
= ll
->last_block
= allocate_new_datablock();
214 if (ll
->first_block
== NULL
)
215 return ZIP_INTERNALERROR
;
218 ldi
= ll
->last_block
;
219 from_copy
= (unsigned char*)buf
;
225 unsigned char* to_copy
;
227 if (ldi
->avail_in_this_block
==0)
229 ldi
->next_datablock
= allocate_new_datablock();
230 if (ldi
->next_datablock
== NULL
)
231 return ZIP_INTERNALERROR
;
232 ldi
= ldi
->next_datablock
;
233 ll
->last_block
= ldi
;
236 if (ldi
->avail_in_this_block
< len
)
237 copy_this
= (uInt
)ldi
->avail_in_this_block
;
239 copy_this
= (uInt
)len
;
241 to_copy
= &(ldi
->data
[ldi
->filled_in_this_block
]);
243 for (i
=0;i
<copy_this
;i
++)
244 *(to_copy
+i
)=*(from_copy
+i
);
246 ldi
->filled_in_this_block
+= copy_this
;
247 ldi
->avail_in_this_block
-= copy_this
;
248 from_copy
+= copy_this
;
256 /****************************************************************************/
258 #ifndef NO_ADDFILEINEXISTINGZIP
259 /* ===========================================================================
260 Inputs a long in LSB order to the given file
261 nbByte == 1, 2 or 4 (byte, short or long)
264 local
int ziplocal_putValue
OF((const zlib_filefunc_def
* pzlib_filefunc_def
,
265 voidpf filestream
, uLong x
, int nbByte
));
266 local
int ziplocal_putValue (pzlib_filefunc_def
, filestream
, x
, nbByte
)
267 const zlib_filefunc_def
* pzlib_filefunc_def
;
272 unsigned char buf
[4];
274 for (n
= 0; n
< nbByte
; n
++)
276 buf
[n
] = (unsigned char)(x
& 0xff);
280 { /* data overflow - hack for ZIP64 (X Roche) */
281 for (n
= 0; n
< nbByte
; n
++)
287 if (ZWRITE(*pzlib_filefunc_def
,filestream
,buf
,nbByte
)!=(uLong
)nbByte
)
293 local
void ziplocal_putValue_inmemory
OF((void* dest
, uLong x
, int nbByte
));
294 local
void ziplocal_putValue_inmemory (dest
, x
, nbByte
)
299 unsigned char* buf
=(unsigned char*)dest
;
301 for (n
= 0; n
< nbByte
; n
++) {
302 buf
[n
] = (unsigned char)(x
& 0xff);
307 { /* data overflow - hack for ZIP64 */
308 for (n
= 0; n
< nbByte
; n
++)
315 /****************************************************************************/
318 local uLong
ziplocal_TmzDateToDosDate(ptm
,dosDate
)
322 uLong year
= (uLong
)ptm
->tm_year
;
328 (uLong
) (((ptm
->tm_mday
) + (32 * (ptm
->tm_mon
+1)) + (512 * year
)) << 16) |
329 ((ptm
->tm_sec
/2) + (32* ptm
->tm_min
) + (2048 * (uLong
)ptm
->tm_hour
));
333 /****************************************************************************/
335 local
int ziplocal_getByte
OF((
336 const zlib_filefunc_def
* pzlib_filefunc_def
,
340 local
int ziplocal_getByte(pzlib_filefunc_def
,filestream
,pi
)
341 const zlib_filefunc_def
* pzlib_filefunc_def
;
346 int err
= (int)ZREAD(*pzlib_filefunc_def
,filestream
,&c
,1);
354 if (ZERROR(*pzlib_filefunc_def
,filestream
))
362 /* ===========================================================================
363 Reads a long in LSB order from the given gz_stream. Sets
365 local
int ziplocal_getShort
OF((
366 const zlib_filefunc_def
* pzlib_filefunc_def
,
370 local
int ziplocal_getShort (pzlib_filefunc_def
,filestream
,pX
)
371 const zlib_filefunc_def
* pzlib_filefunc_def
;
379 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
383 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
393 local
int ziplocal_getLong
OF((
394 const zlib_filefunc_def
* pzlib_filefunc_def
,
398 local
int ziplocal_getLong (pzlib_filefunc_def
,filestream
,pX
)
399 const zlib_filefunc_def
* pzlib_filefunc_def
;
407 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
411 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
415 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
419 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
429 #ifndef BUFREADCOMMENT
430 #define BUFREADCOMMENT (0x400)
433 Locate the Central directory of a zipfile (at the end, just before
436 local uLong ziplocal_SearchCentralDir
OF((
437 const zlib_filefunc_def
* pzlib_filefunc_def
,
440 local uLong
ziplocal_SearchCentralDir(pzlib_filefunc_def
,filestream
)
441 const zlib_filefunc_def
* pzlib_filefunc_def
;
447 uLong uMaxBack
=0xffff; /* maximum size of global comment */
450 if (ZSEEK(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
454 uSizeFile
= ZTELL(*pzlib_filefunc_def
,filestream
);
456 if (uMaxBack
>uSizeFile
)
457 uMaxBack
= uSizeFile
;
459 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
464 while (uBackRead
<uMaxBack
)
466 uLong uReadSize
,uReadPos
;
468 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
469 uBackRead
= uMaxBack
;
471 uBackRead
+=BUFREADCOMMENT
;
472 uReadPos
= uSizeFile
-uBackRead
;
474 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
475 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
476 if (ZSEEK(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
479 if (ZREAD(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
482 for (i
=(int)uReadSize
-3; (i
--)>0;)
483 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
484 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
486 uPosFound
= uReadPos
+i
;
496 #endif /* !NO_ADDFILEINEXISTINGZIP*/
498 /************************************************************/
499 extern zipFile ZEXPORT
zipOpen2 (pathname
, append
, globalcomment
, pzlib_filefunc_def
)
500 const char *pathname
;
502 zipcharpc
* globalcomment
;
503 zlib_filefunc_def
* pzlib_filefunc_def
;
510 if (pzlib_filefunc_def
==NULL
)
511 fill_fopen_filefunc(&ziinit
.z_filefunc
);
513 ziinit
.z_filefunc
= *pzlib_filefunc_def
;
515 ziinit
.filestream
= (*(ziinit
.z_filefunc
.zopen_file
))
516 (ziinit
.z_filefunc
.opaque
,
518 (append
== APPEND_STATUS_CREATE
) ?
519 (ZLIB_FILEFUNC_MODE_READ
| ZLIB_FILEFUNC_MODE_WRITE
| ZLIB_FILEFUNC_MODE_CREATE
) :
520 (ZLIB_FILEFUNC_MODE_READ
| ZLIB_FILEFUNC_MODE_WRITE
| ZLIB_FILEFUNC_MODE_EXISTING
));
522 if (ziinit
.filestream
== NULL
)
524 ziinit
.begin_pos
= ZTELL(ziinit
.z_filefunc
,ziinit
.filestream
);
525 ziinit
.in_opened_file_inzip
= 0;
526 ziinit
.ci
.stream_initialised
= 0;
527 ziinit
.number_entry
= 0;
528 ziinit
.add_position_when_writting_offset
= 0;
529 init_linkedlist(&(ziinit
.central_dir
));
532 zi
= (zip_internal
*)ALLOC(sizeof(zip_internal
));
535 ZCLOSE(ziinit
.z_filefunc
,ziinit
.filestream
);
539 /* now we add file in a zipfile */
540 # ifndef NO_ADDFILEINEXISTINGZIP
541 ziinit
.globalcomment
= NULL
;
542 if (append
== APPEND_STATUS_ADDINZIP
)
544 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
546 uLong size_central_dir
; /* size of the central directory */
547 uLong offset_central_dir
; /* offset of start of central directory */
548 uLong central_pos
,uL
;
550 uLong number_disk
; /* number of the current dist, used for
551 spaning ZIP, unsupported, always 0*/
552 uLong number_disk_with_CD
; /* number the the disk with central dir, used
553 for spaning ZIP, unsupported, always 0*/
555 uLong number_entry_CD
; /* total number of entries in
557 (same than number_entry on nospan) */
560 central_pos
= ziplocal_SearchCentralDir(&ziinit
.z_filefunc
,ziinit
.filestream
);
564 if (ZSEEK(ziinit
.z_filefunc
, ziinit
.filestream
,
565 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
568 /* the signature, already checked */
569 if (ziplocal_getLong(&ziinit
.z_filefunc
, ziinit
.filestream
,&uL
)!=ZIP_OK
)
572 /* number of this disk */
573 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_disk
)!=ZIP_OK
)
576 /* number of the disk with the start of the central directory */
577 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_disk_with_CD
)!=ZIP_OK
)
580 /* total number of entries in the central dir on this disk */
581 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_entry
)!=ZIP_OK
)
584 /* total number of entries in the central dir */
585 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_entry_CD
)!=ZIP_OK
)
588 if ((number_entry_CD
!=number_entry
) ||
589 (number_disk_with_CD
!=0) ||
593 /* size of the central directory */
594 if (ziplocal_getLong(&ziinit
.z_filefunc
, ziinit
.filestream
,&size_central_dir
)!=ZIP_OK
)
597 /* offset of start of central directory with respect to the
598 starting disk number */
599 if (ziplocal_getLong(&ziinit
.z_filefunc
, ziinit
.filestream
,&offset_central_dir
)!=ZIP_OK
)
602 /* zipfile global comment length */
603 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&size_comment
)!=ZIP_OK
)
606 if ((central_pos
<offset_central_dir
+size_central_dir
) &&
612 ZCLOSE(ziinit
.z_filefunc
, ziinit
.filestream
);
618 ziinit
.globalcomment
= ALLOC(size_comment
+1);
619 if (ziinit
.globalcomment
)
621 size_comment
= ZREAD(ziinit
.z_filefunc
, ziinit
.filestream
,ziinit
.globalcomment
,size_comment
);
622 ziinit
.globalcomment
[size_comment
]=0;
626 byte_before_the_zipfile
= central_pos
-
627 (offset_central_dir
+size_central_dir
);
628 ziinit
.add_position_when_writting_offset
= byte_before_the_zipfile
;
631 uLong size_central_dir_to_read
= size_central_dir
;
632 size_t buf_size
= SIZEDATA_INDATABLOCK
;
633 void* buf_read
= (void*)ALLOC(buf_size
);
634 if (ZSEEK(ziinit
.z_filefunc
, ziinit
.filestream
,
635 offset_central_dir
+ byte_before_the_zipfile
,
636 ZLIB_FILEFUNC_SEEK_SET
) != 0)
639 while ((size_central_dir_to_read
>0) && (err
==ZIP_OK
))
641 uLong read_this
= SIZEDATA_INDATABLOCK
;
642 if (read_this
> size_central_dir_to_read
)
643 read_this
= size_central_dir_to_read
;
644 if (ZREAD(ziinit
.z_filefunc
, ziinit
.filestream
,buf_read
,read_this
) != read_this
)
648 err
= add_data_in_datablock(&ziinit
.central_dir
,buf_read
,
650 size_central_dir_to_read
-=read_this
;
654 ziinit
.begin_pos
= byte_before_the_zipfile
;
655 ziinit
.number_entry
= number_entry_CD
;
657 if (ZSEEK(ziinit
.z_filefunc
, ziinit
.filestream
,
658 offset_central_dir
+byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
664 *globalcomment
= ziinit
.globalcomment
;
666 # endif /* !NO_ADDFILEINEXISTINGZIP*/
670 # ifndef NO_ADDFILEINEXISTINGZIP
671 TRYFREE(ziinit
.globalcomment
);
672 # endif /* !NO_ADDFILEINEXISTINGZIP*/
683 extern zipFile ZEXPORT
zipOpen (pathname
, append
)
684 const char *pathname
;
687 return zipOpen2(pathname
,append
,NULL
,NULL
);
690 extern int ZEXPORT
zipOpenNewFileInZip3 (file
, filename
, zipfi
,
691 extrafield_local
, size_extrafield_local
,
692 extrafield_global
, size_extrafield_global
,
693 comment
, method
, level
, raw
,
694 windowBits
, memLevel
, strategy
,
695 password
, crcForCrypting
)
697 const char* filename
;
698 const zip_fileinfo
* zipfi
;
699 const void* extrafield_local
;
700 uInt size_extrafield_local
;
701 const void* extrafield_global
;
702 uInt size_extrafield_global
;
710 const char* password
;
711 uLong crcForCrypting
;
720 if (password
!= NULL
)
721 return ZIP_PARAMERROR
;
725 return ZIP_PARAMERROR
;
726 if ((method
!=0) && (method
!=Z_DEFLATED
))
727 return ZIP_PARAMERROR
;
729 zi
= (zip_internal
*)file
;
731 if (zi
->in_opened_file_inzip
== 1)
733 err
= zipCloseFileInZip (file
);
745 size_comment
= (uInt
)strlen(comment
);
747 size_filename
= (uInt
)strlen(filename
);
753 if (zipfi
->dosDate
!= 0)
754 zi
->ci
.dosDate
= zipfi
->dosDate
;
755 else zi
->ci
.dosDate
= ziplocal_TmzDateToDosDate(&zipfi
->tmz_date
,zipfi
->dosDate
);
759 if ((level
==8) || (level
==9))
765 if (password
!= NULL
)
769 zi
->ci
.method
= method
;
771 zi
->ci
.stream_initialised
= 0;
772 zi
->ci
.pos_in_buffered_data
= 0;
774 zi
->ci
.pos_local_header
= ZTELL(zi
->z_filefunc
,zi
->filestream
) ;
775 zi
->ci
.size_centralheader
= SIZECENTRALHEADER
+ size_filename
+
776 size_extrafield_global
+ size_comment
;
777 zi
->ci
.central_header
= (char*)ALLOC((uInt
)zi
->ci
.size_centralheader
);
779 ziplocal_putValue_inmemory(zi
->ci
.central_header
,(uLong
)CENTRALHEADERMAGIC
,4);
781 ziplocal_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)VERSIONMADEBY
,2);
782 ziplocal_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)20,2);
783 ziplocal_putValue_inmemory(zi
->ci
.central_header
+8,(uLong
)zi
->ci
.flag
,2);
784 ziplocal_putValue_inmemory(zi
->ci
.central_header
+10,(uLong
)zi
->ci
.method
,2);
785 ziplocal_putValue_inmemory(zi
->ci
.central_header
+12,(uLong
)zi
->ci
.dosDate
,4);
786 ziplocal_putValue_inmemory(zi
->ci
.central_header
+16,(uLong
)0,4); /*crc*/
787 ziplocal_putValue_inmemory(zi
->ci
.central_header
+20,(uLong
)0,4); /*compr size*/
788 ziplocal_putValue_inmemory(zi
->ci
.central_header
+24,(uLong
)0,4); /*uncompr size*/
789 ziplocal_putValue_inmemory(zi
->ci
.central_header
+28,(uLong
)size_filename
,2);
790 ziplocal_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)size_extrafield_global
,2);
791 ziplocal_putValue_inmemory(zi
->ci
.central_header
+32,(uLong
)size_comment
,2);
792 ziplocal_putValue_inmemory(zi
->ci
.central_header
+34,(uLong
)0,2); /*disk nm start*/
795 ziplocal_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)0,2);
797 ziplocal_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)zipfi
->internal_fa
,2);
800 ziplocal_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)0,4);
802 ziplocal_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)zipfi
->external_fa
,4);
804 ziplocal_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)zi
->ci
.pos_local_header
- zi
->add_position_when_writting_offset
,4);
806 for (i
=0;i
<size_filename
;i
++)
807 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+i
) = *(filename
+i
);
809 for (i
=0;i
<size_extrafield_global
;i
++)
810 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+i
) =
811 *(((const char*)extrafield_global
)+i
);
813 for (i
=0;i
<size_comment
;i
++)
814 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+
815 size_extrafield_global
+i
) = *(comment
+i
);
816 if (zi
->ci
.central_header
== NULL
)
817 return ZIP_INTERNALERROR
;
819 /* write the local header */
820 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)LOCALHEADERMAGIC
,4);
823 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)20,2);/* version needed to extract */
825 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.flag
,2);
828 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.method
,2);
831 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.dosDate
,4);
834 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* crc 32, unknown */
836 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* compressed size, unknown */
838 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* uncompressed size, unknown */
841 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_filename
,2);
844 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_extrafield_local
,2);
846 if ((err
==ZIP_OK
) && (size_filename
>0))
847 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,filename
,size_filename
)!=size_filename
)
850 if ((err
==ZIP_OK
) && (size_extrafield_local
>0))
851 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,extrafield_local
,size_extrafield_local
)
852 !=size_extrafield_local
)
855 zi
->ci
.stream
.avail_in
= (uInt
)0;
856 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
857 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
858 zi
->ci
.stream
.total_in
= 0;
859 zi
->ci
.stream
.total_out
= 0;
861 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
863 zi
->ci
.stream
.zalloc
= (alloc_func
)0;
864 zi
->ci
.stream
.zfree
= (free_func
)0;
865 zi
->ci
.stream
.opaque
= (voidpf
)0;
868 windowBits
= -windowBits
;
870 err
= deflateInit2(&zi
->ci
.stream
, level
,
871 Z_DEFLATED
, windowBits
, memLevel
, strategy
);
874 zi
->ci
.stream_initialised
= 1;
877 zi
->ci
.crypt_header_size
= 0;
878 if ((err
==Z_OK
) && (password
!= NULL
))
880 unsigned char bufHead
[RAND_HEAD_LEN
];
881 unsigned int sizeHead
;
883 zi
->ci
.pcrc_32_tab
= get_crc_table();
884 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
886 sizeHead
=crypthead(password
,bufHead
,RAND_HEAD_LEN
,zi
->ci
.keys
,zi
->ci
.pcrc_32_tab
,crcForCrypting
);
887 zi
->ci
.crypt_header_size
= sizeHead
;
889 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,bufHead
,sizeHead
) != sizeHead
)
895 zi
->in_opened_file_inzip
= 1;
899 extern int ZEXPORT
zipOpenNewFileInZip2(file
, filename
, zipfi
,
900 extrafield_local
, size_extrafield_local
,
901 extrafield_global
, size_extrafield_global
,
902 comment
, method
, level
, raw
)
904 const char* filename
;
905 const zip_fileinfo
* zipfi
;
906 const void* extrafield_local
;
907 uInt size_extrafield_local
;
908 const void* extrafield_global
;
909 uInt size_extrafield_global
;
915 return zipOpenNewFileInZip3 (file
, filename
, zipfi
,
916 extrafield_local
, size_extrafield_local
,
917 extrafield_global
, size_extrafield_global
,
918 comment
, method
, level
, raw
,
919 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
923 extern int ZEXPORT
zipOpenNewFileInZip (file
, filename
, zipfi
,
924 extrafield_local
, size_extrafield_local
,
925 extrafield_global
, size_extrafield_global
,
926 comment
, method
, level
)
928 const char* filename
;
929 const zip_fileinfo
* zipfi
;
930 const void* extrafield_local
;
931 uInt size_extrafield_local
;
932 const void* extrafield_global
;
933 uInt size_extrafield_global
;
938 return zipOpenNewFileInZip2 (file
, filename
, zipfi
,
939 extrafield_local
, size_extrafield_local
,
940 extrafield_global
, size_extrafield_global
,
941 comment
, method
, level
, 0);
944 local
int zipFlushWriteBuffer(zi
)
949 if (zi
->ci
.encrypt
!= 0)
954 for (i
=0;i
<zi
->ci
.pos_in_buffered_data
;i
++)
955 zi
->ci
.buffered_data
[i
] = zencode(zi
->ci
.keys
, zi
->ci
.pcrc_32_tab
,
956 zi
->ci
.buffered_data
[i
],t
);
959 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,zi
->ci
.buffered_data
,zi
->ci
.pos_in_buffered_data
)
960 !=zi
->ci
.pos_in_buffered_data
)
962 zi
->ci
.pos_in_buffered_data
= 0;
966 extern int ZEXPORT
zipWriteInFileInZip (file
, buf
, len
)
975 return ZIP_PARAMERROR
;
976 zi
= (zip_internal
*)file
;
978 if (zi
->in_opened_file_inzip
== 0)
979 return ZIP_PARAMERROR
;
981 zi
->ci
.stream
.next_in
= (void*)buf
;
982 zi
->ci
.stream
.avail_in
= len
;
983 zi
->ci
.crc32
= crc32(zi
->ci
.crc32
,buf
,len
);
985 while ((err
==ZIP_OK
) && (zi
->ci
.stream
.avail_in
>0))
987 if (zi
->ci
.stream
.avail_out
== 0)
989 if (zipFlushWriteBuffer(zi
) == ZIP_ERRNO
)
991 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
992 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
999 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1001 uLong uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1002 err
=deflate(&zi
->ci
.stream
, Z_NO_FLUSH
);
1003 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1009 if (zi
->ci
.stream
.avail_in
< zi
->ci
.stream
.avail_out
)
1010 copy_this
= zi
->ci
.stream
.avail_in
;
1012 copy_this
= zi
->ci
.stream
.avail_out
;
1013 for (i
=0;i
<copy_this
;i
++)
1014 *(((char*)zi
->ci
.stream
.next_out
)+i
) =
1015 *(((const char*)zi
->ci
.stream
.next_in
)+i
);
1017 zi
->ci
.stream
.avail_in
-= copy_this
;
1018 zi
->ci
.stream
.avail_out
-= copy_this
;
1019 zi
->ci
.stream
.next_in
+= copy_this
;
1020 zi
->ci
.stream
.next_out
+= copy_this
;
1021 zi
->ci
.stream
.total_in
+= copy_this
;
1022 zi
->ci
.stream
.total_out
+= copy_this
;
1023 zi
->ci
.pos_in_buffered_data
+= copy_this
;
1031 extern int ZEXPORT
zipCloseFileInZipRaw (file
, uncompressed_size
, crc32
)
1033 uLong uncompressed_size
;
1037 uLong compressed_size
;
1041 return ZIP_PARAMERROR
;
1042 zi
= (zip_internal
*)file
;
1044 if (zi
->in_opened_file_inzip
== 0)
1045 return ZIP_PARAMERROR
;
1046 zi
->ci
.stream
.avail_in
= 0;
1048 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1051 uLong uTotalOutBefore
;
1052 if (zi
->ci
.stream
.avail_out
== 0)
1054 if (zipFlushWriteBuffer(zi
) == ZIP_ERRNO
)
1056 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1057 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1059 uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1060 err
=deflate(&zi
->ci
.stream
, Z_FINISH
);
1061 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1064 if (err
==Z_STREAM_END
)
1065 err
=ZIP_OK
; /* this is normal */
1067 if ((zi
->ci
.pos_in_buffered_data
>0) && (err
==ZIP_OK
))
1068 if (zipFlushWriteBuffer(zi
)==ZIP_ERRNO
)
1071 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1073 err
=deflateEnd(&zi
->ci
.stream
);
1074 zi
->ci
.stream_initialised
= 0;
1079 crc32
= (uLong
)zi
->ci
.crc32
;
1080 uncompressed_size
= (uLong
)zi
->ci
.stream
.total_in
;
1082 compressed_size
= (uLong
)zi
->ci
.stream
.total_out
;
1084 compressed_size
+= zi
->ci
.crypt_header_size
;
1087 ziplocal_putValue_inmemory(zi
->ci
.central_header
+16,crc32
,4); /*crc*/
1088 ziplocal_putValue_inmemory(zi
->ci
.central_header
+20,
1089 compressed_size
,4); /*compr size*/
1090 if (zi
->ci
.stream
.data_type
== Z_ASCII
)
1091 ziplocal_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)Z_ASCII
,2);
1092 ziplocal_putValue_inmemory(zi
->ci
.central_header
+24,
1093 uncompressed_size
,4); /*uncompr size*/
1096 err
= add_data_in_datablock(&zi
->central_dir
,zi
->ci
.central_header
,
1097 (uLong
)zi
->ci
.size_centralheader
);
1098 free(zi
->ci
.central_header
);
1102 long cur_pos_inzip
= ZTELL(zi
->z_filefunc
,zi
->filestream
);
1103 if (ZSEEK(zi
->z_filefunc
,zi
->filestream
,
1104 zi
->ci
.pos_local_header
+ 14,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1108 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,crc32
,4); /* crc 32, unknown */
1110 if (err
==ZIP_OK
) /* compressed size, unknown */
1111 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,compressed_size
,4);
1113 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1114 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,uncompressed_size
,4);
1116 if (ZSEEK(zi
->z_filefunc
,zi
->filestream
,
1117 cur_pos_inzip
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1121 zi
->number_entry
++;
1122 zi
->in_opened_file_inzip
= 0;
1127 extern int ZEXPORT
zipCloseFileInZip (file
)
1130 return zipCloseFileInZipRaw (file
,0,0);
1133 extern int ZEXPORT
zipClose (file
, global_comment
)
1135 const char* global_comment
;
1139 uLong size_centraldir
= 0;
1140 uLong centraldir_pos_inzip
;
1141 uInt size_global_comment
;
1143 return ZIP_PARAMERROR
;
1144 zi
= (zip_internal
*)file
;
1146 if (zi
->in_opened_file_inzip
== 1)
1148 err
= zipCloseFileInZip (file
);
1151 #ifndef NO_ADDFILEINEXISTINGZIP
1152 if (global_comment
==NULL
)
1153 global_comment
= zi
->globalcomment
;
1155 if (global_comment
==NULL
)
1156 size_global_comment
= 0;
1158 size_global_comment
= (uInt
)strlen(global_comment
);
1160 centraldir_pos_inzip
= ZTELL(zi
->z_filefunc
,zi
->filestream
);
1163 linkedlist_datablock_internal
* ldi
= zi
->central_dir
.first_block
;
1166 if ((err
==ZIP_OK
) && (ldi
->filled_in_this_block
>0))
1167 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,
1168 ldi
->data
,ldi
->filled_in_this_block
)
1169 !=ldi
->filled_in_this_block
)
1172 size_centraldir
+= ldi
->filled_in_this_block
;
1173 ldi
= ldi
->next_datablock
;
1176 free_datablock(zi
->central_dir
.first_block
);
1178 if (err
==ZIP_OK
) /* Magic End */
1179 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ENDHEADERMAGIC
,4);
1181 if (err
==ZIP_OK
) /* number of this disk */
1182 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1184 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1185 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1187 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1188 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1190 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1191 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1193 if (err
==ZIP_OK
) /* size of the central directory */
1194 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_centraldir
,4);
1196 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the
1197 starting disk number */
1198 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,
1199 (uLong
)(centraldir_pos_inzip
- zi
->add_position_when_writting_offset
),4);
1201 if (err
==ZIP_OK
) /* zipfile comment length */
1202 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_global_comment
,2);
1204 if ((err
==ZIP_OK
) && (size_global_comment
>0))
1205 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,
1206 global_comment
,size_global_comment
) != size_global_comment
)
1209 if (ZCLOSE(zi
->z_filefunc
,zi
->filestream
) != 0)
1213 #ifndef NO_ADDFILEINEXISTINGZIP
1214 TRYFREE(zi
->globalcomment
);