5 * Copyright (C) 2010-2011 Scott Smith
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 czip.cpp is based on miniunz.c
27 Version 1.1, February 14h, 2010
28 sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
30 Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
32 Modifications of Unzip for Zip64
33 Copyright (C) 2007-2008 Even Rouault
35 Modifications for Zip64 support on both zip and unzip
36 Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
41 CZip::CZip() : CBase(),
50 void CZip::ListFiles( const string& zipfile, vector<string>& list )
58 uf = unzOpen64( zipfile.c_str() );
62 // Get file info for the zip file
63 err = unzGetGlobalInfo64( uf,&gi );
66 Log( "error %d with zipfile in unzGetGlobalInfo\n",err);
72 Log( "error with zipfile %s in unzOpen64\n", zipfile.c_str() );
75 Log( "Reading zip file %s\n", zipfile.c_str() );
77 // Spit out some information about the files in the zip for debug
78 Log( " Length Method Size Ratio Date Time CRC-32 Name\n" );
79 Log( " ------ ------ ---- ----- ---- ---- ------ ----\n" );
80 for (i=0; i<gi.number_entry; i++)
82 char filename_inzip[256];
83 unz_file_info64 file_info;
85 const char *string_method = NULL;
87 err = unzGetCurrentFileInfo64( uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0 );
90 Log( "error %d with zipfile in unzGetCurrentFileInfo\n",err);
93 if (file_info.uncompressed_size > 0)
94 ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
96 /* display a '*' if the file is crypted */
97 if ((file_info.flag & 1) != 0)
100 if (file_info.compression_method == 0)
101 string_method="Stored";
103 if (file_info.compression_method == Z_DEFLATED)
105 uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
107 string_method="Defl:N";
109 string_method="Defl:X";
110 else if ((iLevel==2) || (iLevel==3))
111 string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
114 if (file_info.compression_method == Z_BZIP2ED)
116 string_method="BZip2 ";
119 string_method="Unkn. ";
121 Display64BitsSize( file_info.uncompressed_size,7 );
122 Log( " %6s%c",string_method,charCrypt);
123 Display64BitsSize( file_info.compressed_size,7 );
124 Log( " %3lu%% %2.2lu-%2.2lu-%2.2lu %2.2lu:%2.2lu %8.8lx %s\n",
126 (uLong)file_info.tmu_date.tm_mon + 1,
127 (uLong)file_info.tmu_date.tm_mday,
128 (uLong)file_info.tmu_date.tm_year % 100,
129 (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
130 (uLong)file_info.crc,filename_inzip);
131 if ((i+1) < gi.number_entry)
133 err = unzGoToNextFile( uf );
136 Log( "error %d with zipfile in unzGoToNextFile\n",err);
141 // Save the names of the files in the zip
142 list.push_back( filename_inzip );
145 // Close the zip file
149 void CZip::ExtractFile( const string& zipfile, const string& location, const string& filename )
154 unz_global_info64 gi;
157 uf = unzOpen64( zipfile.c_str() );
161 // Get file info for the zip file
162 err = unzGetGlobalInfo64( uf,&gi );
165 Log( "error %d with zipfile in unzGetGlobalInfo\n",err);
171 Log( "error with zipfile %s in unzOpen64\n", zipfile.c_str() );
175 for (i=0; i<gi.number_entry; i++)
177 char filename_inzip[256];
178 unz_file_info64 file_info;
180 err = unzGetCurrentFileInfo64( uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0 );
183 Log( "error %d with zipfile in unzGetCurrentFileInfo\n",err);
187 if (filename.compare(filename_inzip) == 0)
189 Extract( uf, location );
193 if ((i+1) < gi.number_entry)
195 err = unzGoToNextFile( uf );
198 Log( "error %d with zipfile in unzGoToNextFile\n",err);
204 // Close the zip file
208 void CZip::ExtractFiles( const string& zipfile, const string& location )
213 unz_global_info64 gi;
215 uf = unzOpen64( zipfile.c_str() );
219 err = unzGetGlobalInfo64( uf, &gi );
222 Log( "error %d with zipfile in unzGetGlobalInfo \n", err );
228 Log( "error with zipfile in unzOpen64 \n" );
232 for (i=0;i<gi.number_entry;i++)
234 if (Extract( uf, location ) != UNZ_OK)
239 if ((uint16_t)(i+1) < gi.number_entry)
242 err = unzGoToNextFile( uf );
245 Log( "error %d with zipfile in unzGoToNextFile\n", err );
251 // Close the zip file
255 #define WRITEBUFFERSIZE (8192)
256 int32_t CZip::Extract( unzFile uf, const string& location )
258 string write_filename;
260 char filename_inzip[256];
263 unz_file_info64 file_info;
265 err = unzGetCurrentFileInfo64( uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0 );
268 Log( "error %d with zipfile in unzGetCurrentFileInfo\n", err );
272 buf = (void*)malloc(WRITEBUFFERSIZE);
275 Log( "Error allocating memory\n" );
277 return UNZ_INTERNALERROR;
280 err = unzOpenCurrentFile( uf );
283 Log( "error %d with zipfile in unzOpenCurrentFile\n", err );
288 write_filename = location + '/' + string(filename_inzip);
290 fout = fopen64( write_filename.c_str(), "wb" );
294 Log( " extracting: %s\n", write_filename.c_str() );
297 err = unzReadCurrentFile( uf, buf, WRITEBUFFERSIZE );
300 Log( "error %d with zipfile in unzReadCurrentFile\n",err);
305 if (fwrite( buf, err, 1, fout ) != 1)
307 Log( "error in writing extracted file\n" );
323 err = unzCloseCurrentFile( uf );
326 Log( "error %d with zipfile in unzCloseCurrentFile\n",err);
329 AddUnzipFile( write_filename );
333 unzCloseCurrentFile( uf ); /* don't lose the error */
340 void CZip::Display64BitsSize(ZPOS64_T n, int size_char)
342 /* to avoid compatibility problem , we do here the conversion */
348 number[offset]=(char)((n%10)+'0');
349 if (number[offset] != '0')
357 int size_display_string = 19-pos_string;
358 while (size_char > size_display_string)
365 Log( "%s",&number[pos_string]);
368 void CZip::AddUnzipFile( const string& filename )
372 for (i=0; i<UnzipFiles.size(); i++)
374 if (UnzipFiles.at(i) == filename)
377 UnzipFiles.push_back( filename );
380 void CZip::DelUnzipFiles( void )
384 for (i=0; i<UnzipFiles.size(); i++)
387 Log( "Removing file %s\n", UnzipFiles.at(i).c_str() );
389 remove( UnzipFiles.at(i).c_str() );
394 int8_t CZip::SaveUnzipList( const string& location )
399 fout.open(location.c_str(), ios_base::trunc);
403 Log( "Failed to open ziplist at %s\n", location.c_str() );
407 // Write out the profile
410 for (i=0; i<UnzipFiles.size(); i++)
412 if (UnzipFiles.at(i).length()>0)
415 Log( "Saving file %s to ziplist\n", UnzipFiles.at(i).c_str());
417 fout << UnzipFiles.at(i) << endl;
425 int8_t CZip::LoadUnzipList( const string& location )
430 fin.open(location.c_str(), ios_base::in);
434 Log( "Failed to open unziplist at %s\n", location.c_str() );
435 return 0; // Dont stop the app if it cant be opened, default values will be used and then save to file.
440 // Read in the profile
447 if (line.length() > 0)
449 UnzipFiles.push_back(line);