Пример #1
0
static void pk_backend_search_files_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **search;
    PkBitfield filters;
    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));

    g_variant_get(params, "(t^a&s)",
                  &filters,
                  &search);

    pk_backend_job_set_allow_cancel(job, true);

    // as we can only search for installed files lets avoid the opposite
    if (!pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_INSTALLED)) {
        if (!apt->init()) {
            g_debug("Failed to create apt cache");
            return;
        }

        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
        PkgList output;
        output = apt->searchPackageFiles(search);

        // It's faster to emit the packages here rather than in the matching part
        apt->emitPackages(output, filters);
    }
}
Пример #2
0
static void backend_get_details_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids;
    PkRoleEnum role;
    role = pk_backend_job_get_role(job);

    g_variant_get(params, "(^a&s)",
                  &package_ids);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug ("Failed to create apt cache");
        return;
    }

    if (package_ids == NULL) {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                  "Invalid package id");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList pkgs = apt->resolvePackageIds(package_ids);

    if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
        apt->emitUpdateDetails(pkgs);
    } else {
        apt->emitDetails(pkgs);
    }
}
Пример #3
0
static void backend_get_updates_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkBitfield filters;
    g_variant_get(params, "(t)", &filters);

    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

    PkgList updates;
    PkgList blocked;
    updates = apt->getUpdates(blocked);

    apt->emitUpdates(updates, filters);
    apt->emitPackages(blocked, filters, PK_INFO_ENUM_BLOCKED);

    apt->emitFinished();
}
Пример #4
0
static void backend_search_groups_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **search;
    PkBitfield filters;

    g_variant_get(params, "(t^a&s)",
                  &filters,
                  &search);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

    // It's faster to emmit the packages here rather than in the matching part
    PkgList output;
    output = apt->getPackagesFromGroup(search);
    apt->emitPackages(output, filters);

    pk_backend_job_set_percentage(job, 100);

    apt->emitFinished();
}
Пример #5
0
static void backend_get_details_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids = nullptr;
    gchar **files = nullptr;
    PkRoleEnum role;
    role = pk_backend_job_get_role(job);

    if (role == PK_ROLE_ENUM_GET_DETAILS_LOCAL) {
        g_variant_get(params, "(^a&s)",
                      &files);
    } else {
        g_variant_get(params, "(^a&s)",
                      &package_ids);
    }

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init(files)) {
        g_debug ("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList pkgs;
    if (role == PK_ROLE_ENUM_GET_DETAILS_LOCAL) {
        pkgs = apt->resolveLocalFiles(files);
    } else {
        pkgs = apt->resolvePackageIds(package_ids);
    }

    if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) {
        apt->emitUpdateDetails(pkgs);
    } else {
        apt->emitDetails(pkgs);
    }
}
Пример #6
0
/**
 * pk_backend_refresh_cache_thread:
 */
