gboolean gs_plugin_add_updates (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { guint i; g_autoptr(GError) error_local = NULL; g_auto(GStrv) package_ids = NULL; /* get the id's if the file exists */ package_ids = pk_offline_get_prepared_ids (&error_local); if (package_ids == NULL) { if (g_error_matches (error_local, PK_OFFLINE_ERROR, PK_OFFLINE_ERROR_NO_DATA)) { return TRUE; } g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "Failed to get prepared IDs: %s", error_local->message); return FALSE; } /* add them to the new array */ for (i = 0; package_ids[i] != NULL; i++) { g_autoptr(GsApp) app = NULL; g_auto(GStrv) split = NULL; /* search in the cache */ app = gs_plugin_cache_lookup (plugin, package_ids[i]); if (app != NULL) { gs_app_list_add (list, app); continue; } /* create new app */ app = gs_app_new (NULL); gs_app_add_quirk (app, AS_APP_QUIRK_NEEDS_REBOOT); gs_app_set_management_plugin (app, "packagekit"); gs_app_add_source_id (app, package_ids[i]); split = pk_package_id_split (package_ids[i]); gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]); gs_app_set_update_version (app, split[PK_PACKAGE_ID_VERSION]); gs_app_set_state (app, AS_APP_STATE_UPDATABLE); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_app_set_size_download (app, 0); gs_app_list_add (list, app); /* save in the cache */ gs_plugin_cache_add (plugin, package_ids[i], app); } return TRUE; }
/** * pk_offline_get_prepared_sack: * @error: A #GError or %NULL * * Gets a package sack of the packages in the prepared transaction. * * Return value: (transfer full): A new #PkPackageSack, or %NULL * * Since: 0.9.6 **/ PkPackageSack * pk_offline_get_prepared_sack (GError **error) { guint i; g_autoptr(PkPackageSack) sack = NULL; g_auto(GStrv) package_ids = NULL; /* get the list of packages */ package_ids = pk_offline_get_prepared_ids (error); if (package_ids == NULL) return NULL; /* add them to the new array */ sack = pk_package_sack_new (); for (i = 0; package_ids[i] != NULL; i++) { if (!pk_package_sack_add_package_by_id (sack, package_ids[i], error)) return NULL; } return g_object_ref (sack); }
/** * main: **/ int main (int argc, char *argv[]) { PkOfflineAction action = PK_OFFLINE_ACTION_UNKNOWN; gint retval; _cleanup_error_free_ GError *error = NULL; _cleanup_main_loop_unref_ GMainLoop *loop = NULL; _cleanup_object_unref_ GFile *file = NULL; _cleanup_object_unref_ PkProgressBar *progressbar = NULL; _cleanup_object_unref_ PkResults *results = NULL; _cleanup_object_unref_ PkTask *task = NULL; _cleanup_strv_free_ gchar **package_ids = NULL; #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 35) g_type_init (); #endif /* ensure root user */ if (getuid () != 0 || geteuid () != 0) { retval = EXIT_FAILURE; g_print ("This program can only be used using root\n"); sd_journal_print (LOG_WARNING, "not called with the root user"); goto out; } /* get the action, and then delete the file */ action = pk_offline_update_get_action (); g_unlink (PK_OFFLINE_ACTION_FILENAME); /* always do this first to avoid a loop if this tool segfaults */ g_unlink (PK_OFFLINE_TRIGGER_FILENAME); /* do stuff on ctrl-c */ g_unix_signal_add_full (G_PRIORITY_DEFAULT, SIGINT, pk_offline_update_sigint_cb, NULL, NULL); /* get the list of packages to update */ package_ids = pk_offline_get_prepared_ids (&error); if (package_ids == NULL) { retval = EXIT_FAILURE; sd_journal_print (LOG_WARNING, "failed to read %s: %s", PK_OFFLINE_PREPARED_FILENAME, error->message); goto out; } /* use a progress bar when the user presses <esc> in plymouth */ progressbar = pk_progress_bar_new (); pk_progress_bar_set_size (progressbar, 25); pk_progress_bar_set_padding (progressbar, 30); /* just update the system */ task = pk_task_new (); pk_client_set_interactive (PK_CLIENT (task), FALSE); pk_offline_update_set_plymouth_mode ("updates"); /* TRANSLATORS: we've started doing offline updates */ pk_offline_update_set_plymouth_msg (_("Installing updates, this could take a while...")); pk_offline_update_write_dummy_results (package_ids); results = pk_client_update_packages (PK_CLIENT (task), 0, package_ids, NULL, /* GCancellable */ pk_offline_update_progress_cb, progressbar, /* user_data */ &error); if (results == NULL) { retval = EXIT_FAILURE; pk_offline_update_write_error (error); sd_journal_print (LOG_WARNING, "failed to update system: %s", error->message); goto out; } pk_progress_bar_end (progressbar); pk_offline_update_write_results (results); /* delete prepared-update file if it's not already been done by the * pk-plugin-systemd-update daemon plugin */ if (!pk_offline_auth_invalidate (&error)) { retval = EXIT_FAILURE; sd_journal_print (LOG_WARNING, "failed to delete %s: %s", PK_OFFLINE_PREPARED_FILENAME, error->message); goto out; } retval = EXIT_SUCCESS; out: /* if we failed, we pause to show any error on the screen */ if (retval != EXIT_SUCCESS) { loop = g_main_loop_new (NULL, FALSE); g_timeout_add_seconds (10, pk_offline_update_loop_quit_cb, loop); g_main_loop_run (loop); } /* we have to manually either restart or shutdown */ if (action == PK_OFFLINE_ACTION_REBOOT) pk_offline_update_reboot (); else if (action == PK_OFFLINE_ACTION_POWER_OFF) pk_offline_update_power_off (); return retval; }