/* * This file is part of the Advance project. * * Copyright (C) 2002, 2003 Andrea Mazzoleni * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "portable.h" #include "zip.h" #include "file.h" #include #include #include using namespace std; void rezip_single(const string& file, unsigned long long& total_0, unsigned long long& total_1, bool quiet, bool standard, shrink_t level) { zip z(file); unsigned size_0; unsigned size_1; if (!file_exists(file)) { throw error() << "File " << file << " doesn't exist"; } try { size_0 = file_size(file); z.open(); z.load(); z.shrink(standard, level); z.save(); z.close(); size_1 = file_size(file); } catch (error& e) { throw e << " on " << file; } if (!quiet) { cout << setw(12) << size_0 << setw(12) << size_1 << " "; if (size_0) { unsigned perc = size_1 * 100LL / size_0; cout << setw(3) << perc; } else { cout << " 0"; } cout << "% " << file << endl; } total_0 += size_0; total_1 += size_1; } void rezip_all(int argc, char* argv[], bool quiet, bool standard, shrink_t level) { unsigned long long total_0 = 0; unsigned long long total_1 = 0; for(int i=0;icrc_get(); cout << " "; cout << dec << setw(0) << setfill(' ') << i->compressed_size_get(); cout << "\n"; } } else { cout << "Archive: " << file << endl; cout << " Length Method Size Ratio Date Time CRC-32 Name" << endl; cout << " -------- ------ ------- ----- ---- ---- ------ ----" << endl; for(zip::iterator i=z.begin();i!=z.end();++i) { // not optimal code for g++ 2.95.3 cout.setf(ios::right, ios::adjustfield); cout << dec << setw(9) << setfill(' ') << i->uncompressed_size_get(); cout << " "; string m; switch (i->method_get()) { case zip_entry::store : m = "Stored"; break; case zip_entry::shrunk : m = "Shrunk"; break; case zip_entry::reduce1 : m = "Reduce1"; break; case zip_entry::reduce2 : m = "Reduce2"; break; case zip_entry::reduce3 : m = "Reduce3"; break; case zip_entry::reduce4 : m = "Reduce4"; break; case zip_entry::implode_4kdict_2tree : m = "Impl:42"; break; case zip_entry::implode_8kdict_2tree : m = "Impl:82"; break; case zip_entry::implode_4kdict_3tree : m = "Impl:43"; break; case zip_entry::implode_8kdict_3tree : m = "Impl:83"; break; case zip_entry::deflate0 : m = "Defl:S"; break; case zip_entry::deflate1 : m = "Defl:S"; break; case zip_entry::deflate2 : m = "Defl:S"; break; case zip_entry::deflate3 : m = "Defl:F"; break; case zip_entry::deflate4 : m = "Defl:F"; break; case zip_entry::deflate5 : m = "Defl:F"; break; case zip_entry::deflate6 : m = "Defl:N"; break; case zip_entry::deflate7 : m = "Defl:N"; break; case zip_entry::deflate8 : m = "Defl:N"; break; case zip_entry::deflate9 : m = "Defl:X"; break; case zip_entry::bzip2 : m = "Bzip2"; break; case zip_entry::lzma : m = "LZMA"; break; default: m = "Unknown"; break; } cout.setf(ios::left, ios::adjustfield); // not optimal code for g++ 2.95.3 cout << setw(7) << m.c_str(); cout.setf(ios::right, ios::adjustfield); cout << setw(8) << i->compressed_size_get(); cout << " "; if (i->uncompressed_size_get()) { unsigned perc = (i->uncompressed_size_get() - i->compressed_size_get()) * 100LL / i->uncompressed_size_get(); cout << setw(3) << perc; } else { cout << " 0"; } cout << "% "; time_t t = i->time_get(); struct tm* tm = localtime(&t); cout << setw(2) << setfill('0') << tm->tm_mon + 1; cout << "-"; cout << setw(2) << setfill('0') << tm->tm_mday; cout << "-"; cout << setw(2) << setfill('0') << (tm->tm_year % 100); cout << " "; cout << setw(2) << setfill('0') << tm->tm_hour; cout << ":"; cout << setw(2) << setfill('0') << tm->tm_min; cout << " "; cout << hex << setw(8) << setfill('0') << i->crc_get(); cout << " "; cout << i->name_get(); cout << endl; uncompressed_size += i->uncompressed_size_get(); compressed_size += i->compressed_size_get(); } cout << " -------- ------- --- -------" << endl; cout << dec << setw(9) << setfill(' ') << uncompressed_size; cout << " "; cout << dec << setw(9) << setfill(' ') << compressed_size; cout << " "; if (uncompressed_size) { unsigned perc = (uncompressed_size - compressed_size) * 100LL / uncompressed_size; cout << setw(3) << perc; } else { cout << " 0"; } cout << "% "; cout << z.size() << " files" << endl; } z.close(); } catch (error& e) { throw e << " on " << file; } } void list_all(int argc, char* argv[], bool crc) { string file(argv[0]); for(int i=0;i 1) throw error() << "Too many archives specified"; if (argc < 1) throw error() << "No archive specified"; zip z(argv[0]); z.open(); z.load(); for(zip::iterator i=z.begin();i!=z.end();++i) { unsigned char* data = (unsigned char*)operator new(i->uncompressed_size_get()); try { i->uncompressed_read(data); string file = i->name_get(); // if end with / it's a directory if (file.length() && file[file.length()-1]!='/') { if (!quiet) cout << file << endl; file_mktree(file); FILE* f = fopen(file.c_str(), "wb"); if (!f) throw error() << "Failed open for writing file " << file; try { if (fwrite(data, i->uncompressed_size_get(), 1, f)!=1) throw error() << "Failed write file " << file; } catch (...) { fclose(f); throw; } fclose(f); file_utime(file, i->time_get()); } } catch (...) { operator delete(data); throw; } operator delete(data); } z.close(); } void add_single(zip& z, const string& local, const string& common, bool quiet, bool standard, shrink_t level) { struct stat st; string file = local + common; string name = file_name(file); // ignore special file if (name == "." || name == "..") return; if (stat(file.c_str(), &st)!=0) throw error() << "Failed stat file " << file; if (S_ISDIR(st.st_mode)) { DIR* d = opendir(file.c_str()); if (!d) throw error() << "Failed open dir " << file; try { struct dirent* dd; while ((dd = readdir(d)) != 0) { add_single(z, local, common + "/" + dd->d_name, quiet, standard, level); } } catch (...) { closedir(d); throw; } closedir(d); } else { unsigned char* data = (unsigned char*)operator new(st.st_size); try { if (!quiet) cout << file << endl; FILE* f = fopen(file.c_str(), "rb"); if (!f) throw error() << "Failed open for reading file " << file; if (fread(data, st.st_size, 1, f)!=1) throw error() << "Failed read file " << file; fclose(f); zip::iterator i = z.insert_uncompressed(common, data, st.st_size, crc32(0, (unsigned char*)data, st.st_size), st.st_mtime, false); if (level != shrink_none) i->shrink(standard, level); } catch (...) { operator delete(data); throw; } operator delete(data); } } void add_all(int argc, char* argv[], bool quiet, bool standard, shrink_t level) { if (argc < 1) throw error() << "No archive specified"; if (argc < 2) throw error() << "No files specified"; zip z(argv[0]); z.create(); for(int i=1;i