1 /* zip.c -- IO on .zip files using zlib
2 Version 1.00, September 10th, 2003
4 Copyright (C) 1998-2003 Gilles Vollant
6 Read zip.h for more info
32 /* compile with -Dlocal if your debugger can't find static symbols */
35 # define VERSIONMADEBY (0x0) /* platform depedent */
39 #define Z_BUFSIZE (16384)
42 #ifndef Z_MAXFILENAMEINZIP
43 #define Z_MAXFILENAMEINZIP (256)
47 # define ALLOC(size) (malloc(size))
50 # define TRYFREE(p) {if (p) free(p);}
54 #define SIZECENTRALDIRITEM (0x2e)
55 #define SIZEZIPLOCALHEADER (0x1e)
58 /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
73 #if MAX_MEM_LEVEL >= 8
74 # define DEF_MEM_LEVEL 8
76 # define DEF_MEM_LEVEL MAX_MEM_LEVEL
79 const char zip_copyright
[] =
80 " zip 1.00 Copyright 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll";
83 #define SIZEDATA_INDATABLOCK (4096-(4*4))
85 #define LOCALHEADERMAGIC (0x04034b50)
86 #define CENTRALHEADERMAGIC (0x02014b50)
87 #define ENDHEADERMAGIC (0x06054b50)
89 #define FLAG_LOCALHEADER_OFFSET (0x06)
90 #define CRC_LOCALHEADER_OFFSET (0x0e)
92 #define SIZECENTRALHEADER (0x2e) /* 46 */
94 typedef struct linkedlist_datablock_internal_s
96 struct linkedlist_datablock_internal_s
* next_datablock
;
97 uLong avail_in_this_block
;
98 uLong filled_in_this_block
;
99 uLong unused
; /* for future use and alignement */
100 unsigned char data
[SIZEDATA_INDATABLOCK
];
101 } linkedlist_datablock_internal
;
103 typedef struct linkedlist_data_s
105 linkedlist_datablock_internal
* first_block
;
106 linkedlist_datablock_internal
* last_block
;
112 z_stream stream
; /* zLib stream structure for inflate */
113 int stream_initialised
; /* 1 is stream is initialised */
114 uInt pos_in_buffered_data
; /* last written byte in buffered_data */
116 uLong pos_local_header
; /* offset of the local header of the file
118 char* central_header
; /* central header data for the current file */
119 uLong size_centralheader
; /* size of the central header for cur file */
120 uLong flag
; /* flag of the file currently writing */
122 int method
; /* compression method of file currenty wr.*/
123 int raw
; /* 1 for directly writing raw data */
124 Byte buffered_data
[Z_BUFSIZE
];/* buffer contain compressed data to be writ*/
129 unsigned long keys
[3]; /* keys defining the pseudo-random sequence */
130 const unsigned long* pcrc_32_tab
;
131 int crypt_header_size
;
137 zlib_filefunc_def z_filefunc
;
138 voidpf filestream
; /* io structore of the zipfile */
139 linkedlist_data central_dir
;/* datablock with central dir in construction*/
140 int in_opened_file_inzip
; /* 1 if a file in the zip is currently writ.*/
141 curfile_info ci
; /* info on the file curretly writing */
143 uLong begin_pos
; /* position of the beginning of the zipfile */
144 uLong add_position_when_writting_offset
;
151 #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
155 local linkedlist_datablock_internal
* allocate_new_datablock()
157 linkedlist_datablock_internal
* ldi
;
158 ldi
= (linkedlist_datablock_internal
*)
159 ALLOC(sizeof(linkedlist_datablock_internal
));
162 ldi
->next_datablock
= NULL
;
163 ldi
->filled_in_this_block
= 0 ;
164 ldi
->avail_in_this_block
= SIZEDATA_INDATABLOCK
;
169 local
void free_datablock(ldi
)
170 linkedlist_datablock_internal
* ldi
;
174 linkedlist_datablock_internal
* ldinext
= ldi
->next_datablock
;
180 local
void init_linkedlist(ll
)
183 ll
->first_block
= ll
->last_block
= NULL
;
186 local
void free_linkedlist(ll
)
189 free_datablock(ll
->first_block
);
190 ll
->first_block
= ll
->last_block
= NULL
;
194 local
int add_data_in_datablock(ll
,buf
,len
)
199 linkedlist_datablock_internal
* ldi
;
200 const unsigned char* from_copy
;
203 return ZIP_INTERNALERROR
;
205 if (ll
->last_block
== NULL
)
207 ll
->first_block
= ll
->last_block
= allocate_new_datablock();
208 if (ll
->first_block
== NULL
)
209 return ZIP_INTERNALERROR
;
212 ldi
= ll
->last_block
;
213 from_copy
= (unsigned char*)buf
;
219 unsigned char* to_copy
;
221 if (ldi
->avail_in_this_block
==0)
223 ldi
->next_datablock
= allocate_new_datablock();
224 if (ldi
->next_datablock
== NULL
)
225 return ZIP_INTERNALERROR
;
226 ldi
= ldi
->next_datablock
;
227 ll
->last_block
= ldi
;
230 if (ldi
->avail_in_this_block
< len
)
231 copy_this
= (uInt
)ldi
->avail_in_this_block
;
233 copy_this
= (uInt
)len
;
235 to_copy
= &(ldi
->data
[ldi
->filled_in_this_block
]);
237 for (i
=0;i
<copy_this
;i
++)
238 *(to_copy
+i
)=*(from_copy
+i
);
240 ldi
->filled_in_this_block
+= copy_this
;
241 ldi
->avail_in_this_block
-= copy_this
;
242 from_copy
+= copy_this
;
250 /****************************************************************************/
252 #ifndef NO_ADDFILEINEXISTINGZIP
253 /* ===========================================================================
254 Inputs a long in LSB order to the given file
255 nbByte == 1, 2 or 4 (byte, short or long)
258 local
int ziplocal_putValue
OF((const zlib_filefunc_def
* pzlib_filefunc_def
,
259 voidpf filestream
, uLong x
, int nbByte
));
260 local
int ziplocal_putValue (pzlib_filefunc_def
, filestream
, x
, nbByte
)
261 const zlib_filefunc_def
* pzlib_filefunc_def
;
266 unsigned char buf
[4];
268 for (n
= 0; n
< nbByte
; n
++) {
269 buf
[n
] = (unsigned char)(x
& 0xff);
272 if (ZWRITE(*pzlib_filefunc_def
,filestream
,buf
,nbByte
)!=(uLong
)nbByte
)
278 local
void ziplocal_putValue_inmemory
OF((void* dest
, uLong x
, int nbByte
));
279 local
void ziplocal_putValue_inmemory (dest
, x
, nbByte
)
284 unsigned char* buf
=(unsigned char*)dest
;
286 for (n
= 0; n
< nbByte
; n
++) {
287 buf
[n
] = (unsigned char)(x
& 0xff);
291 /****************************************************************************/
294 local uLong
ziplocal_TmzDateToDosDate(ptm
,dosDate
)
298 uLong year
= (uLong
)ptm
->tm_year
;
304 (uLong
) (((ptm
->tm_mday
) + (32 * (ptm
->tm_mon
+1)) + (512 * year
)) << 16) |
305 ((ptm
->tm_sec
/2) + (32* ptm
->tm_min
) + (2048 * (uLong
)ptm
->tm_hour
));
309 /****************************************************************************/
311 local
int ziplocal_getByte
OF((
312 const zlib_filefunc_def
* pzlib_filefunc_def
,
316 local
int ziplocal_getByte(pzlib_filefunc_def
,filestream
,pi
)
317 const zlib_filefunc_def
* pzlib_filefunc_def
;
322 int err
= (int)ZREAD(*pzlib_filefunc_def
,filestream
,&c
,1);
330 if (ZERROR(*pzlib_filefunc_def
,filestream
))
338 /* ===========================================================================
339 Reads a long in LSB order from the given gz_stream. Sets
341 local
int ziplocal_getShort
OF((
342 const zlib_filefunc_def
* pzlib_filefunc_def
,
346 local
int ziplocal_getShort (pzlib_filefunc_def
,filestream
,pX
)
347 const zlib_filefunc_def
* pzlib_filefunc_def
;
355 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
359 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
369 local
int ziplocal_getLong
OF((
370 const zlib_filefunc_def
* pzlib_filefunc_def
,
374 local
int ziplocal_getLong (pzlib_filefunc_def
,filestream
,pX
)
375 const zlib_filefunc_def
* pzlib_filefunc_def
;
383 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
387 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
391 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
395 err
= ziplocal_getByte(pzlib_filefunc_def
,filestream
,&i
);
405 #ifndef BUFREADCOMMENT
406 #define BUFREADCOMMENT (0x400)
409 Locate the Central directory of a zipfile (at the end, just before
412 local uLong ziplocal_SearchCentralDir
OF((
413 const zlib_filefunc_def
* pzlib_filefunc_def
,
416 local uLong
ziplocal_SearchCentralDir(pzlib_filefunc_def
,filestream
)
417 const zlib_filefunc_def
* pzlib_filefunc_def
;
423 uLong uMaxBack
=0xffff; /* maximum size of global comment */
426 if (ZSEEK(*pzlib_filefunc_def
,filestream
,0,ZLIB_FILEFUNC_SEEK_END
) != 0)
430 uSizeFile
= ZTELL(*pzlib_filefunc_def
,filestream
);
432 if (uMaxBack
>uSizeFile
)
433 uMaxBack
= uSizeFile
;
435 buf
= (unsigned char*)ALLOC(BUFREADCOMMENT
+4);
440 while (uBackRead
<uMaxBack
)
442 uLong uReadSize
,uReadPos
;
444 if (uBackRead
+BUFREADCOMMENT
>uMaxBack
)
445 uBackRead
= uMaxBack
;
447 uBackRead
+=BUFREADCOMMENT
;
448 uReadPos
= uSizeFile
-uBackRead
;
450 uReadSize
= ((BUFREADCOMMENT
+4) < (uSizeFile
-uReadPos
)) ?
451 (BUFREADCOMMENT
+4) : (uSizeFile
-uReadPos
);
452 if (ZSEEK(*pzlib_filefunc_def
,filestream
,uReadPos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
455 if (ZREAD(*pzlib_filefunc_def
,filestream
,buf
,uReadSize
)!=uReadSize
)
458 for (i
=(int)uReadSize
-3; (i
--)>0;)
459 if (((*(buf
+i
))==0x50) && ((*(buf
+i
+1))==0x4b) &&
460 ((*(buf
+i
+2))==0x05) && ((*(buf
+i
+3))==0x06))
462 uPosFound
= uReadPos
+i
;
472 #endif /* !NO_ADDFILEINEXISTINGZIP*/
474 /************************************************************/
475 extern zipFile ZEXPORT
zipOpen2 (pathname
, append
, globalcomment
, pzlib_filefunc_def
)
476 const char *pathname
;
478 zipcharpc
* globalcomment
;
479 zlib_filefunc_def
* pzlib_filefunc_def
;
486 if (pzlib_filefunc_def
==NULL
)
487 fill_fopen_filefunc(&ziinit
.z_filefunc
);
489 ziinit
.z_filefunc
= *pzlib_filefunc_def
;
491 ziinit
.filestream
= (*(ziinit
.z_filefunc
.zopen_file
))
492 (ziinit
.z_filefunc
.opaque
,
494 (append
== APPEND_STATUS_CREATE
) ?
495 (ZLIB_FILEFUNC_MODE_READ
| ZLIB_FILEFUNC_MODE_WRITE
| ZLIB_FILEFUNC_MODE_CREATE
) :
496 (ZLIB_FILEFUNC_MODE_READ
| ZLIB_FILEFUNC_MODE_WRITE
| ZLIB_FILEFUNC_MODE_EXISTING
));
498 if (ziinit
.filestream
== NULL
)
500 ziinit
.begin_pos
= ZTELL(ziinit
.z_filefunc
,ziinit
.filestream
);
501 ziinit
.in_opened_file_inzip
= 0;
502 ziinit
.ci
.stream_initialised
= 0;
503 ziinit
.number_entry
= 0;
504 ziinit
.add_position_when_writting_offset
= 0;
505 init_linkedlist(&(ziinit
.central_dir
));
508 zi
= (zip_internal
*)ALLOC(sizeof(zip_internal
));
511 ZCLOSE(ziinit
.z_filefunc
,ziinit
.filestream
);
515 /* now we add file in a zipfile */
516 # ifndef NO_ADDFILEINEXISTINGZIP
517 if (append
== APPEND_STATUS_ADDINZIP
)
519 uLong byte_before_the_zipfile
;/* byte before the zipfile, (>0 for sfx)*/
521 uLong size_central_dir
; /* size of the central directory */
522 uLong offset_central_dir
; /* offset of start of central directory */
523 uLong central_pos
,uL
;
525 uLong number_disk
; /* number of the current dist, used for
526 spaning ZIP, unsupported, always 0*/
527 uLong number_disk_with_CD
; /* number the the disk with central dir, used
528 for spaning ZIP, unsupported, always 0*/
530 uLong number_entry_CD
; /* total number of entries in
532 (same than number_entry on nospan) */
535 central_pos
= ziplocal_SearchCentralDir(&ziinit
.z_filefunc
,ziinit
.filestream
);
539 if (ZSEEK(ziinit
.z_filefunc
, ziinit
.filestream
,
540 central_pos
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
543 /* the signature, already checked */
544 if (ziplocal_getLong(&ziinit
.z_filefunc
, ziinit
.filestream
,&uL
)!=ZIP_OK
)
547 /* number of this disk */
548 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_disk
)!=ZIP_OK
)
551 /* number of the disk with the start of the central directory */
552 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_disk_with_CD
)!=ZIP_OK
)
555 /* total number of entries in the central dir on this disk */
556 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_entry
)!=ZIP_OK
)
559 /* total number of entries in the central dir */
560 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&number_entry_CD
)!=ZIP_OK
)
563 if ((number_entry_CD
!=number_entry
) ||
564 (number_disk_with_CD
!=0) ||
568 /* size of the central directory */
569 if (ziplocal_getLong(&ziinit
.z_filefunc
, ziinit
.filestream
,&size_central_dir
)!=ZIP_OK
)
572 /* offset of start of central directory with respect to the
573 starting disk number */
574 if (ziplocal_getLong(&ziinit
.z_filefunc
, ziinit
.filestream
,&offset_central_dir
)!=ZIP_OK
)
577 /* zipfile comment length */
578 if (ziplocal_getShort(&ziinit
.z_filefunc
, ziinit
.filestream
,&size_comment
)!=ZIP_OK
)
581 if ((central_pos
<offset_central_dir
+size_central_dir
) &&
587 ZCLOSE(ziinit
.z_filefunc
, ziinit
.filestream
);
591 byte_before_the_zipfile
= central_pos
-
592 (offset_central_dir
+size_central_dir
);
593 ziinit
.add_position_when_writting_offset
= byte_before_the_zipfile
;
596 uLong size_central_dir_to_read
= size_central_dir
;
597 size_t buf_size
= SIZEDATA_INDATABLOCK
;
598 void* buf_read
= (void*)ALLOC(buf_size
);
599 if (ZSEEK(ziinit
.z_filefunc
, ziinit
.filestream
,
600 offset_central_dir
+ byte_before_the_zipfile
,
601 ZLIB_FILEFUNC_SEEK_SET
) != 0)
604 while ((size_central_dir_to_read
>0) && (err
==ZIP_OK
))
606 uLong read_this
= SIZEDATA_INDATABLOCK
;
607 if (read_this
> size_central_dir_to_read
)
608 read_this
= size_central_dir_to_read
;
609 if (ZREAD(ziinit
.z_filefunc
, ziinit
.filestream
,buf_read
,read_this
) != read_this
)
613 err
= add_data_in_datablock(&ziinit
.central_dir
,buf_read
,
615 size_central_dir_to_read
-=read_this
;
619 ziinit
.begin_pos
= byte_before_the_zipfile
;
620 ziinit
.number_entry
= number_entry_CD
;
622 if (ZSEEK(ziinit
.z_filefunc
, ziinit
.filestream
,
623 offset_central_dir
+byte_before_the_zipfile
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
626 # endif /* !NO_ADDFILEINEXISTINGZIP*/
640 extern zipFile ZEXPORT
zipOpen (pathname
, append
)
641 const char *pathname
;
644 return zipOpen2(pathname
,append
,NULL
,NULL
);
647 extern int ZEXPORT
zipOpenNewFileInZip3 (file
, filename
, zipfi
,
648 extrafield_local
, size_extrafield_local
,
649 extrafield_global
, size_extrafield_global
,
650 comment
, method
, level
, raw
,
651 windowBits
, memLevel
, strategy
,
652 password
, crcForCrypting
)
654 const char* filename
;
655 const zip_fileinfo
* zipfi
;
656 const void* extrafield_local
;
657 uInt size_extrafield_local
;
658 const void* extrafield_global
;
659 uInt size_extrafield_global
;
667 const char* password
;
668 uLong crcForCrypting
;
677 if (password
!= NULL
)
678 return ZIP_PARAMERROR
;
682 return ZIP_PARAMERROR
;
683 if ((method
!=0) && (method
!=Z_DEFLATED
))
684 return ZIP_PARAMERROR
;
686 zi
= (zip_internal
*)file
;
688 if (zi
->in_opened_file_inzip
== 1)
690 err
= zipCloseFileInZip (file
);
702 size_comment
= strlen(comment
);
704 size_filename
= strlen(filename
);
710 if (zipfi
->dosDate
!= 0)
711 zi
->ci
.dosDate
= zipfi
->dosDate
;
712 else zi
->ci
.dosDate
= ziplocal_TmzDateToDosDate(&zipfi
->tmz_date
,zipfi
->dosDate
);
716 if ((level
==8) || (level
==9))
722 if (password
!= NULL
)
726 zi
->ci
.method
= method
;
728 zi
->ci
.stream_initialised
= 0;
729 zi
->ci
.pos_in_buffered_data
= 0;
731 zi
->ci
.pos_local_header
= ZTELL(zi
->z_filefunc
,zi
->filestream
) ;
732 zi
->ci
.size_centralheader
= SIZECENTRALHEADER
+ size_filename
+
733 size_extrafield_global
+ size_comment
;
734 zi
->ci
.central_header
= (char*)ALLOC((uInt
)zi
->ci
.size_centralheader
);
736 ziplocal_putValue_inmemory(zi
->ci
.central_header
,(uLong
)CENTRALHEADERMAGIC
,4);
738 ziplocal_putValue_inmemory(zi
->ci
.central_header
+4,(uLong
)VERSIONMADEBY
,2);
739 ziplocal_putValue_inmemory(zi
->ci
.central_header
+6,(uLong
)20,2);
740 ziplocal_putValue_inmemory(zi
->ci
.central_header
+8,(uLong
)zi
->ci
.flag
,2);
741 ziplocal_putValue_inmemory(zi
->ci
.central_header
+10,(uLong
)zi
->ci
.method
,2);
742 ziplocal_putValue_inmemory(zi
->ci
.central_header
+12,(uLong
)zi
->ci
.dosDate
,4);
743 ziplocal_putValue_inmemory(zi
->ci
.central_header
+16,(uLong
)0,4); /*crc*/
744 ziplocal_putValue_inmemory(zi
->ci
.central_header
+20,(uLong
)0,4); /*compr size*/
745 ziplocal_putValue_inmemory(zi
->ci
.central_header
+24,(uLong
)0,4); /*uncompr size*/
746 ziplocal_putValue_inmemory(zi
->ci
.central_header
+28,(uLong
)size_filename
,2);
747 ziplocal_putValue_inmemory(zi
->ci
.central_header
+30,(uLong
)size_extrafield_global
,2);
748 ziplocal_putValue_inmemory(zi
->ci
.central_header
+32,(uLong
)size_comment
,2);
749 ziplocal_putValue_inmemory(zi
->ci
.central_header
+34,(uLong
)0,2); /*disk nm start*/
752 ziplocal_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)0,2);
754 ziplocal_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)zipfi
->internal_fa
,2);
757 ziplocal_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)0,4);
759 ziplocal_putValue_inmemory(zi
->ci
.central_header
+38,(uLong
)zipfi
->external_fa
,4);
761 ziplocal_putValue_inmemory(zi
->ci
.central_header
+42,(uLong
)zi
->ci
.pos_local_header
- zi
->add_position_when_writting_offset
,4);
763 for (i
=0;i
<size_filename
;i
++)
764 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+i
) = *(filename
+i
);
766 for (i
=0;i
<size_extrafield_global
;i
++)
767 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+i
) =
768 *(((const char*)extrafield_global
)+i
);
770 for (i
=0;i
<size_comment
;i
++)
771 *(zi
->ci
.central_header
+SIZECENTRALHEADER
+size_filename
+
772 size_extrafield_global
+i
) = *(comment
+i
);
773 if (zi
->ci
.central_header
== NULL
)
774 return ZIP_INTERNALERROR
;
776 /* write the local header */
777 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)LOCALHEADERMAGIC
,4);
780 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)20,2);/* version needed to extract */
782 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.flag
,2);
785 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.method
,2);
788 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->ci
.dosDate
,4);
791 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* crc 32, unknown */
793 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* compressed size, unknown */
795 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,4); /* uncompressed size, unknown */
798 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_filename
,2);
801 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_extrafield_local
,2);
803 if ((err
==ZIP_OK
) && (size_filename
>0))
804 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,filename
,size_filename
)!=size_filename
)
807 if ((err
==ZIP_OK
) && (size_extrafield_local
>0))
808 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,extrafield_local
,size_extrafield_local
)
809 !=size_extrafield_local
)
812 zi
->ci
.stream
.avail_in
= (uInt
)0;
813 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
814 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
815 zi
->ci
.stream
.total_in
= 0;
816 zi
->ci
.stream
.total_out
= 0;
818 if ((err
==ZIP_OK
) && (zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
820 zi
->ci
.stream
.zalloc
= (alloc_func
)0;
821 zi
->ci
.stream
.zfree
= (free_func
)0;
822 zi
->ci
.stream
.opaque
= (voidpf
)0;
825 windowBits
= -windowBits
;
827 err
= deflateInit2(&zi
->ci
.stream
, level
,
828 Z_DEFLATED
, windowBits
, memLevel
, strategy
);
831 zi
->ci
.stream_initialised
= 1;
834 zi
->ci
.crypt_header_size
= 0;
835 if ((err
==Z_OK
) && (password
!= NULL
))
837 unsigned char bufHead
[RAND_HEAD_LEN
];
838 unsigned int sizeHead
;
840 zi
->ci
.pcrc_32_tab
= get_crc_table();
841 /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
843 sizeHead
=crypthead(password
,bufHead
,RAND_HEAD_LEN
,zi
->ci
.keys
,zi
->ci
.pcrc_32_tab
,crcForCrypting
);
844 zi
->ci
.crypt_header_size
= sizeHead
;
846 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,bufHead
,sizeHead
) != sizeHead
)
852 zi
->in_opened_file_inzip
= 1;
856 extern int ZEXPORT
zipOpenNewFileInZip2(file
, filename
, zipfi
,
857 extrafield_local
, size_extrafield_local
,
858 extrafield_global
, size_extrafield_global
,
859 comment
, method
, level
, raw
)
861 const char* filename
;
862 const zip_fileinfo
* zipfi
;
863 const void* extrafield_local
;
864 uInt size_extrafield_local
;
865 const void* extrafield_global
;
866 uInt size_extrafield_global
;
872 return zipOpenNewFileInZip3 (file
, filename
, zipfi
,
873 extrafield_local
, size_extrafield_local
,
874 extrafield_global
, size_extrafield_global
,
875 comment
, method
, level
, raw
,
876 -MAX_WBITS
, DEF_MEM_LEVEL
, Z_DEFAULT_STRATEGY
,
880 extern int ZEXPORT
zipOpenNewFileInZip (file
, filename
, zipfi
,
881 extrafield_local
, size_extrafield_local
,
882 extrafield_global
, size_extrafield_global
,
883 comment
, method
, level
)
885 const char* filename
;
886 const zip_fileinfo
* zipfi
;
887 const void* extrafield_local
;
888 uInt size_extrafield_local
;
889 const void* extrafield_global
;
890 uInt size_extrafield_global
;
895 return zipOpenNewFileInZip2 (file
, filename
, zipfi
,
896 extrafield_local
, size_extrafield_local
,
897 extrafield_global
, size_extrafield_global
,
898 comment
, method
, level
, 0);
901 local
int zipFlushWriteBuffer(zi
)
906 if (zi
->ci
.encrypt
!= 0)
911 for (i
=0;i
<zi
->ci
.pos_in_buffered_data
;i
++)
912 zi
->ci
.buffered_data
[i
] = zencode(zi
->ci
.keys
, zi
->ci
.pcrc_32_tab
,
913 zi
->ci
.buffered_data
[i
],t
);
916 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,zi
->ci
.buffered_data
,zi
->ci
.pos_in_buffered_data
)
917 !=zi
->ci
.pos_in_buffered_data
)
919 zi
->ci
.pos_in_buffered_data
= 0;
923 extern int ZEXPORT
zipWriteInFileInZip (file
, buf
, len
)
932 return ZIP_PARAMERROR
;
933 zi
= (zip_internal
*)file
;
935 if (zi
->in_opened_file_inzip
== 0)
936 return ZIP_PARAMERROR
;
938 zi
->ci
.stream
.next_in
= (void*)buf
;
939 zi
->ci
.stream
.avail_in
= len
;
940 zi
->ci
.crc32
= crc32(zi
->ci
.crc32
,buf
,len
);
942 while ((err
==ZIP_OK
) && (zi
->ci
.stream
.avail_in
>0))
944 if (zi
->ci
.stream
.avail_out
== 0)
946 if (zipFlushWriteBuffer(zi
) == ZIP_ERRNO
)
948 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
949 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
956 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
958 uLong uTotalOutBefore
= zi
->ci
.stream
.total_out
;
959 err
=deflate(&zi
->ci
.stream
, Z_NO_FLUSH
);
960 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
966 if (zi
->ci
.stream
.avail_in
< zi
->ci
.stream
.avail_out
)
967 copy_this
= zi
->ci
.stream
.avail_in
;
969 copy_this
= zi
->ci
.stream
.avail_out
;
970 for (i
=0;i
<copy_this
;i
++)
971 *(((char*)zi
->ci
.stream
.next_out
)+i
) =
972 *(((const char*)zi
->ci
.stream
.next_in
)+i
);
974 zi
->ci
.stream
.avail_in
-= copy_this
;
975 zi
->ci
.stream
.avail_out
-= copy_this
;
976 zi
->ci
.stream
.next_in
+= copy_this
;
977 zi
->ci
.stream
.next_out
+= copy_this
;
978 zi
->ci
.stream
.total_in
+= copy_this
;
979 zi
->ci
.stream
.total_out
+= copy_this
;
980 zi
->ci
.pos_in_buffered_data
+= copy_this
;
988 extern int ZEXPORT
zipCloseFileInZipRaw (file
, uncompressed_size
, crc32
)
990 uLong uncompressed_size
;
994 uLong compressed_size
;
998 return ZIP_PARAMERROR
;
999 zi
= (zip_internal
*)file
;
1001 if (zi
->in_opened_file_inzip
== 0)
1002 return ZIP_PARAMERROR
;
1003 zi
->ci
.stream
.avail_in
= 0;
1005 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1008 uLong uTotalOutBefore
;
1009 if (zi
->ci
.stream
.avail_out
== 0)
1011 if (zipFlushWriteBuffer(zi
) == ZIP_ERRNO
)
1013 zi
->ci
.stream
.avail_out
= (uInt
)Z_BUFSIZE
;
1014 zi
->ci
.stream
.next_out
= zi
->ci
.buffered_data
;
1016 uTotalOutBefore
= zi
->ci
.stream
.total_out
;
1017 err
=deflate(&zi
->ci
.stream
, Z_FINISH
);
1018 zi
->ci
.pos_in_buffered_data
+= (uInt
)(zi
->ci
.stream
.total_out
- uTotalOutBefore
) ;
1021 if (err
==Z_STREAM_END
)
1022 err
=ZIP_OK
; /* this is normal */
1024 if ((zi
->ci
.pos_in_buffered_data
>0) && (err
==ZIP_OK
))
1025 if (zipFlushWriteBuffer(zi
)==ZIP_ERRNO
)
1028 if ((zi
->ci
.method
== Z_DEFLATED
) && (!zi
->ci
.raw
))
1030 err
=deflateEnd(&zi
->ci
.stream
);
1031 zi
->ci
.stream_initialised
= 0;
1036 crc32
= (uLong
)zi
->ci
.crc32
;
1037 uncompressed_size
= (uLong
)zi
->ci
.stream
.total_in
;
1039 compressed_size
= (uLong
)zi
->ci
.stream
.total_out
;
1041 compressed_size
+= zi
->ci
.crypt_header_size
;
1044 ziplocal_putValue_inmemory(zi
->ci
.central_header
+16,crc32
,4); /*crc*/
1045 ziplocal_putValue_inmemory(zi
->ci
.central_header
+20,
1046 compressed_size
,4); /*compr size*/
1047 if (zi
->ci
.stream
.data_type
== Z_ASCII
)
1048 ziplocal_putValue_inmemory(zi
->ci
.central_header
+36,(uLong
)Z_ASCII
,2);
1049 ziplocal_putValue_inmemory(zi
->ci
.central_header
+24,
1050 uncompressed_size
,4); /*uncompr size*/
1053 err
= add_data_in_datablock(&zi
->central_dir
,zi
->ci
.central_header
,
1054 (uLong
)zi
->ci
.size_centralheader
);
1055 free(zi
->ci
.central_header
);
1059 long cur_pos_inzip
= ZTELL(zi
->z_filefunc
,zi
->filestream
);
1060 if (ZSEEK(zi
->z_filefunc
,zi
->filestream
,
1061 zi
->ci
.pos_local_header
+ 14,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1065 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,crc32
,4); /* crc 32, unknown */
1067 if (err
==ZIP_OK
) /* compressed size, unknown */
1068 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,compressed_size
,4);
1070 if (err
==ZIP_OK
) /* uncompressed size, unknown */
1071 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,uncompressed_size
,4);
1073 if (ZSEEK(zi
->z_filefunc
,zi
->filestream
,
1074 cur_pos_inzip
,ZLIB_FILEFUNC_SEEK_SET
)!=0)
1078 zi
->number_entry
++;
1079 zi
->in_opened_file_inzip
= 0;
1084 extern int ZEXPORT
zipCloseFileInZip (file
)
1087 return zipCloseFileInZipRaw (file
,0,0);
1090 extern int ZEXPORT
zipClose (file
, global_comment
)
1092 const char* global_comment
;
1096 uLong size_centraldir
= 0;
1097 uLong centraldir_pos_inzip
;
1098 uInt size_global_comment
;
1100 return ZIP_PARAMERROR
;
1101 zi
= (zip_internal
*)file
;
1103 if (zi
->in_opened_file_inzip
== 1)
1105 err
= zipCloseFileInZip (file
);
1108 if (global_comment
==NULL
)
1109 size_global_comment
= 0;
1111 size_global_comment
= strlen(global_comment
);
1114 centraldir_pos_inzip
= ZTELL(zi
->z_filefunc
,zi
->filestream
);
1117 linkedlist_datablock_internal
* ldi
= zi
->central_dir
.first_block
;
1120 if ((err
==ZIP_OK
) && (ldi
->filled_in_this_block
>0))
1121 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,
1122 ldi
->data
,ldi
->filled_in_this_block
)
1123 !=ldi
->filled_in_this_block
)
1126 size_centraldir
+= ldi
->filled_in_this_block
;
1127 ldi
= ldi
->next_datablock
;
1130 free_datablock(zi
->central_dir
.first_block
);
1132 if (err
==ZIP_OK
) /* Magic End */
1133 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)ENDHEADERMAGIC
,4);
1135 if (err
==ZIP_OK
) /* number of this disk */
1136 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1138 if (err
==ZIP_OK
) /* number of the disk with the start of the central directory */
1139 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)0,2);
1141 if (err
==ZIP_OK
) /* total number of entries in the central dir on this disk */
1142 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1144 if (err
==ZIP_OK
) /* total number of entries in the central dir */
1145 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)zi
->number_entry
,2);
1147 if (err
==ZIP_OK
) /* size of the central directory */
1148 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_centraldir
,4);
1150 if (err
==ZIP_OK
) /* offset of start of central directory with respect to the
1151 starting disk number */
1152 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,
1153 (uLong
)(centraldir_pos_inzip
- zi
->add_position_when_writting_offset
),4);
1155 if (err
==ZIP_OK
) /* zipfile comment length */
1156 err
= ziplocal_putValue(&zi
->z_filefunc
,zi
->filestream
,(uLong
)size_global_comment
,2);
1158 if ((err
==ZIP_OK
) && (size_global_comment
>0))
1159 if (ZWRITE(zi
->z_filefunc
,zi
->filestream
,
1160 global_comment
,size_global_comment
) != size_global_comment
)
1163 if (ZCLOSE(zi
->z_filefunc
,zi
->filestream
) != 0)