OLD | NEW |
1 /* zip.c -- IO on .zip files using zlib | 1 /* zip.c -- IO on .zip files using zlib |
2 Version 1.1, February 14h, 2010 | 2 Version 1.1, February 14h, 2010 |
3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html
) | 3 part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html
) |
4 | 4 |
5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.
com/zLibDll/minizip.html ) | 5 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.
com/zLibDll/minizip.html ) |
6 | 6 |
7 Modifications for Zip64 support | 7 Modifications for Zip64 support |
8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) | 8 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) |
9 | 9 |
10 For more info read MiniZip_info.txt | 10 For more info read MiniZip_info.txt |
11 | 11 |
12 Changes | 12 Changes |
13 Oct-2009 - Mathias Svensson - Remove old C style function prototypes | 13 Oct-2009 - Mathias Svensson - Remove old C style function prototypes |
14 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file arch
ives | 14 Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file arch
ives |
15 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get be
tter overview of some functions. | 15 Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get be
tter overview of some functions. |
16 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra fi
eld data from its ZIP64 data | 16 Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra fi
eld data from its ZIP64 data |
17 It is used when recreting zip archive with RAW
when deleting items from a zip. | 17 It is used when recreting zip archive with RAW
when deleting items from a zip. |
18 ZIP64 data is automaticly added to items that n
eeds it, and existing ZIP64 data need to be removed. | 18 ZIP64 data is automatically added to items that
needs it, and existing ZIP64 data need to be removed. |
19 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bz
ip2 lib is required) | 19 Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bz
ip2 lib is required) |
20 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility laye
r | 20 Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility laye
r |
21 | 21 |
22 */ | 22 */ |
23 | 23 |
24 | 24 |
25 #include <stdio.h> | 25 #include <stdio.h> |
26 #include <stdlib.h> | 26 #include <stdlib.h> |
27 #include <string.h> | 27 #include <string.h> |
28 #include <time.h> | 28 #include <time.h> |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 #define FLAG_LOCALHEADER_OFFSET (0x06) | 109 #define FLAG_LOCALHEADER_OFFSET (0x06) |
110 #define CRC_LOCALHEADER_OFFSET (0x0e) | 110 #define CRC_LOCALHEADER_OFFSET (0x0e) |
111 | 111 |
112 #define SIZECENTRALHEADER (0x2e) /* 46 */ | 112 #define SIZECENTRALHEADER (0x2e) /* 46 */ |
113 | 113 |
114 typedef struct linkedlist_datablock_internal_s | 114 typedef struct linkedlist_datablock_internal_s |
115 { | 115 { |
116 struct linkedlist_datablock_internal_s* next_datablock; | 116 struct linkedlist_datablock_internal_s* next_datablock; |
117 uLong avail_in_this_block; | 117 uLong avail_in_this_block; |
118 uLong filled_in_this_block; | 118 uLong filled_in_this_block; |
119 uLong unused; /* for future use and alignement */ | 119 uLong unused; /* for future use and alignment */ |
120 unsigned char data[SIZEDATA_INDATABLOCK]; | 120 unsigned char data[SIZEDATA_INDATABLOCK]; |
121 } linkedlist_datablock_internal; | 121 } linkedlist_datablock_internal; |
122 | 122 |
123 typedef struct linkedlist_data_s | 123 typedef struct linkedlist_data_s |
124 { | 124 { |
125 linkedlist_datablock_internal* first_block; | 125 linkedlist_datablock_internal* first_block; |
126 linkedlist_datablock_internal* last_block; | 126 linkedlist_datablock_internal* last_block; |
127 } linkedlist_data; | 127 } linkedlist_data; |
128 | 128 |
129 | 129 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 | 164 |
165 typedef struct | 165 typedef struct |
166 { | 166 { |
167 zlib_filefunc64_32_def z_filefunc; | 167 zlib_filefunc64_32_def z_filefunc; |
168 voidpf filestream; /* io structore of the zipfile */ | 168 voidpf filestream; /* io structore of the zipfile */ |
169 linkedlist_data central_dir;/* datablock with central dir in construction*/ | 169 linkedlist_data central_dir;/* datablock with central dir in construction*/ |
170 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ | 170 int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ |
171 curfile64_info ci; /* info on the file curretly writing */ | 171 curfile64_info ci; /* info on the file curretly writing */ |
172 | 172 |
173 ZPOS64_T begin_pos; /* position of the beginning of the zipfile *
/ | 173 ZPOS64_T begin_pos; /* position of the beginning of the zipfile *
/ |
174 ZPOS64_T add_position_when_writting_offset; | 174 ZPOS64_T add_position_when_writing_offset; |
175 ZPOS64_T number_entry; | 175 ZPOS64_T number_entry; |
176 | 176 |
177 #ifndef NO_ADDFILEINEXISTINGZIP | 177 #ifndef NO_ADDFILEINEXISTINGZIP |
178 char *globalcomment; | 178 char *globalcomment; |
179 #endif | 179 #endif |
180 | 180 |
181 } zip64_internal; | 181 } zip64_internal; |
182 | 182 |
183 | 183 |
184 #ifndef NOCRYPT | 184 #ifndef NOCRYPT |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 { | 800 { |
801 pziinit->globalcomment = (char*)ALLOC(size_comment+1); | 801 pziinit->globalcomment = (char*)ALLOC(size_comment+1); |
802 if (pziinit->globalcomment) | 802 if (pziinit->globalcomment) |
803 { | 803 { |
804 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->
globalcomment,size_comment); | 804 size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->
globalcomment,size_comment); |
805 pziinit->globalcomment[size_comment]=0; | 805 pziinit->globalcomment[size_comment]=0; |
806 } | 806 } |
807 } | 807 } |
808 | 808 |
809 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); | 809 byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); |
810 pziinit->add_position_when_writting_offset = byte_before_the_zipfile; | 810 pziinit->add_position_when_writing_offset = byte_before_the_zipfile; |
811 | 811 |
812 { | 812 { |
813 ZPOS64_T size_central_dir_to_read = size_central_dir; | 813 ZPOS64_T size_central_dir_to_read = size_central_dir; |
814 size_t buf_size = SIZEDATA_INDATABLOCK; | 814 size_t buf_size = SIZEDATA_INDATABLOCK; |
815 void* buf_read = (void*)ALLOC(buf_size); | 815 void* buf_read = (void*)ALLOC(buf_size); |
816 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + b
yte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) | 816 if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + b
yte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) |
817 err=ZIP_ERRNO; | 817 err=ZIP_ERRNO; |
818 | 818 |
819 while ((size_central_dir_to_read>0) && (err==ZIP_OK)) | 819 while ((size_central_dir_to_read>0) && (err==ZIP_OK)) |
820 { | 820 { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 if (ziinit.filestream == NULL) | 868 if (ziinit.filestream == NULL) |
869 return NULL; | 869 return NULL; |
870 | 870 |
871 if (append == APPEND_STATUS_CREATEAFTER) | 871 if (append == APPEND_STATUS_CREATEAFTER) |
872 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); | 872 ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); |
873 | 873 |
874 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); | 874 ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); |
875 ziinit.in_opened_file_inzip = 0; | 875 ziinit.in_opened_file_inzip = 0; |
876 ziinit.ci.stream_initialised = 0; | 876 ziinit.ci.stream_initialised = 0; |
877 ziinit.number_entry = 0; | 877 ziinit.number_entry = 0; |
878 ziinit.add_position_when_writting_offset = 0; | 878 ziinit.add_position_when_writing_offset = 0; |
879 init_linkedlist(&(ziinit.central_dir)); | 879 init_linkedlist(&(ziinit.central_dir)); |
880 | 880 |
881 | 881 |
882 | 882 |
883 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); | 883 zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); |
884 if (zi==NULL) | 884 if (zi==NULL) |
885 { | 885 { |
886 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); | 886 ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); |
887 return NULL; | 887 return NULL; |
888 } | 888 } |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->inte
rnal_fa,2); | 1157 zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->inte
rnal_fa,2); |
1158 | 1158 |
1159 if (zipfi==NULL) | 1159 if (zipfi==NULL) |
1160 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); | 1160 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); |
1161 else | 1161 else |
1162 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->exte
rnal_fa,4); | 1162 zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->exte
rnal_fa,4); |
1163 | 1163 |
1164 if(zi->ci.pos_local_header >= 0xffffffff) | 1164 if(zi->ci.pos_local_header >= 0xffffffff) |
1165 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4)
; | 1165 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4)
; |
1166 else | 1166 else |
1167 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_lo
cal_header - zi->add_position_when_writting_offset,4); | 1167 zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_lo
cal_header - zi->add_position_when_writing_offset,4); |
1168 | 1168 |
1169 for (i=0;i<size_filename;i++) | 1169 for (i=0;i<size_filename;i++) |
1170 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); | 1170 *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i); |
1171 | 1171 |
1172 for (i=0;i<size_extrafield_global;i++) | 1172 for (i=0;i<size_extrafield_global;i++) |
1173 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) = | 1173 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) = |
1174 *(((const char*)extrafield_global)+i); | 1174 *(((const char*)extrafield_global)+i); |
1175 | 1175 |
1176 for (i=0;i<size_comment;i++) | 1176 for (i=0;i<size_comment;i++) |
1177 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+ | 1177 *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+ |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 } | 1748 } |
1749 | 1749 |
1750 extern int ZEXPORT zipCloseFileInZip (zipFile file) | 1750 extern int ZEXPORT zipCloseFileInZip (zipFile file) |
1751 { | 1751 { |
1752 return zipCloseFileInZipRaw (file,0,0); | 1752 return zipCloseFileInZipRaw (file,0,0); |
1753 } | 1753 } |
1754 | 1754 |
1755 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eo
cd_pos_inzip) | 1755 int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eo
cd_pos_inzip) |
1756 { | 1756 { |
1757 int err = ZIP_OK; | 1757 int err = ZIP_OK; |
1758 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; | 1758 ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writing_offset; |
1759 | 1759 |
1760 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEA
DERMAGIC,4); | 1760 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEA
DERMAGIC,4); |
1761 | 1761 |
1762 /*num disks*/ | 1762 /*num disks*/ |
1763 if (err==ZIP_OK) /* number of the disk with the start of the central directo
ry */ | 1763 if (err==ZIP_OK) /* number of the disk with the start of the central directo
ry */ |
1764 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); | 1764 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); |
1765 | 1765 |
1766 /*relative offset*/ | 1766 /*relative offset*/ |
1767 if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ | 1767 if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ |
1768 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); | 1768 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1801 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry,
8); | 1801 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry,
8); |
1802 | 1802 |
1803 if (err==ZIP_OK) /* total number of entries in the central dir */ | 1803 if (err==ZIP_OK) /* total number of entries in the central dir */ |
1804 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry,
8); | 1804 err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry,
8); |
1805 | 1805 |
1806 if (err==ZIP_OK) /* size of the central directory */ | 1806 if (err==ZIP_OK) /* size of the central directory */ |
1807 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_cent
raldir,8); | 1807 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_cent
raldir,8); |
1808 | 1808 |
1809 if (err==ZIP_OK) /* offset of start of central directory with respect to the s
tarting disk number */ | 1809 if (err==ZIP_OK) /* offset of start of central directory with respect to the s
tarting disk number */ |
1810 { | 1810 { |
1811 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | 1811 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; |
1812 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); | 1812 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); |
1813 } | 1813 } |
1814 return err; | 1814 return err; |
1815 } | 1815 } |
1816 int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
ZPOS64_T centraldir_pos_inzip) | 1816 int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir,
ZPOS64_T centraldir_pos_inzip) |
1817 { | 1817 { |
1818 int err = ZIP_OK; | 1818 int err = ZIP_OK; |
1819 | 1819 |
1820 /*signature*/ | 1820 /*signature*/ |
1821 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC
,4); | 1821 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC
,4); |
(...skipping 20 matching lines...) Expand all Loading... |
1842 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2);
// use value in ZIP64 record | 1842 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2);
// use value in ZIP64 record |
1843 else | 1843 else |
1844 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number
_entry,2); | 1844 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number
_entry,2); |
1845 } | 1845 } |
1846 | 1846 |
1847 if (err==ZIP_OK) /* size of the central directory */ | 1847 if (err==ZIP_OK) /* size of the central directory */ |
1848 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_central
dir,4); | 1848 err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_central
dir,4); |
1849 | 1849 |
1850 if (err==ZIP_OK) /* offset of start of central directory with respect to the s
tarting disk number */ | 1850 if (err==ZIP_OK) /* offset of start of central directory with respect to the s
tarting disk number */ |
1851 { | 1851 { |
1852 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | 1852 ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; |
1853 if(pos >= 0xffffffff) | 1853 if(pos >= 0xffffffff) |
1854 { | 1854 { |
1855 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xfffffff
f,4); | 1855 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xfffffff
f,4); |
1856 } | 1856 } |
1857 else | 1857 else |
1858 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centrald
ir_pos_inzip - zi->add_position_when_writting_offset),4); | 1858 err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centrald
ir_pos_inzip - zi->add_position_when_writing_offset),4); |
1859 } | 1859 } |
1860 | 1860 |
1861 return err; | 1861 return err; |
1862 } | 1862 } |
1863 | 1863 |
1864 int Write_GlobalComment(zip64_internal* zi, const char* global_comment) | 1864 int Write_GlobalComment(zip64_internal* zi, const char* global_comment) |
1865 { | 1865 { |
1866 int err = ZIP_OK; | 1866 int err = ZIP_OK; |
1867 uInt size_global_comment = 0; | 1867 uInt size_global_comment = 0; |
1868 | 1868 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->fill
ed_in_this_block) != ldi->filled_in_this_block) | 1914 if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->fill
ed_in_this_block) != ldi->filled_in_this_block) |
1915 err = ZIP_ERRNO; | 1915 err = ZIP_ERRNO; |
1916 } | 1916 } |
1917 | 1917 |
1918 size_centraldir += ldi->filled_in_this_block; | 1918 size_centraldir += ldi->filled_in_this_block; |
1919 ldi = ldi->next_datablock; | 1919 ldi = ldi->next_datablock; |
1920 } | 1920 } |
1921 } | 1921 } |
1922 free_linkedlist(&(zi->central_dir)); | 1922 free_linkedlist(&(zi->central_dir)); |
1923 | 1923 |
1924 pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; | 1924 pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; |
1925 if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) | 1925 if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) |
1926 { | 1926 { |
1927 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); | 1927 ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); |
1928 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos
_inzip); | 1928 Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos
_inzip); |
1929 | 1929 |
1930 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); | 1930 Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); |
1931 } | 1931 } |
1932 | 1932 |
1933 if (err==ZIP_OK) | 1933 if (err==ZIP_OK) |
1934 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_po
s_inzip); | 1934 err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_po
s_inzip); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1998 | 1998 |
1999 retVal = ZIP_OK; | 1999 retVal = ZIP_OK; |
2000 } | 2000 } |
2001 else | 2001 else |
2002 retVal = ZIP_ERRNO; | 2002 retVal = ZIP_ERRNO; |
2003 | 2003 |
2004 TRYFREE(pNewHeader); | 2004 TRYFREE(pNewHeader); |
2005 | 2005 |
2006 return retVal; | 2006 return retVal; |
2007 } | 2007 } |
OLD | NEW |