/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * * Copyright (C) 2009 Richard Hughes * * Licensed under the GNU Lesser General Public License Version 2.1 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION:pk-task * @short_description: An abstract package task GObject, dealing with unsigned * transactions, GPG keys and EULA requests. */ #include "config.h" #include #include #include #include #include #include "egg-debug.h" static void pk_task_finalize (GObject *object); #define PK_TASK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PK_TYPE_TASK, PkTaskPrivate)) /** * PkTaskPrivate: * * Private #PkTask data **/ struct _PkTaskPrivate { GPtrArray *array; gboolean simulate; }; enum { PROP_0, PROP_SIMULATE, PROP_LAST }; /** * PkTaskState: * * For use in the async methods **/ typedef struct { guint request; PkRoleEnum role; PkExitEnum exit_enum; gboolean simulate; gboolean only_trusted; gchar **package_ids; gboolean allow_deps; gboolean autoremove; gchar **files; GSimpleAsyncResult *res; PkResults *results; gboolean ret; PkTask *task; GCancellable *cancellable; PkProgressCallback progress_callback; gpointer progress_user_data; gboolean enabled; gboolean force; gboolean recursive; gchar *directory; gchar **packages; gchar *repo_id; gchar *transaction_id; gchar **values; PkBitfield filters; PkProvidesEnum provides; } PkTaskState; G_DEFINE_TYPE (PkTask, pk_task, PK_TYPE_CLIENT) static void pk_task_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskState *state); /** * pk_task_generate_request_id: **/ static guint pk_task_generate_request_id (void) { static guint id = 0; return ++id; } /** * pk_task_find_by_request: **/ static PkTaskState * pk_task_find_by_request (PkTask *task, guint request) { PkTaskState *item; guint i; GPtrArray *array; g_return_val_if_fail (PK_IS_TASK (task), NULL); g_return_val_if_fail (request != 0, NULL); array = task->priv->array; for (i=0; ilen; i++) { item = g_ptr_array_index (array, i); if (item->request == request) goto out; } item = NULL; out: return item; } /** * pk_task_generic_state_finish: **/ static void pk_task_generic_state_finish (PkTaskState *state, const GError *error) { /* get result */ if (state->ret) { g_simple_async_result_set_op_res_gpointer (state->res, g_object_ref ((GObject*) state->results), g_object_unref); } else { g_simple_async_result_set_from_error (state->res, error); } /* complete */ g_simple_async_result_complete_in_idle (state->res); /* remove from list */ egg_debug ("remove state %p", state); g_ptr_array_remove (state->task->priv->array, state); /* deallocate */ if (state->cancellable != NULL) g_object_unref (state->cancellable); if (state->results != NULL) g_object_unref (state->results); g_free (state->directory); g_free (state->repo_id); g_free (state->transaction_id); g_strfreev (state->files); g_strfreev (state->package_ids); g_strfreev (state->packages); g_strfreev (state->values); g_object_unref (state->res); g_object_unref (state->task); g_slice_free (PkTaskState, state); } /** * pk_task_do_async_action: **/ static void pk_task_do_async_action (PkTaskState *state) { /* so the callback knows if we are serious or not */ state->simulate = FALSE; /* do the correct action */ if (state->role == PK_ROLE_ENUM_INSTALL_PACKAGES) { pk_client_install_packages_async (PK_CLIENT(state->task), state->only_trusted, state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_UPDATE_PACKAGES) { pk_client_update_packages_async (PK_CLIENT(state->task), state->only_trusted, state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_REMOVE_PACKAGES) { pk_client_remove_packages_async (PK_CLIENT(state->task), state->package_ids, state->allow_deps, state->autoremove, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_UPDATE_SYSTEM) { pk_client_update_system_async (PK_CLIENT(state->task), state->only_trusted, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_INSTALL_FILES) { pk_client_install_files_async (PK_CLIENT(state->task), state->only_trusted, state->files, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_RESOLVE) { pk_client_resolve_async (PK_CLIENT(state->task), state->filters, state->packages, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_SEARCH_NAME) { pk_client_search_names_async (PK_CLIENT(state->task), state->filters, state->values, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_SEARCH_DETAILS) { pk_client_search_details_async (PK_CLIENT(state->task), state->filters, state->values, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_SEARCH_GROUP) { pk_client_search_groups_async (PK_CLIENT(state->task), state->filters, state->values, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_SEARCH_FILE) { pk_client_search_files_async (PK_CLIENT(state->task), state->filters, state->values, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_DETAILS) { pk_client_get_details_async (PK_CLIENT(state->task), state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_UPDATE_DETAIL) { pk_client_get_update_detail_async (PK_CLIENT(state->task), state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_DOWNLOAD_PACKAGES) { pk_client_download_packages_async (PK_CLIENT(state->task), state->package_ids, state->directory, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_UPDATES) { pk_client_get_updates_async (PK_CLIENT(state->task), state->filters, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_DEPENDS) { pk_client_get_depends_async (PK_CLIENT(state->task), state->filters, state->package_ids, state->recursive, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_PACKAGES) { pk_client_get_packages_async (PK_CLIENT(state->task), state->filters, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_REQUIRES) { pk_client_get_requires_async (PK_CLIENT(state->task), state->filters, state->package_ids, state->recursive, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_WHAT_PROVIDES) { pk_client_what_provides_async (PK_CLIENT(state->task), state->filters, state->provides, state->values, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_FILES) { pk_client_get_files_async (PK_CLIENT(state->task), state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_CATEGORIES) { pk_client_get_categories_async (PK_CLIENT(state->task), state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_REFRESH_CACHE) { pk_client_refresh_cache_async (PK_CLIENT(state->task), state->force, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_ROLLBACK) { pk_client_rollback_async (PK_CLIENT(state->task), state->transaction_id, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_GET_REPO_LIST) { pk_client_get_repo_list_async (PK_CLIENT(state->task), state->filters, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_REPO_ENABLE) { pk_client_repo_enable_async (PK_CLIENT(state->task), state->repo_id, state->enabled, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_ready_cb, state); } else { g_assert_not_reached (); } } /** * pk_task_package_filter_cb: **/ static gboolean pk_task_package_filter_cb (PkPackage *package, gpointer user_data) { PkInfoEnum info; info = pk_package_get_info (package); if (info == PK_INFO_ENUM_CLEANUP || info == PK_INFO_ENUM_FINISHED) return FALSE; return TRUE; } /** * pk_task_simulate_ready_cb: **/ static void pk_task_simulate_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskState *state) { PkTaskClass *klass = PK_TASK_GET_CLASS (state->task); GError *error = NULL; PkResults *results; PkPackageSack *sack = NULL; guint length; PkError *error_code; guint idx = 0; guint i; GPtrArray *array = NULL; GPtrArray *array_messages = NULL; PkPackage *item; gboolean ret; PkInfoEnum info; PkMessage *message; PkMessageEnum message_type; const gchar *package_id; /* old results no longer valid */ if (state->results != NULL) g_object_unref (state->results); /* get the results */ results = pk_client_generic_finish (PK_CLIENT(state->task), res, &error); if (results == NULL) { /* handle case where this is not implemented */ if (error->code == PK_CLIENT_ERROR_NOT_SUPPORTED) { pk_task_do_async_action (state); g_error_free (error); goto out; } /* just abort */ pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* we own a copy now */ state->results = g_object_ref (G_OBJECT(results)); /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { error_code = pk_results_get_error_code (state->results); /* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "could not do simulate: %s", pk_error_get_details (error_code)); pk_task_generic_state_finish (state, error); g_error_free (error); g_object_unref (error_code); goto out; } /* if we did a simulate and we got a message that a package was untrusted, * there's no point trying to do the action with only-trusted */ if (state->simulate && state->only_trusted) { array_messages = pk_results_get_message_array (state->results); for (i = 0; i < array_messages->len; i++) { message = g_ptr_array_index (array_messages, i); g_object_get (message, "type", &message_type, NULL); if (message_type == PK_MESSAGE_ENUM_UNTRUSTED_PACKAGE) { egg_debug ("we got an untrusted message, so skipping only-trusted"); state->only_trusted = FALSE; break; } } } /* get data */ sack = pk_results_get_package_sack (results); /* remove all the cleanup and finished packages */ pk_package_sack_remove_by_filter (sack, pk_task_package_filter_cb, state); /* remove all the original packages from the sack */ if (state->package_ids != NULL) { length = g_strv_length (state->package_ids); for (i=0; ipackage_ids[i]); } /* remove packages from the array that will not be useful */ if (state->package_ids != NULL) { array = pk_results_get_package_array (results); while (idx < array->len) { item = g_ptr_array_index (array, idx); package_id = pk_package_get_id (item); g_object_get (item, "info", &info, NULL); /* remove all the cleanup and finished packages */ if (info == PK_INFO_ENUM_CLEANUP || info == PK_INFO_ENUM_FINISHED) { egg_debug ("removing %s", package_id); g_ptr_array_remove (array, item); continue; } /* remove all the original packages */ ret = FALSE; length = g_strv_length (state->package_ids); for (i=0; ipackage_ids[i]) == 0) { egg_debug ("removing %s", package_id); g_ptr_array_remove (array, item); ret = TRUE; break; } } if (ret) continue; /* no removal done */ idx++; } } /* no results from simulate */ if (pk_package_sack_get_size (sack) == 0) { pk_task_do_async_action (state); goto out; } /* sort the list, as clients will mostly want this */ pk_package_sack_sort (sack, PK_PACKAGE_SACK_SORT_TYPE_INFO); /* run the callback */ klass->simulate_question (state->task, state->request, state->results); out: if (array != NULL) g_ptr_array_unref (array); if (array_messages != NULL) g_ptr_array_unref (array_messages); if (results != NULL) g_object_unref (results); if (sack != NULL) g_object_unref (sack); return; } /** * pk_task_do_async_simulate_action: **/ static void pk_task_do_async_simulate_action (PkTaskState *state) { /* so the callback knows if we are serious or not */ state->simulate = TRUE; /* do the correct action */ if (state->role == PK_ROLE_ENUM_INSTALL_PACKAGES) { /* simulate install async */ egg_debug ("doing install"); pk_client_simulate_install_packages_async (PK_CLIENT(state->task), state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_simulate_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_UPDATE_PACKAGES) { /* simulate update async */ egg_debug ("doing update"); pk_client_simulate_update_packages_async (PK_CLIENT(state->task), state->package_ids, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_simulate_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_REMOVE_PACKAGES) { /* simulate remove async */ egg_debug ("doing remove"); pk_client_simulate_remove_packages_async (PK_CLIENT(state->task), state->package_ids, state->autoremove, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_simulate_ready_cb, state); } else if (state->role == PK_ROLE_ENUM_INSTALL_FILES) { /* simulate install async */ egg_debug ("doing install files"); pk_client_simulate_install_files_async (PK_CLIENT(state->task), state->files, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_simulate_ready_cb, state); } else { g_assert_not_reached (); } } /** * pk_task_install_signatures_ready_cb: **/ static void pk_task_install_signatures_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskState *state) { PkTask *task = PK_TASK (source_object); GError *error = NULL; PkResults *results; PkError *error_code; /* old results no longer valid */ if (state->results != NULL) g_object_unref (state->results); /* get the results */ results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (results == NULL) { pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* we own a copy now */ state->results = g_object_ref (G_OBJECT(results)); /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* need untrusted */ if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { error_code = pk_results_get_error_code (state->results); /* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to install signature: %s", pk_error_get_details (error_code)); pk_task_generic_state_finish (state, error); g_error_free (error); g_object_unref (error_code); goto out; } /* now try the action again */ pk_task_do_async_action (state); out: if (results != NULL) g_object_unref (results); return; } /** * pk_task_install_signatures: **/ static void pk_task_install_signatures (PkTaskState *state) { GError *error = NULL; GPtrArray *array; PkRepoSignatureRequired *item; gchar *key_id = NULL; gchar *package_id = NULL; PkSigTypeEnum type; /* get results */ array = pk_results_get_repo_signature_required_array (state->results); if (array == NULL || array->len == 0) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "no signatures to install"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* did we get more than result? */ if (array->len > 1) { /* TODO: support more than one signature */ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "more than one signature to install"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* get first item of data */ item = g_ptr_array_index (array, 0); g_object_get (item, "type", &type, "key-id", &key_id, "package-id", &package_id, NULL); /* do new async method */ pk_client_install_signature_async (PK_CLIENT(state->task), type, key_id, package_id, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_install_signatures_ready_cb, state); out: g_free (package_id); g_free (key_id); if (array != NULL) g_ptr_array_unref (array); } /** * pk_task_accept_eulas_ready_cb: **/ static void pk_task_accept_eulas_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskState *state) { PkTask *task = PK_TASK (source_object); GError *error = NULL; PkResults *results; PkError *error_code; /* old results no longer valid */ if (state->results != NULL) g_object_unref (state->results); /* get the results */ results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (results == NULL) { pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* we own a copy now */ state->results = g_object_ref (G_OBJECT(results)); /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* need untrusted */ if (state->exit_enum != PK_EXIT_ENUM_SUCCESS) { error_code = pk_results_get_error_code (state->results); /* TODO: convert the PkErrorEnum to a PK_CLIENT_ERROR_* enum */ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "failed to accept eula: %s", pk_error_get_details (error_code)); pk_task_generic_state_finish (state, error); g_error_free (error); g_object_unref (error_code); goto out; } /* now try the action again */ pk_task_do_async_action (state); out: if (results != NULL) g_object_unref (results); return; } /** * pk_task_accept_eulas: **/ static void pk_task_accept_eulas (PkTaskState *state) { GError *error = NULL; GPtrArray *array; PkEulaRequired *item; gchar *eula_id = NULL; /* get results */ array = pk_results_get_eula_required_array (state->results); if (array == NULL || array->len == 0) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "no eulas to accept"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* did we get more than result? */ if (array->len > 1) { /* TODO: support more than one eula */ error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "more than one eula to accept"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* get first item of data */ item = g_ptr_array_index (array, 0); g_object_get (item, "eula-id", &eula_id, NULL); /* do new async method */ pk_client_accept_eula_async (PK_CLIENT(state->task), eula_id, state->cancellable, state->progress_callback, state->progress_user_data, (GAsyncReadyCallback) pk_task_accept_eulas_ready_cb, state); out: g_free (eula_id); if (array != NULL) g_ptr_array_unref (array); } /** * pk_task_user_accepted_idle_cb: **/ static gboolean pk_task_user_accepted_idle_cb (PkTaskState *state) { /* this needs another step in the dance */ if (state->exit_enum == PK_EXIT_ENUM_KEY_REQUIRED) { egg_debug ("need to do install-sig"); pk_task_install_signatures (state); goto out; } /* this needs another step in the dance */ if (state->exit_enum == PK_EXIT_ENUM_EULA_REQUIRED) { egg_debug ("need to do accept-eula"); pk_task_accept_eulas (state); goto out; } /* doing task */ egg_debug ("continuing with request %i", state->request); pk_task_do_async_action (state); out: /* never repeat */ return FALSE; } /** * pk_task_user_accepted: * * Since: 0.5.2 **/ gboolean pk_task_user_accepted (PkTask *task, guint request) { guint idle_id; PkTaskState *state; /* get the not-yet-completed request */ state = pk_task_find_by_request (task, request); if (state == NULL) { egg_warning ("request %i not found", request); return FALSE; } idle_id = g_idle_add ((GSourceFunc) pk_task_user_accepted_idle_cb, state); #if GLIB_CHECK_VERSION(2,25,8) g_source_set_name_by_id (idle_id, "[PkTask] user-accept"); #endif return TRUE; } /** * pk_task_user_declined_idle_cb: **/ static gboolean pk_task_user_declined_idle_cb (PkTaskState *state) { GError *error; /* the introduction is finished */ if (state->simulate) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_DECLINED_SIMULATION, "user declined simulation"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* doing task */ egg_debug ("declined request %i", state->request); error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_FAILED, "user declined interaction"); pk_task_generic_state_finish (state, error); g_error_free (error); out: /* never repeat */ return FALSE; } /** * pk_task_user_declined: * * Since: 0.5.2 **/ gboolean pk_task_user_declined (PkTask *task, guint request) { guint idle_id; PkTaskState *state; /* get the not-yet-completed request */ state = pk_task_find_by_request (task, request); if (state == NULL) { egg_warning ("request %i not found", request); return FALSE; } idle_id = g_idle_add ((GSourceFunc) pk_task_user_declined_idle_cb, state); #if GLIB_CHECK_VERSION(2,25,8) g_source_set_name_by_id (idle_id, "[PkTask] user-declined"); #endif return TRUE; } /** * pk_task_ready_cb: **/ static void pk_task_ready_cb (GObject *source_object, GAsyncResult *res, PkTaskState *state) { PkTask *task = PK_TASK (source_object); PkTaskClass *klass = PK_TASK_GET_CLASS (task); GError *error = NULL; PkResults *results; /* old results no longer valid */ if (state->results != NULL) g_object_unref (state->results); /* get the results */ results = pk_client_generic_finish (PK_CLIENT(task), res, &error); if (results == NULL) { pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* we own a copy now */ state->results = g_object_ref (G_OBJECT(results)); /* get exit code */ state->exit_enum = pk_results_get_exit_code (state->results); /* need untrusted */ if (state->exit_enum == PK_EXIT_ENUM_NEED_UNTRUSTED) { state->only_trusted = FALSE; /* no support */ if (klass->untrusted_question == NULL) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do untrusted question as no klass support"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* run the callback */ klass->untrusted_question (task, state->request, state->results); goto out; } /* need key */ if (state->exit_enum == PK_EXIT_ENUM_KEY_REQUIRED) { /* no support */ if (klass->key_question == NULL) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do key question as no klass support"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* run the callback */ klass->key_question (task, state->request, state->results); goto out; } /* need EULA */ if (state->exit_enum == PK_EXIT_ENUM_EULA_REQUIRED) { /* no support */ if (klass->eula_question == NULL) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do eula question as no klass support"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* run the callback */ klass->eula_question (task, state->request, state->results); goto out; } /* need media change */ if (state->exit_enum == PK_EXIT_ENUM_MEDIA_CHANGE_REQUIRED) { /* no support */ if (klass->media_change_question == NULL) { error = g_error_new (PK_CLIENT_ERROR, PK_CLIENT_ERROR_NOT_SUPPORTED, "could not do media change question as no klass support"); pk_task_generic_state_finish (state, error); g_error_free (error); goto out; } /* run the callback */ klass->media_change_question (task, state->request, state->results); goto out; } /* we can't handle this, just finish the async method */ state->ret = TRUE; /* we're done */ pk_task_generic_state_finish (state, error); out: if (results != NULL) g_object_unref (results); return; } /** * pk_task_install_packages_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Merges in details about packages using resolve. * * Since: 0.5.2 **/ void pk_task_install_packages_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_INSTALL_PACKAGES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (state); else pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_update_packages_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Update specific packages to the newest available versions. * * Since: 0.5.2 **/ void pk_task_update_packages_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_update_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_UPDATE_PACKAGES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->only_trusted = TRUE; state->package_ids = g_strdupv (package_ids); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (state); else pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_remove_packages_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @allow_deps: if other dependant packages are allowed to be removed from the computer * @autoremove: if other packages installed at the same time should be tried to remove * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Remove a package (optionally with dependancies) from the system. * If %allow_deps is set to %FALSE, and other packages would have to be removed, * then the transaction would fail. * * Since: 0.5.2 **/ void pk_task_remove_packages_async (PkTask *task, gchar **package_ids, gboolean allow_deps, gboolean autoremove, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_remove_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REMOVE_PACKAGES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->allow_deps = allow_deps; state->autoremove = autoremove; state->package_ids = g_strdupv (package_ids); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (state); else pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_install_files_async: * @task: a valid #PkTask instance * @files: a file such as "/home/hughsie/Desktop/hal-devel-0.10.0.rpm" * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Install a file locally, and get the deps from the repositories. * This is useful for double clicking on a .rpm or .deb file. * * Since: 0.5.2 **/ void pk_task_install_files_async (PkTask *task, gchar **files, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; PkTaskClass *klass = PK_TASK_GET_CLASS (task); g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_files_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_INSTALL_FILES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->only_trusted = TRUE; state->files = g_strdupv (files); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* start trusted install async */ if (task->priv->simulate && klass->simulate_question != NULL) pk_task_do_async_simulate_action (state); else pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_update_system_async: * @task: a valid #PkTask instance * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback_ready: the function to run on completion * @user_data: the data to pass to @callback_ready * * Update all the packages on the system with the highest versions found in all * repositories. * NOTE: you can't choose what repositories to update from, but you can do: * - pk_task_repo_disable() * - pk_task_update_system() * - pk_task_repo_enable() * * Since: 0.5.2 **/ void pk_task_update_system_async (PkTask *task, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_CLIENT (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_update_system_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_UPDATE_SYSTEM; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->only_trusted = TRUE; state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* start trusted install async */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_resolve_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @packages: package names to find * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Resolves a package name to a package-id. * * Since: 0.6.5 **/ void pk_task_resolve_async (PkTask *task, PkBitfield filters, gchar **packages, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_RESOLVE; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->packages = g_strdupv (packages); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_search_names_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: search values * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Searches for a package name. * * Since: 0.6.5 **/ void pk_task_search_names_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_NAME; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_search_details_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: search values * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Searches for some package details. * * Since: 0.6.5 **/ void pk_task_search_details_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_DETAILS; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_search_groups_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: search values * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Searches the group lists. * * Since: 0.6.5 **/ void pk_task_search_groups_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_GROUP; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_search_files_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @values: search values * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Searches for specific files. * * Since: 0.6.5 **/ void pk_task_search_files_async (PkTask *task, PkBitfield filters, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_SEARCH_FILE; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_details_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Gets details about packages. * * Since: 0.6.5 **/ void pk_task_get_details_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_DETAILS; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_update_detail_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Gets details about updates. * * Since: 0.6.5 **/ void pk_task_get_update_detail_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_UPDATE_DETAIL; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_download_packages_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @directory: the destination directory * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Downloads packages * * Since: 0.6.5 **/ void pk_task_download_packages_async (PkTask *task, gchar **package_ids, const gchar *directory, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_DOWNLOAD_PACKAGES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->package_ids = g_strdupv (package_ids); state->directory = g_strdup (directory); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_updates_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Gets the update lists. * * Since: 0.6.5 **/ void pk_task_get_updates_async (PkTask *task, PkBitfield filters, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_UPDATES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_depends_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @recursive: if we should recurse to packages that depend on other packages * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Get the list of dependant packages. * * Since: 0.6.5 **/ void pk_task_get_depends_async (PkTask *task, PkBitfield filters, gchar **package_ids, gboolean recursive, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_DEPENDS; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->package_ids = g_strdupv (package_ids); state->recursive = recursive; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_packages_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Gets the list of packages. * * Since: 0.6.5 **/ void pk_task_get_packages_async (PkTask *task, PkBitfield filters, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_PACKAGES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_requires_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @recursive: if we should return packages that depend on the ones we do * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Get the packages this package requires. * * Since: 0.6.5 **/ void pk_task_get_requires_async (PkTask *task, PkBitfield filters, gchar **package_ids, gboolean recursive, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_REQUIRES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->package_ids = g_strdupv (package_ids); state->recursive = recursive; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_what_provides_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @provides: a #PkProvidesEnum type * @values: values to search for * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Find the package that provides some resource. * * Since: 0.6.5 **/ void pk_task_what_provides_async (PkTask *task, PkBitfield filters, PkProvidesEnum provides, gchar **values, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_WHAT_PROVIDES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->provides = provides; state->values = g_strdupv (values); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_files_async: * @task: a valid #PkTask instance * @package_ids: a null terminated array of package_id structures such as "hal;0.0.1;i386;fedora" * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Get the files in a package. * * Since: 0.6.5 **/ void pk_task_get_files_async (PkTask *task, gchar **package_ids, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_FILES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->package_ids = g_strdupv (package_ids); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_categories_async: * @task: a valid #PkTask instance * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Get the categories available. * * Since: 0.6.5 **/ void pk_task_get_categories_async (PkTask *task, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_CATEGORIES; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_refresh_cache_async: * @task: a valid #PkTask instance * @force: if the metadata should be deleted and re-downloaded even if it is correct * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Refresh the package cache. * * Since: 0.6.5 **/ void pk_task_refresh_cache_async (PkTask *task, gboolean force, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REFRESH_CACHE; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->force = force; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_rollback_async: * @task: a valid #PkTask instance * @transaction_id: The transaction ID of the old transaction * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Rollback to a previous package state. * * Since: 0.6.5 **/ void pk_task_rollback_async (PkTask *task, const gchar *transaction_id, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_ROLLBACK; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->transaction_id = g_strdup (transaction_id); state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_get_repo_list_async: * @task: a valid #PkTask instance * @filters: a bitfield of filters that can be used to limit the results * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Get the list of available repositories. * * Since: 0.6.5 **/ void pk_task_get_repo_list_async (PkTask *task, PkBitfield filters, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_GET_REPO_LIST; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->filters = filters; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_repo_enable_async: * @task: a valid #PkTask instance * @repo_id: The software source ID * @enabled: %TRUE or %FALSE * @cancellable: a #GCancellable or %NULL * @progress_callback: the function to run when the progress changes * @progress_user_data: data to pass to @progress_callback * @callback: the function to run on completion * @user_data: the data to pass to @callback * * Enable or disable a specific repo. * * Since: 0.6.5 **/ void pk_task_repo_enable_async (PkTask *task, const gchar *repo_id, gboolean enabled, GCancellable *cancellable, PkProgressCallback progress_callback, gpointer progress_user_data, GAsyncReadyCallback callback_ready, gpointer user_data) { GSimpleAsyncResult *res; PkTaskState *state; g_return_if_fail (PK_IS_TASK (task)); g_return_if_fail (callback_ready != NULL); res = g_simple_async_result_new (G_OBJECT (task), callback_ready, user_data, pk_task_install_packages_async); /* save state */ state = g_slice_new0 (PkTaskState); state->role = PK_ROLE_ENUM_REPO_ENABLE; state->res = g_object_ref (res); state->task = g_object_ref (task); if (cancellable != NULL) state->cancellable = g_object_ref (cancellable); state->progress_callback = progress_callback; state->progress_user_data = progress_user_data; state->ret = FALSE; state->only_trusted = TRUE; state->repo_id = g_strdup (repo_id); state->enabled = enabled; state->request = pk_task_generate_request_id (); egg_debug ("adding state %p", state); g_ptr_array_add (task->priv->array, state); /* run task with callbacks */ pk_task_do_async_action (state); g_object_unref (res); } /** * pk_task_generic_finish: * @task: a valid #PkTask instance * @res: the #GAsyncResult * @error: A #GError or %NULL * * Gets the result from the asynchronous function. * * Return value: %TRUE for success * * Since: 0.5.2 **/ PkResults * pk_task_generic_finish (PkTask *task, GAsyncResult *res, GError **error) { GSimpleAsyncResult *simple; g_return_val_if_fail (PK_IS_TASK (task), NULL); g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); simple = G_SIMPLE_ASYNC_RESULT (res); if (g_simple_async_result_propagate_error (simple, error)) return NULL; return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple)); } /** * pk_task_get_property: **/ static void pk_task_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { PkTask *task = PK_TASK (object); PkTaskPrivate *priv = task->priv; switch (prop_id) { case PROP_SIMULATE: g_value_set_boolean (value, priv->simulate); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /** * pk_task_set_property: **/ static void pk_task_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { PkTask *task = PK_TASK (object); PkTaskPrivate *priv = task->priv; switch (prop_id) { case PROP_SIMULATE: priv->simulate = g_value_get_boolean (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /** * pk_task_class_init: **/ static void pk_task_class_init (PkTaskClass *klass) { GParamSpec *pspec; GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = pk_task_finalize; object_class->get_property = pk_task_get_property; object_class->set_property = pk_task_set_property; /** * PkTask:simulate: * * Since: 0.5.2 */ pspec = g_param_spec_boolean ("simulate", NULL, NULL, TRUE, G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_SIMULATE, pspec); g_type_class_add_private (klass, sizeof (PkTaskPrivate)); } /** * pk_task_init: **/ static void pk_task_init (PkTask *task) { task->priv = PK_TASK_GET_PRIVATE (task); task->priv->array = g_ptr_array_new (); task->priv->simulate = TRUE; } /** * pk_task_finalize: **/ static void pk_task_finalize (GObject *object) { PkTask *task = PK_TASK (object); g_ptr_array_unref (task->priv->array); G_OBJECT_CLASS (pk_task_parent_class)->finalize (object); } /** * pk_task_new: * * Return value: a new PkTask object. * * Since: 0.5.2 **/ PkTask * pk_task_new (void) { PkTask *task; task = g_object_new (PK_TYPE_TASK, NULL); return PK_TASK (task); }