static void pk_backend_refresh_cache_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        apt->emitFinished();
        return;
    }
    
    PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job));
    if (pk_backend_is_online(backend)) {
        apt->refreshCache();
        
        if (_error->PendingError() == true) {
            show_errors(job, PK_ERROR_ENUM_CANNOT_FETCH_SOURCES, true);
        }
    } else {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_NO_NETWORK,
                                  "Cannot refresh cache whilst offline");
    }

    apt->emitFinished();
}
Пример #7
0
static void backend_what_provides_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkBitfield filters;
    const gchar *provides_text;
    gchar **values;
    bool error = false;
    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));

    g_variant_get(params, "(t^a&s)",
                  &filters,
                  &values);

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

    // We can handle libraries, mimetypes and codecs
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        g_strfreev(values);
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

    PkgList output;
    apt->providesLibrary(output, values);
    apt->providesCodec(output, values);
    apt->providesMimeType(output, values);

    // It's faster to emit the packages here rather than in the matching part
    apt->emitPackages(output, filters);
}
Пример #8
0
static void backend_depends_on_or_requires_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkRoleEnum role;
    PkBitfield filters;
    gchar **package_ids;
    gboolean recursive;
    gchar *pi;

    g_variant_get(params, "(t^a&sb)",
                  &filters,
                  &package_ids,
                  &recursive);
    role = pk_backend_job_get_role(job);

    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList output;
    for (uint i = 0; i < g_strv_length(package_ids); ++i) {
        if (apt->cancelled()) {
            break;
        }
        pi = package_ids[i];
        if (pk_package_id_check(pi) == false) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                      "%s",
                                      pi);
            return;
        }

        const pkgCache::VerIterator &ver = apt->aptCacheFile()->resolvePkgID(pi);
        if (ver.end()) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Couldn't find package %s",
                                      pi);
            return;
        }

        if (role == PK_ROLE_ENUM_DEPENDS_ON) {
            apt->getDepends(output, ver, recursive);
        } else {
            apt->getRequires(output, ver, recursive);
        }
    }

    // It's faster to emit the packages here than in the matching part
    apt->emitPackages(output, filters);
}
Пример #9
0
static void backend_what_provides_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkProvidesEnum provides;
    PkBitfield filters;
    const gchar *provides_text;
    gchar **values;
    bool error = false;
    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));

    g_variant_get(params, "(tu^a&s)",
                  &filters,
                  &provides,
                  &values);

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

    // We can handle libraries, mimetypes and codecs
    if (provides == PK_PROVIDES_ENUM_SHARED_LIB ||
            provides == PK_PROVIDES_ENUM_MIMETYPE ||
            provides == PK_PROVIDES_ENUM_CODEC ||
            provides == PK_PROVIDES_ENUM_ANY) {
        if (!apt->init()) {
            g_debug("Failed to create apt cache");
            g_strfreev(values);
            apt->emitFinished();
            return;
        }

        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);

        PkgList output;
        if (provides == PK_PROVIDES_ENUM_SHARED_LIB) {
            apt->providesLibrary(output, values);
        } else if (provides == PK_PROVIDES_ENUM_MIMETYPE) {
            apt->providesMimeType(output, values);
        } else if (provides == PK_PROVIDES_ENUM_CODEC) {
            apt->providesCodec(output, values);
        } else {
            // PK_PROVIDES_ENUM_ANY, just search for everything a package can provide
            apt->providesLibrary(output, values);
            apt->providesCodec(output, values);
            apt->providesMimeType(output, values);
        }

        // It's faster to emit the packages here rather than in the matching part
        apt->emitPackages(output, filters);
    } else {
        provides_text = pk_provides_enum_to_string(provides);
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_NOT_SUPPORTED,
                                  "Provides %s not supported",
                                  provides_text);
    }

    apt->emitFinished();
}
Пример #10
0
static void backend_get_files_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids;
    gchar *pi;

    g_variant_get(params, "(^a&s)",
                  &package_ids);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        apt->emitFinished();
        return;
    }

    if (package_ids == NULL) {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                  "Invalid package id");
        pk_backend_job_finished(job);
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    for (uint i = 0; i < g_strv_length(package_ids); ++i) {
        pi = package_ids[i];
        if (pk_package_id_check(pi) == false) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                      "%s",
                                      pi);
            apt->emitFinished();
            return;
        }

        const pkgCache::VerIterator &ver = apt->aptCacheFile()->resolvePkgID(pi);
        if (ver.end()) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Couldn't find package %s",
                                      pi);
            apt->emitFinished();
            return;
        }

        apt->emitPackageFiles(pi);
    }

    apt->emitFinished();
}
Пример #11
0
static void backend_search_package_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **values;
    gchar *search;
    PkBitfield filters;
    PkRoleEnum role;

    g_variant_get(params, "(t^a&s)",
                  &filters,
                  &values);
    search = g_strjoinv("|", values);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        g_free(search);
        apt->emitFinished();
        return;
    }

    if (_error->PendingError() == true) {
        g_free(search);
        apt->emitFinished();
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    pk_backend_job_set_percentage(job, PK_BACKEND_PERCENTAGE_INVALID);
    pk_backend_job_set_allow_cancel(job, true);

    PkgList output;
    role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_SEARCH_DETAILS) {
        output = apt->searchPackageDetails(search);
    } else {
        output = apt->searchPackageName(search);
    }
    g_free(search);

    // It's faster to emmit the packages here than in the matching part
    apt->emitPackages(output, filters);

    pk_backend_job_set_percentage(job, 100);

    apt->emitFinished();
}
Пример #12
0
static void backend_get_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    PkBitfield filters;
    g_variant_get(params, "(t)",
                  &filters);
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    PkgList output;
    output = apt->getPackages();

    // It's faster to emit the packages rather here than in the matching part
    apt->emitPackages(output, filters);
}
Пример #13
0
static void pk_backend_resolve_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **search;
    PkBitfield filters;

    g_variant_get(params, "(t^a&s)",
                  &filters,
                  &search);
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    PkgList pkgs = apt->resolvePackageIds(search);

    // It's faster to emit the packages here rather than in the matching part
    apt->emitPackages(pkgs, filters);
}
Пример #14
0
static void backend_repo_manager_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // list
    PkBitfield filters;
    PkBitfield transaction_flags = 0;
    // enable
    const gchar *repo_id;
    gboolean enabled;
    gboolean autoremove;
    bool found = false;
    // generic
    PkRoleEnum role;
    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));

    role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_GET_REPO_LIST) {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
        g_variant_get(params, "(t)",
                      &filters);
    } else if (role == PK_ROLE_ENUM_REPO_REMOVE) {
        g_variant_get(params, "(t&sb)",
                      &transaction_flags,
                      &repo_id,
                      &autoremove);
    } else {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_REQUEST);
        g_variant_get (params, "(&sb)",
                       &repo_id,
                       &enabled);
    }

    SourcesList _lst;
    if (_lst.ReadSources() == false) {
        _error->
        Warning("Ignoring invalid record(s) in sources.list file!");
        //return false;
    }

    if (_lst.ReadVendors() == false) {
        _error->Error("Cannot read vendors.list file");
        show_errors(job, PK_ERROR_ENUM_FAILED_CONFIG_PARSING);
        return;
    }

    for (SourcesListIter it = _lst.SourceRecords.begin();
            it != _lst.SourceRecords.end(); ++it) {
        if ((*it)->Type & SourcesList::Comment) {
            continue;
        }

        string sections = (*it)->joinedSections();

        string repoId = (*it)->repoId();

        if (role == PK_ROLE_ENUM_GET_REPO_LIST) {
            if (pk_bitfield_contain(filters, PK_FILTER_ENUM_NOT_DEVELOPMENT) &&
                    ((*it)->Type & SourcesList::DebSrc ||
                     (*it)->Type & SourcesList::RpmSrc ||
                     (*it)->Type & SourcesList::RpmSrcDir ||
                     (*it)->Type & SourcesList::RepomdSrc)) {
                continue;
            }

            pk_backend_job_repo_detail(job,
                                       repoId.c_str(),
                                       (*it)->niceName().c_str(),
                                       !((*it)->Type & SourcesList::Disabled));
        } else if (repoId.compare(repo_id) == 0) {
            // Found the repo to enable/disable
            found = true;

            if (role == PK_ROLE_ENUM_REPO_ENABLE) {
                if (enabled) {
                    (*it)->Type = (*it)->Type & ~SourcesList::Disabled;
                } else {
                    (*it)->Type |= SourcesList::Disabled;
                }

                // Commit changes
                if (!_lst.UpdateSources()) {
                    _error->Error("Could not update sources file");
                    show_errors(job, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG);
                }
            } else if (role == PK_ROLE_ENUM_REPO_REMOVE) {
                if (autoremove) {
                    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
                    if (!apt->init()) {
                        g_debug("Failed to create apt cache");
                        return;
                    }

                    PkgList removePkgs = apt->getPackagesFromRepo(*it);
                    if (removePkgs.size() > 0) {
                        // Install/Update/Remove packages, or just simulate
                        bool ret;
                        ret = apt->runTransaction(PkgList(),
                                                  removePkgs,
                                                  false,
                                                  false,
                                                  transaction_flags,
                                                  false);
                        if (!ret) {
                            // Print transaction errors
                            g_debug("AptIntf::runTransaction() failed: %i", _error->PendingError());
                            return;
                        }
                    }
                }

                // Now if we are not simulating remove the repository
                if (!pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) {
                    _lst.RemoveSource(*it);

                    // Commit changes
                    if (!_lst.UpdateSources()) {
                        _error->Error("Could not update sources file");
                        show_errors(job, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG);
                    }
                }
            }

            // Leave the search loop
            break;
        }
    }

    if ((role == PK_ROLE_ENUM_REPO_ENABLE || role == PK_ROLE_ENUM_REPO_REMOVE) &&
            !found) {
        _error->Error("Could not found the repository");
        show_errors(job, PK_ERROR_ENUM_REPO_NOT_AVAILABLE);
    }
}
Пример #15
0
static void backend_manage_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // Transaction flags
    PkBitfield transaction_flags = 0;
    gboolean allow_deps = false;
    gboolean autoremove = false;
    bool fileInstall = false;
    gchar **full_paths = NULL;
    gchar **package_ids = NULL;

    // Get the transaction role since this method is called by install/remove/update/repair
    PkRoleEnum role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_INSTALL_FILES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &full_paths);
        fileInstall = true;
    } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
        g_variant_get(params, "(t^a&sbb)",
                      &transaction_flags,
                      &package_ids,
                      &allow_deps,
                      &autoremove);
    } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    }

    // Check if we should only simulate the install (calculate dependencies)
    bool simulate;
    simulate = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE);

    // Check if we should only download all the required packages for this transaction
    bool downloadOnly;
    downloadOnly = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD);

    // Check if we should fix broken packages
    bool fixBroken = false;
    if (role == PK_ROLE_ENUM_REPAIR_SYSTEM) {
        // On fix broken mode no package to remove/install is allowed
        fixBroken = true;
    }

    g_debug("FILE INSTALL: %i", fileInstall);
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList installPkgs, removePkgs;

    if (fileInstall) {
        // File installation EXPERIMENTAL

        // GDebi can not install more than one package at time
        if (g_strv_length(full_paths) > 1) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_NOT_SUPPORTED,
                                      "The backend can only process one file at time.");
            return;
        }

        // get the list of packages to install
        if (!apt->markFileForInstall(full_paths[0], installPkgs, removePkgs)) {
            return;
        }

        cout << "installPkgs.size: " << installPkgs.size() << endl;
        cout << "removePkgs.size: " << removePkgs.size() << endl;

    } else if (!fixBroken) {
        // Resolve the given packages
        if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
            removePkgs = apt->resolvePackageIds(package_ids);
        } else {
            installPkgs = apt->resolvePackageIds(package_ids);
        }

        if (removePkgs.size() == 0 && installPkgs.size() == 0) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Could not find package(s)");
            return;
        }
    }

    // Install/Update/Remove packages, or just simulate
    bool ret;
    ret = apt->runTransaction(installPkgs,
                              removePkgs,
                              fileInstall, // Mark newly installed packages as auto-installed
                              // (they're dependencies of the new local package)
                              fixBroken,
                              transaction_flags,
                              autoremove);
    if (!ret) {
        // Print transaction errors
        g_debug("AptIntf::runTransaction() failed: %i", _error->PendingError());
        return;
    }

    if (fileInstall) {
        // Now perform the installation!
        gchar *path;
        for (uint i = 0; i < g_strv_length(full_paths); ++i) {
            if (apt->cancelled()) {
                break;
            }

            path = full_paths[i];
            if (!apt->installFile(path, simulate)) {
                cout << "Installation of DEB file " << path << " failed." << endl;
                return;
            }
        }
    }
}
Пример #16
0
static void backend_manage_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    // Transaction flags
    PkBitfield transaction_flags = 0;
    gboolean allow_deps = false;
    gboolean autoremove = false;
    bool fileInstall = false;
    gchar **full_paths = NULL;
    gchar **package_ids = NULL;

    // Get the transaction role since this method is called by install/remove/update/repair
    PkRoleEnum role = pk_backend_job_get_role(job);
    if (role == PK_ROLE_ENUM_INSTALL_FILES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &full_paths);
        fileInstall = true;
    } else if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
        g_variant_get(params, "(t^a&sbb)",
                      &transaction_flags,
                      &package_ids,
                      &allow_deps,
                      &autoremove);
    } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
        g_variant_get(params, "(t^a&s)",
                      &transaction_flags,
                      &package_ids);
    }

    // Check if we should only simulate the install (calculate dependencies)
    bool simulate;
    simulate = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE);

    // Check if we should only download all the required packages for this transaction
    bool downloadOnly;
    downloadOnly = pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD);

    // Check if we should fix broken packages
    bool fixBroken = false;
    if (role == PK_ROLE_ENUM_REPAIR_SYSTEM) {
        // On fix broken mode no package to remove/install is allowed
        fixBroken = true;
    }

    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init(full_paths)) {
        g_debug("Failed to create apt cache");
        return;
    }

    pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
    PkgList installPkgs, removePkgs, updatePkgs;

    if (!fixBroken) {
        // Resolve the given packages
        if (role == PK_ROLE_ENUM_REMOVE_PACKAGES) {
            removePkgs = apt->resolvePackageIds(package_ids);
        } else if (role == PK_ROLE_ENUM_INSTALL_PACKAGES) {
            installPkgs = apt->resolvePackageIds(package_ids);
        } else if (role == PK_ROLE_ENUM_UPDATE_PACKAGES) {
            updatePkgs = apt->resolvePackageIds(package_ids);
        } else if (role == PK_ROLE_ENUM_INSTALL_FILES) {
            installPkgs = apt->resolveLocalFiles(full_paths);
        } else {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Could not figure out what to do to apply the change.");
            return;
        }

        if (removePkgs.size() == 0 && installPkgs.size() == 0 && updatePkgs.size() == 0) {
            pk_backend_job_error_code(job,
                                      PK_ERROR_ENUM_PACKAGE_NOT_FOUND,
                                      "Could not find package(s)");
            return;
        }
    }

    // Install/Update/Remove packages, or just simulate
    bool ret = apt->runTransaction(installPkgs,
                                   removePkgs,
                                   updatePkgs,
                                   fixBroken,
                                   transaction_flags,
                                   autoremove);
    if (!ret) {
        // Print transaction errors
        g_debug("AptIntf::runTransaction() failed: %i", _error->PendingError());
        return;
    }
}
Пример #17
0
/**
 * pk_backend_download_packages_thread:
 */
