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"); 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); 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; } 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; } apt->emitPackageFiles(pi); } }
static void backend_search_package_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar **values; PkBitfield filters; PkRoleEnum role; vector<string> queries; g_variant_get(params, "(t^a&s)", &filters, &values); if (*values) { for (gint i = 0; values[i] != NULL; i++) { queries.push_back(values[i]); } } AptIntf *apt = static_cast<AptIntf*>(pk_backend_job_get_user_data(job)); if (!apt->init()) { g_debug("Failed to create apt cache"); return; } if (_error->PendingError() == true) { 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(queries); } else { output = apt->searchPackageName(queries); } // It's faster to emit the packages here than in the matching part apt->emitPackages(output, filters); pk_backend_job_set_percentage(job, 100); }
static void pk_backend_search_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar **vals, *search, *query; sqlite3_stmt *stmt; PkInfoEnum ret; PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job); pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY); pk_backend_job_set_percentage(job, 0); g_variant_get(params, "(t^a&s)", NULL, &vals); search = g_strjoinv("%", vals); query = sqlite3_mprintf("SELECT (p1.name || ';' || p1.ver || ';' || p1.arch || ';' || r.repo), p1.summary, " "p1.full_name FROM pkglist AS p1 NATURAL JOIN repos AS r " "WHERE p1.%s LIKE '%%%q%%' AND p1.ext NOT LIKE 'obsolete' AND p1.repo_order = " "(SELECT MIN(p2.repo_order) FROM pkglist AS p2 WHERE p2.name = p1.name GROUP BY p2.name)", (gchar *) user_data, search); if ((sqlite3_prepare_v2(job_data->db, query, -1, &stmt, NULL) == SQLITE_OK)) { /* Now we're ready to output all packages */ while (sqlite3_step(stmt) == SQLITE_ROW) { ret = katja_pkg_is_installed((gchar *) sqlite3_column_text(stmt, 2)); if ((ret == PK_INFO_ENUM_INSTALLED) || (ret == PK_INFO_ENUM_UPDATING)) { pk_backend_job_package(job, PK_INFO_ENUM_INSTALLED, (gchar *) sqlite3_column_text(stmt, 0), (gchar *) sqlite3_column_text(stmt, 1)); } else if (ret == PK_INFO_ENUM_INSTALLING) { pk_backend_job_package(job, PK_INFO_ENUM_AVAILABLE, (gchar *) sqlite3_column_text(stmt, 0), (gchar *) sqlite3_column_text(stmt, 1)); } } sqlite3_finalize(stmt); } else { pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db)); } sqlite3_free(query); g_free(search); pk_backend_job_set_percentage(job, 100); pk_backend_job_finished(job); }
/** * pk_backend_get_repo_list: */ static void pk_backend_get_repo_list (PkBackend *backend, PkBackendJob *job, PkBitfield filters) { GList *list; GList *li; RepoInfo *repo; pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); list = box_repos_list_get (); for (li = list; li != NULL; li=li->next) { repo = (RepoInfo*) li->data; pk_backend_job_repo_detail (job, repo->name, repo->description, repo->enabled); } box_repos_list_free (list); pk_backend_job_finished (job); }
static void backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gchar **package_ids; gchar **package_id_data; package_ids = pk_backend_get_strv (backend, "package_ids"); /* FIXME: support multiple packages */ package_id_data = pk_package_id_split (package_ids[0]); pk_backend_job_set_status (job, PK_STATUS_ENUM_REMOVE); if (!box_package_uninstall (package_id_data[PK_PACKAGE_ID_NAME], ROOT_DIRECTORY, common_progress, backend, FALSE)) { pk_backend_job_error_code (job, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, "Cannot uninstall"); } pk_backend_finished (backend); }
static void backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gboolean result = TRUE; gchar **package_ids; size_t i; pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); /* FIXME: support only_trusted */ package_ids = pk_backend_get_strv (backend, "package_ids"); for (i = 0; i < g_strv_length (package_ids); i++) { gchar **package_id_data = pk_package_id_split (package_ids[i]); result = box_package_install (package_id_data[PK_PACKAGE_ID_NAME], ROOT_DIRECTORY, common_progress, backend, FALSE); } pk_backend_job_finished (job); }
static void pk_backend_remove_packages (PkBackend *backend, PkBackendJob *job, gchar **package_ids, gboolean allow_deps, gboolean autoremove) { gpointer *params; pk_backend_job_set_status (job, PK_STATUS_ENUM_REMOVE); pk_backend_job_set_percentage (job, PK_BACKEND_PERCENTAGE_INVALID); /* params is a small array we can pack our thread parameters into */ params = g_new0 (gpointer, 2); params[0] = g_strdupv (package_ids); params[1] = GINT_TO_POINTER (allow_deps); params[2] = GINT_TO_POINTER (autoremove); pk_backend_set_pointer (backend, "remove-params", params); pk_backend_job_thread_create (job, backend_remove_packages_thread, NULL, NULL); }
/** * pk_backend_search_names_thread: */ static void pk_backend_search_names_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { GTimer *timer; guint percentage; PkBitfield filters; gchar *filters_text; gchar **search; g_variant_get (params, "(t^a&s)", &filters, &search); filters_text = pk_filter_bitfield_to_string (filters); g_debug ("started task (%p) search=%s filters=%s", job, search[0], filters_text); g_free (filters_text); pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); timer = g_timer_new (); percentage = 0; do { /* now is a good time to see if we should cancel the thread */ if (is_cancelled) { pk_backend_job_error_code (job, PK_ERROR_ENUM_TRANSACTION_CANCELLED, "The thread was stopped successfully"); pk_backend_job_finished (job); return; } pk_backend_job_set_percentage (job, percentage); percentage += 10; g_usleep (1000*100); } while (percentage < 100); g_timer_destroy (timer); pk_backend_job_set_percentage (job, 100); g_debug ("exited task (%p)", job); pk_backend_job_package (job, PK_INFO_ENUM_INSTALLED, "glib2;2.14.0;i386;fedora", "The GLib library"); pk_backend_job_package (job, PK_INFO_ENUM_INSTALLED, "gtk2;gtk2-2.11.6-6.fc8;i386;fedora", "GTK+ Libraries for GIMP"); pk_backend_job_finished (job); }
void pk_backend_run (PkBackend *self, PkStatusEnum status, PkBackendThreadFunc func) { g_return_if_fail (self != NULL); g_return_if_fail (func != NULL); g_static_mutex_lock (&mutex); if (cancellable != NULL) { g_warning ("cancellable was not NULL"); g_object_unref (cancellable); } cancellable = g_cancellable_new (); g_static_mutex_unlock (&mutex); pk_backend_job_set_allow_cancel (self, TRUE); pk_backend_job_set_status (self, status); pk_backend_job_thread_create (self, func); }
/** * pk_backend_thread_start: **/ void pk_backend_thread_start (PkBackend *backend, PkBackendJob *job, gpointer func) { GMutex *mutex; gboolean ret; g_mutex_lock (&backend->priv->thread_hash_mutex); mutex = g_hash_table_lookup (backend->priv->thread_hash, func); if (mutex == NULL) { mutex = g_new0 (GMutex, 1); g_mutex_init (mutex); g_hash_table_insert (backend->priv->thread_hash, func, mutex); } g_mutex_unlock (&backend->priv->thread_hash_mutex); ret = g_mutex_trylock (mutex); if (!ret) { pk_backend_job_set_status (job, PK_STATUS_ENUM_WAITING_FOR_LOCK); g_mutex_lock (mutex); } }
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"); 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); }
static void backend_get_files_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gchar *files; sqlite3 *db; gchar **package_ids; gchar **package_id_data; db = db_open(); package_ids = pk_backend_get_strv (backend, "package_ids"); /* FIXME: support multiple packages */ package_id_data = pk_package_id_split (package_ids[0]); pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); files = box_db_repos_get_files_string (db, package_id_data[PK_PACKAGE_ID_NAME], package_id_data[PK_PACKAGE_ID_VERSION]); pk_backend_job_files (job, package_ids[0], files); db_close (db); g_free (files); pk_backend_finished (backend); }
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"); apt->emitFinished(); return; } pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY); PkgList output; output = apt->getPackages(); // It's faster to emmit the packages rather here than in the matching part apt->emitPackages(output, filters); apt->emitFinished(); }
static void pk_backend_transaction_dlcb (const gchar *basename, off_t complete, off_t total) { guint percentage = 100, sub_percentage = 100; g_return_if_fail (basename != NULL); g_return_if_fail (complete <= total); g_return_if_fail (backend != NULL); if (total > 0) { sub_percentage = complete * 100 / total; } if (dtotal > 0) { percentage = (dcomplete + complete) * 100 / dtotal; } else if (dtotal < 0) { /* database files */ percentage = (dcomplete * 100 + sub_percentage) / -dtotal; if (complete == total) { complete = total = 1; } else { complete = total + 1; } } if (complete == 0) { g_debug ("downloading file %s", basename); pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD); pk_backend_transaction_download_start (backend, basename); } else if (complete == total) { dcomplete += complete; } pk_backend_set_sub_percentage (backend, sub_percentage); pk_backend_job_set_percentage (job, percentage); }
static void pk_backend_get_update_detail_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { guint i; gchar **pkg_ids; pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY); g_variant_get(params, "(^a&s)", &pkg_ids); for (i = 0; pkg_ids[i] != NULL; i++) { pk_backend_job_update_detail (job, pkg_ids[i], NULL, NULL, NULL, NULL, NULL, PK_RESTART_ENUM_NONE, NULL, NULL, PK_UPDATE_STATE_ENUM_STABLE, NULL, NULL); } }
void pk_backend_start_job(PkBackend *backend, PkBackendJob *job) { gchar *db_filename = NULL; PkBackendKatjaJobData *job_data = g_new0(PkBackendKatjaJobData, 1); pk_backend_job_set_allow_cancel(job, TRUE); pk_backend_job_set_allow_cancel(job, FALSE); db_filename = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "metadata", "metadata.db", NULL); if (sqlite3_open(db_filename, &job_data->db) == SQLITE_OK) { /* Some SQLite settings */ sqlite3_exec(job_data->db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL); } else { pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "%s: %s", db_filename, sqlite3_errmsg(job_data->db)); goto out; } pk_backend_job_set_user_data(job, job_data); pk_backend_job_set_status(job, PK_STATUS_ENUM_RUNNING); out: g_free(db_filename); }
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"); 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); PkgList pkgs = apt->resolvePackageIds(package_ids); if (role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) { apt->emitUpdateDetails(pkgs); } else { apt->emitDetails(pkgs); } apt->emitFinished(); }
static void pk_backend_get_details_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar **pkg_ids, **pkg_tokens, *homepage = NULL; gsize i; GString *desc; GRegex *expr; GMatchInfo *match_info; GError *err = NULL; sqlite3_stmt *stmt; PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job); pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY); g_variant_get(params, "(^a&s)", &pkg_ids); if ((sqlite3_prepare_v2(job_data->db, "SELECT p.desc, p.cat, p.uncompressed FROM pkglist AS p NATURAL JOIN repos AS r " "WHERE name LIKE @name AND r.repo LIKE @repo AND ext NOT LIKE 'obsolete'", -1, &stmt, NULL) != SQLITE_OK)) { pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db)); goto out; } pkg_tokens = pk_package_id_split(pkg_ids[0]); sqlite3_bind_text(stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 2, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT); g_strfreev(pkg_tokens); if (sqlite3_step(stmt) != SQLITE_ROW) goto out; desc = g_string_new((gchar *) sqlite3_column_text(stmt, 0)); /* Regular expression for searching a homepage */ expr = g_regex_new("(?:http|ftp):\\/\\/[[:word:]\\/\\-\\.]+[[:word:]\\/](?=\\.?$)", G_REGEX_OPTIMIZE | G_REGEX_DUPNAMES, 0, &err); if (err) { pk_backend_job_error_code(job, PK_ERROR_ENUM_UNKNOWN, "%s", err->message); g_error_free(err); goto out; } if (g_regex_match(expr, desc->str, 0, &match_info)) { homepage = g_match_info_fetch(match_info, 0); /* URL */ /* Remove the last sentence with the copied URL */ for (i = desc->len - 1; i > 0; i--) { if ((desc->str[i - 1] == '.') && (desc->str[i] == ' ')) { g_string_truncate(desc, i); break; } } g_match_info_free(match_info); } g_regex_unref(expr); /* Ready */ pk_backend_job_details(job, pkg_ids[0], NULL, NULL, pk_group_enum_from_string((gchar *) sqlite3_column_text(stmt, 1)), desc->str, homepage, sqlite3_column_int(stmt, 2)); g_free(homepage); if (desc) g_string_free(desc, TRUE); out: sqlite3_finalize(stmt); pk_backend_job_finished(job); }
static gboolean pk_backend_spawn_parse_stdout (PkBackendSpawn *backend_spawn, PkBackendJob *job, const gchar *line, GError **error) { guint size; gchar *command; gchar *text; guint64 speed; guint64 download_size_remaining; PkInfoEnum info; PkRestartEnum restart; PkGroupEnum group; gulong package_size; gint percentage; PkErrorEnum error_enum; PkStatusEnum status_enum; PkRestartEnum restart_enum; PkSigTypeEnum sig_type; PkUpdateStateEnum update_state_enum; PkMediaTypeEnum media_type_enum; PkDistroUpgradeEnum distro_upgrade_enum; PkBackendSpawnPrivate *priv = backend_spawn->priv; g_auto(GStrv) sections = NULL; g_return_val_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn), FALSE); /* check if output line */ if (line == NULL) return FALSE; /* split by tab */ sections = g_strsplit (line, "\t", 0); command = sections[0]; /* get size */ size = g_strv_length (sections); if (g_strcmp0 (command, "package") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (pk_package_id_check (sections[2]) == FALSE) { g_set_error_literal (error, 1, 0, "invalid package_id"); return FALSE; } info = pk_info_enum_from_string (sections[1]); if (info == PK_INFO_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Info enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } g_strdelimit (sections[3], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[3], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[3]); return FALSE; } pk_backend_job_package (job, info, sections[2], sections[3]); } else if (g_strcmp0 (command, "details") == 0) { if (size != 8) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } group = pk_group_enum_from_string (sections[4]); /* ITS4: ignore, checked for overflow */ package_size = atol (sections[7]); if (package_size > 1073741824) { g_set_error_literal (error, 1, 0, "package size cannot be that large"); return FALSE; } g_strdelimit (sections[5], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[4], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[5]); return FALSE; } text = g_strdup (sections[5]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); pk_backend_job_details (job, sections[1], sections[2], sections[3], group, text, sections[6], package_size); g_free (text); } else if (g_strcmp0 (command, "finished") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } pk_backend_job_finished (job); priv->is_busy = FALSE; /* from this point on, we can start the kill timer */ pk_backend_spawn_start_kill_timer (backend_spawn); } else if (g_strcmp0 (command, "files") == 0) { g_auto(GStrv) tmp = NULL; if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } tmp = g_strsplit (sections[2], ";", -1); pk_backend_job_files (job, sections[1], tmp); } else if (g_strcmp0 (command, "repo-detail") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } g_strdelimit (sections[2], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[2], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[2]); return FALSE; } if (g_strcmp0 (sections[3], "true") == 0) { pk_backend_job_repo_detail (job, sections[1], sections[2], TRUE); } else if (g_strcmp0 (sections[3], "false") == 0) { pk_backend_job_repo_detail (job, sections[1], sections[2], FALSE); } else { g_set_error (error, 1, 0, "invalid qualifier '%s'", sections[3]); return FALSE; } } else if (g_strcmp0 (command, "updatedetail") == 0) { g_auto(GStrv) updates = NULL; g_auto(GStrv) obsoletes = NULL; g_auto(GStrv) vendor_urls = NULL; g_auto(GStrv) bugzilla_urls = NULL; g_auto(GStrv) cve_urls = NULL; if (size != 13) { g_set_error (error, 1, 0, "invalid command '%s', size %i", command, size); return FALSE; } restart = pk_restart_enum_from_string (sections[7]); if (restart == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[7]); return FALSE; } g_strdelimit (sections[12], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[12], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[12]); return FALSE; } update_state_enum = pk_update_state_enum_from_string (sections[10]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (sections[8], ";", '\n'); g_strdelimit (sections[9], ";", '\n'); updates = g_strsplit (sections[2], "&", -1); obsoletes = g_strsplit (sections[3], "&", -1); vendor_urls = g_strsplit (sections[4], ";", -1); bugzilla_urls = g_strsplit (sections[5], ";", -1); cve_urls = g_strsplit (sections[6], ";", -1); pk_backend_job_update_detail (job, sections[1], updates, obsoletes, vendor_urls, bugzilla_urls, cve_urls, restart, sections[8], sections[9], update_state_enum, sections[11], sections[12]); } else if (g_strcmp0 (command, "percentage") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_strtoint (sections[1], &percentage)) { g_set_error (error, 1, 0, "invalid percentage value %s", sections[1]); return FALSE; } else if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid percentage value %i", percentage); return FALSE; } else { pk_backend_job_set_percentage (job, percentage); } } else if (g_strcmp0 (command, "item-progress") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_package_id_check (sections[1])) { g_set_error (error, 1, 0, "invalid package_id"); return FALSE; } status_enum = pk_status_enum_from_string (sections[2]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[2]); return FALSE; } if (!pk_strtoint (sections[3], &percentage)) { g_set_error (error, 1, 0, "invalid item-progress value %s", sections[3]); return FALSE; } if (percentage < 0 || percentage > 100) { g_set_error (error, 1, 0, "invalid item-progress value %i", percentage); return FALSE; } pk_backend_job_set_item_progress (job, sections[1], status_enum, percentage); } else if (g_strcmp0 (command, "error") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } error_enum = pk_error_enum_from_string (sections[1]); if (error_enum == PK_ERROR_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Error enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } /* convert back all the ;'s to newlines */ text = g_strdup (sections[2]); /* convert ; to \n as we can't emit them on stdout */ g_strdelimit (text, ";", '\n'); /* convert % else we try to format them */ g_strdelimit (text, "%", '$'); pk_backend_job_error_code (job, error_enum, "%s", text); g_free (text); } else if (g_strcmp0 (command, "requirerestart") == 0) { if (size != 3) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } restart_enum = pk_restart_enum_from_string (sections[1]); if (restart_enum == PK_RESTART_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Restart enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } if (!pk_package_id_check (sections[2])) { g_set_error (error, 1, 0, "invalid package_id"); return FALSE; } pk_backend_job_require_restart (job, restart_enum, sections[2]); } else if (g_strcmp0 (command, "status") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } status_enum = pk_status_enum_from_string (sections[1]); if (status_enum == PK_STATUS_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Status enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } pk_backend_job_set_status (job, status_enum); } else if (g_strcmp0 (command, "speed") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_strtouint64 (sections[1], &speed)) { g_set_error (error, 1, 0, "failed to parse speed: '%s'", sections[1]); return FALSE; } pk_backend_job_set_speed (job, speed); } else if (g_strcmp0 (command, "download-size-remaining") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (!pk_strtouint64 (sections[1], &download_size_remaining)) { g_set_error (error, 1, 0, "failed to parse download_size_remaining: '%s'", sections[1]); return FALSE; } pk_backend_job_set_download_size_remaining (job, download_size_remaining); } else if (g_strcmp0 (command, "allow-cancel") == 0) { if (size != 2) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (g_strcmp0 (sections[1], "true") == 0) { pk_backend_job_set_allow_cancel (job, TRUE); } else if (g_strcmp0 (sections[1], "false") == 0) { pk_backend_job_set_allow_cancel (job, FALSE); } else { g_set_error (error, 1, 0, "invalid section '%s'", sections[1]); return FALSE; } } else if (g_strcmp0 (command, "no-percentage-updates") == 0) { if (size != 1) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } pk_backend_job_set_percentage (job, PK_BACKEND_PERCENTAGE_INVALID); } else if (g_strcmp0 (command, "repo-signature-required") == 0) { if (size != 9) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } sig_type = pk_sig_type_enum_from_string (sections[8]); if (sig_type == PK_SIGTYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "Sig enum not recognised, and hence ignored: '%s'", sections[8]); return FALSE; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[1]); return FALSE; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "repository name blank, and hence ignored: '%s'", sections[2]); return FALSE; } /* pass _all_ of the data */ pk_backend_job_repo_signature_required (job, sections[1], sections[2], sections[3], sections[4], sections[5], sections[6], sections[7], sig_type); } else if (g_strcmp0 (command, "eula-required") == 0) { if (size != 5) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (pk_strzero (sections[1])) { g_set_error (error, 1, 0, "eula_id blank, and hence ignored: '%s'", sections[1]); return FALSE; } if (pk_strzero (sections[2])) { g_set_error (error, 1, 0, "package_id blank, and hence ignored: '%s'", sections[2]); return FALSE; } if (pk_strzero (sections[4])) { g_set_error (error, 1, 0, "agreement name blank, and hence ignored: '%s'", sections[4]); return FALSE; } pk_backend_job_eula_required (job, sections[1], sections[2], sections[3], sections[4]); } else if (g_strcmp0 (command, "media-change-required") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } media_type_enum = pk_media_type_enum_from_string (sections[1]); if (media_type_enum == PK_MEDIA_TYPE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "media type enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } pk_backend_job_media_change_required (job, media_type_enum, sections[2], sections[3]); } else if (g_strcmp0 (command, "distro-upgrade") == 0) { if (size != 4) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } distro_upgrade_enum = pk_distro_upgrade_enum_from_string (sections[1]); if (distro_upgrade_enum == PK_DISTRO_UPGRADE_ENUM_UNKNOWN) { g_set_error (error, 1, 0, "distro upgrade enum not recognised, and hence ignored: '%s'", sections[1]); return FALSE; } g_strdelimit (sections[3], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[3], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[3]); return FALSE; } pk_backend_job_distro_upgrade (job, distro_upgrade_enum, sections[2], sections[3]); } else if (g_strcmp0 (command, "category") == 0) { if (size != 6) { g_set_error (error, 1, 0, "invalid command'%s', size %i", command, size); return FALSE; } if (g_strcmp0 (sections[1], sections[2]) == 0) { g_set_error_literal (error, 1, 0, "cat_id cannot be the same as parent_id"); return FALSE; } if (pk_strzero (sections[2])) { g_set_error_literal (error, 1, 0, "cat_id cannot not blank"); return FALSE; } if (pk_strzero (sections[3])) { g_set_error_literal (error, 1, 0, "name cannot not blank"); return FALSE; } g_strdelimit (sections[4], PK_UNSAFE_DELIMITERS, ' '); if (!g_utf8_validate (sections[4], -1, NULL)) { g_set_error (error, 1, 0, "text '%s' was not valid UTF8!", sections[4]); return FALSE; } if (pk_strzero (sections[5])) { g_set_error_literal (error, 1, 0, "icon cannot not blank"); return FALSE; } if (g_str_has_prefix (sections[5], "/")) { g_set_error (error, 1, 0, "icon '%s' should be a named icon, not a path", sections[5]); return FALSE; } pk_backend_job_category (job, sections[1], sections[2], sections[3], sections[4], sections[5]); } else { g_set_error (error, 1, 0, "invalid command '%s'", command); return FALSE; } return TRUE; }
/** * pk_plugin_transaction_finished_results: */ void pk_plugin_transaction_finished_results (PkPlugin *plugin, PkTransaction *transaction) { gchar **package_ids = NULL; gchar *package_id_tmp; GPtrArray *array = NULL; GPtrArray *list = NULL; guint i; PkInfoEnum info; PkPackage *item; PkResults *results; PkRoleEnum role; /* skip simulate actions */ if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction), PK_TRANSACTION_FLAG_ENUM_SIMULATE)) { goto out; } /* skip only-download */ if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction), PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD)) { goto out; } /* load */ if (plugin->priv->db == NULL) pk_transaction_plugin_load_db (plugin, transaction); /* no database */ if (plugin->priv->db == NULL) goto out; /* check the role */ role = pk_transaction_get_role (transaction); if (role != PK_ROLE_ENUM_INSTALL_PACKAGES) goto out; /* connect to backend */ if (!pk_backend_is_implemented (plugin->backend, PK_ROLE_ENUM_GET_FILES)) { g_debug ("cannot get files"); goto out; } /* get results */ results = pk_transaction_get_results (transaction); array = pk_results_get_package_array (results); /* filter on INSTALLING | UPDATING */ list = g_ptr_array_new_with_free_func (g_free); for (i=0; i<array->len; i++) { item = g_ptr_array_index (array, i); info = pk_package_get_info (item); if (info == PK_INFO_ENUM_INSTALLING || info == PK_INFO_ENUM_UPDATING) { /* we convert the package_id data to be 'installed' */ package_id_tmp = pk_package_id_build (pk_package_get_name (item), pk_package_get_version (item), pk_package_get_arch (item), "installed"); g_ptr_array_add (list, package_id_tmp); } } /* process file lists on these packages */ g_debug ("processing %i packags for desktop files", list->len); if (list->len == 0) goto out; /* get all the files touched in the packages we just installed */ pk_backend_reset_job (plugin->backend, plugin->job); pk_backend_job_set_vfunc (plugin->job, PK_BACKEND_SIGNAL_FINISHED, (PkBackendJobVFunc) pk_plugin_finished_cb, plugin); pk_backend_job_set_vfunc (plugin->job, PK_BACKEND_SIGNAL_FILES, (PkBackendJobVFunc) pk_plugin_files_cb, plugin); pk_backend_job_set_status (plugin->job, PK_STATUS_ENUM_SCAN_APPLICATIONS); pk_backend_job_set_percentage (plugin->job, 101); package_ids = pk_ptr_array_to_strv (list); pk_backend_get_files (plugin->backend, plugin->job, package_ids); /* wait for finished */ g_main_loop_run (plugin->priv->loop); pk_backend_job_set_percentage (plugin->job, 100); out: if (array != NULL) g_ptr_array_unref (array); if (list != NULL) g_ptr_array_unref (list); g_strfreev (package_ids); }
/** * pk_plugin_transaction_finished_end: */ void pk_plugin_transaction_finished_end (PkPlugin *plugin, PkTransaction *transaction) { gchar *error_msg = NULL; gchar *path; gchar *statement; gfloat step; gint rc; GPtrArray *array = NULL; guint i; PkRoleEnum role; /* skip simulate actions */ if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction), PK_TRANSACTION_FLAG_ENUM_SIMULATE)) { goto out; } /* skip only-download */ if (pk_bitfield_contain (pk_transaction_get_transaction_flags (transaction), PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD)) { goto out; } /* load */ if (plugin->priv->db == NULL) pk_transaction_plugin_load_db (plugin, transaction); /* no database */ if (plugin->priv->db == NULL) goto out; /* check the role */ role = pk_transaction_get_role (transaction); if (role != PK_ROLE_ENUM_REFRESH_CACHE) goto out; /* connect to backend */ if (!pk_backend_is_implemented (plugin->backend, PK_ROLE_ENUM_SEARCH_FILE)) { g_debug ("cannot search files"); goto out; } /* use a local backend instance */ pk_backend_reset_job (plugin->backend, plugin->job); pk_backend_job_set_vfunc (plugin->job, PK_BACKEND_SIGNAL_FINISHED, (PkBackendJobVFunc) pk_plugin_finished_cb, plugin); pk_backend_job_set_vfunc (plugin->job, PK_BACKEND_SIGNAL_PACKAGE, (PkBackendJobVFunc) pk_plugin_package_cb, plugin); pk_backend_job_set_status (plugin->job, PK_STATUS_ENUM_SCAN_APPLICATIONS); /* reset hash */ g_hash_table_remove_all (plugin->priv->hash); pk_backend_job_set_percentage (plugin->job, 101); /* first go through the existing data, and look for * modifications and removals */ statement = g_strdup ("SELECT filename, md5 FROM cache"); rc = sqlite3_exec (plugin->priv->db, statement, pk_plugin_sqlite_cache_rescan_cb, plugin, &error_msg); g_free (statement); if (rc != SQLITE_OK) { g_warning ("SQL error: %s\n", error_msg); sqlite3_free (error_msg); goto out; } array = g_ptr_array_new_with_free_func (g_free); pk_plugin_get_desktop_files (plugin, PK_DESKTOP_DEFAULT_APPLICATION_DIR, array); if (array->len) { step = 100.0f / array->len; pk_backend_job_set_status (plugin->job, PK_STATUS_ENUM_GENERATE_PACKAGE_LIST); /* process files in an array */ for (i=0; i<array->len; i++) { pk_backend_job_set_percentage (plugin->job, i * step); path = g_ptr_array_index (array, i); pk_plugin_sqlite_add_filename (plugin, path, NULL); } } pk_backend_job_set_percentage (plugin->job, 100); pk_backend_job_set_status (plugin->job, PK_STATUS_ENUM_FINISHED); out: if (array != NULL) g_ptr_array_unref (array); }
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; } }
static void backend_repo_manager_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { // list PkBitfield filters; // enable const gchar *repo_id; gboolean enabled; bool found = false; // generic PkRoleEnum role; const char *const salt = "$1$/iSaq7rB$EoUw5jJPPvAPECNaaWzMK/"; 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 { 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); apt->emitFinished(); return; } for (SourcesListIter it = _lst.SourceRecords.begin(); it != _lst.SourceRecords.end(); ++it) { if ((*it)->Type & SourcesList::Comment) { continue; } string Sections; for (unsigned int j = 0; j < (*it)->NumSections; ++j) { Sections += (*it)->Sections[j]; Sections += " "; } 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; } string repo; repo = (*it)->GetType(); repo += " " + (*it)->VendorID; repo += " " + (*it)->URI; repo += " " + (*it)->Dist; repo += " " + Sections; gchar *hash; const gchar allowedChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; hash = crypt(repo.c_str(), salt); g_strcanon(hash, allowedChars, 'D'); string repoId(hash); if (role == PK_ROLE_ENUM_GET_REPO_LIST) { pk_backend_job_repo_detail(job, repoId.c_str(), repo.c_str(), !((*it)->Type & SourcesList::Disabled)); } else { if (repoId.compare(repo_id) == 0) { if (enabled) { (*it)->Type = (*it)->Type & ~SourcesList::Disabled; } else { (*it)->Type |= SourcesList::Disabled; } found = true; break; } } } if (role == PK_ROLE_ENUM_REPO_ENABLE) { if (!found) { _error->Error("Could not found the repositorie"); show_errors(job, PK_ERROR_ENUM_REPO_NOT_AVAILABLE); } else if (!_lst.UpdateSources()) { _error->Error("Could not update sources file"); show_errors(job, PK_ERROR_ENUM_CANNOT_WRITE_REPO_CONFIG); } } apt->emitFinished(); }
static void pk_backend_refresh_cache_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar *tmp_dir_name, *db_err, *path = NULL; gint ret; gboolean force; GSList *file_list = NULL, *l; GFile *db_file = NULL; GFileInfo *file_info = NULL; GError *err = NULL; sqlite3_stmt *stmt = NULL; PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job); pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD_CHANGELOG); /* Create temporary directory */ tmp_dir_name = g_dir_make_tmp("PackageKit.XXXXXX", &err); if (!tmp_dir_name) { pk_backend_job_error_code(job, PK_ERROR_ENUM_INTERNAL_ERROR, "%s", err->message); g_error_free(err); pk_backend_job_finished(job); return; } g_variant_get(params, "(b)", &force); /* Force the complete cache refresh if the read configuration file is newer than the metadata cache */ if (!force) { path = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "metadata", "metadata.db", NULL); db_file = g_file_new_for_path(path); file_info = g_file_query_info(db_file, "time::modified-usec", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &err); if (err) { pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "%s: %s", path, err->message); g_error_free(err); goto out; } ret = sqlite3_prepare_v2(job_data->db, "SELECT value FROM cache_info WHERE key LIKE 'last_modification'", -1, &stmt, NULL); if ((ret != SQLITE_OK) || ((ret = sqlite3_step(stmt)) != SQLITE_ROW)) { pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "%s: %s", path, sqlite3_errstr(ret)); goto out; } if ((guint32) sqlite3_column_int(stmt, 0) > g_file_info_get_attribute_uint32(file_info, "time::modified-usec")) force = TRUE; } if (force) { /* It should empty all tables */ if (sqlite3_exec(job_data->db, "DELETE FROM repos", NULL, 0, &db_err) != SQLITE_OK) { pk_backend_job_error_code(job, PK_ERROR_ENUM_INTERNAL_ERROR, "%s", db_err); sqlite3_free(db_err); goto out; } } for (l = repos; l; l = g_slist_next(l)) /* Get list of files that should be downloaded */ file_list = g_slist_concat(file_list, katja_pkgtools_collect_cache_info(l->data, tmp_dir_name)); /* Download repository */ pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD_REPOSITORY); for (l = file_list; l; l = g_slist_next(l)) katja_get_file(&job_data->curl, ((gchar **)l->data)[0], ((gchar **)l->data)[1]); g_slist_free_full(file_list, (GDestroyNotify)g_strfreev); /* Refresh cache */ pk_backend_job_set_status(job, PK_STATUS_ENUM_REFRESH_CACHE); for (l = repos; l; l = g_slist_next(l)) katja_pkgtools_generate_cache(l->data, job, tmp_dir_name); out: sqlite3_finalize(stmt); if (file_info) g_object_unref(file_info); if (db_file) g_object_unref(db_file); g_free(path); pk_directory_remove_contents(tmp_dir_name); g_rmdir(tmp_dir_name); g_free(tmp_dir_name); pk_backend_job_finished(job); }
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; } } } }
static void backend_get_depends_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"); apt->emitFinished(); 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); 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; } if (role == PK_ROLE_ENUM_GET_DEPENDS) { apt->getDepends(output, ver, recursive); } else { apt->getRequires(output, ver, recursive); } } // It's faster to emmit the packages here than in the matching part apt->emitPackages(output, filters); apt->emitFinished(); }
/** * 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"); } }
static void pk_backend_install_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar *dest_dir_name, **pkg_tokens, **pkg_ids; guint i; gdouble percent_step; GSList *repo, *install_list = NULL, *l; sqlite3_stmt *pkglist_stmt = NULL, *collection_stmt = NULL; PkBitfield transaction_flags = 0; PkInfoEnum ret; PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job); g_variant_get(params, "(t^a&s)", &transaction_flags, &pkg_ids); pk_backend_job_set_status(job, PK_STATUS_ENUM_DEP_RESOLVE); if ((sqlite3_prepare_v2(job_data->db, "SELECT summary, cat FROM pkglist NATURAL JOIN repos " "WHERE name LIKE @name AND ver LIKE @ver AND arch LIKE @arch AND repo LIKE @repo", -1, &pkglist_stmt, NULL) != SQLITE_OK) || (sqlite3_prepare_v2(job_data->db, "SELECT (c.collection_pkg || ';' || p.ver || ';' || p.arch || ';' || r.repo), p.summary, " "p.full_name, p.ext FROM collections AS c " "JOIN pkglist AS p ON c.collection_pkg = p.name " "JOIN repos AS r ON p.repo_order = r.repo_order " "WHERE c.name LIKE @name AND r.repo LIKE @repo", -1, &collection_stmt, NULL) != SQLITE_OK)) { pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db)); goto out; } for (i = 0; pkg_ids[i]; i++) { pkg_tokens = pk_package_id_split(pkg_ids[i]); sqlite3_bind_text(pkglist_stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT); sqlite3_bind_text(pkglist_stmt, 2, pkg_tokens[PK_PACKAGE_ID_VERSION], -1, SQLITE_TRANSIENT); sqlite3_bind_text(pkglist_stmt, 3, pkg_tokens[PK_PACKAGE_ID_ARCH], -1, SQLITE_TRANSIENT); sqlite3_bind_text(pkglist_stmt, 4, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT); if (sqlite3_step(pkglist_stmt) == SQLITE_ROW) { /* If it isn't a collection */ if (g_strcmp0((gchar *) sqlite3_column_text(pkglist_stmt, 1), "collections")) { if (pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) { pk_backend_job_package(job, PK_INFO_ENUM_INSTALLING, pkg_ids[i], (gchar *) sqlite3_column_text(pkglist_stmt, 0)); } else { install_list = g_slist_append(install_list, g_strdup(pkg_ids[i])); } } else { sqlite3_bind_text(collection_stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT); sqlite3_bind_text(collection_stmt, 2, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT); while (sqlite3_step(collection_stmt) == SQLITE_ROW) { ret = katja_pkg_is_installed((gchar *) sqlite3_column_text(collection_stmt, 2)); if ((ret == PK_INFO_ENUM_INSTALLING) || (ret == PK_INFO_ENUM_UPDATING)) { if ((pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) && !g_strcmp0((gchar *) sqlite3_column_text(collection_stmt, 3), "obsolete")) { /* TODO: Don't just skip obsolete packages but remove them */ } else if (pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) { pk_backend_job_package(job, ret, (gchar *) sqlite3_column_text(collection_stmt, 0), (gchar *) sqlite3_column_text(collection_stmt, 1)); } else { install_list = g_slist_append(install_list, g_strdup((gchar *) sqlite3_column_text(collection_stmt, 0))); } } } sqlite3_clear_bindings(collection_stmt); sqlite3_reset(collection_stmt); } } sqlite3_clear_bindings(pkglist_stmt); sqlite3_reset(pkglist_stmt); g_strfreev(pkg_tokens); } if (install_list && !pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) { /* / 2 means total percentage for installing and for downloading */ percent_step = 100.0 / g_slist_length(install_list) / 2; /* Download the packages */ pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD); dest_dir_name = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "downloads", NULL); for (l = install_list, i = 0; l; l = g_slist_next(l), i++) { pk_backend_job_set_percentage(job, percent_step * i); pkg_tokens = pk_package_id_split(l->data); repo = g_slist_find_custom(repos, pkg_tokens[PK_PACKAGE_ID_DATA], katja_cmp_repo); if (repo) katja_pkgtools_download(KATJA_PKGTOOLS(repo->data), job, dest_dir_name, pkg_tokens[PK_PACKAGE_ID_NAME]); g_strfreev(pkg_tokens); } g_free(dest_dir_name); /* Install the packages */ pk_backend_job_set_status(job, PK_STATUS_ENUM_INSTALL); for (l = install_list; l; l = g_slist_next(l), i++) { pk_backend_job_set_percentage(job, percent_step * i); pkg_tokens = pk_package_id_split(l->data); repo = g_slist_find_custom(repos, pkg_tokens[PK_PACKAGE_ID_DATA], katja_cmp_repo); if (repo) katja_pkgtools_install(KATJA_PKGTOOLS(repo->data), job, pkg_tokens[PK_PACKAGE_ID_NAME]); g_strfreev(pkg_tokens); } } g_slist_free_full(install_list, g_free); out: sqlite3_finalize(pkglist_stmt); sqlite3_finalize(collection_stmt); pk_backend_job_finished (job); }
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); } }
static void pk_backend_get_updates_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar *pkg_id, *full_name, *desc, **pkg_tokens; const gchar *pkg_metadata_filename; GFile *pkg_metadata_dir; GFileEnumerator *pkg_metadata_enumerator; GFileInfo *pkg_metadata_file_info; GError *err = NULL; sqlite3_stmt *stmt; PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job); pk_backend_job_set_status(job, PK_STATUS_ENUM_QUERY); if ((sqlite3_prepare_v2(job_data->db, "SELECT p1.full_name, p1.name, p1.ver, p1.arch, r.repo, p1.summary, p1.ext " "FROM pkglist AS p1 NATURAL JOIN repos AS r " "WHERE p1.name LIKE @name AND p1.repo_order = " "(SELECT MIN(p2.repo_order) FROM pkglist AS p2 WHERE p2.name = p1.name GROUP BY p2.name)", -1, &stmt, NULL) != SQLITE_OK)) { pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db)); goto out; } /* Read the package metadata directory and comprare all installed packages with ones in the cache */ pkg_metadata_dir = g_file_new_for_path("/var/log/packages"); pkg_metadata_enumerator = g_file_enumerate_children(pkg_metadata_dir, "standard::name", G_FILE_QUERY_INFO_NONE, NULL, &err); g_object_unref(pkg_metadata_dir); if (err) { pk_backend_job_error_code(job, PK_ERROR_ENUM_NO_CACHE, "/var/log/packages: %s", err->message); g_error_free(err); goto out; } while ((pkg_metadata_file_info = g_file_enumerator_next_file(pkg_metadata_enumerator, NULL, NULL))) { pkg_metadata_filename = g_file_info_get_name(pkg_metadata_file_info); pkg_tokens = katja_cut_pkg(pkg_metadata_filename); /* Select the package from the database */ sqlite3_bind_text(stmt, 1, pkg_tokens[0], -1, SQLITE_TRANSIENT); /* If there are more packages with the same name, remember the one from the repository with the lowest order */ if ((sqlite3_step(stmt) == SQLITE_ROW) || g_slist_find_custom(repos, ((gchar *) sqlite3_column_text(stmt, 4)), katja_cmp_repo)) { full_name = g_strdup((gchar *) sqlite3_column_text(stmt, 0)); if (!g_strcmp0((gchar *) sqlite3_column_text(stmt, 6), "obsolete")) { /* Remove if obsolete */ pkg_id = pk_package_id_build(pkg_tokens[PK_PACKAGE_ID_NAME], pkg_tokens[PK_PACKAGE_ID_VERSION], pkg_tokens[PK_PACKAGE_ID_ARCH], "obsolete"); /* TODO: * 1: Use the repository name instead of "obsolete" above and check in pk_backend_update_packages() if the package is obsolete or not * 2: Get description from /var/log/packages, not from the database */ desc = g_strdup((gchar *) sqlite3_column_text(stmt, 5)); pk_backend_job_package(job, PK_INFO_ENUM_REMOVING, pkg_id, desc); g_free(desc); g_free(pkg_id); } else if (g_strcmp0(pkg_metadata_filename, full_name)) { /* Update available */ pkg_id = pk_package_id_build((gchar *) sqlite3_column_text(stmt, 1), (gchar *) sqlite3_column_text(stmt, 2), (gchar *) sqlite3_column_text(stmt, 3), (gchar *) sqlite3_column_text(stmt, 4)); desc = g_strdup((gchar *) sqlite3_column_text(stmt, 5)); pk_backend_job_package(job, PK_INFO_ENUM_NORMAL, pkg_id, desc); g_free(desc); g_free(pkg_id); } g_free(full_name); } sqlite3_clear_bindings(stmt); sqlite3_reset(stmt); g_strfreev(pkg_tokens); g_object_unref(pkg_metadata_file_info); } g_object_unref(pkg_metadata_enumerator); out: sqlite3_finalize(stmt); pk_backend_job_finished (job); }