Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}