diff --git a/contrib/debian/fwupd.install b/contrib/debian/fwupd.install index 5b8a2263a..f9dfd4f69 100644 --- a/contrib/debian/fwupd.install +++ b/contrib/debian/fwupd.install @@ -10,6 +10,7 @@ usr/share/locale usr/share/metainfo/* usr/lib/*/fwupd usr/lib/*/fwupdagent +usr/lib/*/fwupdoffline usr/lib/*/fwupdtool usr/share/man/man1/* lib/systemd/system/* diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in index 9426e8427..62956097a 100644 --- a/contrib/fwupd.spec.in +++ b/contrib/fwupd.spec.in @@ -214,6 +214,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg %{_libexecdir}/fwupd/fwupd %{_libexecdir}/fwupd/fwupdtool %{_libexecdir}/fwupd/fwupdagent +%{_libexecdir}/fwupd/fwupdoffline %if 0%{?have_uefi} %{_libexecdir}/fwupd/efi/*.efi %{_libexecdir}/fwupd/efi/*.efi.signed diff --git a/data/bash-completion/fwupdmgr b/data/bash-completion/fwupdmgr index 7887bd31a..96483b34d 100644 --- a/data/bash-completion/fwupdmgr +++ b/data/bash-completion/fwupdmgr @@ -16,7 +16,6 @@ _fwupdmgr_cmd_list=( 'get-topology' 'get-updates' 'install' - 'install-prepared' 'modify-remote' 'refresh' 'report-history' diff --git a/data/fwupd-offline-update.service.in b/data/fwupd-offline-update.service.in index cdc5489a4..f6002c0b6 100644 --- a/data/fwupd-offline-update.service.in +++ b/data/fwupd-offline-update.service.in @@ -9,5 +9,5 @@ Before=shutdown.target system-update.target [Service] Type=oneshot -ExecStart=@bindir@/fwupdmgr install-prepared +ExecStart=@bindir@/fwupdoffline FailureAction=reboot diff --git a/po/POTFILES.in b/po/POTFILES.in index 85277aa6e..d8025f3f5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -8,6 +8,7 @@ src/fu-agent.c src/fu-config.c src/fu-debug.c src/fu-main.c +src/fu-offline.c src/fu-tool.c src/fu-progressbar.c src/fu-util.c diff --git a/src/fu-offline.c b/src/fu-offline.c new file mode 100644 index 000000000..c31b43870 --- /dev/null +++ b/src/fu-offline.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2015-2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "fu-history.h" +#include "fu-plugin-private.h" +#include "fu-util-common.h" + +int +main (int argc, char *argv[]) +{ + gint vercmp; + guint cnt = 0; + g_autofree gchar *link = NULL; + g_autoptr(FuHistory) history = NULL; + g_autoptr(FwupdClient) client = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GPtrArray) results = NULL; + + setlocale (LC_ALL, ""); + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + /* verify this is pointing to our cache */ + link = g_file_read_link (FU_OFFLINE_TRIGGER_FILENAME, NULL); + if (link == NULL) + return EXIT_SUCCESS; + if (g_strcmp0 (link, "/var/lib/fwupd") != 0) + return EXIT_SUCCESS; + + /* do this first to avoid a loop if this tool segfaults */ + g_unlink (FU_OFFLINE_TRIGGER_FILENAME); + + /* ensure root user */ + if (getuid () != 0 || geteuid () != 0) { + /* TRANSLATORS: the user needs to stop playing with stuff */ + g_printerr ("%s\n", _("This tool can only be used by the root user")); + return EXIT_FAILURE; + } + + /* ensure D-Bus errors are registered */ + fwupd_error_quark (); + + /* get prepared updates */ + history = fu_history_new (); + results = fu_history_get_devices (history, &error); + if (results == NULL) { + /* TRANSLATORS: we could not get the devices to update offline */ + g_printerr ("%s: %s\n", _("Failed to get pending devices"), + error->message); + return EXIT_FAILURE; + } + + /* connect to the daemon */ + client = fwupd_client_new (); + if (!fwupd_client_connect (client, NULL, &error)) { + /* TRANSLATORS: we could not talk to the fwupd daemon */ + g_printerr ("%s: %s\n", _("Failed to connect to daemon"), + error->message); + return EXIT_FAILURE; + } + + /* apply each update */ + for (guint i = 0; i < results->len; i++) { + FwupdDevice *dev = g_ptr_array_index (results, i); + FwupdRelease *rel = fwupd_device_get_release_default (dev); + + /* check not already done */ + if (fwupd_device_get_update_state (dev) != FWUPD_UPDATE_STATE_PENDING) + continue; + + /* tell the user what's going to happen */ + vercmp = fu_common_vercmp (fwupd_device_get_version (dev), + fwupd_release_get_version (rel)); + if (vercmp == 0) { + /* TRANSLATORS: the first replacement is a display name + * e.g. "ColorHugALS" and the second is a version number + * e.g. "1.2.3" */ + g_print (_("Reinstalling %s with %s... "), + fwupd_device_get_name (dev), + fwupd_release_get_version (rel)); + } else if (vercmp > 0) { + /* TRANSLATORS: the first replacement is a display name + * e.g. "ColorHugALS" and the second and third are + * version numbers e.g. "1.2.3" */ + g_print (_("Downgrading %s from %s to %s... "), + fwupd_device_get_name (dev), + fwupd_device_get_version (dev), + fwupd_release_get_version (rel)); + } else if (vercmp < 0) { + /* TRANSLATORS: the first replacement is a display name + * e.g. "ColorHugALS" and the second and third are + * version numbers e.g. "1.2.3" */ + g_print (_("Updating %s from %s to %s... "), + fwupd_device_get_name (dev), + fwupd_device_get_version (dev), + fwupd_release_get_version (rel)); + } + if (!fwupd_client_install (client, + fwupd_device_get_id (dev), + fwupd_release_get_filename (rel), + FWUPD_INSTALL_FLAG_NONE, + NULL, + &error)) { + /* TRANSLATORS: we could not install for some reason */ + g_printerr ("%s: %s\n", _("Failed to install firmware update"), + error->message); + return EXIT_FAILURE; + } + cnt++; + } + + /* nothing to do */ + if (cnt == 0) { + /* TRANSLATORS: nothing was updated offline */ + g_printerr ("%s\n", _("No updates were applied")); + return EXIT_FAILURE; + } + + /* reboot */ + if (!fu_util_update_reboot (&error)) { + /* TRANSLATORS: we could not reboot for some reason */ + g_printerr ("%s: %s\n", _("Failed to reboot"), error->message); + return EXIT_FAILURE; + } + + /* success */ + g_print ("%s\n", _("Done!")); + return EXIT_SUCCESS; +} diff --git a/src/fu-util-common.c b/src/fu-util-common.c index 46d228770..2e3d701b6 100644 --- a/src/fu-util-common.c +++ b/src/fu-util-common.c @@ -219,7 +219,7 @@ fu_util_update_shutdown (GError **error) return val != NULL; } -static gboolean +gboolean fu_util_update_reboot (GError **error) { g_autoptr(GDBusConnection) connection = NULL; diff --git a/src/fu-util-common.h b/src/fu-util-common.h index 5c3d44caf..85eb81dae 100644 --- a/src/fu-util-common.h +++ b/src/fu-util-common.h @@ -41,6 +41,7 @@ gchar *fu_util_get_versions (void); gboolean fu_util_prompt_complete (FwupdDeviceFlags flags, gboolean prompt, GError **error); +gboolean fu_util_update_reboot (GError **error); GPtrArray *fu_util_cmd_array_new (void); void fu_util_cmd_array_add (GPtrArray *array, diff --git a/src/fu-util.c b/src/fu-util.c index 6c22e33d1..d0f756832 100644 --- a/src/fu-util.c +++ b/src/fu-util.c @@ -562,115 +562,6 @@ fu_util_get_details (FuUtilPrivate *priv, gchar **values, GError **error) return TRUE; } -static gboolean -fu_util_install_prepared (FuUtilPrivate *priv, gchar **values, GError **error) -{ - gint vercmp; - guint cnt = 0; - g_autofree gchar *link = NULL; - g_autoptr(GPtrArray) results = NULL; - g_autoptr(FuHistory) history = NULL; - - /* verify this is pointing to our cache */ - link = g_file_read_link (FU_OFFLINE_TRIGGER_FILENAME, NULL); - if (link == NULL) { - g_debug ("No %s, exiting", FU_OFFLINE_TRIGGER_FILENAME); - return TRUE; - } - if (g_strcmp0 (link, "/var/lib/fwupd") != 0) { - g_debug ("Another framework set up the trigger, exiting"); - return TRUE; - } - - /* do this first to avoid a loop if this tool segfaults */ - g_unlink (FU_OFFLINE_TRIGGER_FILENAME); - - if (g_strv_length (values) != 0) { - g_set_error_literal (error, - FWUPD_ERROR, - FWUPD_ERROR_INVALID_ARGS, - "Invalid arguments: none expected"); - return FALSE; - } - - /* ensure root user */ - if (getuid () != 0 || geteuid () != 0) { - g_set_error_literal (error, - FWUPD_ERROR, - FWUPD_ERROR_INVALID_ARGS, - "This function can only be used as root"); - return FALSE; - } - - /* get prepared updates */ - history = fu_history_new (); - results = fu_history_get_devices (history, error); - if (results == NULL) - return FALSE; - - /* apply each update */ - for (guint i = 0; i < results->len; i++) { - FwupdDevice *dev = g_ptr_array_index (results, i); - FwupdRelease *rel = fwupd_device_get_release_default (dev); - - /* check not already done */ - if (fwupd_device_get_update_state (dev) != FWUPD_UPDATE_STATE_PENDING) - continue; - - /* tell the user what's going to happen */ - vercmp = fu_common_vercmp (fwupd_device_get_version (dev), - fwupd_release_get_version (rel)); - if (vercmp == 0) { - /* TRANSLATORS: the first replacement is a display name - * e.g. "ColorHugALS" and the second is a version number - * e.g. "1.2.3" */ - g_print (_("Reinstalling %s with %s... "), - fwupd_device_get_name (dev), - fwupd_release_get_version (rel)); - } else if (vercmp > 0) { - /* TRANSLATORS: the first replacement is a display name - * e.g. "ColorHugALS" and the second and third are - * version numbers e.g. "1.2.3" */ - g_print (_("Downgrading %s from %s to %s... "), - fwupd_device_get_name (dev), - fwupd_device_get_version (dev), - fwupd_release_get_version (rel)); - } else if (vercmp < 0) { - /* TRANSLATORS: the first replacement is a display name - * e.g. "ColorHugALS" and the second and third are - * version numbers e.g. "1.2.3" */ - g_print (_("Updating %s from %s to %s... "), - fwupd_device_get_name (dev), - fwupd_device_get_version (dev), - fwupd_release_get_version (rel)); - } - if (!fwupd_client_install (priv->client, - fwupd_device_get_id (dev), - fwupd_release_get_filename (rel), - priv->flags, - NULL, - error)) - return FALSE; - cnt++; - } - - /* nothing to do */ - if (cnt == 0) { - g_set_error_literal (error, - FWUPD_ERROR, - FWUPD_ERROR_NOTHING_TO_DO, - "No updates prepared"); - return FALSE; - } - - /* reboot */ - if (!fu_util_prompt_complete (FWUPD_DEVICE_FLAG_NEEDS_REBOOT, FALSE, error)) - return FALSE; - - g_print ("%s\n", _("Done!")); - return TRUE; -} - static gboolean fu_util_clear_history (FuUtilPrivate *priv, gchar **values, GError **error) { @@ -2297,12 +2188,6 @@ main (int argc, char *argv[]) /* TRANSLATORS: command description */ _("Get all devices according to the system topology"), fu_util_get_topology); - fu_util_cmd_array_add (cmd_array, - "install-prepared", - NULL, - /* TRANSLATORS: command description */ - _("Install prepared updates now"), - fu_util_install_prepared); fu_util_cmd_array_add (cmd_array, "get-history", NULL, diff --git a/src/meson.build b/src/meson.build index 50d7cc5ea..6757b7e70 100644 --- a/src/meson.build +++ b/src/meson.build @@ -128,6 +128,35 @@ fwupdagent = executable( ) endif +if get_option('systemd') +fwupdagent = executable( + 'fwupdoffline', + sources : [ + 'fu-offline.c', + 'fu-util-common.c', + ], + include_directories : [ + include_directories('..'), + include_directories('../libfwupd'), + ], + dependencies : [ + giounix, + gudev, + gusb, + soup, + ], + link_with : [ + fwupd, + libfwupdprivate, + ], + c_args : [ + '-DFU_OFFLINE_DESTDIR=""', + ], + install : true, + install_dir : join_paths(libexecdir, 'fwupd') +) +endif + resources_src = gnome.compile_resources( 'fwupd-resources', 'fwupd.gresource.xml',