gboolean pk_backend_finish (PkBackend *self, GError *error) { gboolean cancelled = FALSE; g_return_val_if_fail (self != NULL, FALSE); pk_backend_job_set_allow_cancel (self, FALSE); g_static_mutex_lock (&mutex); if (cancellable != NULL) { cancelled = g_cancellable_is_cancelled (cancellable); g_object_unref (cancellable); cancellable = NULL; } g_static_mutex_unlock (&mutex); if (error != NULL) { pk_backend_error (self, error); g_error_free (error); } if (cancelled) { pk_backend_job_set_status (self, PK_STATUS_ENUM_CANCEL); } pk_backend_job_finished (self); return (error == NULL); }
/** * pk_backend_job_thread_setup: **/ static gpointer pk_backend_job_thread_setup (gpointer thread_data) { PkBackendJobThreadHelper *helper = (PkBackendJobThreadHelper *) thread_data; /* run original function with automatic locking */ pk_backend_thread_start (helper->backend, helper->job, helper->func); helper->func (helper->job, helper->job->priv->params, helper->user_data); pk_backend_job_finished (helper->job); pk_backend_thread_stop (helper->backend, helper->job, helper->func); /* set idle IO priority */ #ifdef PK_BUILD_DAEMON if (helper->job->priv->background == TRUE) { g_debug ("setting ioprio class to idle"); pk_ioprio_set_idle (0); } #endif /* unref the thread here as it holds a reference itself and we do * not need to join() this at any stage */ g_thread_unref (helper->job->priv->thread); /* destroy helper */ g_object_unref (helper->job); if (helper->destroy_func != NULL) helper->destroy_func (helper->user_data); g_free (helper); /* no return value */ return NULL; }
/** * pk_backend_search_names: */ void pk_backend_search_names (PkBackend *backend, PkBackendJob *job, PkBitfield filters, gchar **values) { pk_backend_job_error_code (job, PK_ERROR_ENUM_INTERNAL_ERROR, "Error number 1"); pk_backend_job_finished (job); }
/** * pk_backend_upgrade_system: */ void pk_backend_upgrade_system (PkBackend *backend, PkBackendJob *job, PkBitfield transaction_flags, const gchar *distro_id, PkUpgradeKindEnum upgrade_kind) { pk_backend_job_error_code (job, PK_ERROR_ENUM_INSTALL_ROOT_INVALID, "Cannot find boot partition"); pk_backend_job_finished (job); }
/** * pk_backend_search_name_timeout: **/ static gboolean pk_backend_search_name_timeout (gpointer data) { PkBackendJob *job = (PkBackendJob *) data; pk_backend_job_finished (job); return FALSE; }
static void backend_install_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gint err, i; gchar **package_ids; gchar **parts; package_ids = pk_backend_get_strv (backend, "pkids"); err = 0; for (i = 0; package_ids[i]; i++) { pk_backend_job_package (job, PK_INFO_ENUM_INSTALLING, package_ids[i], NULL); parts = pk_package_id_split (package_ids[i]); err = opkg_install_package (parts[PK_PACKAGE_ID_NAME], pk_opkg_progress_cb, backend); if (err) handle_install_error (backend, err); g_strfreev (parts); if (err != 0) break; } pk_backend_job_finished (job); }
static void pk_backend_spawn_exit_cb (PkSpawn *spawn, PkSpawnExitType exit_enum, PkBackendSpawn *backend_spawn) { gboolean ret; g_return_if_fail (PK_IS_BACKEND_SPAWN (backend_spawn)); /* reset the busy flag */ backend_spawn->priv->is_busy = FALSE; /* if we force killed the process, set an error */ if (exit_enum == PK_SPAWN_EXIT_TYPE_SIGKILL) { /* we just call this failed, and set an error */ pk_backend_job_error_code (backend_spawn->priv->job, PK_ERROR_ENUM_PROCESS_KILL, "Process had to be killed to be cancelled"); } if (exit_enum == PK_SPAWN_EXIT_TYPE_DISPATCHER_EXIT || exit_enum == PK_SPAWN_EXIT_TYPE_DISPATCHER_CHANGED) { g_debug ("dispatcher exited, nothing to see here"); return; } /* only emit if not finished */ if (!backend_spawn->priv->finished) { g_debug ("script exited without doing finished, tidying up"); ret = pk_backend_job_has_set_error_code (backend_spawn->priv->job); if (!ret) { pk_backend_job_error_code (backend_spawn->priv->job, PK_ERROR_ENUM_INTERNAL_ERROR, "The backend exited unexpectedly. " "This is a serious error as the spawned backend did not complete the pending transaction."); } pk_backend_job_finished (backend_spawn->priv->job); } }
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); } pk_backend_job_finished (job); }
static void pk_backend_repo_enable_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { const gchar *repo; GError *error = NULL; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (disabled != NULL, FALSE); repo = pk_backend_get_string (self, "repo_id"); if (g_hash_table_remove (disabled, repo)) { /* reload configuration to preserve ordering */ if (disabled_repos_configure (disabled, &error)) { pk_backend_repo_list_changed (self); } } else { int code = PM_ERR_DB_NOT_NULL; g_set_error (&error, ALPM_ERROR, code, "[%s]: %s", repo, alpm_strerror (code)); } if (error != NULL) { pk_backend_error (self, error); g_error_free (error); } pk_backend_job_finished (self); }
/** * pk_backend_get_details: */ static void backend_get_details_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gchar **package_ids; gchar **parts; int group_index; PkGroupEnum group = 0; pkg_t *pkg; gchar *newid; package_ids = pk_backend_get_strv(backend, "package_ids"); parts = pk_package_id_split (package_ids[0]); if (!parts) { pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id"); pk_backend_job_finished (job); return; } pkg = opkg_find_package (parts[PK_PACKAGE_ID_NAME], parts[PK_PACKAGE_ID_VERSION], parts[PK_PACKAGE_ID_ARCH], parts[PK_PACKAGE_ID_DATA]); g_strfreev (parts); if (!pkg) { pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, NULL); pk_backend_job_finished (job); return; } newid = g_strdup_printf ("%s;%s;%s;%s", pkg->name, pkg->version, pkg->architecture, pkg->src->name); if (pkg->tags) { for (group_index = 0; group < PK_GROUP_ENUM_LAST; group_index++) { group = 1 << group_index; if (!(group & pk_backend_get_groups(backend))) continue; if (opkg_check_tag(pkg, (const gchar *)pk_group_enum_to_string(group))) break; } } pk_backend_job_details (job, newid, NULL, NULL, group, pkg->description, NULL, pkg->size); g_free (newid); pk_backend_job_finished (job); }
/** * pk_backend_remove_packages: */ void pk_backend_remove_packages (PkBackend *backend, PkBackendJob *job, PkBitfield transaction_flags, gchar **package_ids, gboolean allow_deps, gboolean autoremove) { pk_backend_job_finished (job); }
/** * pk_backend_repo_enable: */ static void pk_backend_repo_enable (PkBackend *backend, PkBackendJob *job, const gchar *rid, gboolean enabled) { pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); box_repos_enable_repo(rid, enabled); pk_backend_job_finished (job); }
/** * pk_backend_update_packages: */ static void pk_backend_update_packages (PkBackend *backend, PkBackendJob *job, gboolean only_trusted, gchar **package_ids) { /* check network state */ if (!pk_backend_is_online (backend)) { pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_NETWORK, "Cannot update when offline"); pk_backend_job_finished (job); return; } pk_backend_job_thread_create (job, backend_update_packages_thread, NULL, NULL); }
/** * pk_backend_repo_set_data: */ static void pk_backend_repo_set_data (PkBackend *backend, PkBackendJob *job, const gchar *rid, const gchar *parameter, const gchar *value) { pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); if (!box_repos_set_param (rid, parameter, value)) { g_warning ("Cannot set PARAMETER '%s' TO '%s' for REPO '%s'", parameter, value, rid); } pk_backend_job_finished (job); }
/** * 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); }
static void pk_backend_update_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar *dest_dir_name, *cmd_line, **pkg_tokens, **pkg_ids; guint i; GSList *repo; PkBitfield transaction_flags = 0; g_variant_get(params, "(t^a&s)", &transaction_flags, &pkg_ids); if (!pk_bitfield_contain(transaction_flags, PK_TRANSACTION_FLAG_ENUM_SIMULATE)) { pk_backend_job_set_status(job, PK_STATUS_ENUM_DOWNLOAD); /* Download the packages */ dest_dir_name = g_build_filename(LOCALSTATEDIR, "cache", "PackageKit", "downloads", NULL); for (i = 0; pkg_ids[i]; i++) { pkg_tokens = pk_package_id_split(pkg_ids[i]); if (g_strcmp0(pkg_tokens[PK_PACKAGE_ID_DATA], "obsolete")) { 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_UPDATE); for (i = 0; pkg_ids[i]; i++) { pkg_tokens = pk_package_id_split(pkg_ids[i]); if (g_strcmp0(pkg_tokens[PK_PACKAGE_ID_DATA], "obsolete")) { 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]); } else { /* Remove obsolete package * TODO: Removing should be an independent operation (not during installing updates) */ cmd_line = g_strconcat("/sbin/removepkg ", pkg_tokens[PK_PACKAGE_ID_NAME], NULL); g_spawn_command_line_sync(cmd_line, NULL, NULL, NULL, NULL); g_free(cmd_line); } g_strfreev(pkg_tokens); } } pk_backend_job_finished(job); }
/** * pk_backend_refresh_cache: */ void pk_backend_refresh_cache (PkBackend *backend, PkBackendJob *job, gboolean force) { /* check network state */ if (!pk_backend_is_online (backend)) { pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); pk_backend_job_finished (job); return; } pk_backend_spawn_helper (spawn, job, BACKEND_FILE, "refresh-cache", pk_backend_bool_to_string (force), NULL); }
/** * pk_backend_start_job: */ void pk_backend_start_job (PkBackend *backend, PkBackendJob *job) { if (pk_backend_spawn_is_busy (priv->spawn)) { pk_backend_job_error_code (job, PK_ERROR_ENUM_LOCK_REQUIRED, "spawned backend requires lock"); pk_backend_job_finished (job); return; } pk_backend_enable_media_repo (TRUE); }
/** * pk_backend_search_groups_thread: */ static void pk_backend_search_groups_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); /* emit */ 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); }
/** * pk_backend_refresh_cache: */ static void pk_backend_refresh_cache (PkBackend *backend, PkBackendJob *job, gboolean force) { /* check network state */ if (!pk_backend_is_online (backend)) { pk_backend_job_error_code (job, PK_ERROR_ENUM_NO_NETWORK, "Cannot refresh cache whilst offline"); pk_backend_job_finished (job); return; } /* FIXME: support force */ pk_backend_job_thread_create (job, backend_refresh_cache_thread, NULL, NULL); }
static void backend_update_system_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gint err; /* FIXME: support only_trusted */ err = opkg_upgrade_all (pk_opkg_progress_cb, backend); if (err) opkg_unknown_error (backend, err, "Upgrading system"); pk_backend_job_finished (job); }
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(); }
static void backend_search_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { SearchParams *params; params = pk_backend_get_pointer (backend, "search-params"); opkg_list_packages (pk_opkg_package_list_cb, params); pk_backend_job_finished (params->backend); g_free (params->needle); g_free (params); }
static void backend_install_files_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gboolean result; gchar **full_paths; pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY); full_paths = pk_backend_get_strv (backend, "full_paths"); result = box_package_install (full_paths[0], ROOT_DIRECTORY, common_progress, backend, FALSE); pk_backend_job_finished (job); return result; }
static void backend_refresh_cache_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { int ret; ret = opkg_update_package_lists (pk_opkg_progress_cb, backend); if (ret) { // if (ret == OPKG_DOWNLOAD_FAILED) // pk_backend_job_error_code (job, PK_ERROR_ENUM_REPO_NOT_AVAILABLE, NULL); // else opkg_unknown_error (backend, ret, "Refreshing cache"); } pk_backend_job_finished (job); }
static void backend_remove_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_data) { gint err, i; gchar **package_ids; gchar **parts; gboolean allow_deps; gboolean autoremove; gpointer *data; data = pk_backend_get_pointer (backend, "remove-params"); package_ids = (gchar**) data[0]; allow_deps = GPOINTER_TO_INT (data[1]); autoremove = GPOINTER_TO_INT (data[2]); g_free (data); opkg_set_option ((char *)"autoremove", &autoremove); opkg_set_option ((char *)"force_removal_of_dependent_packages", &allow_deps); err = 0; for (i = 0; package_ids[i]; i++) { pk_backend_job_package (job, PK_INFO_ENUM_REMOVING, package_ids[i], NULL); parts = pk_package_id_split (package_ids[i]); err = opkg_remove_package (parts[PK_PACKAGE_ID_NAME], pk_opkg_progress_cb, backend); switch (err) { //case OPKG_NO_ERROR: // break; //case OPKG_PACKAGE_NOT_INSTALLED: // pk_backend_job_error_code (job, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, NULL); // break; default: opkg_unknown_error (backend, err, "Remove"); } g_strfreev (parts); if (err != 0) break; } pk_backend_job_finished (job); }
static void pk_backend_download_packages_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar *dir_path, *path, **pkg_ids, **pkg_tokens, *to_strv[] = {NULL, NULL}; guint i; GSList *repo; sqlite3_stmt *stmt; PkBackendKatjaJobData *job_data = pk_backend_job_get_user_data(job); g_variant_get(params, "(^a&ss)", &pkg_ids, &dir_path); pk_backend_job_set_status (job, PK_STATUS_ENUM_DOWNLOAD); if ((sqlite3_prepare_v2(job_data->db, "SELECT summary, (full_name || '.' || ext) FROM pkglist NATURAL JOIN repos " "WHERE name LIKE @name AND ver LIKE @ver AND arch LIKE @arch AND repo LIKE @repo", -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; } for (i = 0; pkg_ids[i]; i++) { pkg_tokens = pk_package_id_split(pkg_ids[i]); sqlite3_bind_text(stmt, 1, pkg_tokens[PK_PACKAGE_ID_NAME], -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 2, pkg_tokens[PK_PACKAGE_ID_VERSION], -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 3, pkg_tokens[PK_PACKAGE_ID_ARCH], -1, SQLITE_TRANSIENT); sqlite3_bind_text(stmt, 4, pkg_tokens[PK_PACKAGE_ID_DATA], -1, SQLITE_TRANSIENT); if (sqlite3_step(stmt) == SQLITE_ROW) { if ((repo = g_slist_find_custom(repos, pkg_tokens[PK_PACKAGE_ID_DATA], katja_cmp_repo))) { pk_backend_job_package(job, PK_INFO_ENUM_DOWNLOADING, pkg_ids[i], (gchar *) sqlite3_column_text(stmt, 0)); katja_pkgtools_download(KATJA_PKGTOOLS(repo->data), job, dir_path, pkg_tokens[PK_PACKAGE_ID_NAME]); path = g_build_filename(dir_path, (gchar *) sqlite3_column_text(stmt, 1), NULL); to_strv[0] = path; pk_backend_job_files(job, NULL, to_strv); g_free(path); } } sqlite3_clear_bindings(stmt); sqlite3_reset(stmt); g_strfreev(pkg_tokens); } out: sqlite3_finalize(stmt); pk_backend_job_finished (job); }
static void pk_backend_resolve_thread(PkBackendJob *job, GVariant *params, gpointer user_data) { gchar **vals, **val; 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); if ((sqlite3_prepare_v2(job_data->db, "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.name LIKE @search 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)) { /* Output packages matching each pattern */ for (val = vals; *val; val++) { sqlite3_bind_text(stmt, 1, *val, -1, SQLITE_TRANSIENT); 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_clear_bindings(stmt); sqlite3_reset(stmt); } sqlite3_finalize(stmt); } else { pk_backend_job_error_code(job, PK_ERROR_ENUM_CANNOT_GET_FILELIST, "%s", sqlite3_errmsg(job_data->db)); } pk_backend_job_set_percentage(job, 100); pk_backend_job_finished(job); }
static void backend_update_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++) { result |= box_package_install (package_ids[i], ROOT_DIRECTORY, common_progress, backend, FALSE); } pk_backend_job_finished (job); }
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); }