diff options
Diffstat (limited to 'libnm/nm-remote-connection.c')
| -rw-r--r-- | libnm/nm-remote-connection.c | 857 |
1 files changed, 857 insertions, 0 deletions
diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c new file mode 100644 index 00000000..3afe7f8e --- /dev/null +++ b/libnm/nm-remote-connection.c @@ -0,0 +1,857 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2007 - 2008 Novell, Inc. + * Copyright 2007 - 2011 Red Hat, Inc. + */ + +#include "config.h" + +#include <string.h> +#include <gio/gio.h> +#include <glib/gi18n-lib.h> + +#include <nm-dbus-interface.h> +#include <nm-utils.h> +#include <nm-setting-connection.h> +#include "nm-remote-connection.h" +#include "nm-remote-connection-private.h" +#include "nm-object-private.h" +#include "nm-glib-compat.h" +#include "nm-dbus-helpers.h" + +#include "nmdbus-settings-connection.h" + +static void nm_remote_connection_connection_iface_init (NMConnectionInterface *iface); +static void nm_remote_connection_initable_iface_init (GInitableIface *iface); +static void nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface); +static GInitableIface *nm_remote_connection_parent_initable_iface; +static GAsyncInitableIface *nm_remote_connection_parent_async_initable_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); + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_remote_connection_initable_iface_init); + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_remote_connection_async_initable_iface_init); + ) + +enum { + PROP_0, + PROP_UNSAVED, + PROP_VISIBLE, + + LAST_PROP +}; + +typedef struct { + NMDBusSettingsConnection *proxy; + + gboolean unsaved; + + gboolean visible; +} NMRemoteConnectionPrivate; + +#define NM_REMOTE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionPrivate)) + +/****************************************************************/ + +/** + * 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. + **/ +gboolean +nm_remote_connection_commit_changes (NMRemoteConnection *connection, + gboolean save_to_disk, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + GVariant *settings; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL); + if (save_to_disk) { + ret = nmdbus_settings_connection_call_update_sync (priv->proxy, + settings, + cancellable, error); + } else { + ret = nmdbus_settings_connection_call_update_unsaved_sync (priv->proxy, + settings, + cancellable, error); + } + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +update_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + gboolean (*finish_func) (NMDBusSettingsConnection *, GAsyncResult *, GError **); + GError *error = NULL; + + finish_func = g_object_get_data (G_OBJECT (simple), "finish_func"); + if (finish_func (NMDBUS_SETTINGS_CONNECTION (proxy), result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * 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) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + GVariant *settings; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_commit_changes_async); + + settings = nm_connection_to_dbus (NM_CONNECTION (connection), NM_CONNECTION_SERIALIZE_ALL); + if (save_to_disk) { + g_object_set_data (G_OBJECT (simple), "finish_func", + nmdbus_settings_connection_call_update_finish); + nmdbus_settings_connection_call_update (priv->proxy, + settings, + cancellable, + update_cb, simple); + } else { + g_object_set_data (G_OBJECT (simple), "finish_func", + nmdbus_settings_connection_call_update_unsaved_finish); + nmdbus_settings_connection_call_update_unsaved (priv->proxy, + settings, + cancellable, + update_cb, simple); + } +} + +/** + * 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) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_commit_changes_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * 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. + **/ +gboolean +nm_remote_connection_save (NMRemoteConnection *connection, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + ret = nmdbus_settings_connection_call_save_sync (priv->proxy, cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +save_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_settings_connection_call_save_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * 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) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_save_async); + nmdbus_settings_connection_call_save (priv->proxy, cancellable, save_cb, simple); +} + +/** + * 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) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_save_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * 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. + **/ +gboolean +nm_remote_connection_delete (NMRemoteConnection *connection, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + gboolean ret; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + ret = nmdbus_settings_connection_call_delete_sync (priv->proxy, cancellable, error); + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return ret; +} + +static void +delete_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GError *error = NULL; + + if (nmdbus_settings_connection_call_delete_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + result, &error)) + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * 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) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_delete_async); + nmdbus_settings_connection_call_delete (priv->proxy, cancellable, delete_cb, simple); +} + +/** + * 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) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_delete_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return g_simple_async_result_get_op_res_gboolean (simple); +} + +/** + * 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: a #GVariant of type %NM_VARIANT_TYPE_CONNECTION containing + * @connection's secrets, or %NULL on error. + **/ +GVariant * +nm_remote_connection_get_secrets (NMRemoteConnection *connection, + const char *setting_name, + GCancellable *cancellable, + GError **error) +{ + NMRemoteConnectionPrivate *priv; + GVariant *secrets; + + g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + if (nmdbus_settings_connection_call_get_secrets_sync (priv->proxy, + setting_name, + &secrets, + cancellable, error)) + return secrets; + else { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return NULL; + } +} + +static void +get_secrets_cb (GObject *proxy, GAsyncResult *result, gpointer user_data) +{ + GSimpleAsyncResult *simple = user_data; + GVariant *secrets = NULL; + GError *error = NULL; + + if (nmdbus_settings_connection_call_get_secrets_finish (NMDBUS_SETTINGS_CONNECTION (proxy), + &secrets, result, &error)) + g_simple_async_result_set_op_res_gpointer (simple, secrets, (GDestroyNotify) g_variant_unref); + else { + g_dbus_error_strip_remote_error (error); + g_simple_async_result_take_error (simple, error); + } + + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +/** + * 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) +{ + NMRemoteConnectionPrivate *priv; + GSimpleAsyncResult *simple; + + g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection)); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (connection); + + simple = g_simple_async_result_new (G_OBJECT (connection), callback, user_data, + nm_remote_connection_get_secrets_async); + + nmdbus_settings_connection_call_get_secrets (priv->proxy, + setting_name, + cancellable, + get_secrets_cb, simple); +} + +/** + * 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) +{ + GSimpleAsyncResult *simple; + + g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (connection), nm_remote_connection_get_secrets_async), FALSE); + + simple = G_SIMPLE_ASYNC_RESULT (result); + if (g_simple_async_result_propagate_error (simple, error)) + return NULL; + else + return g_variant_ref (g_simple_async_result_get_op_res_gpointer (simple)); +} + +/** + * 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_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; +} + +/****************************************************************/ + +static void +replace_settings (NMRemoteConnection *self, GVariant *new_settings) +{ + GError *error = NULL; + + if (!nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) { + g_warning ("%s: error updating connection %s settings: (%d) %s", + __func__, + nm_connection_get_path (NM_CONNECTION (self)), + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + } +} + +static void +updated_get_settings_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + NMRemoteConnection *self = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + GVariant *new_settings; + gboolean visible; + + if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &new_settings, + result, NULL)) { + /* Connection is no longer visible to this user. */ + nm_connection_clear_settings (NM_CONNECTION (self)); + + visible = FALSE; + } else { + replace_settings (self, new_settings); + g_variant_unref (new_settings); + + visible = TRUE; + } + + if (visible != priv->visible) { + priv->visible = visible; + g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_VISIBLE); + } +} + +static void +updated_cb (NMDBusSettingsConnection *proxy, gpointer user_data) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data); + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + + /* The connection got updated; request the replacement settings */ + nmdbus_settings_connection_call_get_settings (priv->proxy, + NULL, + updated_get_settings_cb, self); +} + +/****************************************************************/ + +static void +init_dbus (NMObject *object) +{ + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object); + const NMPropertiesInfo property_info[] = { + { NM_REMOTE_CONNECTION_UNSAVED, &priv->unsaved }, + { NULL }, + }; + + NM_OBJECT_CLASS (nm_remote_connection_parent_class)->init_dbus (object); + + priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS_CONNECTION)); + g_assert (priv->proxy); + + _nm_object_register_properties (object, + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + property_info); + + g_signal_connect (priv->proxy, "updated", + G_CALLBACK (updated_cb), object); +} + +static gboolean +init_sync (GInitable *initable, GCancellable *cancellable, GError **error) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (initable); + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (initable); + GVariant *settings; + + if (!nm_remote_connection_parent_initable_iface->init (initable, cancellable, error)) + return FALSE; + + if (!nmdbus_settings_connection_call_get_settings_sync (priv->proxy, + &settings, + cancellable, error)) { + if (error && *error) + g_dbus_error_strip_remote_error (*error); + return FALSE; + } + + priv->visible = TRUE; + replace_settings (self, settings); + g_variant_unref (settings); + + return TRUE; +} + +typedef struct { + NMRemoteConnection *connection; + GCancellable *cancellable; + GSimpleAsyncResult *result; +} NMRemoteConnectionInitData; + +static void +init_async_complete (NMRemoteConnectionInitData *init_data, GError *error) +{ + if (error) + g_simple_async_result_take_error (init_data->result, error); + else + g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE); + + g_simple_async_result_complete (init_data->result); + g_object_unref (init_data->result); + g_clear_object (&init_data->cancellable); + g_slice_free (NMRemoteConnectionInitData, init_data); +} + +static void +init_get_settings_cb (GObject *proxy, + GAsyncResult *result, + gpointer user_data) +{ + NMRemoteConnectionInitData *init_data = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); + GVariant *settings; + GError *error = NULL; + + if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &settings, + result, &error)) { + g_dbus_error_strip_remote_error (error); + init_async_complete (init_data, error); + return; + } + + priv->visible = TRUE; + replace_settings (init_data->connection, settings); + g_variant_unref (settings); + + init_async_complete (init_data, NULL); +} + +static void +init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data) +{ + NMRemoteConnectionInitData *init_data = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (init_data->connection); + GError *error = NULL; + + if (!nm_remote_connection_parent_async_initable_iface->init_finish (G_ASYNC_INITABLE (source), result, &error)) { + init_async_complete (init_data, error); + return; + } + + nmdbus_settings_connection_call_get_settings (priv->proxy, + init_data->cancellable, + init_get_settings_cb, init_data); +} + +static void +init_async (GAsyncInitable *initable, int io_priority, + GCancellable *cancellable, GAsyncReadyCallback callback, + gpointer user_data) +{ + NMRemoteConnectionInitData *init_data; + + init_data = g_slice_new0 (NMRemoteConnectionInitData); + init_data->connection = NM_REMOTE_CONNECTION (initable); + init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback, + user_data, init_async); + + nm_remote_connection_parent_async_initable_iface-> + init_async (initable, io_priority, cancellable, init_async_parent_inited, init_data); +} + +static gboolean +init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error) +{ + GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result); + + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + else + return TRUE; +} + +static void +nm_remote_connection_init (NMRemoteConnection *self) +{ +} + +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_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 +constructed (GObject *object) +{ + nm_connection_set_path (NM_CONNECTION (object), + nm_object_get_path (NM_OBJECT (object))); +} + +static void +nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (remote_class); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS (remote_class); + + g_type_class_add_private (object_class, sizeof (NMRemoteConnectionPrivate)); + + _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_SETTINGS_CONNECTION); + _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + NMDBUS_TYPE_SETTINGS_CONNECTION_PROXY); + + /* virtual methods */ + object_class->constructed = constructed; + object_class->get_property = get_property; + + nm_object_class->init_dbus = init_dbus; + + /* Properties */ + /** + * 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. + **/ + g_object_class_install_property + (object_class, PROP_UNSAVED, + g_param_spec_boolean (NM_REMOTE_CONNECTION_UNSAVED, "", "", + FALSE, + 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.) + **/ + g_object_class_install_property + (object_class, PROP_VISIBLE, + g_param_spec_boolean (NM_REMOTE_CONNECTION_VISIBLE, "", "", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); +} + +static void +nm_remote_connection_connection_iface_init (NMConnectionInterface *iface) +{ +} + +static void +nm_remote_connection_initable_iface_init (GInitableIface *iface) +{ + nm_remote_connection_parent_initable_iface = g_type_interface_peek_parent (iface); + + iface->init = init_sync; +} + +static void +nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface) +{ + nm_remote_connection_parent_async_initable_iface = g_type_interface_peek_parent (iface); + + iface->init_async = init_async; + iface->init_finish = init_finish; +} |