File indexing completed on 2024-04-28 07:41:00
0001 /* 0002 * SPDX-FileCopyrightText: 2002-2013 David Faure <faure@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "kzip.h" 0008 #include "kcompressiondevice.h" 0009 0010 #include <QCoreApplication> 0011 #include <QDebug> 0012 #include <QFile> 0013 0014 #include <stdio.h> 0015 0016 void recursive_print(const KArchiveDirectory *dir, const QString &path) 0017 { 0018 const QStringList lst = dir->entries(); 0019 for (const QString &it : lst) { 0020 const KArchiveEntry *entry = dir->entry(it); 0021 printf("mode=%07o %s %s \"%s%s\" size: %lld pos: %lld isdir=%d%s", 0022 entry->permissions(), 0023 entry->user().toLatin1().constData(), 0024 entry->group().toLatin1().constData(), 0025 path.toLatin1().constData(), 0026 it.toLatin1().constData(), 0027 entry->isDirectory() ? 0 : (static_cast<const KArchiveFile *>(entry))->size(), 0028 entry->isDirectory() ? 0 : (static_cast<const KArchiveFile *>(entry))->position(), 0029 entry->isDirectory(), 0030 entry->symLinkTarget().isEmpty() ? "" : QStringLiteral(" symlink: %1").arg(entry->symLinkTarget()).toLatin1().constData()); 0031 0032 // if (!entry->isDirectory()) printf("%d", (static_cast<const KArchiveFile *>(entry))->size()); 0033 printf("\n"); 0034 if (entry->isDirectory()) { 0035 recursive_print(static_cast<const KArchiveDirectory *>(entry), path + it + '/'); 0036 } 0037 } 0038 } 0039 0040 void recursive_transfer(const KArchiveDirectory *dir, const QString &path, KZip *zip) 0041 { 0042 const QStringList lst = dir->entries(); 0043 for (const QString &it : lst) { 0044 const KArchiveEntry *e = dir->entry(it); 0045 qDebug() << "actual file: " << e->name(); 0046 if (e->isFile()) { 0047 Q_ASSERT(e && e->isFile()); 0048 const KArchiveFile *f = static_cast<const KArchiveFile *>(e); 0049 printf("FILE=%s\n", qPrintable(e->name())); 0050 0051 QByteArray arr(f->data()); 0052 printf("SIZE=%lli\n", arr.size()); 0053 QString str(arr); 0054 printf("DATA=%s\n", qPrintable(str)); 0055 0056 if (e->symLinkTarget().isEmpty()) { 0057 zip->writeFile(path + e->name(), arr); 0058 } else { 0059 zip->writeSymLink(path + e->name(), e->symLinkTarget()); 0060 } 0061 } else if (e->isDirectory()) { 0062 recursive_transfer(static_cast<const KArchiveDirectory *>(e), path + e->name() + '/', zip); 0063 } 0064 } 0065 } 0066 0067 static int doList(const QString &fileName) 0068 { 0069 KZip zip(fileName); 0070 if (!zip.open(QIODevice::ReadOnly)) { 0071 qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString(); 0072 return 1; 0073 } 0074 const KArchiveDirectory *dir = zip.directory(); 0075 recursive_print(dir, QString()); 0076 zip.close(); 0077 return 0; 0078 } 0079 0080 static int doPrintAll(const QString &fileName) 0081 { 0082 KZip zip(fileName); 0083 qDebug() << "Opening zip file"; 0084 if (!zip.open(QIODevice::ReadOnly)) { 0085 qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString(); 0086 return 1; 0087 } 0088 const KArchiveDirectory *dir = zip.directory(); 0089 qDebug() << "Listing toplevel of zip file"; 0090 const QStringList lst = dir->entries(); 0091 for (const QString &it : lst) { 0092 const KArchiveEntry *e = dir->entry(it); 0093 qDebug() << "Printing" << it; 0094 if (e->isFile()) { 0095 Q_ASSERT(e && e->isFile()); 0096 const KArchiveFile *f = static_cast<const KArchiveFile *>(e); 0097 const QByteArray data(f->data()); 0098 printf("SIZE=%lli\n", data.size()); 0099 QString str = QString::fromUtf8(data); 0100 printf("DATA=%s\n", qPrintable(str)); 0101 } 0102 } 0103 zip.close(); 0104 return 0; 0105 } 0106 0107 static int doSave(const QString &fileName) 0108 { 0109 KZip zip(fileName); 0110 if (!zip.open(QIODevice::WriteOnly)) { 0111 qWarning() << "Could not open" << fileName << "for writing:" << zip.errorString(); 0112 return 1; 0113 } 0114 0115 const QByteArray data = "This is the data for the main file"; 0116 bool writeOk = zip.writeFile(QStringLiteral("maindoc.txt"), data); 0117 if (!writeOk) { 0118 qWarning() << "Write error (main file)"; 0119 return 1; 0120 } 0121 const QByteArray data2 = "This is the data for the other file"; 0122 writeOk = zip.writeFile(QStringLiteral("subdir/other.txt"), data2); 0123 if (!writeOk) { 0124 qWarning() << "Write error (other file)"; 0125 return 1; 0126 } 0127 // writeOk = zip.addLocalFile("David.jpg", "picture.jpg"); 0128 // if (!writeOk) { 0129 // qWarning() << "Write error (picture)"; 0130 // return 1; 0131 //} 0132 return 0; 0133 } 0134 0135 static int doLoad(const QString &fileName) 0136 { 0137 KZip zip(fileName); 0138 if (!zip.open(QIODevice::ReadOnly)) { 0139 qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString(); 0140 return 1; 0141 } 0142 const KArchiveDirectory *dir = zip.directory(); 0143 const KArchiveEntry *mainEntry = dir->entry(QStringLiteral("maindoc.txt")); 0144 Q_ASSERT(mainEntry && mainEntry->isFile()); 0145 const KArchiveFile *mainFile = static_cast<const KArchiveFile *>(mainEntry); 0146 qDebug() << "maindoc.txt:" << mainFile->data(); 0147 return 0; 0148 } 0149 0150 static int doPrint(const QString &fileName, const QString &entryName) 0151 { 0152 KZip zip(fileName); 0153 if (!zip.open(QIODevice::ReadOnly)) { 0154 qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString(); 0155 return 1; 0156 } 0157 const KArchiveDirectory *dir = zip.directory(); 0158 const KArchiveEntry *e = dir->entry(entryName); 0159 Q_ASSERT(e && e->isFile()); 0160 const KArchiveFile *f = static_cast<const KArchiveFile *>(e); 0161 0162 const QByteArray arr(f->data()); 0163 printf("SIZE=%lli\n", arr.size()); 0164 0165 QString str = QString::fromUtf8(arr); 0166 printf("%s", qPrintable(str)); 0167 return zip.close() ? 0 : 1 /*error*/; 0168 } 0169 0170 static int doCreate(const QString &archiveName, const QStringList &fileNames) 0171 { 0172 KZip zip(archiveName); 0173 if (!zip.open(QIODevice::WriteOnly)) { 0174 qWarning() << "Could not open" << archiveName << "for writing:" << zip.errorString(); 0175 return 1; 0176 } 0177 for (const QString &fileName : fileNames) { 0178 QFile f(fileName); 0179 if (!f.open(QIODevice::ReadOnly)) { 0180 qWarning() << "Could not open" << fileName << "for reading:" << zip.errorString(); 0181 return 1; 0182 } 0183 zip.writeFile(fileName, f.readAll()); 0184 } 0185 return zip.close() ? 0 : 1 /*error*/; 0186 } 0187 0188 static int doUpdate(const QString &archiveName, const QString &fileName) 0189 { 0190 KZip zip(archiveName); 0191 if (!zip.open(QIODevice::ReadWrite)) { 0192 qWarning() << "Could not open" << archiveName << "for read/write:" << zip.errorString(); 0193 return 1; 0194 } 0195 0196 QFile f(fileName); 0197 if (!f.open(QIODevice::ReadOnly)) { 0198 qWarning() << "Could not open" << fileName << "for reading:" << zip.errorString(); 0199 return 1; 0200 } 0201 0202 zip.writeFile(fileName, f.readAll()); 0203 return zip.close() ? 0 : 1 /*error*/; 0204 } 0205 0206 static int doTransfer(const QString &sourceFile, const QString &destFile) 0207 { 0208 KZip zip1(sourceFile); 0209 KZip zip2(destFile); 0210 if (!zip1.open(QIODevice::ReadOnly)) { 0211 qWarning() << "Could not open" << sourceFile << "for reading. ZIP file doesn't exist or is invalid:" << zip1.errorString(); 0212 return 1; 0213 } 0214 if (!zip2.open(QIODevice::WriteOnly)) { 0215 qWarning() << "Could not open" << destFile << "for writing:" << zip2.errorString(); 0216 return 1; 0217 } 0218 const KArchiveDirectory *dir1 = zip1.directory(); 0219 0220 recursive_transfer(dir1, QLatin1String(""), &zip2); 0221 0222 zip1.close(); 0223 zip2.close(); 0224 return 0; 0225 } 0226 0227 static bool save(QIODevice *device) 0228 { 0229 const QByteArray data = "This is some text that will be compressed.\n"; 0230 const int written = device->write(data); 0231 if (written != data.size()) { 0232 qWarning() << "Error writing data"; 0233 return 1; 0234 } 0235 // success 0236 return 0; 0237 } 0238 0239 static int doCompress(const QString &fileName) 0240 { 0241 KCompressionDevice device(fileName, KCompressionDevice::BZip2); 0242 if (!device.open(QIODevice::WriteOnly)) { 0243 qWarning() << "Could not open" << fileName << "for writing:" << device.errorString(); 0244 return 1; 0245 } 0246 0247 return save(&device); 0248 } 0249 0250 static bool load(QIODevice *device) 0251 { 0252 const QByteArray data = device->readAll(); 0253 printf("%s", data.constData()); 0254 return true; 0255 } 0256 0257 static int doUncompress(const QString &fileName) 0258 { 0259 KCompressionDevice device(fileName, KCompressionDevice::BZip2); 0260 if (!device.open(QIODevice::ReadOnly)) { 0261 qWarning() << "Could not open" << fileName << "for reading:" << device.errorString(); 0262 return 1; 0263 } 0264 return load(&device); 0265 } 0266 0267 int main(int argc, char **argv) 0268 { 0269 if (argc < 3) { 0270 // ###### Note: please consider adding new tests to karchivetest (so that they can be automated) 0271 // rather than here (interactive) 0272 printf( 0273 "\n" 0274 " Usage :\n" 0275 " ./kziptest list /path/to/existing_file.zip tests listing an existing zip\n" 0276 " ./kziptest print-all file.zip prints contents of all files.\n" 0277 " ./kziptest print file.zip filename prints contents of one file.\n" 0278 " ./kziptest create file.zip filenames create a new zip file with these files.\n" 0279 " ./kziptest update file.zip filename update filename in file.zip.\n" 0280 " ./kziptest save file.zip save file.\n" 0281 " ./kziptest load file.zip load file.\n" 0282 " ./kziptest write file.bz2 write compressed file.\n" 0283 " ./kziptest read file.bz2 read uncompressed file.\n"); 0284 return 1; 0285 } 0286 QCoreApplication app(argc, argv); 0287 QString command = argv[1]; 0288 if (command == QLatin1String("list")) { 0289 return doList(QFile::decodeName(argv[2])); 0290 } else if (command == QLatin1String("print-all")) { 0291 return doPrintAll(QFile::decodeName(argv[2])); 0292 } else if (command == QLatin1String("print")) { 0293 if (argc != 4) { 0294 printf("usage: kziptest print archivename filename"); 0295 return 1; 0296 } 0297 return doPrint(QFile::decodeName(argv[2]), argv[3]); 0298 } else if (command == QLatin1String("save")) { 0299 return doSave(QFile::decodeName(argv[2])); 0300 } else if (command == QLatin1String("load")) { 0301 return doLoad(QFile::decodeName(argv[2])); 0302 } else if (command == QLatin1String("write")) { 0303 return doCompress(QFile::decodeName(argv[2])); 0304 } else if (command == QLatin1String("read")) { 0305 return doUncompress(QFile::decodeName(argv[2])); 0306 } else if (command == QLatin1String("create")) { 0307 if (argc < 4) { 0308 printf("usage: kziptest create archivename filenames"); 0309 return 1; 0310 } 0311 const QStringList fileNames = app.arguments().mid(3); 0312 return doCreate(QFile::decodeName(argv[2]), fileNames); 0313 } else if (command == QLatin1String("update")) { 0314 if (argc != 4) { 0315 printf("usage: kziptest update archivename filename"); 0316 return 1; 0317 } 0318 return doUpdate(QFile::decodeName(argv[2]), QFile::decodeName(argv[3])); 0319 } else if (command == QLatin1String("transfer")) { 0320 if (argc != 4) { 0321 printf("usage: kziptest transfer sourcefile destfile"); 0322 return 1; 0323 } 0324 return doTransfer(QFile::decodeName(argv[2]), QFile::decodeName(argv[3])); 0325 } else { 0326 printf("Unknown command\n"); 0327 } 0328 }