00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "zip.h"
00025 #include "unzip.h"
00026
00027 #include <QFile>
00028 #include <QFileInfo>
00029
00030 #include <QString>
00031 #include <QStringList>
00032 #include <QList>
00033
00034 #include <iostream>
00035 #include <iomanip>
00036
00037 void invalidCMD();
00038 bool decompress(const QString& file, const QString& out, const QString& pwd);
00039 bool compress(const QString& zip, const QString& dir, const QString& pwd);
00040 bool listFiles(const QString& file, const QString& pwd);
00041
00042 using namespace std;
00043
00044 int main(int argc, char** argv)
00045 {
00046 if (argc < 3)
00047 {
00048 cout << "Test routine for the OSDaB Project Zip/UnZip classes" << endl << endl;
00049 cout << "Compression: zip [-p PWD] ZIPFILE DIRECTORY" << endl;
00050 cout << "List files: zip -l [-p PWD] ZIPFILE" << endl;
00051 cout << "Decompression: zip -d [-p PWD] ZIPFILE OUTPUT_DIR" << endl << endl;
00052 cout << "(C) 2007 Angius Fabrizio\nLicensed under the terms of the GNU GPL Version 2 or later" << endl;
00053 return -1;
00054 }
00055
00056 QString fname;
00057 QString dname;
00058 QString pwd;
00059
00060 bool resOK = true;
00061
00062 if (strlen(argv[1]) == 2 && argv[1][0] == '-')
00063 {
00064 switch (argv[1][1])
00065 {
00066 case 'd':
00067 {
00068 if (argc >= 6)
00069 {
00070 if (strcmp(argv[2], "-p") == 0)
00071 {
00072 pwd = QString(argv[3]);
00073 fname = QString(argv[4]);
00074 dname = QString(argv[5]);
00075 }
00076 else invalidCMD();
00077 }
00078 else if (argc >= 4)
00079 {
00080 fname = QString(argv[2]);
00081 dname = QString(argv[3]);
00082 }
00083 else invalidCMD();
00084
00085 resOK = decompress(fname, dname, pwd);
00086 }
00087 break;
00088 case 'l':
00089 {
00090 if (argc >= 5)
00091 {
00092 if (strcmp(argv[2], "-p") == 0)
00093 {
00094 pwd = QString(argv[3]);
00095 fname = QString(argv[4]);
00096 }
00097 else invalidCMD();
00098 }
00099 else if (argc >= 3)
00100 {
00101 fname = QString(argv[2]);
00102 }
00103 else invalidCMD();
00104
00105 resOK = listFiles(fname, pwd);
00106 }
00107 break;
00108 case 'p':
00109 {
00110 if (argc >= 5)
00111 {
00112 pwd = QString(argv[2]);
00113 fname = QString(argv[3]);
00114 dname = QString(argv[4]);
00115 }
00116 else invalidCMD();
00117
00118 resOK = compress(fname, dname, pwd);
00119 }
00120 break;
00121 default: invalidCMD();
00122 }
00123 }
00124 else
00125 {
00126
00127 resOK = compress(QString(argv[1]), QString(argv[2]), 0);
00128 }
00129
00130
00131 if (!resOK)
00132 {
00133 cout << "Sorry, some error occurred!" << endl;
00134 return -1;
00135 }
00136
00137 return 0;
00138 }
00139
00140 void invalidCMD()
00141 {
00142 cout << "Invalid command line. Usage:" << endl;
00143 cout << "Compression: zip [-p PWD] DIRECTORY" << endl;
00144 cout << "List files: zip -l [-p PWD] ZIPFILE" << endl;
00145 cout << "Decompression: zip -d [-p PWD] ZIPFILE OUTPUT_DIR" << endl << endl;
00146 exit(-1);
00147 }
00148
00149 bool decompress(const QString& file, const QString& out, const QString& pwd)
00150 {
00151
00152 if (!QFile::exists(file))
00153 {
00154 cout << "File does not exist." << endl << endl;
00155 return false;
00156 }
00157
00158 UnZip::ErrorCode ec;
00159 UnZip uz;
00160
00161 if (!pwd.isEmpty())
00162 uz.setPassword(pwd);
00163
00164 ec = uz.openArchive(file);
00165 if (ec != UnZip::Ok)
00166 {
00167 cout << "Failed to open archive: " << uz.formatError(ec).toAscii().data() << endl << endl;
00168 return false;
00169 }
00170
00171 ec = uz.extractAll(out);
00172 if (ec != UnZip::Ok)
00173 {
00174 cout << "Extraction failed: " << uz.formatError(ec).toAscii().data() << endl << endl;
00175 uz.closeArchive();
00176 return false;
00177 }
00178
00179 return true;
00180 }
00181
00182 bool compress(const QString& zip, const QString& dir, const QString& pwd)
00183 {
00184 QFileInfo fi(dir);
00185 if (!fi.isDir())
00186 {
00187 cout << "Directory does not exist." << endl << endl;
00188 return false;
00189 }
00190
00191 Zip::ErrorCode ec;
00192 Zip uz;
00193
00194 ec = uz.createArchive(zip);
00195 if (ec != Zip::Ok)
00196 {
00197 cout << "Unable to create archive: " << uz.formatError(ec).toAscii().data() << endl << endl;
00198 return false;
00199 }
00200
00201 uz.setPassword(pwd);
00202 ec = uz.addDirectory(dir);
00203 if (ec != Zip::Ok)
00204 {
00205 cout << "Unable to add directory: " << uz.formatError(ec).toAscii().data() << endl << endl;
00206 }
00207
00208 uz.setArchiveComment("This archive has been created using OSDaB Zip (http://osdab.sourceforge.net/).");
00209
00210 if (uz.closeArchive() != Zip::Ok)
00211 {
00212 cout << "Unable to close the archive: " << uz.formatError(ec).toAscii().data() << endl << endl;
00213 }
00214
00215 return ec == Zip::Ok;
00216 }
00217
00218 bool listFiles(const QString& file, const QString& pwd)
00219 {
00220 if (!QFile::exists(file))
00221 {
00222 cout << "File does not exist." << endl << endl;
00223 return false;
00224 }
00225
00226 UnZip::ErrorCode ec;
00227 UnZip uz;
00228
00229 if (!pwd.isEmpty())
00230 uz.setPassword(pwd);
00231
00232 ec = uz.openArchive(file);
00233 if (ec != UnZip::Ok)
00234 {
00235 cout << "Unable to open archive: " << uz.formatError(ec).toAscii().data() << endl << endl;
00236 return false;
00237 }
00238
00239 QString comment = uz.archiveComment();
00240 if (!comment.isEmpty())
00241 cout << "Archive comment: " << comment.toAscii().data() << endl << endl;
00242
00243 QList<UnZip::ZipEntry> list = uz.entryList();
00244 if (list.isEmpty())
00245 {
00246 cout << "Empty archive.";
00247 }
00248 else
00249 {
00250 cout.setf(ios::left);
00251 cout << setw(40) << "Filename";
00252 cout.unsetf(ios::left);
00253 cout << setw(10) << "Size" << setw(10) << "Ratio" << setw(10) << "CRC32" << endl;
00254 cout.setf(ios::left);
00255 cout << setw(40) << "--------";
00256 cout.unsetf(ios::left);
00257 cout << setw(10) << "----" << setw(10) << "-----" << setw(10) << "-----" << endl;
00258
00259 for (int i = 0; i < list.size(); ++i)
00260 {
00261 const UnZip::ZipEntry& entry = list.at(i);
00262
00263 double ratio = entry.uncompressedSize == 0 ? 0 : 100 - (double) entry.compressedSize * 100 / (double) entry.uncompressedSize;
00264
00265 QString ratioS = QString::number(ratio, 'f', 2).append("%");
00266 QString crc;
00267 crc = crc.sprintf("%X", entry.crc32).rightJustified(8, '0');
00268 QString file = entry.filename;
00269 int idx = file.lastIndexOf("/");
00270 if (idx >= 0 && idx != file.length()-1)
00271 file = file.right(file.length() - idx - 1);
00272 file = file.leftJustified(40, ' ', true);
00273
00274 if (entry.encrypted)
00275 file.append("*");
00276
00277 cout << setw(40) << file.toAscii().data() << setw(10) << entry.uncompressedSize << setw(10) << ratioS.toAscii().data() << setw(10) << crc.toAscii().data() << endl;
00278 }
00279 }
00280
00281 uz.closeArchive();
00282 return true;
00283 }