diff --git a/libfwupd/fwupd-client.c b/libfwupd/fwupd-client.c
index 0e64a33ba..0c28458b1 100644
--- a/libfwupd/fwupd-client.c
+++ b/libfwupd/fwupd-client.c
@@ -287,6 +287,26 @@ fwupd_client_parse_devices_from_variant (GVariant *val)
return array;
}
+static GPtrArray *
+fwupd_client_parse_remotes_from_data (GVariant *devices)
+{
+ GPtrArray *remotes = NULL;
+ gsize sz;
+ g_autoptr(GVariant) untuple = NULL;
+
+ remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ untuple = g_variant_get_child_value (devices, 0);
+ sz = g_variant_n_children (untuple);
+ for (guint i = 0; i < sz; i++) {
+ FwupdRemote *remote;
+ g_autoptr(GVariant) data = g_variant_get_child_value (untuple, i);
+ remote = fwupd_remote_new_from_data (data);
+ g_ptr_array_add (remotes, remote);
+ }
+
+ return remotes;
+}
+
static void
fwupd_client_fixup_dbus_error (GError *error)
{
@@ -1251,131 +1271,6 @@ fwupd_client_update_metadata_with_id (FwupdClient *client,
return TRUE;
}
-static GPtrArray *
-fwupd_client_get_config_paths (void)
-{
- GPtrArray *paths = g_ptr_array_new_with_free_func (g_free);
- const gchar *remotes_dir;
- const gchar *system_prefixlibdir = "/usr/lib/fwupd";
- const gchar *system_sysconfdir = "/etc/fwupd";
- g_autofree gchar *sysconfdir = NULL;
-
- /* only set by the self test program */
- remotes_dir = g_getenv ("FU_SELF_TEST_REMOTES_DIR");
- if (remotes_dir != NULL) {
- g_ptr_array_add (paths, g_strdup (remotes_dir));
- return paths;
- }
-
- /* use sysconfig, and then fall back to /etc */
- sysconfdir = g_build_filename (SYSCONFDIR, "fwupd", NULL);
- if (g_file_test (sysconfdir, G_FILE_TEST_EXISTS)) {
- g_ptr_array_add (paths, g_steal_pointer (&sysconfdir));
- } else {
- g_debug ("falling back to system path");
- if (g_file_test (system_sysconfdir, G_FILE_TEST_EXISTS))
- g_ptr_array_add (paths, g_strdup (system_sysconfdir));
- }
-
- /* add in system-wide locations */
- if (g_file_test (system_prefixlibdir, G_FILE_TEST_EXISTS))
- g_ptr_array_add (paths, g_strdup (system_prefixlibdir));
-
- return paths;
-}
-
-static gboolean
-fwupd_client_add_remotes_for_path (FwupdClient *client,
- GPtrArray *remotes,
- const gchar *path,
- GCancellable *cancellable,
- GError **error)
-{
- const gchar *tmp;
- g_autofree gchar *path_remotes = NULL;
- g_autoptr(GDir) dir = NULL;
-
- path_remotes = g_build_filename (path, "remotes.d", NULL);
- if (!g_file_test (path_remotes, G_FILE_TEST_EXISTS))
- return TRUE;
- dir = g_dir_open (path_remotes, 0, error);
- if (dir == NULL)
- return FALSE;
- while ((tmp = g_dir_read_name (dir)) != NULL) {
- g_autofree gchar *filename = g_build_filename (path_remotes, tmp, NULL);
- g_autoptr(FwupdRemote) remote = fwupd_remote_new ();
- g_debug ("loading from %s", filename);
- if (!fwupd_remote_load_from_filename (remote, filename,
- cancellable, error))
- return FALSE;
- g_ptr_array_add (remotes, g_steal_pointer (&remote));
- }
- return TRUE;
-}
-
-static gint
-fwupd_client_remote_sort_cb (gconstpointer a, gconstpointer b)
-{
- FwupdRemote *remote_a = *((FwupdRemote **) a);
- FwupdRemote *remote_b = *((FwupdRemote **) b);
-
- /* use priority first */
- if (fwupd_remote_get_priority (remote_a) < fwupd_remote_get_priority (remote_b))
- return 1;
- if (fwupd_remote_get_priority (remote_a) > fwupd_remote_get_priority (remote_b))
- return -1;
-
- /* fall back to name */
- return g_strcmp0 (fwupd_remote_get_id (remote_a),
- fwupd_remote_get_id (remote_b));
-}
-
-static FwupdRemote *
-fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
-{
- for (guint i = 0; i < remotes->len; i++) {
- FwupdRemote *remote = g_ptr_array_index (remotes, i);
- if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0)
- return remote;
- }
- return NULL;
-}
-
-static guint
-fwupd_client_remotes_depsolve_with_direction (GPtrArray *remotes, gint inc)
-{
- guint cnt = 0;
- for (guint i = 0; i < remotes->len; i++) {
- FwupdRemote *remote = g_ptr_array_index (remotes, i);
- gchar **order = inc < 0 ? fwupd_remote_get_order_after (remote) :
- fwupd_remote_get_order_before (remote);
- if (order == NULL)
- continue;
- for (guint j = 0; order[j] != NULL; j++) {
- FwupdRemote *remote2;
- if (g_strcmp0 (order[j], fwupd_remote_get_id (remote)) == 0) {
- g_warning ("ignoring self-dep remote %s", order[j]);
- continue;
- }
- remote2 = fwupd_client_get_remote_by_id_noref (remotes, order[j]);
- if (remote2 == NULL) {
- g_warning ("ignoring unfound remote %s", order[j]);
- continue;
- }
- if (fwupd_remote_get_priority (remote) > fwupd_remote_get_priority (remote2))
- continue;
- g_debug ("ordering %s=%s+%i",
- fwupd_remote_get_id (remote),
- fwupd_remote_get_id (remote2),
- inc);
- fwupd_remote_set_priority (remote, fwupd_remote_get_priority (remote2) + inc);
-
- /* increment changes counter */
- cnt++;
- }
- }
- return cnt;
-}
/**
* fwupd_client_get_remotes:
* @client: A #FwupdClient
@@ -1391,64 +1286,42 @@ fwupd_client_remotes_depsolve_with_direction (GPtrArray *remotes, gint inc)
GPtrArray *
fwupd_client_get_remotes (FwupdClient *client, GCancellable *cancellable, GError **error)
{
- guint depsolve_check;
- g_autoptr(GPtrArray) paths = NULL;
- g_autoptr(GPtrArray) remotes = NULL;
+ FwupdClientPrivate *priv = GET_PRIVATE (client);
+ g_autoptr(GVariant) val = NULL;
g_return_val_if_fail (FWUPD_IS_CLIENT (client), NULL);
g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- /* get a list of all config paths */
- paths = fwupd_client_get_config_paths ();
- if (paths->len == 0) {
- g_set_error_literal (error,
- FWUPD_ERROR,
- FWUPD_ERROR_NOT_FOUND,
- "No search paths found");
+ /* connect */
+ if (!fwupd_client_connect (client, cancellable, error))
+ return NULL;
+
+ /* call into daemon */
+ val = g_dbus_proxy_call_sync (priv->proxy,
+ "GetRemotes",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ error);
+ if (val == NULL) {
+ if (error != NULL)
+ fwupd_client_fixup_dbus_error (*error);
return NULL;
}
+ return fwupd_client_parse_remotes_from_data (val);
+}
- /* look for all remotes */
- remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
- for (guint i = 0; i < paths->len; i++) {
- const gchar *path = g_ptr_array_index (paths, i);
- g_debug ("using config path of %s", path);
- if (!fwupd_client_add_remotes_for_path (client, remotes, path,
- cancellable, error))
- return FALSE;
+static FwupdRemote *
+fwupd_client_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
+{
+ for (guint i = 0; i < remotes->len; i++) {
+ FwupdRemote *remote = g_ptr_array_index (remotes, i);
+ if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0)
+ return remote;
}
-
- /* nothing found */
- if (remotes->len == 0) {
- g_set_error_literal (error,
- FWUPD_ERROR,
- FWUPD_ERROR_NOT_FOUND,
- "No remotes found in search paths");
- return NULL;
- }
-
- /* depsolve */
- for (depsolve_check = 0; depsolve_check < 100; depsolve_check++) {
- guint cnt = 0;
- cnt += fwupd_client_remotes_depsolve_with_direction (remotes, 1);
- cnt += fwupd_client_remotes_depsolve_with_direction (remotes, -1);
- if (cnt == 0)
- break;
- }
- if (depsolve_check == 100) {
- g_set_error_literal (error,
- FWUPD_ERROR,
- FWUPD_ERROR_INTERNAL,
- "Cannot depsolve remotes ordering");
- return NULL;
- }
-
- /* order these by priority, then name */
- g_ptr_array_sort (remotes, fwupd_client_remote_sort_cb);
-
- /* success */
- return g_steal_pointer (&remotes);
+ return NULL;
}
/**
diff --git a/libfwupd/fwupd-remote-private.h b/libfwupd/fwupd-remote-private.h
index 734ea0125..349d3f268 100644
--- a/libfwupd/fwupd-remote-private.h
+++ b/libfwupd/fwupd-remote-private.h
@@ -26,6 +26,9 @@
G_BEGIN_DECLS
+FwupdRemote *fwupd_remote_new_from_data (GVariant *data);
+GVariant *fwupd_remote_to_data (FwupdRemote *self,
+ const gchar *type_string);
gboolean fwupd_remote_load_from_filename (FwupdRemote *self,
const gchar *filename,
GCancellable *cancellable,
diff --git a/libfwupd/fwupd-remote.c b/libfwupd/fwupd-remote.c
index 434bc2e06..5597ecb80 100644
--- a/libfwupd/fwupd-remote.c
+++ b/libfwupd/fwupd-remote.c
@@ -368,6 +368,94 @@ fwupd_remote_get_id (FwupdRemote *self)
return self->id;
}
+static void
+fwupd_remote_to_variant_builder (FwupdRemote *self, GVariantBuilder *builder)
+{
+ if (self->id != NULL) {
+ g_variant_builder_add (builder, "{sv}", "Id",
+ g_variant_new_string (self->id));
+ }
+ if (self->username != NULL) {
+ g_variant_builder_add (builder, "{sv}", "Username",
+ g_variant_new_string (self->username));
+ }
+ if (self->password != NULL) {
+ g_variant_builder_add (builder, "{sv}", "Password",
+ g_variant_new_string (self->password));
+ }
+ if (self->url != NULL) {
+ g_variant_builder_add (builder, "{sv}", "Url",
+ g_variant_new_string (self->url));
+ }
+ if (self->priority != 0) {
+ g_variant_builder_add (builder, "{sv}", "Priority",
+ g_variant_new_int32 (self->priority));
+ }
+ g_variant_builder_add (builder, "{sv}", "Enabled",
+ g_variant_new_boolean (self->enabled));
+}
+
+static void
+fwupd_remote_set_from_variant_iter (FwupdRemote *self, GVariantIter *iter)
+{
+ GVariant *value;
+ const gchar *key;
+ g_autoptr(GVariantIter) iter2 = g_variant_iter_copy (iter);
+ g_autoptr(GVariantIter) iter3 = g_variant_iter_copy (iter);
+
+ /* three passes, as we have to construct Id -> Url -> * */
+ while (g_variant_iter_loop (iter, "{sv}", &key, &value)) {
+ if (g_strcmp0 (key, "Id") == 0)
+ fwupd_remote_set_id (self, g_variant_get_string (value, NULL));
+ }
+ while (g_variant_iter_loop (iter2, "{sv}", &key, &value)) {
+ if (g_strcmp0 (key, "Url") == 0)
+ fwupd_remote_set_url (self, g_variant_get_string (value, NULL));
+ }
+ while (g_variant_iter_loop (iter3, "{sv}", &key, &value)) {
+ if (g_strcmp0 (key, "Username") == 0) {
+ fwupd_remote_set_username (self, g_variant_get_string (value, NULL));
+ } else if (g_strcmp0 (key, "Password") == 0) {
+ fwupd_remote_set_password (self, g_variant_get_string (value, NULL));
+ } else if (g_strcmp0 (key, "Enabled") == 0) {
+ self->enabled = g_variant_get_boolean (value);
+ } else if (g_strcmp0 (key, "Priority") == 0) {
+ self->priority = g_variant_get_int32 (value);
+ }
+ }
+}
+
+/**
+ * fwupd_remote_to_data:
+ * @remote: A #FwupdRemote
+ * @type_string: The Gvariant type string, e.g. "a{sv}" or "(a{sv})"
+ *
+ * Creates a GVariant from the remote data.
+ *
+ * Returns: the GVariant, or %NULL for error
+ *
+ * Since: 0.9.5
+ **/
+GVariant *
+fwupd_remote_to_data (FwupdRemote *self, const gchar *type_string)
+{
+ GVariantBuilder builder;
+
+ g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
+ g_return_val_if_fail (type_string != NULL, NULL);
+
+ /* create an array with all the metadata in */
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+ fwupd_remote_to_variant_builder (self, &builder);
+
+ /* supported types */
+ if (g_strcmp0 (type_string, "a{sv}") == 0)
+ return g_variant_new ("a{sv}", &builder);
+ if (g_strcmp0 (type_string, "(a{sv})") == 0)
+ return g_variant_new ("(a{sv})", &builder);
+ return NULL;
+}
+
static void
fwupd_remote_get_property (GObject *obj, guint prop_id,
GValue *value, GParamSpec *pspec)
@@ -464,6 +552,39 @@ fwupd_remote_finalize (GObject *obj)
G_OBJECT_CLASS (fwupd_remote_parent_class)->finalize (obj);
}
+/**
+ * fwupd_remote_new_from_data:
+ * @data: a #GVariant
+ *
+ * Creates a new remote using packed data.
+ *
+ * Returns: a new #FwupdRemote, or %NULL if @data was invalid
+ *
+ * Since: 0.9.5
+ **/
+FwupdRemote *
+fwupd_remote_new_from_data (GVariant *data)
+{
+ FwupdRemote *rel = NULL;
+ const gchar *type_string;
+ g_autoptr(GVariantIter) iter = NULL;
+
+ type_string = g_variant_get_type_string (data);
+ if (g_strcmp0 (type_string, "(a{sv})") == 0) {
+ rel = fwupd_remote_new ();
+ g_variant_get (data, "(a{sv})", &iter);
+ fwupd_remote_set_from_variant_iter (rel, iter);
+ fwupd_remote_set_from_variant_iter (rel, iter);
+ } else if (g_strcmp0 (type_string, "a{sv}") == 0) {
+ rel = fwupd_remote_new ();
+ g_variant_get (data, "a{sv}", &iter);
+ fwupd_remote_set_from_variant_iter (rel, iter);
+ } else {
+ g_warning ("type %s not known", type_string);
+ }
+ return rel;
+}
+
/**
* fwupd_remote_new:
*
diff --git a/src/fu-config.c b/src/fu-config.c
index 7eed66c94..18d0a9980 100644
--- a/src/fu-config.c
+++ b/src/fu-config.c
@@ -26,12 +26,17 @@
#include "fu-config.h"
+#include "fwupd-error.h"
+#include "fwupd-remote-private.h"
+
static void fu_config_finalize (GObject *obj);
struct _FuConfig
{
GObject parent_instance;
GKeyFile *keyfile;
+ GPtrArray *remotes;
+ GPtrArray *monitors;
GPtrArray *blacklist_devices;
GPtrArray *blacklist_plugins;
gboolean enable_option_rom;
@@ -47,15 +52,217 @@ fu_config_get_sysconfig_dir (void)
return "/etc";
}
+static GPtrArray *
+fu_config_get_config_paths (void)
+{
+ GPtrArray *paths = g_ptr_array_new_with_free_func (g_free);
+ const gchar *remotes_dir;
+ const gchar *system_prefixlibdir = "/usr/lib/fwupd";
+ const gchar *system_sysconfdir = "/etc/fwupd";
+ g_autofree gchar *sysconfdir = NULL;
+
+ /* only set by the self test program */
+ remotes_dir = g_getenv ("FU_SELF_TEST_REMOTES_DIR");
+ if (remotes_dir != NULL) {
+ g_ptr_array_add (paths, g_strdup (remotes_dir));
+ return paths;
+ }
+
+ /* use sysconfig, and then fall back to /etc */
+ sysconfdir = g_build_filename (SYSCONFDIR, "fwupd", NULL);
+ if (g_file_test (sysconfdir, G_FILE_TEST_EXISTS)) {
+ g_ptr_array_add (paths, g_steal_pointer (&sysconfdir));
+ } else {
+ g_debug ("falling back to system path");
+ if (g_file_test (system_sysconfdir, G_FILE_TEST_EXISTS))
+ g_ptr_array_add (paths, g_strdup (system_sysconfdir));
+ }
+
+ /* add in system-wide locations */
+ if (g_file_test (system_prefixlibdir, G_FILE_TEST_EXISTS))
+ g_ptr_array_add (paths, g_strdup (system_prefixlibdir));
+
+ return paths;
+}
+
+static void
+fu_config_monitor_changed_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ FuConfig *self = FU_CONFIG (user_data);
+ g_autoptr(GError) error = NULL;
+ g_autofree gchar *filename = g_file_get_path (file);
+ g_debug ("%s changed, reloading all configs", filename);
+ if (!fu_config_load (self, &error))
+ g_warning ("failed to rescan config: %s", error->message);
+}
+
+static gboolean
+fu_config_add_remotes_for_path (FuConfig *self, const gchar *path, GError **error)
+{
+ const gchar *tmp;
+ g_autofree gchar *path_remotes = NULL;
+ g_autoptr(GDir) dir = NULL;
+
+ path_remotes = g_build_filename (path, "remotes.d", NULL);
+ if (!g_file_test (path_remotes, G_FILE_TEST_EXISTS))
+ return TRUE;
+ dir = g_dir_open (path_remotes, 0, error);
+ if (dir == NULL)
+ return FALSE;
+ while ((tmp = g_dir_read_name (dir)) != NULL) {
+ GFileMonitor *monitor;
+ g_autofree gchar *filename = g_build_filename (path_remotes, tmp, NULL);
+ g_autoptr(FwupdRemote) remote = fwupd_remote_new ();
+ g_autoptr(GFile) file = g_file_new_for_path (filename);
+ g_debug ("loading from %s", filename);
+ if (!fwupd_remote_load_from_filename (remote, filename,
+ NULL, error))
+ return FALSE;
+ g_ptr_array_add (self->remotes, g_steal_pointer (&remote));
+
+ /* set up a notify watch */
+ monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, error);
+ if (monitor == NULL)
+ return FALSE;
+ g_signal_connect (monitor, "changed",
+ G_CALLBACK (fu_config_monitor_changed_cb), self);
+ g_ptr_array_add (self->monitors, monitor);
+ }
+ return TRUE;
+}
+
+static gint
+fu_config_remote_sort_cb (gconstpointer a, gconstpointer b)
+{
+ FwupdRemote *remote_a = *((FwupdRemote **) a);
+ FwupdRemote *remote_b = *((FwupdRemote **) b);
+
+ /* use priority first */
+ if (fwupd_remote_get_priority (remote_a) < fwupd_remote_get_priority (remote_b))
+ return 1;
+ if (fwupd_remote_get_priority (remote_a) > fwupd_remote_get_priority (remote_b))
+ return -1;
+
+ /* fall back to name */
+ return g_strcmp0 (fwupd_remote_get_id (remote_a),
+ fwupd_remote_get_id (remote_b));
+}
+
+static FwupdRemote *
+fu_config_get_remote_by_id_noref (GPtrArray *remotes, const gchar *remote_id)
+{
+ for (guint i = 0; i < remotes->len; i++) {
+ FwupdRemote *remote = g_ptr_array_index (remotes, i);
+ if (g_strcmp0 (remote_id, fwupd_remote_get_id (remote)) == 0)
+ return remote;
+ }
+ return NULL;
+}
+
+static guint
+fu_config_remotes_depsolve_with_direction (FuConfig *self, gint inc)
+{
+ guint cnt = 0;
+ for (guint i = 0; i < self->remotes->len; i++) {
+ FwupdRemote *remote = g_ptr_array_index (self->remotes, i);
+ gchar **order = inc < 0 ? fwupd_remote_get_order_after (remote) :
+ fwupd_remote_get_order_before (remote);
+ if (order == NULL)
+ continue;
+ for (guint j = 0; order[j] != NULL; j++) {
+ FwupdRemote *remote2;
+ if (g_strcmp0 (order[j], fwupd_remote_get_id (remote)) == 0) {
+ g_warning ("ignoring self-dep remote %s", order[j]);
+ continue;
+ }
+ remote2 = fu_config_get_remote_by_id_noref (self->remotes, order[j]);
+ if (remote2 == NULL) {
+ g_warning ("ignoring unfound remote %s", order[j]);
+ continue;
+ }
+ if (fwupd_remote_get_priority (remote) > fwupd_remote_get_priority (remote2))
+ continue;
+ g_debug ("ordering %s=%s+%i",
+ fwupd_remote_get_id (remote),
+ fwupd_remote_get_id (remote2),
+ inc);
+ fwupd_remote_set_priority (remote, fwupd_remote_get_priority (remote2) + inc);
+
+ /* increment changes counter */
+ cnt++;
+ }
+ }
+ return cnt;
+}
+
+static gboolean
+fu_config_load_remotes (FuConfig *self, GError **error)
+{
+ guint depsolve_check;
+ g_autoptr(GPtrArray) paths = NULL;
+
+ /* get a list of all config paths */
+ paths = fu_config_get_config_paths ();
+ if (paths->len == 0) {
+ g_set_error_literal (error,
+ FWUPD_ERROR,
+ FWUPD_ERROR_NOT_FOUND,
+ "No search paths found");
+ return FALSE;
+ }
+
+ /* look for all remotes */
+ for (guint i = 0; i < paths->len; i++) {
+ const gchar *path = g_ptr_array_index (paths, i);
+ g_debug ("using config path of %s", path);
+ if (!fu_config_add_remotes_for_path (self, path, error))
+ return FALSE;
+ }
+
+ /* depsolve */
+ for (depsolve_check = 0; depsolve_check < 100; depsolve_check++) {
+ guint cnt = 0;
+ cnt += fu_config_remotes_depsolve_with_direction (self, 1);
+ cnt += fu_config_remotes_depsolve_with_direction (self, -1);
+ if (cnt == 0)
+ break;
+ }
+ if (depsolve_check == 100) {
+ g_set_error_literal (error,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INTERNAL,
+ "Cannot depsolve remotes ordering");
+ return FALSE;
+ }
+
+ /* order these by priority, then name */
+ g_ptr_array_sort (self->remotes, fu_config_remote_sort_cb);
+
+ /* success */
+ return TRUE;
+}
+
gboolean
fu_config_load (FuConfig *self, GError **error)
{
+ GFileMonitor *monitor;
g_autofree gchar *config_file = NULL;
g_auto(GStrv) devices = NULL;
g_auto(GStrv) plugins = NULL;
+ g_autoptr(GFile) file = NULL;
g_return_val_if_fail (FU_IS_CONFIG (self), FALSE);
+ /* ensure empty in case we're called from a monitor change */
+ g_ptr_array_set_size (self->blacklist_devices, 0);
+ g_ptr_array_set_size (self->blacklist_plugins, 0);
+ g_ptr_array_set_size (self->monitors, 0);
+ g_ptr_array_set_size (self->remotes, 0);
+
/* load the main daemon config file */
config_file = g_build_filename (fu_config_get_sysconfig_dir (),
"fwupd.conf", NULL);
@@ -64,6 +271,15 @@ fu_config_load (FuConfig *self, GError **error)
G_KEY_FILE_NONE, error))
return FALSE;
+ /* set up a notify watch */
+ file = g_file_new_for_path (config_file);
+ monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, error);
+ if (monitor == NULL)
+ return FALSE;
+ g_signal_connect (monitor, "changed",
+ G_CALLBACK (fu_config_monitor_changed_cb), self);
+ g_ptr_array_add (self->monitors, monitor);
+
/* optional, at the moment */
self->enable_option_rom =
g_key_file_get_boolean (self->keyfile,
@@ -97,9 +313,21 @@ fu_config_load (FuConfig *self, GError **error)
}
}
+ /* load remotes */
+ if (!fu_config_load_remotes (self, error))
+ return FALSE;
+
+ /* success */
return TRUE;
}
+GPtrArray *
+fu_config_get_remotes (FuConfig *self)
+{
+ g_return_val_if_fail (FU_IS_CONFIG (self), NULL);
+ return self->remotes;
+}
+
GPtrArray *
fu_config_get_blacklist_devices (FuConfig *self)
{
@@ -134,6 +362,8 @@ fu_config_init (FuConfig *self)
self->keyfile = g_key_file_new ();
self->blacklist_devices = g_ptr_array_new_with_free_func (g_free);
self->blacklist_plugins = g_ptr_array_new_with_free_func (g_free);
+ self->remotes = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ self->monitors = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
}
static void
@@ -144,6 +374,8 @@ fu_config_finalize (GObject *obj)
g_key_file_unref (self->keyfile);
g_ptr_array_unref (self->blacklist_devices);
g_ptr_array_unref (self->blacklist_plugins);
+ g_ptr_array_unref (self->remotes);
+ g_ptr_array_unref (self->monitors);
G_OBJECT_CLASS (fu_config_parent_class)->finalize (obj);
}
diff --git a/src/fu-config.h b/src/fu-config.h
index 6f1931005..49866b569 100644
--- a/src/fu-config.h
+++ b/src/fu-config.h
@@ -36,6 +36,7 @@ gboolean fu_config_load (FuConfig *self,
GPtrArray *fu_config_get_blacklist_devices (FuConfig *self);
GPtrArray *fu_config_get_blacklist_plugins (FuConfig *self);
gboolean fu_config_get_enable_option_rom (FuConfig *self);
+GPtrArray *fu_config_get_remotes (FuConfig *self);
G_END_DECLS
diff --git a/src/fu-main.c b/src/fu-main.c
index 071c5582f..a290386ee 100644
--- a/src/fu-main.c
+++ b/src/fu-main.c
@@ -36,6 +36,7 @@
#include "fwupd-common-private.h"
#include "fwupd-enums-private.h"
#include "fwupd-release-private.h"
+#include "fwupd-remote-private.h"
#include "fwupd-resources.h"
#include "fu-config.h"
@@ -1911,6 +1912,32 @@ fu_main_get_details_local_from_fd (FuMainPrivate *priv, gint fd, GError **error)
return g_variant_new ("(a{sa{sv}})", &builder);
}
+static GVariant *
+fu_main_get_remotes_as_variant (FuMainPrivate *priv, GError **error)
+{
+ GVariantBuilder builder;
+ GPtrArray *remotes;
+
+ /* get the list of remotes */
+ remotes = fu_config_get_remotes (priv->config);
+ if (remotes->len == 0) {
+ g_set_error (error,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INTERNAL,
+ "no remotes configured");
+ return NULL;
+ }
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
+ for (guint i = 0; i < remotes->len; i++) {
+ GVariant *tmp;
+ FwupdRemote *remote = g_ptr_array_index (remotes, i);
+ tmp = fwupd_remote_to_data (remote, "a{sv}");
+ g_variant_builder_add_value (&builder, tmp);
+ }
+ return g_variant_new ("(aa{sv})", &builder);
+}
+
static void
fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
const gchar *object_path, const gchar *interface_name,
@@ -1995,6 +2022,18 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
return;
}
+ /* return variant */
+ if (g_strcmp0 (method_name, "GetRemotes") == 0) {
+ g_debug ("Called %s()", method_name);
+ val = fu_main_get_remotes_as_variant (priv, &error);
+ if (val == NULL) {
+ fu_main_invocation_return_error (priv, invocation, error);
+ return;
+ }
+ fu_main_invocation_return_value (priv, invocation, val);
+ return;
+ }
+
/* return '' */
if (g_strcmp0 (method_name, "ClearResults") == 0) {
FuDeviceItem *item = NULL;
diff --git a/src/fu-util.c b/src/fu-util.c
index 4913afef7..3b665ddc9 100644
--- a/src/fu-util.c
+++ b/src/fu-util.c
@@ -1227,7 +1227,7 @@ fu_util_get_remotes (FuUtilPrivate *priv, gchar **values, GError **error)
if (uri != NULL) {
g_autofree gchar *uri_str = soup_uri_to_string (uri, FALSE);
/* TRANSLATORS: remote URI */
- fu_util_print_data (_("URI"), uri_str);
+ fu_util_print_data (_("URL"), uri_str);
}
uri = fwupd_remote_get_uri_asc (remote);
if (uri != NULL) {
diff --git a/src/org.freedesktop.fwupd.xml b/src/org.freedesktop.fwupd.xml
index 27faa1b88..99cfdb246 100644
--- a/src/org.freedesktop.fwupd.xml
+++ b/src/org.freedesktop.fwupd.xml
@@ -294,6 +294,24 @@
+
+
+
+
+
+ Gets the list of remotes.
+
+
+
+
+
+
+ The array remotes, with properties
+
+
+
+
+