summaryrefslogtreecommitdiff
path: root/src/libnm-client-impl/nm-remote-connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-client-impl/nm-remote-connection.c')
-rw-r--r--src/libnm-client-impl/nm-remote-connection.c839
1 files changed, 839 insertions, 0 deletions
diff --git a/src/libnm-client-impl/nm-remote-connection.c b/src/libnm-client-impl/nm-remote-connection.c
new file mode 100644
index 0000000000..007da3aa87
--- /dev/null
+++ b/src/libnm-client-impl/nm-remote-connection.c
@@ -0,0 +1,839 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2007 - 2008 Novell, Inc.
+ * Copyright (C) 2007 - 2011 Red Hat, Inc.
+ */
+
+#include "libnm-client-impl/nm-default-libnm.h"
+
+#include "nm-remote-connection.h"
+
+#include "libnm-glib-aux/nm-dbus-aux.h"
+#include "nm-dbus-interface.h"
+#include "nm-utils.h"
+#include "nm-setting-connection.h"
+#include "libnm-core-intern/nm-core-internal.h"
+#include "nm-remote-connection-private.h"
+#include "nm-object-private.h"
+#include "nm-dbus-helpers.h"
+
+/**
+ * SECTION:nm-remote-connection
+ * @short_description: A connection managed by NetworkManager server
+ *
+ * A #NMRemoteConnection represents a connection that is exported via
+ * NetworkManager D-Bus interface.
+ **/
+
+/*****************************************************************************/
+
+NM_GOBJECT_PROPERTIES_DEFINE(NMRemoteConnection,
+ PROP_UNSAVED,
+ PROP_FLAGS,
+ PROP_FILENAME,
+ PROP_VISIBLE, );
+
+typedef struct {
+ GCancellable *get_settings_cancellable;
+
+ char * filename;
+ guint32 flags;
+ bool unsaved;
+
+ bool visible : 1;
+ bool is_initialized : 1;
+} NMRemoteConnectionPrivate;
+
+struct _NMRemoteConnection {
+ NMObject parent;
+ NMRemoteConnectionPrivate _priv;
+};
+
+struct _NMRemoteConnectionClass {
+ NMObjectClass parent_class;
+};
+
+static void nm_remote_connection_connection_iface_init(NMConnectionInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE(NMRemoteConnection,
+ nm_remote_connection,
+ NM_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(NM_TYPE_CONNECTION,
+ nm_remote_connection_connection_iface_init);)
+
+#define NM_REMOTE_CONNECTION_GET_PRIVATE(self) \
+ _NM_GET_PRIVATE(self, NMRemoteConnection, NM_IS_REMOTE_CONNECTION, NMObject)
+
+/*****************************************************************************/
+
+/**
+ * nm_remote_connection_update2:
+ * @connection: the #NMRemoteConnection
+ * @settings: (allow-none): optional connection to update the settings.
+ * @flags: update-flags
+ * @args: (allow-none): optional arguments.
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the commit operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Asynchronously calls the Update2() D-Bus method.
+ *
+ * Since: 1.12
+ **/
+void
+nm_remote_connection_update2(NMRemoteConnection * connection,
+ GVariant * settings,
+ NMSettingsUpdate2Flags flags,
+ GVariant * args,
+ GCancellable * cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection));
+ g_return_if_fail(!settings || g_variant_is_of_type(settings, NM_VARIANT_TYPE_CONNECTION));
+ g_return_if_fail(!args || g_variant_is_of_type(args, G_VARIANT_TYPE("a{sv}")));
+ g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
+
+ if (!settings)
+ settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0);
+ if (!args)
+ args = g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0);
+
+ _nm_client_dbus_call(_nm_object_get_client(connection),
+ connection,
+ nm_remote_connection_update2,
+ cancellable,
+ callback,
+ user_data,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Update2",
+ g_variant_new("(@a{sa{sv}}u@a{sv})", settings, (guint32) flags, args),
+ G_VARIANT_TYPE("(a{sv})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
+}
+
+/**
+ * nm_remote_connection_update2_finish:
+ * @connection: the #NMRemoteConnection
+ * @result: the result passed to the #GAsyncReadyCallback
+ * @error: location for a #GError, or %NULL
+ *
+ * Gets the result of a call to nm_remote_connection_commit_changes_async().
+ *
+ * Returns: (transfer full): on success, a #GVariant of type "a{sv}" with the result. On failure,
+ * %NULL.
+ **/
+GVariant *
+nm_remote_connection_update2_finish(NMRemoteConnection *connection,
+ GAsyncResult * result,
+ GError ** error)
+{
+ gs_unref_variant GVariant *ret = NULL;
+ GVariant * v_result;
+
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL);
+ g_return_val_if_fail(nm_g_task_is_valid(result, connection, nm_remote_connection_update2),
+ NULL);
+
+ ret = g_task_propagate_pointer(G_TASK(result), error);
+ if (!ret)
+ return NULL;
+
+ g_variant_get(ret, "(@a{sv})", &v_result);
+
+ return v_result;
+}
+
+/*****************************************************************************/
+
+/**
+ * nm_remote_connection_commit_changes:
+ * @connection: the #NMRemoteConnection
+ * @save_to_disk: whether to persist the changes to disk
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: location for a #GError, or %NULL
+ *
+ * Send any local changes to the settings and properties of @connection to
+ * NetworkManager. If @save_to_disk is %TRUE, the updated connection will be saved to
+ * disk; if %FALSE, then only the in-memory representation will be changed.
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ *
+ * Deprecated: 1.22: Use nm_remote_connection_commit_changes_async() or GDBusConnection.
+ **/
+gboolean
+nm_remote_connection_commit_changes(NMRemoteConnection *connection,
+ gboolean save_to_disk,
+ GCancellable * cancellable,
+ GError ** error)
+{
+ gs_unref_variant GVariant *ret = NULL;
+
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+ g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE);
+
+ ret = _nm_client_dbus_call_sync(
+ _nm_object_get_client(connection),
+ cancellable,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Update2",
+ g_variant_new("(@a{sa{sv}}u@a{sv})",
+ nm_connection_to_dbus(NM_CONNECTION(connection), NM_CONNECTION_SERIALIZE_ALL),
+ (guint32)(save_to_disk ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK
+ : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY),
+ g_variant_new_array(G_VARIANT_TYPE("{sv}"), NULL, 0)),
+ G_VARIANT_TYPE("(a{sv})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ TRUE,
+ error);
+ if (!ret)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * nm_remote_connection_commit_changes_async:
+ * @connection: the #NMRemoteConnection
+ * @save_to_disk: whether to save the changes to persistent storage
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the commit operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Asynchronously sends any local changes to the settings and properties of
+ * @connection to NetworkManager. If @save is %TRUE, the updated connection will
+ * be saved to disk; if %FALSE, then only the in-memory representation will be
+ * changed.
+ **/
+void
+nm_remote_connection_commit_changes_async(NMRemoteConnection *connection,
+ gboolean save_to_disk,
+ GCancellable * cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection));
+ g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
+
+ nm_remote_connection_update2(
+ connection,
+ nm_connection_to_dbus(NM_CONNECTION(connection), NM_CONNECTION_SERIALIZE_ALL),
+ save_to_disk ? NM_SETTINGS_UPDATE2_FLAG_TO_DISK : NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY,
+ NULL,
+ cancellable,
+ callback,
+ user_data);
+}
+
+/**
+ * nm_remote_connection_commit_changes_finish:
+ * @connection: the #NMRemoteConnection
+ * @result: the result passed to the #GAsyncReadyCallback
+ * @error: location for a #GError, or %NULL
+ *
+ * Gets the result of a call to nm_remote_connection_commit_changes_async().
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ **/
+gboolean
+nm_remote_connection_commit_changes_finish(NMRemoteConnection *connection,
+ GAsyncResult * result,
+ GError ** error)
+{
+ gs_unref_variant GVariant *v_result = NULL;
+
+ v_result = nm_remote_connection_update2_finish(connection, result, error);
+ return !!v_result;
+}
+
+/*****************************************************************************/
+
+/**
+ * nm_remote_connection_save:
+ * @connection: the #NMRemoteConnection
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: location for a #GError, or %NULL
+ *
+ * Saves the connection to disk if the connection has changes that have not yet
+ * been written to disk, or if the connection has never been saved.
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ *
+ * Deprecated: 1.22: Use nm_remote_connection_save_async() or GDBusConnection.
+ **/
+gboolean
+nm_remote_connection_save(NMRemoteConnection *connection, GCancellable *cancellable, GError **error)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+ g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), FALSE);
+
+ return _nm_client_dbus_call_sync_void(_nm_object_get_client(connection),
+ cancellable,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Save",
+ g_variant_new("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ TRUE,
+ error);
+}
+
+/**
+ * nm_remote_connection_save_async:
+ * @connection: the #NMRemoteConnection
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the save operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Saves the connection to disk if the connection has changes that have not yet
+ * been written to disk, or if the connection has never been saved.
+ **/
+void
+nm_remote_connection_save_async(NMRemoteConnection *connection,
+ GCancellable * cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection));
+ g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
+
+ _nm_client_dbus_call(_nm_object_get_client(connection),
+ connection,
+ nm_remote_connection_save_async,
+ cancellable,
+ callback,
+ user_data,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Save",
+ g_variant_new("()"),
+ G_VARIANT_TYPE("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
+}
+
+/**
+ * nm_remote_connection_save_finish:
+ * @connection: the #NMRemoteConnection
+ * @result: the result passed to the #GAsyncReadyCallback
+ * @error: location for a #GError, or %NULL
+ *
+ * Gets the result of a call to nm_remote_connection_save_async().
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ **/
+gboolean
+nm_remote_connection_save_finish(NMRemoteConnection *connection,
+ GAsyncResult * result,
+ GError ** error)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+ g_return_val_if_fail(nm_g_task_is_valid(result, connection, nm_remote_connection_save_async),
+ FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
+
+/*****************************************************************************/
+
+/**
+ * nm_remote_connection_delete:
+ * @connection: the #NMRemoteConnection
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: location for a #GError, or %NULL
+ *
+ * Deletes the connection.
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ *
+ * Deprecated: 1.22: Use nm_remote_connection_delete_async() or GDBusConnection.
+ **/
+gboolean
+nm_remote_connection_delete(NMRemoteConnection *connection,
+ GCancellable * cancellable,
+ GError ** error)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+
+ return _nm_client_dbus_call_sync_void(_nm_object_get_client(connection),
+ cancellable,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Delete",
+ g_variant_new("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ TRUE,
+ error);
+}
+
+/**
+ * nm_remote_connection_delete_async:
+ * @connection: the #NMRemoteConnection
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the delete operation completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Asynchronously deletes the connection.
+ **/
+void
+nm_remote_connection_delete_async(NMRemoteConnection *connection,
+ GCancellable * cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection));
+ g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
+
+ _nm_client_dbus_call(_nm_object_get_client(connection),
+ connection,
+ nm_remote_connection_delete_async,
+ cancellable,
+ callback,
+ user_data,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Delete",
+ g_variant_new("()"),
+ G_VARIANT_TYPE("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ nm_dbus_connection_call_finish_void_strip_dbus_error_cb);
+}
+
+/**
+ * nm_remote_connection_delete_finish:
+ * @connection: the #NMRemoteConnection
+ * @result: the result passed to the #GAsyncReadyCallback
+ * @error: location for a #GError, or %NULL
+ *
+ * Gets the result of a call to nm_remote_connection_delete_async().
+ *
+ * Returns: %TRUE on success, %FALSE on error, in which case @error will be set.
+ **/
+gboolean
+nm_remote_connection_delete_finish(NMRemoteConnection *connection,
+ GAsyncResult * result,
+ GError ** error)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+ g_return_val_if_fail(nm_g_task_is_valid(result, connection, nm_remote_connection_delete_async),
+ FALSE);
+
+ return g_task_propagate_boolean(G_TASK(result), error);
+}
+
+/**
+ * nm_remote_connection_get_secrets:
+ * @connection: the #NMRemoteConnection
+ * @setting_name: the #NMSetting object name to get secrets for
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: location for a #GError, or %NULL
+ *
+ * Request the connection's secrets. Note that this is a blocking D-Bus call,
+ * not a simple property accessor.
+ *
+ * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing
+ * @connection's secrets, or %NULL on error.
+ *
+ * Deprecated: 1.22: Use nm_remote_connection_get_secrets_async() or GDBusConnection.
+ **/
+GVariant *
+nm_remote_connection_get_secrets(NMRemoteConnection *connection,
+ const char * setting_name,
+ GCancellable * cancellable,
+ GError ** error)
+{
+ gs_unref_variant GVariant *ret = NULL;
+ GVariant * secrets;
+
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL);
+ g_return_val_if_fail(setting_name, NULL);
+ g_return_val_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable), NULL);
+
+ ret = _nm_client_dbus_call_sync(_nm_object_get_client(connection),
+ cancellable,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "GetSecrets",
+ g_variant_new("(s)", setting_name),
+ G_VARIANT_TYPE("(a{sa{sv}})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ TRUE,
+ error);
+ if (!ret)
+ return NULL;
+
+ g_variant_get(ret, "(@a{sa{sv}})", &secrets);
+
+ return secrets;
+}
+
+/**
+ * nm_remote_connection_get_secrets_async:
+ * @connection: the #NMRemoteConnection
+ * @setting_name: the #NMSetting object name to get secrets for
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to be called when the secret request completes
+ * @user_data: caller-specific data passed to @callback
+ *
+ * Asynchronously requests the connection's secrets.
+ **/
+void
+nm_remote_connection_get_secrets_async(NMRemoteConnection *connection,
+ const char * setting_name,
+ GCancellable * cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail(NM_IS_REMOTE_CONNECTION(connection));
+ g_return_if_fail(setting_name);
+ g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
+
+ _nm_client_dbus_call(_nm_object_get_client(connection),
+ connection,
+ nm_remote_connection_get_secrets_async,
+ cancellable,
+ callback,
+ user_data,
+ _nm_object_get_path(connection),
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "GetSecrets",
+ g_variant_new("(s)", setting_name),
+ G_VARIANT_TYPE("(a{sa{sv}})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ nm_dbus_connection_call_finish_variant_strip_dbus_error_cb);
+}
+
+/**
+ * nm_remote_connection_get_secrets_finish:
+ * @connection: the #NMRemoteConnection
+ * @result: the result passed to the #GAsyncReadyCallback
+ * @error: location for a #GError, or %NULL
+ *
+ * Gets the result of a call to nm_remote_connection_get_secrets_async().
+ *
+ * Returns: (transfer full): a #GVariant of type %NM_VARIANT_TYPE_CONNECTION
+ * containing @connection's secrets, or %NULL on error.
+ **/
+GVariant *
+nm_remote_connection_get_secrets_finish(NMRemoteConnection *connection,
+ GAsyncResult * result,
+ GError ** error)
+{
+ gs_unref_variant GVariant *ret = NULL;
+ GVariant * secrets;
+
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL);
+ g_return_val_if_fail(
+ nm_g_task_is_valid(result, connection, nm_remote_connection_get_secrets_async),
+ FALSE);
+
+ ret = g_task_propagate_pointer(G_TASK(result), error);
+ if (!ret)
+ return NULL;
+
+ g_variant_get(ret, "(@a{sa{sv}})", &secrets);
+
+ return secrets;
+}
+
+/**
+ * nm_remote_connection_get_unsaved:
+ * @connection: the #NMRemoteConnection
+ *
+ * Returns: %TRUE if the remote connection contains changes that have not
+ * been saved to disk, %FALSE if the connection is the same as its on-disk
+ * representation.
+ **/
+gboolean
+nm_remote_connection_get_unsaved(NMRemoteConnection *connection)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+
+ return NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->unsaved;
+}
+
+/**
+ * nm_remote_connection_get_flags:
+ * @connection: the #NMRemoteConnection
+ *
+ * Returns: the flags of the connection of type #NMSettingsConnectionFlags.
+ *
+ * Since: 1.12
+ **/
+NMSettingsConnectionFlags
+nm_remote_connection_get_flags(NMRemoteConnection *connection)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+
+ return (NMSettingsConnectionFlags) NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->flags;
+}
+
+/**
+ * nm_remote_connection_get_filename:
+ * @connection: the #NMRemoteConnection
+ *
+ * Returns: file that stores the connection in case the connection is file-backed.
+ *
+ * Since: 1.12
+ **/
+const char *
+nm_remote_connection_get_filename(NMRemoteConnection *connection)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), NULL);
+
+ return NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->filename;
+}
+
+/**
+ * nm_remote_connection_get_visible:
+ * @connection: the #NMRemoteConnection
+ *
+ * Checks if the connection is visible to the current user. If the
+ * connection is not visible then it is essentially useless; it will
+ * not contain any settings, and operations such as
+ * nm_remote_connection_save() and nm_remote_connection_delete() will
+ * always fail. (#NMRemoteSettings will not normally return
+ * non-visible connections to callers, but it is possible for a
+ * connection's visibility to change after you already have a
+ * reference to it.)
+ *
+ * Returns: %TRUE if the remote connection is visible to the current
+ * user, %FALSE if not.
+ **/
+gboolean
+nm_remote_connection_get_visible(NMRemoteConnection *connection)
+{
+ g_return_val_if_fail(NM_IS_REMOTE_CONNECTION(connection), FALSE);
+
+ return NM_REMOTE_CONNECTION_GET_PRIVATE(connection)->visible;
+}
+
+/*****************************************************************************/
+
+GCancellable *
+_nm_remote_settings_get_settings_prepare(NMRemoteConnection *self)
+{
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(self);
+
+ nm_clear_g_cancellable(&priv->get_settings_cancellable);
+ priv->get_settings_cancellable = g_cancellable_new();
+ return priv->get_settings_cancellable;
+}
+
+void
+_nm_remote_settings_get_settings_commit(NMRemoteConnection *self, GVariant *settings)
+{
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(self);
+ GError * error = NULL;
+ gboolean visible = FALSE;
+ gboolean changed = FALSE;
+
+ g_clear_object(&priv->get_settings_cancellable);
+
+ if (!priv->is_initialized) {
+ changed = TRUE;
+ priv->is_initialized = TRUE;
+ }
+
+ if (settings) {
+ if (!_nm_connection_replace_settings((NMConnection *) self,
+ settings,
+ NM_SETTING_PARSE_FLAGS_BEST_EFFORT,
+ &error)) {
+ NML_NMCLIENT_LOG_E(_nm_object_get_client(self),
+ "[%s] failure to update settings: %s",
+ _nm_object_get_path(self),
+ error->message);
+ g_clear_error(&error);
+ } else
+ visible = TRUE;
+ } else
+ nm_connection_clear_settings(NM_CONNECTION(self));
+
+ if (priv->visible != visible) {
+ priv->visible = visible;
+ _nm_client_queue_notify_object(_nm_object_get_client(self),
+ self,
+ obj_properties[PROP_VISIBLE]);
+ changed = TRUE;
+ }
+
+ if (changed)
+ _nm_client_notify_object_changed(_nm_object_get_client(self), _nm_object_get_dbobj(self));
+}
+
+/*****************************************************************************/
+
+static gboolean
+is_ready(NMObject *nmobj)
+{
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(nmobj);
+
+ if (!priv->is_initialized)
+ return FALSE;
+
+ return NM_OBJECT_CLASS(nm_remote_connection_parent_class)->is_ready(nmobj);
+}
+
+/*****************************************************************************/
+
+static void
+register_client(NMObject *nmobj, NMClient *client, NMLDBusObject *dbobj)
+{
+ NM_OBJECT_CLASS(nm_remote_connection_parent_class)->register_client(nmobj, client, dbobj);
+ nm_connection_set_path(NM_CONNECTION(nmobj), dbobj->dbus_path->str);
+ _nm_client_get_settings_call(client, dbobj);
+}
+
+static void
+unregister_client(NMObject *nmobj, NMClient *client, NMLDBusObject *dbobj)
+{
+ nm_clear_g_cancellable(&NM_REMOTE_CONNECTION_GET_PRIVATE(nmobj)->get_settings_cancellable);
+ NM_OBJECT_CLASS(nm_remote_connection_parent_class)->unregister_client(nmobj, client, dbobj);
+}
+
+/*****************************************************************************/
+
+static void
+get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_UNSAVED:
+ g_value_set_boolean(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->unsaved);
+ break;
+ case PROP_FLAGS:
+ g_value_set_uint(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->flags);
+ break;
+ case PROP_FILENAME:
+ g_value_set_string(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->filename);
+ break;
+ case PROP_VISIBLE:
+ g_value_set_boolean(value, NM_REMOTE_CONNECTION_GET_PRIVATE(object)->visible);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_remote_connection_init(NMRemoteConnection *self)
+{}
+
+static void
+dispose(GObject *object)
+{
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE(object);
+
+ nm_clear_g_free(&priv->filename);
+
+ G_OBJECT_CLASS(nm_remote_connection_parent_class)->dispose(object);
+}
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings_connection = NML_DBUS_META_IFACE_INIT_PROP(
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ nm_remote_connection_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES(
+ NML_DBUS_META_PROPERTY_INIT_S("Filename",
+ PROP_FILENAME,
+ NMRemoteConnection,
+ _priv.filename),
+ NML_DBUS_META_PROPERTY_INIT_U("Flags", PROP_FLAGS, NMRemoteConnection, _priv.flags),
+ NML_DBUS_META_PROPERTY_INIT_B("Unsaved",
+ PROP_UNSAVED,
+ NMRemoteConnection,
+ _priv.unsaved), ), );
+
+static void
+nm_remote_connection_class_init(NMRemoteConnectionClass *klass)
+{
+ GObjectClass * object_class = G_OBJECT_CLASS(klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass);
+
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ nm_object_class->is_ready = is_ready;
+ nm_object_class->register_client = register_client;
+ nm_object_class->unregister_client = unregister_client;
+
+ /**
+ * NMRemoteConnection:unsaved:
+ *
+ * %TRUE if the remote connection contains changes that have not been saved
+ * to disk, %FALSE if the connection is the same as its on-disk representation.
+ **/
+ obj_properties[PROP_UNSAVED] = g_param_spec_boolean(NM_REMOTE_CONNECTION_UNSAVED,
+ "",
+ "",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * NMRemoteConnection:flags:
+ *
+ * The flags of the connection as unsigned integer. The values
+ * correspond to the #NMSettingsConnectionFlags enum.
+ *
+ * Since: 1.12
+ **/
+ obj_properties[PROP_FLAGS] = g_param_spec_uint(NM_REMOTE_CONNECTION_FLAGS,
+ "",
+ "",
+ 0,
+ G_MAXUINT32,
+ 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * NMRemoteConnection:filename:
+ *
+ * File that stores the connection in case the connection is
+ * file-backed.
+ *
+ * Since: 1.12
+ **/
+ obj_properties[PROP_FILENAME] = g_param_spec_string(NM_REMOTE_CONNECTION_FILENAME,
+ "",
+ "",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * NMRemoteConnection:visible:
+ *
+ * %TRUE if the remote connection is visible to the current user, %FALSE if
+ * not. If the connection is not visible then it is essentially useless; it
+ * will not contain any settings, and operations such as
+ * nm_remote_connection_save() and nm_remote_connection_delete() will always
+ * fail. (#NMRemoteSettings will not normally return non-visible connections
+ * to callers, but it is possible for a connection's visibility to change
+ * after you already have a reference to it.)
+ **/
+ obj_properties[PROP_VISIBLE] = g_param_spec_boolean(NM_REMOTE_CONNECTION_VISIBLE,
+ "",
+ "",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ _nml_dbus_meta_class_init_with_properties(object_class,
+ &_nml_dbus_meta_iface_nm_settings_connection);
+}
+
+static void
+nm_remote_connection_connection_iface_init(NMConnectionInterface *iface)
+{}