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