1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the
15 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301 USA.
18 * Copyright 2008 Novell, Inc.
19 * Copyright 2009 - 2012 Red Hat, Inc.
22 #include "nm-default.h"
24 #include "nm-remote-settings.h"
28 #include "nm-dbus-interface.h"
29 #include "nm-connection.h"
31 #include "nm-client.h"
32 #include "nm-remote-connection.h"
33 #include "nm-remote-connection-private.h"
34 #include "nm-object-private.h"
35 #include "nm-dbus-helpers.h"
36 #include "nm-object-private.h"
37 #include "nm-core-internal.h"
39 #include "nmdbus-settings.h"
41 G_DEFINE_TYPE (NMRemoteSettings, nm_remote_settings, NM_TYPE_OBJECT)
43 #define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate))
46 NMDBusSettings *proxy;
47 GPtrArray *all_connections;
48 GPtrArray *visible_connections;
49 GCancellable *props_cancellable;
51 /* AddConnectionInfo objects that are waiting for the connection to become initialized */
56 } NMRemoteSettingsPrivate;
74 static guint signals[LAST_SIGNAL] = { 0 };
76 /**********************************************************************/
79 NMRemoteSettings *self;
80 GSimpleAsyncResult *simple;
85 static AddConnectionInfo *
86 add_connection_info_find (NMRemoteSettings *self, const char *path)
88 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
91 for (iter = priv->add_list; iter; iter = g_slist_next (iter)) {
92 AddConnectionInfo *info = iter->data;
94 if (!g_strcmp0 (info->path, path))
102 add_connection_info_complete (NMRemoteSettings *self,
103 AddConnectionInfo *info,
104 NMRemoteConnection *connection,
107 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
109 g_return_if_fail (info != NULL);
112 g_simple_async_result_set_op_res_gpointer (info->simple,
113 g_object_ref (connection),
116 g_simple_async_result_set_from_error (info->simple, error);
117 g_simple_async_result_complete (info->simple);
119 g_object_unref (info->simple);
120 priv->add_list = g_slist_remove (priv->add_list, info);
123 g_slice_free (AddConnectionInfo, info);
126 typedef const char * (*ConnectionStringGetter) (NMConnection *);
128 static NMRemoteConnection *
129 get_connection_by_string (NMRemoteSettings *settings,
131 ConnectionStringGetter get_comparison_string)
133 NMRemoteSettingsPrivate *priv;
134 NMConnection *candidate;
137 if (!_nm_object_get_nm_running (NM_OBJECT (settings)))
140 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
142 for (i = 0; i < priv->visible_connections->len; i++) {
143 candidate = priv->visible_connections->pdata[i];
144 if (!g_strcmp0 (string, get_comparison_string (candidate)))
145 return NM_REMOTE_CONNECTION (candidate);
152 nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings, const char *id)
154 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
155 g_return_val_if_fail (id != NULL, NULL);
157 return get_connection_by_string (settings, id, nm_connection_get_id);
161 nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path)
163 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
164 g_return_val_if_fail (path != NULL, NULL);
166 return get_connection_by_string (settings, path, nm_connection_get_path);
170 nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const char *uuid)
172 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
173 g_return_val_if_fail (uuid != NULL, NULL);
175 return get_connection_by_string (settings, uuid, nm_connection_get_uuid);
179 connection_visible_changed (GObject *object,
183 NMRemoteConnection *connection = NM_REMOTE_CONNECTION (object);
184 NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
186 if (nm_remote_connection_get_visible (connection))
187 g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection);
189 g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection);
193 cleanup_connection (NMRemoteSettings *self,
194 NMRemoteConnection *remote)
196 g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (connection_visible_changed), self);
200 connection_removed (NMRemoteSettings *self,
201 NMRemoteConnection *remote)
203 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
204 gboolean still_exists = FALSE;
207 /* Check if the connection was actually removed or if it just turned invisible. */
208 for (i = 0; i < priv->all_connections->len; i++) {
209 if (remote == priv->all_connections->pdata[i]) {
216 cleanup_connection (self, remote);
218 /* Allow the signal to propagate if and only if @remote was in visible_connections */
219 if (!g_ptr_array_remove (priv->visible_connections, remote))
220 g_signal_stop_emission (self, signals[CONNECTION_REMOVED], 0);
224 connection_added (NMRemoteSettings *self,
225 NMRemoteConnection *remote)
227 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
228 AddConnectionInfo *addinfo;
231 if (!g_signal_handler_find (remote, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL,
232 G_CALLBACK (connection_visible_changed), self)) {
233 g_signal_connect (remote,
234 "notify::" NM_REMOTE_CONNECTION_VISIBLE,
235 G_CALLBACK (connection_visible_changed),
239 if (nm_remote_connection_get_visible (remote))
240 g_ptr_array_add (priv->visible_connections, remote);
242 g_signal_stop_emission (self, signals[CONNECTION_ADDED], 0);
244 path = nm_connection_get_path (NM_CONNECTION (remote));
245 addinfo = add_connection_info_find (self, path);
247 add_connection_info_complete (self, addinfo, remote, NULL);
251 object_creation_failed (NMObject *object, const char *failed_path)
253 NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
254 AddConnectionInfo *addinfo;
257 addinfo = add_connection_info_find (self, failed_path);
259 add_error = g_error_new_literal (NM_CLIENT_ERROR,
260 NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
261 _("Connection removed before it was initialized"));
262 add_connection_info_complete (self, addinfo, NULL, add_error);
263 g_error_free (add_error);
268 nm_remote_settings_get_connections (NMRemoteSettings *settings)
270 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
272 return NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->visible_connections;
276 add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data)
278 AddConnectionInfo *info = user_data;
279 GError *error = NULL;
282 nmdbus_settings_call_add_connection_finish (NMDBUS_SETTINGS (proxy),
286 nmdbus_settings_call_add_connection_unsaved_finish (NMDBUS_SETTINGS (proxy),
292 g_dbus_error_strip_remote_error (error);
293 add_connection_info_complete (info->self, info, NULL, error);
294 g_clear_error (&error);
297 /* On success, we still have to wait until the connection is fully
298 * initialized before calling the callback.
303 nm_remote_settings_add_connection_async (NMRemoteSettings *settings,
304 NMConnection *connection,
305 gboolean save_to_disk,
306 GCancellable *cancellable,
307 GAsyncReadyCallback callback,
310 NMRemoteSettingsPrivate *priv;
311 AddConnectionInfo *info;
312 GVariant *new_settings;
314 g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings));
315 g_return_if_fail (NM_IS_CONNECTION (connection));
317 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
319 info = g_slice_new0 (AddConnectionInfo);
320 info->self = settings;
321 info->simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data,
322 nm_remote_settings_add_connection_async);
323 info->saved = save_to_disk;
325 new_settings = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
328 nmdbus_settings_call_add_connection (priv->proxy,
331 add_connection_done, info);
333 nmdbus_settings_call_add_connection_unsaved (priv->proxy,
336 add_connection_done, info);
339 priv->add_list = g_slist_append (priv->add_list, info);
343 nm_remote_settings_add_connection_finish (NMRemoteSettings *settings,
344 GAsyncResult *result,
347 GSimpleAsyncResult *simple;
349 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_add_connection_async), NULL);
351 simple = G_SIMPLE_ASYNC_RESULT (result);
352 if (g_simple_async_result_propagate_error (simple, error))
355 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
359 nm_remote_settings_load_connections (NMRemoteSettings *settings,
362 GCancellable *cancellable,
365 NMRemoteSettingsPrivate *priv;
368 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE);
369 g_return_val_if_fail (filenames != NULL, FALSE);
371 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
373 if (!nmdbus_settings_call_load_connections_sync (priv->proxy,
374 (const char * const *) filenames,
377 cancellable, error)) {
379 g_dbus_error_strip_remote_error (*error);
386 load_connections_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
388 GSimpleAsyncResult *simple = user_data;
389 GError *error = NULL;
391 char **failures = NULL;
393 if (nmdbus_settings_call_load_connections_finish (NMDBUS_SETTINGS (proxy),
396 g_simple_async_result_set_op_res_gpointer (simple, failures, (GDestroyNotify) g_strfreev);
398 g_dbus_error_strip_remote_error (error);
399 g_simple_async_result_take_error (simple, error);
402 g_simple_async_result_complete (simple);
403 g_object_unref (simple);
407 nm_remote_settings_load_connections_async (NMRemoteSettings *settings,
409 GCancellable *cancellable,
410 GAsyncReadyCallback callback,
413 NMRemoteSettingsPrivate *priv;
414 GSimpleAsyncResult *simple;
416 g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings));
417 g_return_if_fail (filenames != NULL);
419 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
421 simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data,
422 nm_remote_settings_load_connections_async);
424 nmdbus_settings_call_load_connections (priv->proxy,
425 (const char * const *) filenames,
426 cancellable, load_connections_cb, simple);
430 nm_remote_settings_load_connections_finish (NMRemoteSettings *settings,
432 GAsyncResult *result,
435 GSimpleAsyncResult *simple;
437 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_load_connections_async), FALSE);
439 simple = G_SIMPLE_ASYNC_RESULT (result);
440 if (g_simple_async_result_propagate_error (simple, error))
443 *failures = g_strdupv (g_simple_async_result_get_op_res_gpointer (simple));
449 nm_remote_settings_reload_connections (NMRemoteSettings *settings,
450 GCancellable *cancellable,
453 NMRemoteSettingsPrivate *priv;
456 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE);
458 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
460 if (!nmdbus_settings_call_reload_connections_sync (priv->proxy, &success,
461 cancellable, error)) {
463 g_dbus_error_strip_remote_error (*error);
471 reload_connections_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
473 GSimpleAsyncResult *simple = user_data;
475 GError *error = NULL;
477 if (nmdbus_settings_call_reload_connections_finish (NMDBUS_SETTINGS (proxy),
480 g_simple_async_result_set_op_res_gboolean (simple, success);
482 g_dbus_error_strip_remote_error (error);
483 g_simple_async_result_take_error (simple, error);
486 g_simple_async_result_complete (simple);
487 g_object_unref (simple);
491 nm_remote_settings_reload_connections_async (NMRemoteSettings *settings,
492 GCancellable *cancellable,
493 GAsyncReadyCallback callback,
496 NMRemoteSettingsPrivate *priv;
497 GSimpleAsyncResult *simple;
499 g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings));
501 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
503 simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data,
504 nm_remote_settings_reload_connections_async);
506 nmdbus_settings_call_reload_connections (priv->proxy, cancellable,
507 reload_connections_cb, simple);
511 nm_remote_settings_reload_connections_finish (NMRemoteSettings *settings,
512 GAsyncResult *result,
515 GSimpleAsyncResult *simple;
517 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_reload_connections_async), FALSE);
519 simple = G_SIMPLE_ASYNC_RESULT (result);
520 if (g_simple_async_result_propagate_error (simple, error))
523 return g_simple_async_result_get_op_res_gboolean (simple);
527 nm_remote_settings_save_hostname (NMRemoteSettings *settings,
528 const char *hostname,
529 GCancellable *cancellable,
532 NMRemoteSettingsPrivate *priv;
536 g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE);
538 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
540 ret = nmdbus_settings_call_save_hostname_sync (priv->proxy,
541 hostname ? hostname : "",
544 g_dbus_error_strip_remote_error (*error);
549 save_hostname_cb (GObject *proxy,
550 GAsyncResult *result,
553 GSimpleAsyncResult *simple = user_data;
554 GError *error = NULL;
556 if (nmdbus_settings_call_save_hostname_finish (NMDBUS_SETTINGS (proxy), result, &error))
557 g_simple_async_result_set_op_res_gboolean (simple, TRUE);
559 g_dbus_error_strip_remote_error (error);
560 g_simple_async_result_take_error (simple, error);
562 g_simple_async_result_complete (simple);
563 g_object_unref (simple);
567 nm_remote_settings_save_hostname_async (NMRemoteSettings *settings,
568 const char *hostname,
569 GCancellable *cancellable,
570 GAsyncReadyCallback callback,
573 NMRemoteSettingsPrivate *priv;
574 GSimpleAsyncResult *simple;
576 g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings));
578 priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
580 simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data,
581 nm_remote_settings_save_hostname_async);
583 nmdbus_settings_call_save_hostname (priv->proxy,
584 hostname ? hostname : "",
585 cancellable, save_hostname_cb, simple);
589 nm_remote_settings_save_hostname_finish (NMRemoteSettings *settings,
590 GAsyncResult *result,
593 GSimpleAsyncResult *simple;
595 g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_save_hostname_async), FALSE);
597 simple = G_SIMPLE_ASYNC_RESULT (result);
598 if (g_simple_async_result_propagate_error (simple, error))
601 return g_simple_async_result_get_op_res_gboolean (simple);
605 updated_properties (GObject *object, GAsyncResult *result, gpointer user_data)
607 GError *error = NULL;
609 if (!_nm_object_reload_properties_finish (NM_OBJECT (object), result, &error)) {
610 if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
611 g_warning ("%s: error reading NMRemoteSettings properties: %s", __func__, error->message);
612 g_error_free (error);
617 nm_running_changed (GObject *object,
621 NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
622 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
624 g_object_freeze_notify (object);
626 if (!_nm_object_get_nm_running (NM_OBJECT (self))) {
627 GPtrArray *connections;
630 nm_clear_g_cancellable (&priv->props_cancellable);
632 /* Clear connections */
633 connections = priv->all_connections;
634 priv->all_connections = g_ptr_array_new ();
635 for (i = 0; i < connections->len; i++)
636 g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connections->pdata[i]);
637 g_ptr_array_unref (connections);
639 /* Clear properties */
640 if (priv->hostname) {
641 g_free (priv->hostname);
642 priv->hostname = NULL;
643 g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_HOSTNAME);
646 if (priv->can_modify) {
647 priv->can_modify = FALSE;
648 g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_CAN_MODIFY);
651 _nm_object_suppress_property_updates (NM_OBJECT (self), TRUE);
653 _nm_object_suppress_property_updates (NM_OBJECT (self), FALSE);
655 nm_clear_g_cancellable (&priv->props_cancellable);
656 priv->props_cancellable = g_cancellable_new ();
657 _nm_object_reload_properties_async (NM_OBJECT (self), priv->props_cancellable, updated_properties, self);
660 g_object_thaw_notify (object);
663 /****************************************************************/
666 nm_remote_settings_init (NMRemoteSettings *self)
668 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
670 priv->all_connections = g_ptr_array_new ();
671 priv->visible_connections = g_ptr_array_new ();
675 init_dbus (NMObject *object)
677 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
678 const NMPropertiesInfo property_info[] = {
679 { NM_REMOTE_SETTINGS_CONNECTIONS, &priv->all_connections, NULL, NM_TYPE_REMOTE_CONNECTION, "connection" },
680 { NM_REMOTE_SETTINGS_HOSTNAME, &priv->hostname },
681 { NM_REMOTE_SETTINGS_CAN_MODIFY, &priv->can_modify },
685 NM_OBJECT_CLASS (nm_remote_settings_parent_class)->init_dbus (object);
687 priv->proxy = NMDBUS_SETTINGS (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS));
688 _nm_object_register_properties (object,
689 NM_DBUS_INTERFACE_SETTINGS,
692 g_signal_connect (object, "notify::" NM_OBJECT_NM_RUNNING,
693 G_CALLBACK (nm_running_changed), object);
697 constructor (GType type,
698 guint n_construct_params,
699 GObjectConstructParam *construct_params)
702 const char *dbus_path;
704 /* Fill in the right D-Bus path if none was specified */
705 for (i = 0; i < n_construct_params; i++) {
706 if (strcmp (construct_params[i].pspec->name, NM_OBJECT_PATH) == 0) {
707 dbus_path = g_value_get_string (construct_params[i].value);
708 if (dbus_path == NULL) {
709 g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH_SETTINGS);
711 if (!g_variant_is_object_path (dbus_path)) {
712 g_warning ("Passed D-Bus object path '%s' is invalid; using default '%s' instead",
713 dbus_path, NM_DBUS_PATH);
714 g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH_SETTINGS);
721 return G_OBJECT_CLASS (nm_remote_settings_parent_class)->constructor (type,
727 dispose (GObject *object)
729 NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
730 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
733 if (priv->all_connections) {
734 for (i = 0; i < priv->all_connections->len; i++)
735 cleanup_connection (self, priv->all_connections->pdata[i]);
736 g_clear_pointer (&priv->all_connections, g_ptr_array_unref);
739 g_signal_handlers_disconnect_by_func (object, G_CALLBACK (nm_running_changed), self);
741 g_clear_pointer (&priv->visible_connections, g_ptr_array_unref);
742 g_clear_pointer (&priv->hostname, g_free);
744 G_OBJECT_CLASS (nm_remote_settings_parent_class)->dispose (object);
748 get_property (GObject *object, guint prop_id,
749 GValue *value, GParamSpec *pspec)
751 NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
754 case PROP_CONNECTIONS:
755 g_value_take_boxed (value, _nm_utils_copy_object_array (priv->visible_connections));
758 g_value_set_string (value, priv->hostname);
760 case PROP_CAN_MODIFY:
761 g_value_set_boolean (value, priv->can_modify);
764 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
770 nm_remote_settings_class_init (NMRemoteSettingsClass *class)
772 GObjectClass *object_class = G_OBJECT_CLASS (class);
773 NMObjectClass *nm_object_class = NM_OBJECT_CLASS (class);
775 g_type_class_add_private (class, sizeof (NMRemoteSettingsPrivate));
777 _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_SETTINGS);
778 _nm_dbus_register_proxy_type (NM_DBUS_INTERFACE_SETTINGS, NMDBUS_TYPE_SETTINGS_PROXY);
780 /* Virtual methods */
781 object_class->constructor = constructor;
782 object_class->get_property = get_property;
783 object_class->dispose = dispose;
785 nm_object_class->init_dbus = init_dbus;
786 nm_object_class->object_creation_failed = object_creation_failed;
788 class->connection_added = connection_added;
789 class->connection_removed = connection_removed;
793 g_object_class_install_property
794 (object_class, PROP_CONNECTIONS,
795 g_param_spec_boxed (NM_REMOTE_SETTINGS_CONNECTIONS, "", "",
798 G_PARAM_STATIC_STRINGS));
800 g_object_class_install_property
801 (object_class, PROP_HOSTNAME,
802 g_param_spec_string (NM_REMOTE_SETTINGS_HOSTNAME, "", "",
805 G_PARAM_STATIC_STRINGS));
807 g_object_class_install_property
808 (object_class, PROP_CAN_MODIFY,
809 g_param_spec_boolean (NM_REMOTE_SETTINGS_CAN_MODIFY, "", "",
812 G_PARAM_STATIC_STRINGS));
815 signals[CONNECTION_ADDED] =
816 g_signal_new (NM_REMOTE_SETTINGS_CONNECTION_ADDED,
817 G_OBJECT_CLASS_TYPE (object_class),
819 G_STRUCT_OFFSET (NMRemoteSettingsClass, connection_added),
822 NM_TYPE_REMOTE_CONNECTION);
824 signals[CONNECTION_REMOVED] =
825 g_signal_new (NM_REMOTE_SETTINGS_CONNECTION_REMOVED,
826 G_OBJECT_CLASS_TYPE (object_class),
828 G_STRUCT_OFFSET (NMRemoteSettingsClass, connection_removed),
831 NM_TYPE_REMOTE_CONNECTION);