00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "coreengine.h"
00021
00022 #include "entryhandler.h"
00023 #include "providerhandler.h"
00024 #include "entryloader.h"
00025 #include "providerloader.h"
00026 #include "installation.h"
00027 #include "security.h"
00028
00029 #include <kaboutdata.h>
00030 #include <kconfig.h>
00031 #include <kconfiggroup.h>
00032 #include <kcomponentdata.h>
00033 #include <kdebug.h>
00034 #include <kstandarddirs.h>
00035 #include <kcodecs.h>
00036 #include <kprocess.h>
00037 #include <kshell.h>
00038
00039 #include <kio/job.h>
00040 #include <kmimetype.h>
00041 #include <krandom.h>
00042 #include <ktar.h>
00043 #include <kzip.h>
00044
00045 #include <QtCore/QDir>
00046 #include <QtXml/qdom.h>
00047 #include <QtCore/Q_PID>
00048
00049 #if defined(Q_OS_WIN)
00050 #include <windows.h>
00051 #define _WIN32_IE 0x0500
00052 #include <shlobj.h>
00053 #endif
00054
00055 using namespace KNS;
00056
00057 CoreEngine::CoreEngine(QObject* parent)
00058 : QObject(parent), m_uploadedentry(NULL), m_uploadprovider(NULL), m_installation(NULL), m_activefeeds(0),
00059 m_initialized(false), m_cachepolicy(CacheNever), m_automationpolicy(AutomationOn)
00060 {
00061 }
00062
00063 CoreEngine::~CoreEngine()
00064 {
00065 shutdown();
00066 }
00067
00068 bool CoreEngine::init(const QString &configfile)
00069 {
00070 kDebug() << "Initializing KNS::CoreEngine from '" << configfile << "'";
00071
00072 KConfig conf(configfile);
00073 if (conf.accessMode() == KConfig::NoAccess) {
00074 kError() << "No knsrc file named '" << configfile << "' was found." << endl;
00075 return false;
00076 }
00077
00078
00079
00080
00081 if (KStandardDirs::locate("config", configfile).isEmpty()) {
00082 kError() << "No knsrc file named '" << configfile << "' was found." << endl;
00083 return false;
00084 }
00085
00086 if (!conf.hasGroup("KNewStuff2")) {
00087 kError() << "A knsrc file was found but it doesn't contain a KNewStuff2 section." << endl;
00088 return false;
00089 }
00090
00091 KConfigGroup group = conf.group("KNewStuff2");
00092 m_providersurl = group.readEntry("ProvidersUrl", QString());
00093
00094 m_componentname = QFileInfo(KStandardDirs::locate("config", configfile)).baseName() + ':';
00095
00096
00097
00098 m_installation = new Installation();
00099 QString uncompresssetting = group.readEntry("Uncompress", QString("never"));
00100
00101 if (uncompresssetting == "true") {
00102 uncompresssetting = "always";
00103 }
00104 if (uncompresssetting != "always" && uncompresssetting != "archive" && uncompresssetting != "never") {
00105 kError() << "invalid Uncompress setting chosen, must be one of: always, archive, or never" << endl;
00106 return false;
00107 }
00108 m_installation->setUncompression(uncompresssetting);
00109
00110 m_installation->setCommand(group.readEntry("InstallationCommand", QString()));
00111 m_installation->setUninstallCommand(group.readEntry("UninstallCommand", QString()));
00112 m_installation->setStandardResourceDir(group.readEntry("StandardResource", QString()));
00113 m_installation->setTargetDir(group.readEntry("TargetDir", QString()));
00114 m_installation->setInstallPath(group.readEntry("InstallPath", QString()));
00115 m_installation->setAbsoluteInstallPath(group.readEntry("AbsoluteInstallPath", QString()));
00116 m_installation->setCustomName(group.readEntry("CustomName", false));
00117
00118 QString checksumpolicy = group.readEntry("ChecksumPolicy", QString());
00119 if (!checksumpolicy.isEmpty()) {
00120 if (checksumpolicy == "never")
00121 m_installation->setChecksumPolicy(Installation::CheckNever);
00122 else if (checksumpolicy == "ifpossible")
00123 m_installation->setChecksumPolicy(Installation::CheckIfPossible);
00124 else if (checksumpolicy == "always")
00125 m_installation->setChecksumPolicy(Installation::CheckAlways);
00126 else {
00127 kError() << "The checksum policy '" + checksumpolicy + "' is unknown." << endl;
00128 return false;
00129 }
00130 }
00131
00132 QString signaturepolicy = group.readEntry("SignaturePolicy", QString());
00133 if (!signaturepolicy.isEmpty()) {
00134 if (signaturepolicy == "never")
00135 m_installation->setSignaturePolicy(Installation::CheckNever);
00136 else if (signaturepolicy == "ifpossible")
00137 m_installation->setSignaturePolicy(Installation::CheckIfPossible);
00138 else if (signaturepolicy == "always")
00139 m_installation->setSignaturePolicy(Installation::CheckAlways);
00140 else {
00141 kError() << "The signature policy '" + signaturepolicy + "' is unknown." << endl;
00142 return false;
00143 }
00144 }
00145
00146 QString scope = group.readEntry("Scope", QString());
00147 if (!scope.isEmpty()) {
00148 if (scope == "user")
00149 m_installation->setScope(Installation::ScopeUser);
00150 else if (scope == "system")
00151 m_installation->setScope(Installation::ScopeSystem);
00152 else {
00153 kError() << "The scope '" + scope + "' is unknown." << endl;
00154 return false;
00155 }
00156
00157 if (m_installation->scope() == Installation::ScopeSystem) {
00158 if (!m_installation->installPath().isEmpty()) {
00159 kError() << "System installation cannot be mixed with InstallPath." << endl;
00160 return false;
00161 }
00162 }
00163 }
00164
00165 QString cachePolicy = group.readEntry("CachePolicy", QString());
00166 if (!cachePolicy.isEmpty()) {
00167 if (cachePolicy == "never") {
00168 m_cachepolicy = CacheNever;
00169 } else if (cachePolicy == "replaceable") {
00170 m_cachepolicy = CacheReplaceable;
00171 } else if (cachePolicy == "resident") {
00172 m_cachepolicy = CacheResident;
00173 } else if (cachePolicy == "only") {
00174 m_cachepolicy = CacheOnly;
00175 } else {
00176 kError() << "Cache policy '" + cachePolicy + "' is unknown." << endl;
00177 }
00178 }
00179 kDebug() << "cache policy: " << cachePolicy;
00180
00181 m_initialized = true;
00182
00183 return true;
00184 }
00185
00186 void CoreEngine::start()
00187 {
00188
00189
00190 if (!m_initialized) {
00191 kError() << "Must call KNS::CoreEngine::init() first." << endl;
00192 return;
00193 }
00194
00195
00196 loadRegistry();
00197
00198
00199 if (m_cachepolicy != CacheNever) {
00200 loadProvidersCache();
00201 }
00202
00203
00204 if (m_cachepolicy == CacheOnly) {
00205
00206 return;
00207 }
00208
00209 ProviderLoader *provider_loader = new ProviderLoader(this);
00210
00211
00212 connect(provider_loader,
00213 SIGNAL(signalProvidersLoaded(KNS::Provider::List)),
00214 SLOT(slotProvidersLoaded(KNS::Provider::List)));
00215 connect(provider_loader,
00216 SIGNAL(signalProvidersFailed()),
00217 SLOT(slotProvidersFailed()));
00218
00219 provider_loader->load(m_providersurl);
00220 }
00221
00222 void CoreEngine::loadEntries(Provider *provider)
00223 {
00224
00225
00226 if (m_cachepolicy == CacheOnly) {
00227 return;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 QStringList feeds = provider->feeds();
00238 for (int i = 0; i < feeds.count(); i++) {
00239 Feed *feed = provider->downloadUrlFeed(feeds.at(i));
00240 if (feed) {
00241 ++m_activefeeds;
00242
00243 EntryLoader *entry_loader = new EntryLoader(this);
00244
00245 connect(entry_loader,
00246 SIGNAL(signalEntriesLoaded(KNS::Entry::List)),
00247 SLOT(slotEntriesLoaded(KNS::Entry::List)));
00248 connect(entry_loader,
00249 SIGNAL(signalEntriesFailed()),
00250 SLOT(slotEntriesFailed()));
00251 connect(entry_loader,
00252 SIGNAL(signalProgress(KJob*, unsigned long)),
00253 SLOT(slotProgress(KJob*, unsigned long)));
00254
00255 entry_loader->load(provider, feed);
00256 }
00257 }
00258 }
00259
00260 void CoreEngine::downloadPreview(Entry *entry)
00261 {
00262 if (m_previewfiles.contains(entry)) {
00263
00264
00265 emit signalPreviewLoaded(KUrl::fromPath(m_previewfiles[entry]));
00266 return;
00267 }
00268
00269 KUrl source = KUrl(entry->preview().representation());
00270
00271 if (!source.isValid()) {
00272 kError() << "The entry doesn't have a preview." << endl;
00273 return;
00274 }
00275
00276 KUrl destination = KGlobal::dirs()->saveLocation("tmp") + KRandom::randomString(10);
00277
00278
00279
00280 KIO::FileCopyJob *job = KIO::file_copy(source, destination, -1, KIO::Overwrite | KIO::HideProgressInfo);
00281 connect(job,
00282 SIGNAL(result(KJob*)),
00283 SLOT(slotPreviewResult(KJob*)));
00284 connect(job,
00285 SIGNAL(progress(KJob*, unsigned long)),
00286 SLOT(slotProgress(KJob*, unsigned long)));
00287
00288 m_entry_jobs[job] = entry;
00289 }
00290
00291 void CoreEngine::downloadPayload(Entry *entry)
00292 {
00293 if(!entry) {
00294 emit signalPayloadFailed(entry);
00295 return;
00296 }
00297 KUrl source = KUrl(entry->payload().representation());
00298
00299 if (!source.isValid()) {
00300 kError() << "The entry doesn't have a payload." << endl;
00301 emit signalPayloadFailed(entry);
00302 return;
00303 }
00304
00305 if (m_installation->isRemote()) {
00306
00307
00308 entry->setStatus(Entry::Installed);
00309 m_payloadfiles[entry] = entry->payload().representation();
00310 install(source.pathOrUrl());
00311 emit signalPayloadLoaded(source);
00312
00313 return;
00314 }
00315
00316 KUrl destination = KGlobal::dirs()->saveLocation("tmp") + KRandom::randomString(10);
00317 kDebug() << "Downloading payload '" << source << "' to '" << destination << "'";
00318
00319
00320 KIO::FileCopyJob *job = KIO::file_copy(source, destination, -1, KIO::Overwrite | KIO::HideProgressInfo);
00321 connect(job,
00322 SIGNAL(result(KJob*)),
00323 SLOT(slotPayloadResult(KJob*)));
00324 connect(job,
00325 SIGNAL(percent(KJob*, unsigned long)),
00326 SLOT(slotProgress(KJob*, unsigned long)));
00327
00328 m_entry_jobs[job] = entry;
00329 }
00330
00331 bool CoreEngine::uploadEntry(Provider *provider, Entry *entry)
00332 {
00333
00334
00335 if (m_uploadedentry) {
00336 kError() << "Another upload is in progress!" << endl;
00337 return false;
00338 }
00339
00340 if (!provider->uploadUrl().isValid()) {
00341 kError() << "The provider doesn't support uploads." << endl;
00342 return false;
00343
00344
00345 }
00346
00347
00348
00349 m_uploadedentry = entry;
00350
00351 KUrl sourcepayload = KUrl(entry->payload().representation());
00352 KUrl destfolder = provider->uploadUrl();
00353
00354 destfolder.setFileName(sourcepayload.fileName());
00355
00356 KIO::FileCopyJob *fcjob = KIO::file_copy(sourcepayload, destfolder, -1, KIO::Overwrite | KIO::HideProgressInfo);
00357 connect(fcjob,
00358 SIGNAL(result(KJob*)),
00359 SLOT(slotUploadPayloadResult(KJob*)));
00360
00361 return true;
00362 }
00363
00364 void CoreEngine::slotProvidersLoaded(KNS::Provider::List list)
00365 {
00366
00367 ProviderLoader *loader = dynamic_cast<ProviderLoader*>(sender());
00368 delete loader;
00369
00370 mergeProviders(list);
00371 }
00372
00373 void CoreEngine::slotProvidersFailed()
00374 {
00375 kDebug() << "slotProvidersFailed";
00376 ProviderLoader *loader = dynamic_cast<ProviderLoader*>(sender());
00377 delete loader;
00378
00379 emit signalProvidersFailed();
00380 }
00381
00382 void CoreEngine::slotEntriesLoaded(KNS::Entry::List list)
00383 {
00384 EntryLoader *loader = dynamic_cast<EntryLoader*>(sender());
00385 if (!loader) return;
00386 const Provider *provider = loader->provider();
00387 Feed *feed = loader->feed();
00388 delete loader;
00389 m_activefeeds--;
00390
00391
00392
00393
00394
00395
00396 mergeEntries(list, feed, provider);
00397 }
00398
00399 void CoreEngine::slotEntriesFailed()
00400 {
00401 EntryLoader *loader = dynamic_cast<EntryLoader*>(sender());
00402 delete loader;
00403 m_activefeeds--;
00404
00405 emit signalEntriesFailed();
00406 }
00407
00408 void CoreEngine::slotProgress(KJob *job, unsigned long percent)
00409 {
00410 QString url;
00411 KIO::FileCopyJob * copyJob = qobject_cast<KIO::FileCopyJob*>(job);
00412 KIO::TransferJob * transferJob = qobject_cast<KIO::TransferJob*>(job);
00413 if (copyJob != NULL) {
00414 url = copyJob->srcUrl().fileName();
00415 } else if (transferJob != NULL) {
00416 url = transferJob->url().fileName();
00417 }
00418
00419 QString message = QString("loading %1").arg(url);
00420 emit signalProgress(message, percent);
00421 }
00422
00423 void CoreEngine::slotPayloadResult(KJob *job)
00424 {
00425
00426 if (m_entry_jobs.contains(job)) {
00427 Entry *entry = m_entry_jobs[job];
00428 m_entry_jobs.remove(job);
00429
00430 if (job->error()) {
00431 kError() << "Cannot load payload file." << endl;
00432 kError() << job->errorString() << endl;
00433
00434 emit signalPayloadFailed(entry);
00435 } else {
00436 KIO::FileCopyJob *fcjob = static_cast<KIO::FileCopyJob*>(job);
00437 m_payloadfiles[entry] = fcjob->destUrl().path();
00438
00439 install(fcjob->destUrl().pathOrUrl());
00440
00441 emit signalPayloadLoaded(fcjob->destUrl());
00442 }
00443 }
00444 }
00445
00446
00447 void CoreEngine::slotPreviewResult(KJob *job)
00448 {
00449 if (job->error()) {
00450 kError() << "Cannot load preview file." << endl;
00451 kError() << job->errorString() << endl;
00452
00453 m_entry_jobs.remove(job);
00454 emit signalPreviewFailed();
00455 } else {
00456 KIO::FileCopyJob *fcjob = static_cast<KIO::FileCopyJob*>(job);
00457
00458 if (m_entry_jobs.contains(job)) {
00459
00460 Entry *entry = m_entry_jobs[job];
00461 m_entry_jobs.remove(job);
00462 m_previewfiles[entry] = fcjob->destUrl().path();
00463 cacheEntry(entry);
00464 }
00465
00466
00467 emit signalPreviewLoaded(fcjob->destUrl());
00468 }
00469 }
00470
00471 void CoreEngine::slotUploadPayloadResult(KJob *job)
00472 {
00473 if (job->error()) {
00474 kError() << "Cannot upload payload file." << endl;
00475 kError() << job->errorString() << endl;
00476
00477 m_uploadedentry = NULL;
00478 m_uploadprovider = NULL;
00479
00480 emit signalEntryFailed();
00481 return;
00482 }
00483
00484 if (m_uploadedentry->preview().isEmpty()) {
00485
00486 slotUploadPreviewResult(job);
00487 return;
00488 }
00489
00490 KUrl sourcepreview = KUrl(m_uploadedentry->preview().representation());
00491 KUrl destfolder = m_uploadprovider->uploadUrl();
00492
00493 KIO::FileCopyJob *fcjob = KIO::file_copy(sourcepreview, destfolder, -1, KIO::Overwrite | KIO::HideProgressInfo);
00494 connect(fcjob,
00495 SIGNAL(result(KJob*)),
00496 SLOT(slotUploadPreviewResult(KJob*)));
00497 }
00498
00499 void CoreEngine::slotUploadPreviewResult(KJob *job)
00500 {
00501 if (job->error()) {
00502 kError() << "Cannot upload preview file." << endl;
00503 kError() << job->errorString() << endl;
00504
00505 m_uploadedentry = NULL;
00506 m_uploadprovider = NULL;
00507
00508 emit signalEntryFailed();
00509 return;
00510 }
00511
00512
00513
00514
00515
00516 KUrl sourcemeta = KGlobal::dirs()->saveLocation("tmp") + KRandom::randomString(10) + ".meta";
00517 KUrl destfolder = m_uploadprovider->uploadUrl();
00518
00519 EntryHandler eh(*m_uploadedentry);
00520 QDomElement exml = eh.entryXML();
00521
00522 QFile f(sourcemeta.path());
00523 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
00524 kError() << "Cannot write meta information to '" << sourcemeta << "'." << endl;
00525
00526 m_uploadedentry = NULL;
00527 m_uploadprovider = NULL;
00528
00529 emit signalEntryFailed();
00530 return;
00531 }
00532 QTextStream metastream(&f);
00533 metastream << exml;
00534 f.close();
00535
00536 KIO::FileCopyJob *fcjob = KIO::file_copy(sourcemeta, destfolder, -1, KIO::Overwrite | KIO::HideProgressInfo);
00537 connect(fcjob,
00538 SIGNAL(result(KJob*)),
00539 SLOT(slotUploadMetaResult(KJob*)));
00540 }
00541
00542 void CoreEngine::slotUploadMetaResult(KJob *job)
00543 {
00544 if (job->error()) {
00545 kError() << "Cannot upload meta file." << endl;
00546 kError() << job->errorString() << endl;
00547
00548 m_uploadedentry = NULL;
00549 m_uploadprovider = NULL;
00550
00551 emit signalEntryFailed();
00552 return;
00553 } else {
00554 m_uploadedentry = NULL;
00555 m_uploadprovider = NULL;
00556
00557
00558 emit signalEntryUploaded();
00559 }
00560 }
00561
00562 void CoreEngine::loadRegistry()
00563 {
00564 KStandardDirs d;
00565
00566
00567
00568 QString realAppName = m_componentname.split(':')[0];
00569
00570
00571 const QStringList dirs = d.findDirs("data", "knewstuff2-entries.registry");
00572 for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
00573
00574 QDir dir((*it));
00575 const QStringList files = dir.entryList(QDir::Files | QDir::Readable);
00576 for (QStringList::const_iterator fit = files.begin(); fit != files.end(); ++fit) {
00577 QString filepath = (*it) + '/' + (*fit);
00578
00579
00580 bool ret;
00581 QFileInfo info(filepath);
00582 QFile f(filepath);
00583
00584
00585
00586
00587 QString thisAppName = QString::fromUtf8(QByteArray::fromBase64(info.baseName().toUtf8()));
00588
00589
00590
00591 thisAppName = thisAppName.split(':')[0];
00592
00593 if (thisAppName != realAppName) {
00594 continue;
00595 }
00596
00597 ret = f.open(QIODevice::ReadOnly);
00598 if (!ret) {
00599 kWarning() << "The file could not be opened.";
00600 continue;
00601 }
00602
00603 QDomDocument doc;
00604 ret = doc.setContent(&f);
00605 if (!ret) {
00606 kWarning() << "The file could not be parsed.";
00607 continue;
00608 }
00609
00610 QDomElement root = doc.documentElement();
00611 if (root.tagName() != "ghnsinstall") {
00612 kWarning() << "The file doesn't seem to be of interest.";
00613 continue;
00614 }
00615
00616 QDomElement stuff = root.firstChildElement("stuff");
00617 if (stuff.isNull()) {
00618 kWarning() << "Missing GHNS installation metadata.";
00619 continue;
00620 }
00621
00622 EntryHandler handler(stuff);
00623 if (!handler.isValid()) {
00624 kWarning() << "Invalid GHNS installation metadata.";
00625 continue;
00626 }
00627
00628 Entry *e = handler.entryptr();
00629 e->setStatus(Entry::Installed);
00630 e->setSource(Entry::Registry);
00631 m_entry_registry.insert(id(e), e);
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647 }
00648 }
00649 }
00650
00651 void CoreEngine::loadProvidersCache()
00652 {
00653 KStandardDirs d;
00654
00655
00656 QString cachefile = d.findResource("cache", m_componentname + "kns2providers.cache.xml");
00657 if (cachefile.isEmpty()) {
00658 kDebug() << "Cache not present, skip loading.";
00659 return;
00660 }
00661
00662 kDebug() << "Loading provider cache from file '" + cachefile + "'.";
00663
00664
00665 bool ret;
00666 QFile f(cachefile);
00667 ret = f.open(QIODevice::ReadOnly);
00668 if (!ret) {
00669 kWarning() << "The file could not be opened.";
00670 return;
00671 }
00672
00673
00674 QDomDocument doc;
00675 ret = doc.setContent(&f);
00676 if (!ret) {
00677 kWarning() << "The file could not be parsed.";
00678 return;
00679 }
00680
00681
00682 QDomElement root = doc.documentElement();
00683 if (root.tagName() != "ghnsproviders") {
00684 kWarning() << "The file doesn't seem to be of interest.";
00685 return;
00686 }
00687
00688
00689 QDomElement provider = root.firstChildElement("provider");
00690 if (provider.isNull()) {
00691 kWarning() << "Missing provider entries in the cache.";
00692 return;
00693 }
00694
00695
00696 while (!provider.isNull()) {
00697 ProviderHandler handler(provider);
00698 if (!handler.isValid()) {
00699 kWarning() << "Invalid provider metadata.";
00700 continue;
00701 }
00702
00703 Provider *p = handler.providerptr();
00704 m_provider_cache.append(p);
00705 m_provider_index[pid(p)] = p;
00706
00707 emit signalProviderLoaded(p);
00708
00709 loadFeedCache(p);
00710
00711
00712
00713
00714
00715
00716 provider = provider.nextSiblingElement("provider");
00717 }
00718
00719 if (m_cachepolicy == CacheOnly) {
00720 emit signalEntriesFinished();
00721 }
00722 }
00723
00724 void CoreEngine::loadFeedCache(Provider *provider)
00725 {
00726 KStandardDirs d;
00727
00728 kDebug() << "Loading feed cache.";
00729
00730 QStringList cachedirs = d.findDirs("cache", m_componentname + "kns2feeds.cache");
00731 if (cachedirs.size() == 0) {
00732 kDebug() << "Cache directory not present, skip loading.";
00733 return;
00734 }
00735 QString cachedir = cachedirs.first();
00736
00737 QStringList entrycachedirs = d.findDirs("cache", "knewstuff2-entries.cache/");
00738 if (entrycachedirs.size() == 0) {
00739 kDebug() << "Cache directory not present, skip loading.";
00740 return;
00741 }
00742 QString entrycachedir = entrycachedirs.first();
00743
00744 kDebug() << "Load from directory: " + cachedir;
00745
00746 QStringList feeds = provider->feeds();
00747 for (int i = 0; i < feeds.count(); i++) {
00748 Feed *feed = provider->downloadUrlFeed(feeds.at(i));
00749 QString feedname = feeds.at(i);
00750
00751 QString idbase64 = QString(pid(provider).toUtf8().toBase64() + '-' + feedname);
00752 QString cachefile = cachedir + '/' + idbase64 + ".xml";
00753
00754 kDebug() << " + Load from file: " + cachefile;
00755
00756 bool ret;
00757 QFile f(cachefile);
00758 ret = f.open(QIODevice::ReadOnly);
00759 if (!ret) {
00760 kWarning() << "The file could not be opened.";
00761 return;
00762 }
00763
00764 QDomDocument doc;
00765 ret = doc.setContent(&f);
00766 if (!ret) {
00767 kWarning() << "The file could not be parsed.";
00768 return;
00769 }
00770
00771 QDomElement root = doc.documentElement();
00772 if (root.tagName() != "ghnsfeeds") {
00773 kWarning() << "The file doesn't seem to be of interest.";
00774 return;
00775 }
00776
00777 QDomElement entryel = root.firstChildElement("entry-id");
00778 if (entryel.isNull()) {
00779 kWarning() << "Missing entries in the cache.";
00780 return;
00781 }
00782
00783 while (!entryel.isNull()) {
00784 QString idbase64 = entryel.text();
00785
00786
00787 QString filepath = entrycachedir + '/' + idbase64 + ".meta";
00788
00789
00790
00791
00792 Entry *entry = loadEntryCache(filepath);
00793 if (entry) {
00794 QString entryid = id(entry);
00795
00796 if (m_entry_registry.contains(entryid)) {
00797 Entry * registryEntry = m_entry_registry.value(entryid);
00798 entry->setStatus(registryEntry->status());
00799 entry->setInstalledFiles(registryEntry->installedFiles());
00800 }
00801
00802 feed->addEntry(entry);
00803
00804 emit signalEntryLoaded(entry, feed, provider);
00805 }
00806
00807 entryel = entryel.nextSiblingElement("entry-id");
00808 }
00809 }
00810 }
00811
00812 KNS::Entry *CoreEngine::loadEntryCache(const QString& filepath)
00813 {
00814 bool ret;
00815 QFile f(filepath);
00816 ret = f.open(QIODevice::ReadOnly);
00817 if (!ret) {
00818 kWarning() << "The file " << filepath << " could not be opened.";
00819 return NULL;
00820 }
00821
00822 QDomDocument doc;
00823 ret = doc.setContent(&f);
00824 if (!ret) {
00825 kWarning() << "The file could not be parsed.";
00826 return NULL;
00827 }
00828
00829 QDomElement root = doc.documentElement();
00830 if (root.tagName() != "ghnscache") {
00831 kWarning() << "The file doesn't seem to be of interest.";
00832 return NULL;
00833 }
00834
00835 QDomElement stuff = root.firstChildElement("stuff");
00836 if (stuff.isNull()) {
00837 kWarning() << "Missing GHNS cache metadata.";
00838 return NULL;
00839 }
00840
00841 EntryHandler handler(stuff);
00842 if (!handler.isValid()) {
00843 kWarning() << "Invalid GHNS installation metadata.";
00844 return NULL;
00845 }
00846
00847 Entry *e = handler.entryptr();
00848 e->setStatus(Entry::Downloadable);
00849 m_entry_cache.append(e);
00850 m_entry_index[id(e)] = e;
00851
00852 if (root.hasAttribute("previewfile")) {
00853 m_previewfiles[e] = root.attribute("previewfile");
00854
00855 }
00856
00857 if (root.hasAttribute("payloadfile")) {
00858 m_payloadfiles[e] = root.attribute("payloadfile");
00859
00860 }
00861
00862 e->setSource(Entry::Cache);
00863
00864 return e;
00865 }
00866
00867
00868 #if 0
00869 void CoreEngine::loadEntriesCache()
00870 {
00871 KStandardDirs d;
00872
00873
00874
00875 QStringList cachedirs = d.findDirs("cache", "knewstuff2-entries.cache/" + m_componentname);
00876 if (cachedirs.size() == 0) {
00877
00878 return;
00879 }
00880 QString cachedir = cachedirs.first();
00881
00882
00883
00884 QDir dir(cachedir);
00885 QStringList files = dir.entryList(QDir::Files | QDir::Readable);
00886 for (QStringList::iterator fit = files.begin(); fit != files.end(); ++fit) {
00887 QString filepath = cachedir + '/' + (*fit);
00888
00889
00890 Entry *e = loadEntryCache(filepath);
00891
00892 if (e) {
00893
00894 emit signalEntryLoaded(e, NULL, NULL);
00895 }
00896 }
00897 }
00898 #endif
00899
00900 void CoreEngine::shutdown()
00901 {
00902 m_entry_index.clear();
00903 m_provider_index.clear();
00904
00905 qDeleteAll(m_entry_cache);
00906 qDeleteAll(m_provider_cache);
00907
00908 m_entry_cache.clear();
00909 m_provider_cache.clear();
00910
00911 delete m_installation;
00912 }
00913
00914 bool CoreEngine::providerCached(Provider *provider)
00915 {
00916 if (m_cachepolicy == CacheNever) return false;
00917
00918 if (m_provider_index.contains(pid(provider)))
00919 return true;
00920 return false;
00921 }
00922
00923 bool CoreEngine::providerChanged(Provider *oldprovider, Provider *provider)
00924 {
00925 QStringList oldfeeds = oldprovider->feeds();
00926 QStringList feeds = provider->feeds();
00927 if (oldfeeds.count() != feeds.count())
00928 return true;
00929 for (int i = 0; i < feeds.count(); i++) {
00930 Feed *oldfeed = oldprovider->downloadUrlFeed(feeds.at(i));
00931 Feed *feed = provider->downloadUrlFeed(feeds.at(i));
00932 if (!oldfeed)
00933 return true;
00934 if (feed->feedUrl() != oldfeed->feedUrl())
00935 return true;
00936 }
00937 return false;
00938 }
00939
00940 void CoreEngine::mergeProviders(Provider::List providers)
00941 {
00942 for (Provider::List::Iterator it = providers.begin(); it != providers.end(); ++it) {
00943 Provider *p = (*it);
00944
00945 if (providerCached(p)) {
00946 kDebug() << "CACHE: hit provider " << p->name().representation();
00947 Provider *oldprovider = m_provider_index[pid(p)];
00948 if (providerChanged(oldprovider, p)) {
00949 kDebug() << "CACHE: update provider";
00950 cacheProvider(p);
00951 emit signalProviderChanged(p);
00952 }
00953
00954
00955
00956
00957 } else {
00958 if (m_cachepolicy != CacheNever) {
00959 kDebug() << "CACHE: miss provider " << p->name().representation();
00960 cacheProvider(p);
00961 }
00962 emit signalProviderLoaded(p);
00963
00964
00965
00966
00967
00968 }
00969
00970 m_provider_cache.append(p);
00971 m_provider_index[pid(p)] = p;
00972 }
00973
00974 emit signalProvidersFinished();
00975 }
00976
00977 bool CoreEngine::entryCached(Entry *entry)
00978 {
00979 if (m_cachepolicy == CacheNever) return false;
00980
00981
00982
00983 if (m_entry_index.contains(id(entry)) && m_entry_index[id(entry)]->source() == Entry::Cache) {
00984 return true;
00985 }
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996 for (int i = 0; i < m_entry_cache.count(); i++) {
00997 Entry *oldentry = m_entry_cache.at(i);
00998 if (id(entry) == id(oldentry)) return true;
00999
01000
01001
01003
01004 }
01005
01006 return false;
01007 }
01008
01009 bool CoreEngine::entryChanged(Entry *oldentry, Entry *entry)
01010 {
01011
01012 if ((!oldentry) || (entry->releaseDate() > oldentry->releaseDate())
01013 || (entry->version() > oldentry->version())
01014 || (entry->release() > oldentry->release()))
01015 return true;
01016 return false;
01017 }
01018
01019 void CoreEngine::mergeEntries(Entry::List entries, Feed *feed, const Provider *provider)
01020 {
01021 for (Entry::List::Iterator it = entries.begin(); it != entries.end(); ++it) {
01022
01023
01024 Entry *e = (*it);
01025 QString thisId = id(e);
01026
01027
01028 if (m_entry_registry.contains(thisId)) {
01029
01030 Entry *registryentry = m_entry_registry[thisId];
01031 e->setInstalledFiles(registryentry->installedFiles());
01032
01033 if (entryChanged(registryentry, e)) {
01034 e->setStatus(Entry::Updateable);
01035 emit signalEntryChanged(e);
01036 } else {
01037
01038 e->setStatus(registryentry->status());
01039 }
01040
01041 if (entryCached(e)) {
01042
01043 Entry * cachedentry = m_entry_index[thisId];
01044 if (entryChanged(cachedentry, e)) {
01045
01046 cachedentry->setStatus(Entry::Updateable);
01047
01048 if (m_cachepolicy != CacheNever) {
01049 cacheEntry(e);
01050 }
01051 emit signalEntryChanged(e);
01052 }
01053
01054
01055 feed->removeEntry(cachedentry);
01056
01057 } else {
01058 emit signalEntryLoaded(e, feed, provider);
01059 }
01060
01061 } else {
01062 e->setStatus(Entry::Downloadable);
01063
01064 if (entryCached(e)) {
01065
01066
01067 Entry *cachedentry = m_entry_index[thisId];
01068 if (entryChanged(cachedentry, e)) {
01069
01070 e->setStatus(Entry::Updateable);
01071
01072 if (m_cachepolicy != CacheNever) {
01073 cacheEntry(e);
01074 }
01075 emit signalEntryChanged(e);
01076
01077
01078 }
01079
01080 feed->removeEntry(cachedentry);
01081
01082 } else {
01083 if (m_cachepolicy != CacheNever) {
01084
01085 cacheEntry(e);
01086 }
01087 emit signalEntryLoaded(e, feed, provider);
01088 }
01089
01090 m_entry_cache.append(e);
01091 m_entry_index[thisId] = e;
01092 }
01093 }
01094
01095 if (m_cachepolicy != CacheNever) {
01096
01097
01098
01099 QStringList feeds = provider->feeds();
01100 QString feedname;
01101 for (int i = 0; i < feeds.size(); ++i) {
01102 if (provider->downloadUrlFeed(feeds[i]) == feed) {
01103 feedname = feeds[i];
01104 }
01105 }
01106 cacheFeed(provider, feedname, feed, entries);
01107 }
01108
01109 emit signalEntriesFeedFinished(feed);
01110 if (m_activefeeds == 0) {
01111 emit signalEntriesFinished();
01112 }
01113 }
01114
01115 void CoreEngine::cacheProvider(Provider *provider)
01116 {
01117 KStandardDirs d;
01118
01119 kDebug() << "Caching provider.";
01120
01121 QString cachedir = d.saveLocation("cache");
01122 QString cachefile = cachedir + m_componentname + "kns2providers.cache.xml";
01123
01124 kDebug() << " + Save to file '" + cachefile + "'.";
01125
01126 QDomDocument doc;
01127 QDomElement root = doc.createElement("ghnsproviders");
01128
01129 for (Provider::List::Iterator it = m_provider_cache.begin(); it != m_provider_cache.end(); ++it) {
01130 Provider *p = (*it);
01131 ProviderHandler ph(*p);
01132 QDomElement pxml = ph.providerXML();
01133 root.appendChild(pxml);
01134 }
01135 ProviderHandler ph(*provider);
01136 QDomElement pxml = ph.providerXML();
01137 root.appendChild(pxml);
01138
01139 QFile f(cachefile);
01140 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
01141 kError() << "Cannot write meta information to '" << cachedir << "'." << endl;
01142
01143 return;
01144 }
01145 QTextStream metastream(&f);
01146 metastream << root;
01147 f.close();
01148
01149
01150
01151
01152
01153
01154 }
01155
01156 void CoreEngine::cacheFeed(const Provider *provider, const QString & feedname, const Feed *feed, Entry::List entries)
01157 {
01158
01159 KStandardDirs d;
01160
01161 Q_UNUSED(feed);
01162
01163 QString cachedir = d.saveLocation("cache", m_componentname + "kns2feeds.cache");
01164
01165 QString idbase64 = QString(pid(provider).toUtf8().toBase64() + '-' + feedname);
01166 QString cachefile = idbase64 + ".xml";
01167
01168 kDebug() << "Caching feed to file '" + cachefile + "'.";
01169
01170 QDomDocument doc;
01171 QDomElement root = doc.createElement("ghnsfeeds");
01172 for (int i = 0; i < entries.count(); i++) {
01173 QString idbase64 = id(entries.at(i)).toUtf8().toBase64();
01174 QDomElement entryel = doc.createElement("entry-id");
01175 root.appendChild(entryel);
01176 QDomText entrytext = doc.createTextNode(idbase64);
01177 entryel.appendChild(entrytext);
01178 }
01179
01180 QFile f(cachedir + cachefile);
01181 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
01182 kError() << "Cannot write meta information to '" << cachedir + cachefile << "'." << endl;
01183
01184 return;
01185 }
01186 QTextStream metastream(&f);
01187 metastream << root;
01188 f.close();
01189 }
01190
01191 void CoreEngine::cacheEntry(Entry *entry)
01192 {
01193 KStandardDirs d;
01194
01195 QString cachedir = d.saveLocation("cache", "knewstuff2-entries.cache/");
01196
01197 kDebug() << "Caching entry in directory '" + cachedir + "'.";
01198
01199
01200
01201 QString idbase64 = QString(id(entry).toUtf8().toBase64());
01202 QString cachefile = idbase64 + ".meta";
01203
01204 kDebug() << "Caching to file '" + cachefile + "'.";
01205
01206
01207
01208
01209 EntryHandler eh(*entry);
01210 QDomElement exml = eh.entryXML();
01211
01212 QDomDocument doc;
01213 QDomElement root = doc.createElement("ghnscache");
01214 root.appendChild(exml);
01215
01216 if (m_previewfiles.contains(entry)) {
01217 root.setAttribute("previewfile", m_previewfiles[entry]);
01218 }
01219
01220
01221
01222
01223 QFile f(cachedir + cachefile);
01224 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
01225 kError() << "Cannot write meta information to '" << cachedir + cachefile << "'." << endl;
01226
01227 return;
01228 }
01229 QTextStream metastream(&f);
01230 metastream << root;
01231 f.close();
01232 }
01233
01234 void CoreEngine::registerEntry(Entry *entry)
01235 {
01236 m_entry_registry.insert(id(entry), entry);
01237 KStandardDirs d;
01238
01239
01240
01241
01242 QString registrydir = d.saveLocation("data", "knewstuff2-entries.registry");
01243
01244
01245
01246
01247 QString registryfile = QString(id(entry).toUtf8().toBase64()) + ".meta";
01248
01249
01250
01251 EntryHandler eh(*entry);
01252 QDomElement exml = eh.entryXML();
01253
01254 QDomDocument doc;
01255 QDomElement root = doc.createElement("ghnsinstall");
01256 root.appendChild(exml);
01257
01258 if (m_payloadfiles.contains(entry)) {
01259 root.setAttribute("payloadfile", m_payloadfiles[entry]);
01260 }
01261
01262 QFile f(registrydir + registryfile);
01263 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
01264 kError() << "Cannot write meta information to '" << registrydir + registryfile << "'." << endl;
01265
01266 return;
01267 }
01268 QTextStream metastream(&f);
01269 metastream << root;
01270 f.close();
01271 }
01272
01273 void KNS::CoreEngine::unregisterEntry(Entry * entry)
01274 {
01275 KStandardDirs d;
01276
01277
01278 QString registrydir = d.saveLocation("data", "knewstuff2-entries.registry");
01279
01280
01281 QString registryfile = QString(id(entry).toUtf8().toBase64()) + ".meta";
01282
01283 QFile::remove(registrydir + registryfile);
01284
01285
01286 m_entry_registry.remove(id(entry));
01287 }
01288
01289 QString CoreEngine::id(Entry *e)
01290 {
01291
01292
01293
01294 return m_componentname + e->name().language() + ':' + e->name().representation();
01295 }
01296
01297 QString CoreEngine::pid(const Provider *p)
01298 {
01299
01300
01301
01302
01303
01304 QStringList feeds = p->feeds();
01305 for (int i = 0; i < feeds.count(); i++) {
01306 QString feedtype = feeds.at(i);
01307 Feed *f = p->downloadUrlFeed(feedtype);
01308 if (f->feedUrl().isValid())
01309 return m_componentname + f->feedUrl().url();
01310 }
01311 if (p->webService().isValid())
01312 return m_componentname + p->webService().url();
01313 return m_componentname;
01314 }
01315
01316 bool CoreEngine::install(const QString &payloadfile)
01317 {
01318 QList<Entry*> entries = m_payloadfiles.keys(payloadfile);
01319 if (entries.size() != 1) {
01320
01321 kError() << "ASSERT: payloadfile is not associated" << endl;
01322 return false;
01323 }
01324 Entry *entry = entries.first();
01325
01326 bool update = (entry->status() == Entry::Updateable);
01327
01328 entry->setStatus(Entry::Installed);
01329
01330
01331
01332
01333
01334 if (m_installation->checksumPolicy() != Installation::CheckNever) {
01335 if (entry->checksum().isEmpty()) {
01336 if (m_installation->checksumPolicy() == Installation::CheckIfPossible) {
01337
01338 } else {
01339 kError() << "Checksum verification not possible" << endl;
01340 return false;
01341 }
01342 } else {
01343
01344 }
01345 }
01346 if (m_installation->signaturePolicy() != Installation::CheckNever) {
01347 if (entry->signature().isEmpty()) {
01348 if (m_installation->signaturePolicy() == Installation::CheckIfPossible) {
01349
01350 } else {
01351 kError() << "Signature verification not possible" << endl;
01352 return false;
01353 }
01354 } else {
01355
01356 }
01357 }
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368 QStringList installedFiles;
01369 QString installpath(payloadfile);
01370 if (!m_installation->isRemote()) {
01371
01372 QString installdir;
01373
01374 int pathcounter = 0;
01375 if (!m_installation->standardResourceDir().isEmpty()) {
01376 if (m_installation->scope() == Installation::ScopeUser) {
01377 installdir = KStandardDirs::locateLocal(m_installation->standardResourceDir().toUtf8(), "/");
01378 } else {
01379 installdir = KStandardDirs::installPath(m_installation->standardResourceDir().toUtf8());
01380 }
01381 pathcounter++;
01382 }
01383 if (!m_installation->targetDir().isEmpty()) {
01384 if (m_installation->scope() == Installation::ScopeUser) {
01385 installdir = KStandardDirs::locateLocal("data", m_installation->targetDir() + '/');
01386 } else {
01387 installdir = KStandardDirs::installPath("data") + m_installation->targetDir() + '/';
01388 }
01389 pathcounter++;
01390 }
01391 if (!m_installation->installPath().isEmpty()) {
01392 #if defined(Q_WS_WIN)
01393 WCHAR wPath[MAX_PATH+1];
01394 if ( SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, wPath) == S_OK) {
01395 installdir = QString::fromUtf16((const ushort *) wPath) + QLatin1Char('/') + m_installation->installPath() + QLatin1Char('/');
01396 } else {
01397 installdir = QDir::home().path() + QLatin1Char('/') + m_installation->installPath() + QLatin1Char('/');
01398 }
01399 #else
01400 installdir = QDir::home().path() + '/' + m_installation->installPath() + '/';
01401 #endif
01402 pathcounter++;
01403 }
01404 if (!m_installation->absoluteInstallPath().isEmpty()) {
01405 installdir = m_installation->absoluteInstallPath() + '/';
01406 pathcounter++;
01407 }
01408 if (pathcounter != 1) {
01409 kError() << "Wrong number of installation directories given." << endl;
01410 return false;
01411 }
01412
01413 kDebug() << "installdir: " << installdir;
01414 bool isarchive = true;
01415
01416
01417 if (m_installation->uncompression() == "always" || m_installation->uncompression() == "archive") {
01418
01419 installpath = installdir;
01420 KMimeType::Ptr mimeType = KMimeType::findByPath(payloadfile);
01421
01422
01423
01424
01425 KArchive *archive = 0;
01426
01427 if (mimeType->name() == "application/zip") {
01428 archive = new KZip(payloadfile);
01429 } else if (mimeType->name() == "application/tar"
01430 || mimeType->name() == "application/x-gzip"
01431 || mimeType->name() == "application/x-bzip") {
01432 archive = new KTar(payloadfile);
01433 } else {
01434 delete archive;
01435 kError() << "Could not determine type of archive file '" << payloadfile << "'";
01436 if (m_installation->uncompression() == "always") {
01437 return false;
01438 }
01439 isarchive = false;
01440 }
01441
01442 if (isarchive) {
01443 bool success = archive->open(QIODevice::ReadOnly);
01444 if (!success) {
01445 kError() << "Cannot open archive file '" << payloadfile << "'";
01446 if (m_installation->uncompression() == "always") {
01447 return false;
01448 }
01449
01450 isarchive = false;
01451 }
01452
01453 if (isarchive) {
01454 const KArchiveDirectory *dir = archive->directory();
01455 dir->copyTo(installdir);
01456
01457 installedFiles << archiveEntries(installdir, dir);
01458 installedFiles << installdir + '/';
01459
01460 archive->close();
01461 QFile::remove(payloadfile);
01462 delete archive;
01463 }
01464 }
01465 }
01466
01467 kDebug() << "isarchive: " << isarchive;
01468
01469 if (m_installation->uncompression() == "never" || (m_installation->uncompression() == "archive" && !isarchive)) {
01470
01471
01473
01474 KUrl source = KUrl(entry->payload().representation());
01475 kDebug() << "installing non-archive from " << source.url();
01476 QString installfile;
01477 QString ext = source.fileName().section('.', -1);
01478 if (m_installation->customName()) {
01479 installfile = entry->name().representation();
01480 installfile += '-' + entry->version();
01481 if (!ext.isEmpty()) installfile += '.' + ext;
01482 } else {
01483 installfile = source.fileName();
01484 }
01485 installpath = installdir + '/' + installfile;
01486
01487
01488
01489
01490
01491
01492
01493 QFile file(payloadfile);
01494 bool success = true;
01495
01496 if (QFile::exists(installpath) && update) {
01497 success = QFile::remove(installpath);
01498 }
01499 if (success) {
01500 success = file.rename(installpath);
01501 }
01502 if (!success) {
01503 kError() << "Cannot move file '" << payloadfile << "' to destination '" << installpath << "'";
01504 return false;
01505 }
01506 installedFiles << installpath;
01507 installedFiles << installdir + '/';
01508 }
01509 }
01510
01511 entry->setInstalledFiles(installedFiles);
01512
01513 if (!m_installation->command().isEmpty()) {
01514 KProcess process;
01515 QString command(m_installation->command());
01516 QString fileArg(KShell::quoteArg(installpath));
01517 command.replace("%f", fileArg);
01518
01519
01520
01521
01522 process.setShellCommand(command);
01523 int exitcode = process.execute();
01524
01525 if (exitcode) {
01526 kError() << "Command failed" << endl;
01527 } else {
01528
01529 }
01530 }
01531
01532
01533
01534
01535 Security *sec = Security::ref();
01536
01537 connect(sec,
01538 SIGNAL(validityResult(int)),
01539 SLOT(slotInstallationVerification(int)));
01540
01541
01542 sec->checkValidity(QString());
01543
01544 m_payloadfiles[entry] = installpath;
01545 registerEntry(entry);
01546
01547
01548
01549 emit signalEntryChanged(entry);
01550
01551 return true;
01552 }
01553
01554 bool CoreEngine::uninstall(KNS::Entry *entry)
01555 {
01556 entry->setStatus(Entry::Deleted);
01557
01558 if (!m_installation->uninstallCommand().isEmpty()) {
01559 KProcess process;
01560 foreach (const QString& file, entry->installedFiles()) {
01561 QFileInfo info(file);
01562 if (info.isFile()) {
01563 QString fileArg(KShell::quoteArg(file));
01564 QString command(m_installation->uninstallCommand());
01565 command.replace("%f", fileArg);
01566
01567 process.setShellCommand(command);
01568 int exitcode = process.execute();
01569
01570 if (exitcode) {
01571 kError() << "Command failed" << endl;
01572 } else {
01573
01574 }
01575 }
01576 }
01577 }
01578
01579 foreach(const QString &file, entry->installedFiles()) {
01580 if (file.endsWith('/')) {
01581 QDir dir;
01582 bool worked = dir.rmdir(file);
01583 if (!worked) {
01584
01585 continue;
01586 }
01587 } else {
01588 if (QFile::exists(file)) {
01589 bool worked = QFile::remove(file);
01590 if (!worked) {
01591 kWarning() << "unable to delete file " << file;
01592 return false;
01593 }
01594 } else {
01595 kWarning() << "unable to delete file " << file << ". file does not exist.";
01596 }
01597 }
01598 }
01599 entry->setUnInstalledFiles(entry->installedFiles());
01600 entry->setInstalledFiles(QStringList());
01601 unregisterEntry(entry);
01602
01603 emit signalEntryChanged(entry);
01604
01605 return true;
01606 }
01607
01608 void CoreEngine::slotInstallationVerification(int result)
01609 {
01610
01611
01612 if (result & Security::SIGNED_OK)
01613 emit signalInstallationFinished();
01614 else
01615 emit signalInstallationFailed();
01616 }
01617
01618 void CoreEngine::setAutomationPolicy(AutomationPolicy policy)
01619 {
01620 m_automationpolicy = policy;
01621 }
01622
01623 void CoreEngine::setCachePolicy(CachePolicy policy)
01624 {
01625 m_cachepolicy = policy;
01626 }
01627
01628 QStringList KNS::CoreEngine::archiveEntries(const QString& path, const KArchiveDirectory * dir)
01629 {
01630 QStringList files;
01631 foreach(const QString &entry, dir->entries()) {
01632 QString childPath = path + '/' + entry;
01633 if (dir->entry(entry)->isFile()) {
01634 files << childPath;
01635 }
01636
01637 if (dir->entry(entry)->isDirectory()) {
01638 const KArchiveDirectory* childDir = static_cast<const KArchiveDirectory*>(dir->entry(entry));
01639 files << archiveEntries(childPath, childDir);
01640 files << childPath + '/';
01641 }
01642 }
01643 return files;
01644 }
01645
01646
01647 #include "coreengine.moc"