//============================================================================= // // File : libkvipackage.cpp // Creation date : Tue 7 Dec 00:05:59 2002 GMT by Szymon Stefanek // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net) // // 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #include "KviModule.h" #include "KviPackageReader.h" #include "KviLocale.h" #include "KviKvsHash.h" #include "KviKvsArray.h" #include "KviFileUtils.h" #include "KviApplication.h" #include #include #include #include static QString createRandomDir() { QString szDirName; char chars[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '-', '_', '.' }; // Generate dir name for(int i = 0; i < 10; i++) { int n = rand() % sizeof(chars); szDirName.append(chars[n]); } return szDirName; } /* @doc: package.info @type: function @title: $package.info @short: Returns informations about a KVIrc package file @syntax: $package.info() @description: Returns a set of informations about a KVIrc package file (*.kvt or *.kva). The set is a structured hash. If the specified path does not lead to a valid KVIrc package the returned hash will contain a single element with key "error". */ static bool package_kvs_fnc_info(KviKvsModuleFunctionCall * c) { QString szPath; KVSM_PARAMETERS_BEGIN(c) KVSM_PARAMETER("package_path", KVS_PT_NONEMPTYSTRING, 0, szPath) KVSM_PARAMETERS_END(c) KviKvsHash * pHash = new KviKvsHash(); c->returnValue()->setHash(pHash); // Create a random extraction dir QString szTmpPath, szUnpackPath; QString szRandomDir = createRandomDir(); g_pApp->getLocalKvircDirectory(szTmpPath, KviApplication::Tmp); KviQString::ensureLastCharIs(szTmpPath, QChar(KVI_PATH_SEPARATOR_CHAR)); szUnpackPath = szTmpPath + szRandomDir; QDir szTmpDir(szUnpackPath); // Check for dir existence while(szTmpDir.exists()) { szRandomDir = createRandomDir(); szUnpackPath = szTmpPath + szRandomDir; szTmpDir = QDir(szUnpackPath); } KviPackageReader r; // Unpack addon package into the random tmp dir if(!r.unpack(szPath, szUnpackPath)) { pHash->set("error", new KviKvsVariant(r.lastError())); return true; } KviKvsHash * pInfoHash = new KviKvsHash(); pHash->set("info", new KviKvsVariant(pInfoHash)); QFileInfo inf(szPath); pInfoHash->set("path", new KviKvsVariant(szPath)); pInfoHash->set("name", new KviKvsVariant(inf.fileName())); pInfoHash->set("size", new KviKvsVariant((kvs_int_t)inf.size())); KviKvsHash * pMetadataHash = new KviKvsHash(); pHash->set("metadata", new KviKvsVariant(pMetadataHash)); KviPointerHashTable * pInfoFields1 = r.stringInfoFields(); KviPointerHashTableIterator it(*pInfoFields1); while(it.current()) { pMetadataHash->set(it.currentKey(), new KviKvsVariant(*(it.current()))); it.moveNext(); } KviPointerHashTable * pInfoFields2 = r.binaryInfoFields(); KviPointerHashTableIterator it2(*pInfoFields2); while(it2.current()) { pMetadataHash->set(it2.currentKey(), new KviKvsVariant(QString("").arg(it2.current()->size()))); it2.moveNext(); } KviKvsArray * pFilesArray = new KviKvsArray(); pHash->set("files", new KviKvsVariant(pFilesArray)); QStringList sl = KviFileUtils::getFileListing(szUnpackPath); Q_FOREACH(QString fn, sl) pFilesArray->append(new KviKvsVariant(fn)); // delete the random tmp dir if(!KviFileUtils::deleteDir(szUnpackPath)) qDebug("Could not delete temporary directory %s", szUnpackPath.toUtf8().data()); return true; } /* @doc: package.extractfield @type: command @title: package.extractfield @short: Extract a package binary field and save it to a file. @syntax: package.extractfield @description: Extracts a package binary metadata field and saves it to the specified file. This is useful to extract images from the packages. */ static bool package_kvs_cmd_extractField(KviKvsModuleCommandCall * c) { QString szPackagePath, szFieldId, szTargetFileName; KVSM_PARAMETERS_BEGIN(c) KVSM_PARAMETER("package_path", KVS_PT_NONEMPTYSTRING, 0, szPackagePath) KVSM_PARAMETER("field_id", KVS_PT_NONEMPTYSTRING, 0, szFieldId) KVSM_PARAMETER("target_file_name", KVS_PT_NONEMPTYSTRING, 0, szTargetFileName) KVSM_PARAMETERS_END(c) KviPackageReader r; // Unpack addon package into the random tmp dir if(!r.readHeader(szPackagePath)) { c->warning(__tr2qs_ctx("Failed to load package file: %1", "package").arg(r.lastError())); return true; } QByteArray * pField = r.binaryInfoFields()->find(szFieldId); if(!pField) { c->warning(__tr2qs_ctx("Package doesn't contain binary field %1", "package").arg(szFieldId)); return true; } if(!KviFileUtils::writeFile(szTargetFileName, *pField, false)) { c->warning(__tr2qs_ctx("Failed to save file %1", "package").arg(szTargetFileName)); return true; } return true; } static bool package_module_init(KviModule * m) { KVSM_REGISTER_FUNCTION(m, "info", package_kvs_fnc_info); KVSM_REGISTER_SIMPLE_COMMAND(m, "extractField", package_kvs_cmd_extractField); return true; } static bool package_module_cleanup(KviModule *) { return true; } KVIRC_MODULE( "package", // module name "1.0.0", // module version "Copyright (C) 2015 Szymon Stefanek (pragma at kvirc dot net)", // author & (C) "Interface to KVIrc package files", package_module_init, 0, 0, package_module_cleanup, 0)