/* -*- 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 #include #include #include #include #include #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); } g_object_unref (self); } 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, g_object_ref (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; }