Use FwupdClient from libfwupd in fwupdmgr

This commit is contained in:
Richard Hughes 2016-03-17 10:09:03 +00:00
parent 0f41340740
commit cb07a3eb3f

View File

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
* Copyright (C) 2015 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
*
* Licensed under the GNU General Public License Version 2
*
@ -47,12 +47,8 @@ typedef struct {
GMainLoop *loop;
GOptionContext *context;
GPtrArray *cmd_array;
GVariant *val; /* for async */
GDBusMessage *message; /* for async */
GError *error; /* for async */
FwupdUpdateFlags flags;
GDBusConnection *conn;
GDBusProxy *proxy;
FwupdClient *client;
} FuUtilPrivate;
typedef gboolean (*FuUtilPrivateCb) (FuUtilPrivate *util,
@ -198,16 +194,11 @@ fu_util_run (FuUtilPrivate *priv, const gchar *command, gchar **values, GError *
* fu_util_status_changed_cb:
**/
static void
fu_util_status_changed_cb (GDBusProxy *proxy, GVariant *changed_properties,
GStrv invalidated_properties, gpointer user_data)
fu_util_status_changed_cb (FwupdClient *client,
FwupdStatus status,
FuUtilPrivate *priv)
{
g_autoptr(GVariant) val = NULL;
/* print to the console */
val = g_dbus_proxy_get_cached_property (proxy, "Status");
if (val == NULL)
return;
switch (g_variant_get_uint32 (val)) {
switch (status) {
case FWUPD_STATUS_IDLE:
/* TRANSLATORS: daemon is inactive */
g_print (" * %s\n", _("Idle"));
@ -241,307 +232,38 @@ fu_util_status_changed_cb (GDBusProxy *proxy, GVariant *changed_properties,
}
}
/**
* fu_util_get_devices_cb:
**/
static void
fu_util_get_devices_cb (GObject *source, GAsyncResult *res, gpointer user_data)
{
FuUtilPrivate *priv = (FuUtilPrivate *) user_data;
priv->val = g_dbus_proxy_call_finish (G_DBUS_PROXY (source),
res, &priv->error);
g_main_loop_quit (priv->loop);
}
/**
* fu_util_get_devices_internal:
**/
static GPtrArray *
fu_util_get_devices_internal (FuUtilPrivate *priv, GError **error)
{
GVariantIter *iter_device;
GPtrArray *devices = NULL;
FuDevice *dev;
gchar *id;
g_autoptr(GVariantIter) iter = NULL;
g_dbus_proxy_call (priv->proxy,
"GetDevices",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
fu_util_get_devices_cb, priv);
g_main_loop_run (priv->loop);
if (priv->val == NULL) {
g_propagate_error (error, priv->error);
return NULL;
}
/* parse */
g_variant_get (priv->val, "(a{sa{sv}})", &iter);
devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
while (g_variant_iter_next (iter, "{&sa{sv}}", &id, &iter_device)) {
dev = fu_device_new ();
fu_device_set_id (dev, id);
fu_device_set_metadata_from_iter (dev, iter_device);
g_ptr_array_add (devices, dev);
g_variant_iter_free (iter_device);
}
return devices;
}
/**
* fu_util_get_updates_internal:
**/
static GPtrArray *
fu_util_get_updates_internal (FuUtilPrivate *priv, GError **error)
{
GVariantIter *iter_device;
GPtrArray *devices = NULL;
FuDevice *dev;
gchar *id;
g_autoptr(GVariantIter) iter = NULL;
g_dbus_proxy_call (priv->proxy,
"GetUpdates",
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
fu_util_get_devices_cb, priv);
g_main_loop_run (priv->loop);
if (priv->val == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
return NULL;
}
/* parse */
g_variant_get (priv->val, "(a{sa{sv}})", &iter);
devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
while (g_variant_iter_next (iter, "{&sa{sv}}", &id, &iter_device)) {
dev = fu_device_new ();
fu_device_set_id (dev, id);
fu_device_set_metadata_from_iter (dev, iter_device);
g_ptr_array_add (devices, dev);
g_variant_iter_free (iter_device);
}
return devices;
}
/**
* pad_print:
**/
static void
pad_print (const gchar *key, const gchar *value)
{
guint k;
g_print (" %s:", key);
for (k = strlen (key); k < 15; k++)
g_print (" ");
g_print (" %s\n", value);
}
/**
* fu_util_device_flags_to_string:
**/
static gchar *
fu_util_device_flags_to_string (FwupdDeviceFlags device_flags)
{
GString *str;
guint i;
str = g_string_new ("");
for (i = 1; i < FU_DEVICE_FLAG_LAST; i *= 2) {
if ((device_flags & i) == 0)
continue;
g_string_append_printf (str, "%s|",
fwupd_device_flag_to_string (i));
}
if (str->len == 0) {
g_string_append (str, fwupd_device_flag_to_string (0));
} else {
g_string_truncate (str, str->len - 1);
}
return g_string_free (str, FALSE);
}
/**
* fu_util_get_devices:
**/
static gboolean
fu_util_get_devices (FuUtilPrivate *priv, gchar **values, GError **error)
{
FuDevice *dev;
g_autoptr(GPtrArray) devices = NULL;
FwupdResult *res;
guint i;
guint j;
guint64 flags;
const gchar *value;
const gchar *keys[] = {
FU_DEVICE_KEY_DISPLAY_NAME,
FU_DEVICE_KEY_PROVIDER,
FU_DEVICE_KEY_CREATED,
FU_DEVICE_KEY_MODIFIED,
FU_DEVICE_KEY_APPSTREAM_ID,
FU_DEVICE_KEY_GUID,
FU_DEVICE_KEY_VERSION,
FU_DEVICE_KEY_URL_HOMEPAGE,
FU_DEVICE_KEY_NAME,
FU_DEVICE_KEY_SUMMARY,
FU_DEVICE_KEY_DESCRIPTION,
FU_DEVICE_KEY_LICENSE,
FU_DEVICE_KEY_FLAGS,
FU_DEVICE_KEY_TRUSTED,
FU_DEVICE_KEY_SIZE,
FU_DEVICE_KEY_FIRMWARE_HASH,
NULL };
g_autoptr(GPtrArray) results = NULL;
/* get devices from daemon */
devices = fu_util_get_devices_internal (priv, error);
if (devices == NULL)
/* get results from daemon */
results = fwupd_client_get_devices (priv->client, NULL, error);
if (results == NULL)
return FALSE;
/* print */
if (devices->len == 0) {
if (results->len == 0) {
/* TRANSLATORS: nothing attached that can be upgraded */
g_print ("%s\n", _("No hardware detected with firmware update capability"));
return TRUE;
}
for (i = 0; i < devices->len; i++) {
dev = g_ptr_array_index (devices, i);
g_print ("Device: %s\n", fu_device_get_id (dev));
for (j = 0; keys[j] != NULL; j++) {
if (g_strcmp0 (keys[j], FU_DEVICE_KEY_FLAGS) == 0) {
g_autofree gchar *tmp = NULL;
flags = fu_device_get_flags (dev);
tmp = fu_util_device_flags_to_string (flags);
pad_print (keys[j], tmp);
continue;
}
if (g_strcmp0 (keys[j], FU_DEVICE_KEY_CREATED) == 0) {
g_autoptr(GDateTime) date = NULL;
g_autofree gchar *date_str = NULL;
date = g_date_time_new_from_unix_utc (fu_device_get_created (dev));
date_str = g_date_time_format (date, "%F");
pad_print (keys[j], date_str);
}
if (g_strcmp0 (keys[j], FU_DEVICE_KEY_MODIFIED) == 0) {
g_autoptr(GDateTime) date = NULL;
g_autofree gchar *date_str = NULL;
if (fu_device_get_modified (dev) > 0) {
date = g_date_time_new_from_unix_utc (fu_device_get_modified (dev));
date_str = g_date_time_format (date, "%F");
pad_print (keys[j], date_str);
}
}
value = fu_device_get_metadata (dev, keys[j]);
if (value != NULL)
pad_print (keys[j], value);
}
for (i = 0; i < results->len; i++) {
g_autofree gchar *tmp = NULL;
res = g_ptr_array_index (results, i);
tmp = fwupd_result_to_string (res);
g_print ("%s\n", tmp);
}
return TRUE;
}
/**
* fu_util_update_cb:
**/
static void
fu_util_update_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
{
FuUtilPrivate *priv = (FuUtilPrivate *) user_data;
GDBusConnection *con = G_DBUS_CONNECTION (source_object);
priv->message = g_dbus_connection_send_message_with_reply_finish (con, res,
&priv->error);
g_main_loop_quit (priv->loop);
}
/**
* fu_util_install_internal:
**/
static gboolean
fu_util_install_internal (FuUtilPrivate *priv, const gchar *id,
const gchar *filename, GError **error)
{
GVariant *body;
GVariantBuilder builder;
gint retval;
gint fd;
g_autoptr(GDBusMessage) request = NULL;
g_autoptr(GUnixFDList) fd_list = NULL;
/* set options */
g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
g_variant_builder_add (&builder, "{sv}",
"reason", g_variant_new_string ("user-action"));
g_variant_builder_add (&builder, "{sv}",
"filename", g_variant_new_string (filename));
if (priv->flags & FWUPD_UPDATE_FLAG_OFFLINE) {
g_variant_builder_add (&builder, "{sv}",
"offline", g_variant_new_boolean (TRUE));
}
if (priv->flags & FWUPD_UPDATE_FLAG_ALLOW_OLDER) {
g_variant_builder_add (&builder, "{sv}",
"allow-older", g_variant_new_boolean (TRUE));
}
if (priv->flags & FWUPD_UPDATE_FLAG_ALLOW_REINSTALL) {
g_variant_builder_add (&builder, "{sv}",
"allow-reinstall", g_variant_new_boolean (TRUE));
}
/* open file */
fd = open (filename, O_RDONLY);
if (fd < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to open %s",
filename);
return FALSE;
}
/* set out of band file descriptor */
fd_list = g_unix_fd_list_new ();
retval = g_unix_fd_list_append (fd_list, fd, NULL);
g_assert (retval != -1);
request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
FWUPD_DBUS_PATH,
FWUPD_DBUS_INTERFACE,
"Install");
g_dbus_message_set_unix_fd_list (request, fd_list);
/* g_unix_fd_list_append did a dup() already */
close (fd);
/* send message */
body = g_variant_new ("(sha{sv})", id, fd > -1 ? 0 : -1, &builder);
g_dbus_message_set_body (request, body);
g_dbus_connection_send_message_with_reply (priv->conn,
request,
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-1,
NULL,
NULL,
fu_util_update_cb,
priv);
g_main_loop_run (priv->loop);
if (priv->message == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
return FALSE;
}
if (g_dbus_message_to_gerror (priv->message, error)) {
g_dbus_error_strip_remote_error (*error);
return FALSE;
}
/* TRANSLATORS: update completed, no errors */
g_print ("%s\n", _("Done!"));
return TRUE;
}
/**
* fu_util_install_with_fallback:
**/
@ -552,7 +274,8 @@ fu_util_install_with_fallback (FuUtilPrivate *priv, const gchar *id,
g_autoptr(GError) error_local = NULL;
/* install with flags chosen by the user */
if (fu_util_install_internal (priv, id, filename, &error_local))
if (fwupd_client_install (priv->client, id, filename, priv->flags,
NULL, &error_local))
return TRUE;
/* some other failure */
@ -566,7 +289,8 @@ fu_util_install_with_fallback (FuUtilPrivate *priv, const gchar *id,
/* TRANSLATOR: the provider only supports offline */
g_print ("%s...\n", _("Retrying as an offline update"));
priv->flags |= FWUPD_UPDATE_FLAG_OFFLINE;
return fu_util_install_internal (priv, id, filename, error);
return fwupd_client_install (priv->client, id, filename, priv->flags,
NULL, error);
}
/**
@ -594,57 +318,14 @@ fu_util_install (FuUtilPrivate *priv, gchar **values, GError **error)
return fu_util_install_with_fallback (priv, id, values[0], error);
}
/**
* fu_util_print_metadata:
**/
static void
fu_util_print_metadata (GVariant *val)
{
GVariant *variant;
const gchar *key;
const gchar *type;
guint i;
g_autoptr(GVariantIter) iter = NULL;
g_variant_get (val, "(a{sv})", &iter);
while (g_variant_iter_next (iter, "{&sv}", &key, &variant)) {
g_print ("%s", key);
for (i = strlen (key); i < 15; i++)
g_print (" ");
if (g_strcmp0 (key, FU_DEVICE_KEY_FLAGS) == 0) {
g_autofree gchar *tmp = NULL;
guint64 flags = g_variant_get_uint64 (variant);
tmp = fu_util_device_flags_to_string (flags);
g_print ("%s\n", tmp);
} else {
type = g_variant_get_type_string (variant);
if (g_strcmp0 (type, "s") == 0) {
g_print ("%s\n", g_variant_get_string (variant, NULL));
} else if (g_strcmp0 (type, "b") == 0) {
g_print ("%s\n", g_variant_get_boolean (variant) ? "True" : "False");
} else if (g_strcmp0 (type, "t") == 0) {
g_print ("%" G_GUINT64_FORMAT "\n", g_variant_get_uint64 (variant));
} else {
g_print ("???? [%s]\n", type);
}
}
g_variant_unref (variant);
}
}
/**
* fu_util_get_details:
**/
static gboolean
fu_util_get_details (FuUtilPrivate *priv, gchar **values, GError **error)
{
GVariant *body;
GVariant *val;
gint fd;
gint retval;
g_autoptr(GDBusMessage) message = NULL;
g_autoptr(GDBusMessage) request = NULL;
g_autoptr(GUnixFDList) fd_list = NULL;
g_autofree gchar *tmp = NULL;
g_autoptr(FwupdResult) res = NULL;
/* check args */
if (g_strv_length (values) != 1) {
@ -654,53 +335,11 @@ fu_util_get_details (FuUtilPrivate *priv, gchar **values, GError **error)
"Invalid arguments: expected 'filename'");
return FALSE;
}
/* open file */
fd = open (values[0], O_RDONLY);
if (fd < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to open %s",
values[0]);
res = fwupd_client_get_details (priv->client, values[0], NULL, error);
if (res == NULL)
return FALSE;
}
/* set out of band file descriptor */
fd_list = g_unix_fd_list_new ();
retval = g_unix_fd_list_append (fd_list, fd, NULL);
g_assert (retval != -1);
request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
FWUPD_DBUS_PATH,
FWUPD_DBUS_INTERFACE,
"GetDetails");
g_dbus_message_set_unix_fd_list (request, fd_list);
/* g_unix_fd_list_append did a dup() already */
close (fd);
/* send message */
body = g_variant_new ("(h)", fd > -1 ? 0 : -1);
g_dbus_message_set_body (request, body);
message = g_dbus_connection_send_message_with_reply_sync (priv->conn,
request,
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-1,
NULL,
NULL,
error);
if (message == NULL) {
g_dbus_error_strip_remote_error (*error);
return FALSE;
}
if (g_dbus_message_to_gerror (message, error)) {
g_dbus_error_strip_remote_error (*error);
return FALSE;
}
/* print results */
val = g_dbus_message_get_body (message);
fu_util_print_metadata (val);
tmp = fwupd_result_to_string (res);
g_print ("%s", tmp);
return TRUE;
}
@ -742,9 +381,8 @@ fu_util_install_prepared (FuUtilPrivate *priv, gchar **values, GError **error)
gint vercmp;
guint cnt = 0;
guint i;
const gchar *tmp;
g_autofree gchar *link = NULL;
g_autoptr(GPtrArray) devices = NULL;
g_autoptr(GPtrArray) results = NULL;
g_autoptr(FuPending) pending = NULL;
/* verify this is pointing to our cache */
@ -780,51 +418,52 @@ fu_util_install_prepared (FuUtilPrivate *priv, gchar **values, GError **error)
/* get prepared updates */
pending = fu_pending_new ();
devices = fu_pending_get_devices (pending, error);
if (devices == NULL)
results = fu_pending_get_devices (pending, error);
if (results == NULL)
return FALSE;
/* apply each update */
for (i = 0; i < devices->len; i++) {
FuDevice *device;
device = g_ptr_array_index (devices, i);
for (i = 0; i < results->len; i++) {
FwupdResult *res;
res = g_ptr_array_index (results, i);
/* check not already done */
tmp = fu_device_get_metadata (device, FU_DEVICE_KEY_PENDING_STATE);
if (g_strcmp0 (tmp, "pending") != 0)
if (fwupd_result_get_update_state (res) != FWUPD_UPDATE_STATE_PENDING)
continue;
/* tell the user what's going to happen */
vercmp = as_utils_vercmp (fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION),
fu_device_get_metadata (device, FU_DEVICE_KEY_UPDATE_VERSION));
vercmp = as_utils_vercmp (fwupd_result_get_device_version (res),
fwupd_result_get_update_version (res));
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... "),
fu_device_get_display_name (device),
fu_device_get_metadata (device, FU_DEVICE_KEY_UPDATE_VERSION));
fwupd_result_get_device_name (res),
fwupd_result_get_update_version (res));
} 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... "),
fu_device_get_display_name (device),
fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION),
fu_device_get_metadata (device, FU_DEVICE_KEY_UPDATE_VERSION));
fwupd_result_get_device_name (res),
fwupd_result_get_device_version (res),
fwupd_result_get_update_version (res));
} 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... "),
fu_device_get_display_name (device),
fu_device_get_metadata (device, FU_DEVICE_KEY_VERSION),
fu_device_get_metadata (device, FU_DEVICE_KEY_UPDATE_VERSION));
fwupd_result_get_device_name (res),
fwupd_result_get_device_version (res),
fwupd_result_get_update_version (res));
}
if (!fu_util_install_internal (priv,
fu_device_get_id (device),
fu_device_get_metadata (device, FU_DEVICE_KEY_FILENAME_CAB),
error))
if (!fwupd_client_install (priv->client,
fwupd_result_get_device_id (res),
fwupd_result_get_update_filename (res),
priv->flags,
NULL,
error))
return FALSE;
cnt++;
}
@ -858,22 +497,7 @@ fu_util_clear_results (FuUtilPrivate *priv, gchar **values, GError **error)
"Invalid arguments: expected 'id'");
return FALSE;
}
/* clear results, and wait for reply */
g_dbus_proxy_call (priv->proxy,
"ClearResults",
g_variant_new ("(s)", values[0]),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
fu_util_get_devices_cb, priv);
g_main_loop_run (priv->loop);
if (priv->val == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
return FALSE;
}
return TRUE;
return fwupd_client_clear_results (priv->client, values[0], NULL, error);
}
/**
@ -1051,79 +675,6 @@ fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error)
error);
}
/**
* fu_util_refresh_internal:
**/
static gboolean
fu_util_refresh_internal (FuUtilPrivate *priv,
const gchar *data_fn,
const gchar *sig_fn,
GError **error)
{
GVariant *body;
gint fd;
gint fd_sig;
g_autoptr(GDBusMessage) request = NULL;
g_autoptr(GUnixFDList) fd_list = NULL;
/* open file */
fd = open (data_fn, O_RDONLY);
if (fd < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to open %s",
data_fn);
return FALSE;
}
fd_sig = open (sig_fn, O_RDONLY);
if (fd_sig < 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to open %s",
sig_fn);
return FALSE;
}
/* set out of band file descriptor */
fd_list = g_unix_fd_list_new ();
g_unix_fd_list_append (fd_list, fd, NULL);
g_unix_fd_list_append (fd_list, fd_sig, NULL);
request = g_dbus_message_new_method_call (FWUPD_DBUS_SERVICE,
FWUPD_DBUS_PATH,
FWUPD_DBUS_INTERFACE,
"UpdateMetadata");
g_dbus_message_set_unix_fd_list (request, fd_list);
/* g_unix_fd_list_append did a dup() already */
close (fd);
close (fd_sig);
/* send message */
body = g_variant_new ("(hh)", fd, fd_sig);
g_dbus_message_set_body (request, body);
g_dbus_connection_send_message_with_reply (priv->conn,
request,
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
-1,
NULL,
NULL,
fu_util_update_cb,
priv);
g_main_loop_run (priv->loop);
if (priv->message == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
return FALSE;
}
if (g_dbus_message_to_gerror (priv->message, error)) {
g_dbus_error_strip_remote_error (*error);
return FALSE;
}
return TRUE;
}
/**
* fu_util_download_file:
**/
@ -1234,7 +785,7 @@ fu_util_download_metadata (FuUtilPrivate *priv, GError **error)
return FALSE;
/* send all this to fwupd */
return fu_util_refresh_internal (priv, data_fn, sig_fn, error);
return fwupd_client_refresh (priv->client, data_fn, sig_fn, NULL, error);
}
/**
@ -1254,7 +805,7 @@ fu_util_refresh (FuUtilPrivate *priv, gchar **values, GError **error)
}
/* open file */
return fu_util_refresh_internal (priv, values[0], values[1], error);
return fwupd_client_refresh (priv->client, values[0], values[1], NULL, error);
}
/**
@ -1263,6 +814,9 @@ fu_util_refresh (FuUtilPrivate *priv, gchar **values, GError **error)
static gboolean
fu_util_get_results (FuUtilPrivate *priv, gchar **values, GError **error)
{
g_autofree gchar *tmp = NULL;
g_autoptr(FwupdResult) res = NULL;
if (g_strv_length (values) != 1) {
g_set_error_literal (error,
FWUPD_ERROR,
@ -1270,77 +824,44 @@ fu_util_get_results (FuUtilPrivate *priv, gchar **values, GError **error)
"Invalid arguments: expected 'id'");
return FALSE;
}
/* clear results, and wait for reply */
g_dbus_proxy_call (priv->proxy,
"GetResults",
g_variant_new ("(s)", values[0]),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
fu_util_get_devices_cb, priv);
g_main_loop_run (priv->loop);
if (priv->val == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
res = fwupd_client_get_results (priv->client, values[0], NULL, error);
if (res == NULL)
return FALSE;
}
fu_util_print_metadata (priv->val);
tmp = fwupd_result_to_string (res);
g_print ("%s", tmp);
return TRUE;
}
/**
* fu_util_verify_internal:
**/
static gboolean
fu_util_verify_internal (FuUtilPrivate *priv, const gchar *id, GError **error)
{
g_dbus_proxy_call (priv->proxy,
"Verify",
g_variant_new ("(s)", id),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
fu_util_get_devices_cb, priv);
g_main_loop_run (priv->loop);
if (priv->val == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
priv->error = NULL;
return FALSE;
}
return TRUE;
}
/**
* fu_util_verify_all:
**/
static gboolean
fu_util_verify_all (FuUtilPrivate *priv, GError **error)
{
FuDevice *dev;
FwupdResult *res;
guint i;
g_autoptr(GPtrArray) devices = NULL;
g_autoptr(GPtrArray) results = NULL;
/* get devices from daemon */
devices = fu_util_get_devices_internal (priv, error);
if (devices == NULL)
results = fwupd_client_get_devices (priv->client, NULL, error);
if (results == NULL)
return FALSE;
/* get results */
for (i = 0; i < devices->len; i++) {
for (i = 0; i < results->len; i++) {
g_autoptr(GError) error_local = NULL;
dev = g_ptr_array_index (devices, i);
if (!fu_util_verify_internal (priv, fu_device_get_id (dev), &error_local)) {
res = g_ptr_array_index (results, i);
if (!fwupd_client_verify (priv->client,
fwupd_result_get_device_id (res),
NULL,
&error_local)) {
g_print ("%s\tFAILED: %s\n",
fu_device_get_guid (dev),
fwupd_result_get_guid (res),
error_local->message);
continue;
}
g_print ("%s\t%s\n",
fu_device_get_guid (dev),
fwupd_result_get_guid (res),
_("OK"));
}
return TRUE;
@ -1361,7 +882,7 @@ fu_util_verify (FuUtilPrivate *priv, gchar **values, GError **error)
"Invalid arguments: expected 'id'");
return FALSE;
}
return fu_util_verify_internal (priv, values[0], error);
return fwupd_client_verify (priv->client, values[0], NULL, error);
}
/**
@ -1377,21 +898,7 @@ fu_util_unlock (FuUtilPrivate *priv, gchar **values, GError **error)
"Invalid arguments: expected 'id'");
return FALSE;
}
g_dbus_proxy_call (priv->proxy,
"Unlock",
g_variant_new ("(s)", values[0]),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
fu_util_get_devices_cb, priv);
g_main_loop_run (priv->loop);
if (priv->val == NULL) {
g_dbus_error_strip_remote_error (priv->error);
g_propagate_error (error, priv->error);
priv->error = NULL;
return FALSE;
}
return TRUE;
return fwupd_client_unlock (priv->client, values[0], NULL, error);
}
/**
@ -1426,44 +933,39 @@ fu_util_print_data (const gchar *title, const gchar *msg)
static gboolean
fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error)
{
FuDevice *dev;
GPtrArray *devices = NULL;
FwupdResult *res;
GPtrArray *results = NULL;
const gchar *tmp;
guint i;
/* print any updates */
devices = fu_util_get_updates_internal (priv, error);
if (devices == NULL)
results = fwupd_client_get_updates (priv->client, NULL, error);
if (results == NULL)
return FALSE;
for (i = 0; i < devices->len; i++) {
dev = g_ptr_array_index (devices, i);
for (i = 0; i < results->len; i++) {
res = g_ptr_array_index (results, i);
/* TRANSLATORS: first replacement is device name */
g_print (_("%s has firmware updates:"), fu_device_get_display_name (dev));
g_print (_("%s has firmware updates:"), fwupd_result_get_device_name (res));
g_print ("\n");
/* TRANSLATORS: Appstream ID for the hardware type */
fu_util_print_data (_("ID"),
fu_device_get_metadata (dev, FU_DEVICE_KEY_APPSTREAM_ID));
fu_util_print_data (_("ID"), fwupd_result_get_update_id (res));
/* TRANSLATORS: a GUID for the hardware */
fu_util_print_data (_("GUID"),
fu_device_get_metadata (dev, FU_DEVICE_KEY_GUID));
fu_util_print_data (_("GUID"), fwupd_result_get_guid (res));
/* TRANSLATORS: section header for firmware version */
fu_util_print_data (_("Version"),
fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_VERSION));
fu_util_print_data (_("Version"), fwupd_result_get_update_version (res));
/* TRANSLATORS: section header for firmware SHA1 */
fu_util_print_data (_("Checksum"),
fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_HASH));
fu_util_print_data (_("Checksum"), fwupd_result_get_update_checksum (res));
/* TRANSLATORS: section header for firmware remote http:// */
fu_util_print_data (_("Location"),
fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_URI));
fu_util_print_data (_("Location"), fwupd_result_get_update_uri (res));
/* convert XML -> text */
tmp = fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_DESCRIPTION);
tmp = fwupd_result_get_update_description (res);
if (tmp != NULL) {
g_autofree gchar *md = NULL;
md = as_markup_convert (tmp,
@ -1485,40 +987,40 @@ fu_util_get_updates (FuUtilPrivate *priv, gchar **values, GError **error)
static gboolean
fu_util_update (FuUtilPrivate *priv, gchar **values, GError **error)
{
FuDevice *dev;
GPtrArray *devices = NULL;
FwupdResult *res;
GPtrArray *results = NULL;
guint i;
/* apply any updates */
devices = fu_util_get_updates_internal (priv, error);
if (devices == NULL)
results = fwupd_client_get_updates (priv->client, NULL, error);
if (results == NULL)
return FALSE;
for (i = 0; i < devices->len; i++) {
for (i = 0; i < results->len; i++) {
const gchar *checksum;
const gchar *uri;
g_autofree gchar *basename = NULL;
g_autofree gchar *fn = NULL;
dev = g_ptr_array_index (devices, i);
res = g_ptr_array_index (results, i);
/* download file */
checksum = fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_HASH);
checksum = fwupd_result_get_update_checksum (res);
if (checksum == NULL)
continue;
uri = fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_URI);
uri = fwupd_result_get_update_uri (res);
if (uri == NULL)
continue;
g_print ("Downloading %s for %s...\n",
fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_VERSION),
fu_device_get_display_name (dev));
fwupd_result_get_update_version (res),
fwupd_result_get_device_name (res));
basename = g_path_get_basename (uri);
fn = g_build_filename (g_get_tmp_dir (), basename, NULL);
if (!fu_util_download_file (priv, uri, fn, checksum, error))
return FALSE;
g_print ("Updating %s on %s...\n",
fu_device_get_metadata (dev, FU_DEVICE_KEY_UPDATE_VERSION),
fu_device_get_display_name (dev));
if (!fu_util_install_with_fallback (priv, fu_device_get_id (dev), fn, error))
fwupd_result_get_update_version (res),
fwupd_result_get_device_name (res));
if (!fu_util_install_with_fallback (priv, fwupd_result_get_device_id (res), fn, error))
return FALSE;
}
@ -1696,28 +1198,8 @@ main (int argc, char *argv[])
priv->flags |= FWUPD_UPDATE_FLAG_ALLOW_OLDER;
/* connect to the daemon */
priv->conn = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (priv->conn == NULL) {
/* TRANSLATORS: the user is in a bad place */
g_print ("%s: %s\n", _("Failed to connect to D-Bus"),
error->message);
goto out;
}
priv->proxy = g_dbus_proxy_new_sync (priv->conn,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
FWUPD_DBUS_SERVICE,
FWUPD_DBUS_PATH,
FWUPD_DBUS_INTERFACE,
NULL,
&error);
if (priv->proxy == NULL) {
/* TRANSLATORS: we can't connect to the daemon */
g_print ("%s: %s\n", _("Failed to connect to fwupd"),
error->message);
goto out;
}
g_signal_connect (priv->proxy, "g-properties-changed",
priv->client = fwupd_client_new ();
g_signal_connect (priv->client, "status-changed",
G_CALLBACK (fu_util_status_changed_cb), priv);
/* run the specified command */
@ -1739,14 +1221,8 @@ out:
if (priv != NULL) {
if (priv->cmd_array != NULL)
g_ptr_array_unref (priv->cmd_array);
if (priv->val != NULL)
g_variant_unref (priv->val);
if (priv->message != NULL)
g_object_unref (priv->message);
if (priv->conn != NULL)
g_object_unref (priv->conn);
if (priv->proxy != NULL)
g_object_unref (priv->proxy);
if (priv->client != NULL)
g_object_unref (priv->client);
g_main_loop_unref (priv->loop);
g_option_context_free (priv->context);
g_free (priv);