static void pk_backend_download_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data)
{
    gchar **package_ids;
    const gchar *tmpDir;
    string directory;

    g_variant_get(params, "(^a&ss)",
                  &package_ids,
                  &tmpDir);
    directory = _config->FindDir("Dir::Cache::archives");
    pk_backend_job_set_allow_cancel(job, true);

    AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job));
    if (!apt->init()) {
        g_debug("Failed to create apt cache");
        return;
    }

    PkBackend *backend = PK_BACKEND(pk_backend_job_get_backend(job));
    if (pk_backend_is_online(backend)) {
        pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY);
        // Create the progress
        AcqPackageKitStatus Stat(apt, job);

        // get a fetcher
        pkgAcquire fetcher(&Stat);
        gchar *pi;

        // TODO this might be useful when the item is in the cache
        // 	for (pkgAcquire::ItemIterator I = fetcher.ItemsBegin(); I < fetcher.ItemsEnd();)
        // 	{
        // 		if ((*I)->Local == true)
        // 		{
        // 			I++;
        // 			continue;
        // 		}
        //
        // 		// Close the item and check if it was found in cache
        // 		(*I)->Finished();
        // 		if ((*I)->Complete == false) {
        // 			Transient = true;
        // 		}
        //
        // 		// Clear it out of the fetch list
        // 		delete *I;
        // 		I = fetcher.ItemsBegin();
        // 	}

        for (uint i = 0; i < g_strv_length(package_ids); ++i) {
            pi = package_ids[i];
            if (pk_package_id_check(pi) == false) {
                pk_backend_job_error_code(job,
                                          PK_ERROR_ENUM_PACKAGE_ID_INVALID,
                                          "%s",
                                          pi);
                return;
            }

            if (apt->cancelled()) {
                break;
            }

            const pkgCache::VerIterator &ver = apt->aptCacheFile()->resolvePkgID(pi);
            // Ignore packages that could not be found or that exist only due to dependencies.
            if (ver.end()) {
                _error->Error("Can't find this package id \"%s\".", pi);
                continue;
            } else {
                if(!ver.Downloadable()) {
                    _error->Error("No downloadable files for %s,"
                                  "perhaps it is a local or obsolete" "package?",
                                  pi);
                    continue;
                }

                string storeFileName;
                if (!apt->getArchive(&fetcher,
                                     ver,
                                     directory,
                                     storeFileName)) {
                    return;
                }

                gchar **files = (gchar **) g_malloc(2 * sizeof(gchar *));
                files[0] = g_strdup_printf("%s/%s", directory.c_str(), flNotDir(storeFileName).c_str());
                files[1] = NULL;
                pk_backend_job_files(job, pi, files);
                g_strfreev(files);
            }
        }

        if (fetcher.Run() != pkgAcquire::Continue
                && apt->cancelled() == false) {
            // We failed and we did not cancel
            show_errors(job, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
            return;
        }

    } else {
        pk_backend_job_error_code(job,
                                  PK_ERROR_ENUM_NO_NETWORK,
                                  "Cannot download packages whilst offline");
    }
}