void AptCacheFile::tryToRemove(pkgProblemResolver &Fix, const pkgCache::VerIterator &ver) { pkgCache::PkgIterator Pkg = ver.ParentPkg(); // The package is not installed if (Pkg->CurrentVer == 0) { Fix.Clear(Pkg); Fix.Protect(Pkg); Fix.Remove(Pkg); return; } Fix.Clear(Pkg); Fix.Protect(Pkg); Fix.Remove(Pkg); // TODO this is false since PackageKit can't // tell it want's o purge GetDepCache()->MarkDelete(Pkg, false); }
bool AptCacheFile::tryToInstall(pkgProblemResolver &Fix, const pkgCache::VerIterator &ver, bool BrokenFix, bool autoInst, bool preserveAuto) { pkgCache::PkgIterator Pkg = ver.ParentPkg(); // Check if there is something at all to install GetDepCache()->SetCandidateVersion(ver); pkgDepCache::StateCache &State = (*this)[Pkg]; if (State.CandidateVer == 0) { pk_backend_job_error_code(m_job, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, "Package %s is virtual and has no installation candidate", Pkg.Name()); return false; } // On updates we want to always preserve the autoflag as updates are usually // non-indicative of whether or not the user explicitly wants this package to be // installed or simply wants it to be updated. const bool fromUser = preserveAuto ? !(State.Flags & pkgCache::Flag::Auto) : true; // FIXME: this is ignoring the return value. OTOH the return value means little to us // since we run markinstall twice, once without autoinst and once with. // We probably should change the return value behavior and have the callee decide whether to // error out or call us again with autoinst. This however is further complicated by us // having protected, so we'd have to lift protection before this? GetDepCache()->MarkInstall(Pkg, autoInst, 0, fromUser); // Protect against further resolver changes. Fix.Clear(Pkg); Fix.Protect(Pkg); return true; }
string fetchChangelogData(AptCacheFile &CacheFile, pkgAcquire &Fetcher, pkgCache::VerIterator Ver, pkgCache::VerIterator currver, string *update_text, string *updated, string *issued) { string changelog; pkgAcqChangelog *c = new pkgAcqChangelog(&Fetcher, Ver); // try downloading it, if that fails, try third-party-changelogs location // FIXME: Fetcher.Run() is "Continue" even if I get a 404?!? Fetcher.Run(); // error pkgRecords Recs(CacheFile); pkgCache::PkgIterator Pkg = Ver.ParentPkg(); pkgRecords::Parser &rec=Recs.Lookup(Ver.FileList()); string srcpkg = rec.SourcePkg().empty() ? Pkg.Name() : rec.SourcePkg(); changelog = "Changelog for this version is not yet available"; // return empty string if we don't have a file to read if (!FileExists(c->DestFile)) { return changelog; } if (_error->PendingError()) { return changelog; } ifstream in(c->DestFile.c_str()); string line; g_autoptr(GRegex) regexVer = NULL; regexVer = g_regex_new("(?'source'.+) \\((?'version'.*)\\) " "(?'dist'.+); urgency=(?'urgency'.+)", G_REGEX_CASELESS, G_REGEX_MATCH_ANCHORED, 0); g_autoptr(GRegex) regexDate = NULL; regexDate = g_regex_new("^ -- (?'maintainer'.+) (?'mail'<.+>) (?'date'.+)$", G_REGEX_CASELESS, G_REGEX_MATCH_ANCHORED, 0); changelog = ""; while (getline(in, line)) { // we don't want the additional whitespace, because it can confuse // some markdown parsers used by client tools if (starts_with(line, " ")) line.erase(0,1); // no need to free str later, it is allocated in a static buffer const char *str = utf8(line.c_str()); if (strcmp(str, "") == 0) { changelog.append("\n"); continue; } else { changelog.append(str); changelog.append("\n"); } if (starts_with(str, srcpkg.c_str())) { // Check to see if the the text isn't about the current package, // otherwise add a == version == GMatchInfo *match_info; if (g_regex_match(regexVer, str, G_REGEX_MATCH_ANCHORED, &match_info)) { gchar *version; version = g_match_info_fetch_named(match_info, "version"); // Compare if the current version is shown in the changelog, to not // display old changelog information if (_system != 0 && _system->VS->DoCmpVersion(version, version + strlen(version), currver.VerStr(), currver.VerStr() + strlen(currver.VerStr())) <= 0) { g_free (version); break; } else { if (!update_text->empty()) { update_text->append("\n\n"); } update_text->append(" == "); update_text->append(version); update_text->append(" =="); g_free (version); } } g_match_info_free (match_info); } else if (starts_with(str, " ")) { // update descritption update_text->append("\n"); update_text->append(str); } else if (starts_with(str, " --")) { // Parse the text to know when the update was issued, // and when it got updated GMatchInfo *match_info; if (g_regex_match(regexDate, str, G_REGEX_MATCH_ANCHORED, &match_info)) { GTimeVal dateTime = {0, 0}; gchar *date; date = g_match_info_fetch_named(match_info, "date"); time_t time; g_warn_if_fail(RFC1123StrToTime(date, time)); dateTime.tv_sec = time; g_free(date); *issued = g_time_val_to_iso8601(&dateTime); if (updated->empty()) { *updated = g_time_val_to_iso8601(&dateTime); } } g_match_info_free(match_info); } } return changelog; }