NetworkManager r3299 - in trunk: . system-settings/plugins/ifcfg-fedora system-settings/src



Author: dcbw
Date: Thu Feb  7 20:11:31 2008
New Revision: 3299
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3299&view=rev

Log:
2008-02-07  Dan Williams  <dcbw redhat com>

	* system-settings/src/dbus-settings.c
	  system-settings/src/dbus-settings.h
		- (add_one_secret_to_hash): copy secrets out of the plugin-returned hash
			table of secrets
		- (connection_settings_get_secrets): consolidate error returns into
			one place; use the new get_secrets() plugin interface function to
			get secrets from the plugin itself rather than using GObject data
			magic

	* system-settings/src/main.c
		- (connection_added_cb, connection_removed_cb, free_plugin_connections,
		   load_connections): keep a private list of the plugin-returned
			connections, don't use the plugin's GSList

	* system-settings/plugins/ifcfg-fedora/plugin.c
		- (watch_path): watch the path, not the filename (duh)
		- (reload_all_connections): use the direct hash/equal functions; the
			ones for int aren't appropriate here
		- (get_secrets, system_config_interface_init): implement the
			get_secrets() function
		- (build_one_connection, find_connection_by_path): ifcfg file path is
			now in the connection's ConnectionData instead of being a GObject
			data property
		- (handle_profile_item_changed): ifcfg file path is now in the
			connection's ConnectionData instead of being a GObject data property;
			be sure to copy secrets over from the new connection to the existing
			connection when updating the connection's settings
		- (init): sc_plugin_inotify_init() returns success/fail, not the inotify
			file descriptor

	* system-settings/plugins/ifcfg-fedora/parser.c
	  system-settings/plugins/ifcfg-fedora/parser.h
		- (connection_data_get, copy_one_cdata_secret, clear_one_cdata_secret,
		   connection_data_copy_secrets, connection_data_free,
		   connection_data_add): new functions; connection data manipulation
		- (make_wireless_security_setting): stuff secrets into the
			connection data, not as GObject data items; make sure to close
			the keys ifcfg file
		- (wireless_connection_from_ifcfg, wired_connection_from_ifcfg): add
			connection data to the connection



Modified:
   trunk/ChangeLog
   trunk/system-settings/plugins/ifcfg-fedora/parser.c
   trunk/system-settings/plugins/ifcfg-fedora/parser.h
   trunk/system-settings/plugins/ifcfg-fedora/plugin.c
   trunk/system-settings/src/dbus-settings.c
   trunk/system-settings/src/dbus-settings.h
   trunk/system-settings/src/main.c

Modified: trunk/system-settings/plugins/ifcfg-fedora/parser.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/parser.c	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/parser.c	Thu Feb  7 20:11:31 2008
@@ -41,6 +41,69 @@
 #include "parser.h"
 #include "plugin.h"
 
+#define CONNECTION_DATA_TAG "plugin-data"
+
+ConnectionData *
+connection_data_get (NMConnection *connection)
+{
+	return (ConnectionData *) g_object_get_data (G_OBJECT (connection), CONNECTION_DATA_TAG);
+}
+
+static void
+copy_one_cdata_secret (gpointer key, gpointer data, gpointer user_data)
+{
+	ConnectionData *to = (ConnectionData *) user_data;
+
+	g_hash_table_insert (to->secrets, key, g_strdup (data));
+}
+
+static void
+clear_one_cdata_secret (gpointer key, gpointer data, gpointer user_data)
+{
+	guint32 len = strlen (data);
+	memset (data, 0, len);
+}
+
+void
+connection_data_copy_secrets (ConnectionData *from, ConnectionData *to)
+{
+	g_return_if_fail (from != NULL);
+	g_return_if_fail (to != NULL);
+
+	g_hash_table_foreach (to->secrets, clear_one_cdata_secret, NULL);
+	g_hash_table_remove_all (to->secrets);
+
+	g_hash_table_foreach (from->secrets, copy_one_cdata_secret, to);
+}
+
+static void
+connection_data_free (gpointer userdata)
+{
+	ConnectionData *cdata = (ConnectionData *) userdata;
+
+	g_return_if_fail (cdata != NULL);
+
+	g_free (cdata->ifcfg_path);
+	g_hash_table_foreach (cdata->secrets, clear_one_cdata_secret, NULL);
+	g_hash_table_destroy (cdata->secrets);
+	memset (cdata, 0, sizeof (ConnectionData));
+	g_free (cdata);
+}
+
+ConnectionData *
+connection_data_add (NMConnection *connection, const char *ifcfg_path)
+{
+	ConnectionData *cdata;
+
+	cdata = g_malloc0 (sizeof (ConnectionData));
+	cdata->ifcfg_path = g_strdup (ifcfg_path);
+	cdata->secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+
+	g_object_set_data_full (G_OBJECT (connection),
+	                        CONNECTION_DATA_TAG, cdata,
+	                        connection_data_free);
+	return cdata;
+}
 
 static gboolean
 get_int (const char *str, int *value)
@@ -342,17 +405,15 @@
 	return key;
 }
 
-#define READ_WEP_KEY(idx, ifcfg_file) \
+#define READ_WEP_KEY(idx, ifcfg_file, cdata) \
 	{ \
 		char *key = get_one_wep_key (ifcfg_file, idx, error); \
 		if (*error) \
 			goto error; \
 		if (key) { \
-			g_object_set_data_full (G_OBJECT (s_wireless_sec), \
-			                        NM_SETTING_WIRELESS_SECURITY_WEP_KEY##idx, \
-			                        key, \
-			                        g_free); \
-			have_key = TRUE; \
+			g_hash_table_insert (cdata->secrets, \
+			                     NM_SETTING_WIRELESS_SECURITY_WEP_KEY##idx, \
+			                     key); \
 		} \
 	}
 
@@ -388,28 +449,27 @@
 static NMSetting *
 make_wireless_security_setting (shvarFile *ifcfg,
                                 const char *file,
+                                ConnectionData *cdata,
                                 GError **error)
 {
 	NMSettingWirelessSecurity *s_wireless_sec;
-	gboolean have_key = FALSE;
 	char *value;
-	shvarFile *keys_ifcfg;
+	shvarFile *keys_ifcfg = NULL;
 
 	s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ());
 
-	READ_WEP_KEY(0, ifcfg)
-	READ_WEP_KEY(1, ifcfg)
-	READ_WEP_KEY(2, ifcfg)
-	READ_WEP_KEY(3, ifcfg)
+	READ_WEP_KEY(0, ifcfg, cdata)
+	READ_WEP_KEY(1, ifcfg, cdata)
+	READ_WEP_KEY(2, ifcfg, cdata)
+	READ_WEP_KEY(3, ifcfg, cdata)
 
 	/* Try to get keys from the "shadow" key file */
 	keys_ifcfg = get_keys_ifcfg (file);
 	if (keys_ifcfg) {
-		READ_WEP_KEY(0, keys_ifcfg)
-		READ_WEP_KEY(1, keys_ifcfg)
-		READ_WEP_KEY(2, keys_ifcfg)
-		READ_WEP_KEY(3, keys_ifcfg)
-		svCloseFile (keys_ifcfg);
+		READ_WEP_KEY(0, keys_ifcfg, cdata)
+		READ_WEP_KEY(1, keys_ifcfg, cdata)
+		READ_WEP_KEY(2, keys_ifcfg, cdata)
+		READ_WEP_KEY(3, keys_ifcfg, cdata)
 	}
 
 	value = svGetValue (ifcfg, "DEFAULTKEY");
@@ -453,11 +513,16 @@
 	// FIXME: unencrypted and WEP-only for now
 	s_wireless_sec->key_mgmt = g_strdup ("none");
 
+	if (keys_ifcfg)
+		svCloseFile (keys_ifcfg);
+
 	return NM_SETTING (s_wireless_sec);
 
 error:
 	if (s_wireless_sec)
 		g_object_unref (s_wireless_sec);
+	if (keys_ifcfg)
+		svCloseFile (keys_ifcfg);
 	return NULL;
 }
 
@@ -531,6 +596,7 @@
 	NMSettingWireless *tmp;
 	NMSetting *security_setting = NULL;
 	char *printable_ssid = NULL;
+	ConnectionData *cdata;
 
 	g_return_val_if_fail (file != NULL, NULL);
 	g_return_val_if_fail (ifcfg != NULL, NULL);
@@ -544,8 +610,11 @@
 		return NULL;
 	}
 
+	/* Add plugin specific data to connection */
+	cdata = connection_data_add (connection, file);
+
 	/* Wireless security */
-	security_setting = make_wireless_security_setting (ifcfg, file, error);
+	security_setting = make_wireless_security_setting (ifcfg, file, cdata, error);
 	if (*error)
 		goto error;
 	if (security_setting)
@@ -622,6 +691,7 @@
 	NMConnection *connection = NULL;
 	NMSetting *con_setting = NULL;
 	NMSetting *wired_setting = NULL;
+	ConnectionData *cdata;
 
 	g_return_val_if_fail (file != NULL, NULL);
 	g_return_val_if_fail (ifcfg != NULL, NULL);
@@ -641,6 +711,9 @@
 	}
 	nm_connection_add_setting (connection, con_setting);
 
+	/* Add plugin data to connection */
+	cdata = connection_data_add (connection, file);
+
 	wired_setting = make_wired_setting (ifcfg, error);
 	if (!wired_setting)
 		goto error;

Modified: trunk/system-settings/plugins/ifcfg-fedora/parser.h
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/parser.h	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/parser.h	Thu Feb  7 20:11:31 2008
@@ -28,6 +28,15 @@
 #define IFCFG_TAG "ifcfg-"
 #define BAK_TAG ".bak"
 
+typedef struct {
+	char *ifcfg_path;
+	GHashTable *secrets;
+} ConnectionData;
+
 NMConnection * parser_parse_file (const char *file, GError **error);
 
+ConnectionData *connection_data_get (NMConnection *connection);
+ConnectionData *connection_data_add (NMConnection *connection, const char *ifcfg_path);
+void connection_data_copy_secrets (ConnectionData *from, ConnectionData *to);
+
 #endif /* _PARSER_H_ */

Modified: trunk/system-settings/plugins/ifcfg-fedora/plugin.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/plugin.c	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/plugin.c	Thu Feb  7 20:11:31 2008
@@ -25,8 +25,10 @@
 #include <string.h>
 #include <sys/inotify.h>
 #include <unistd.h>
+#include <errno.h>
 
 #include <nm-setting-connection.h>
+#include <nm-setting-wireless-security.h>
 
 #include "plugin.h"
 #include "parser.h"
@@ -45,8 +47,6 @@
 #define SC_PLUGIN_IFCFG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFCFG, SCPluginIfcfgPrivate))
 
 
-#define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
-
 typedef struct {
 	gboolean initialized;
 	GSList *connections;
@@ -111,29 +111,32 @@
 static void
 watch_path (const char *path, const int inotify_fd, GHashTable *table)
 {
-	char *basename;
+	char *dirname;
 	int wd;
 	struct FindInfo info;
 
-	basename = g_path_get_basename (path);
-	g_return_if_fail (basename != NULL);
+	dirname = g_path_get_dirname (path);
+	g_return_if_fail (dirname != NULL);
 
 	info.found = FALSE;
-	info.path = basename;
+	info.path = dirname;
 	g_hash_table_foreach (table, find_watched_path, &info);
 	if (info.found)
 		goto error;
 
-	wd = inotify_add_watch (inotify_fd, basename,
+	wd = inotify_add_watch (inotify_fd, dirname,
 	                        IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MOVE);
-	if (wd == -1)
+	if (wd == -1) {
+		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    inotify error watching '%s': errno %d",
+		              dirname, errno);
 		goto error;
+	}
 
-	g_hash_table_insert (table, GINT_TO_POINTER (wd), basename);
+	g_hash_table_insert (table, GINT_TO_POINTER (wd), dirname);
 	return;
 
 error:
-	g_free (basename);
+	g_free (dirname);
 }
 
 static NMConnection *
@@ -159,8 +162,6 @@
 		g_assert (s_con);
 		g_assert (s_con->id);
 		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    found connection '%s'", s_con->id);
-		g_object_set_data_full (G_OBJECT (connection), IFCFG_FILE_PATH_TAG,
-		                        ifcfg_file, (GDestroyNotify) g_free);
 	} else {
 		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    error: %s",
 		              error->message ? error->message : "(unknown)");
@@ -250,7 +251,7 @@
 
 	clear_all_connections (plugin);
 
-	priv->watch_table = g_hash_table_new_full (g_int_hash, g_int_equal, NULL, g_free);
+	priv->watch_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
 
 	/* Add connections from the current profile */
 	priv->connections = get_connections_for_profile (priv->profile, priv->ifd, priv->watch_table);
@@ -268,6 +269,25 @@
 	return priv->connections;
 }
 
+static GHashTable *
+get_secrets (NMSystemConfigInterface *config,
+             NMConnection *connection,
+             NMSetting *setting)
+{
+	ConnectionData *cdata;
+
+	/* wifi security only for now */
+	if (!NM_IS_SETTING_WIRELESS_SECURITY (setting))
+		return NULL;
+
+	cdata = connection_data_get (connection);
+	if (!cdata || !cdata->secrets)
+		return NULL;
+
+	g_hash_table_ref (cdata->secrets);
+	return cdata->secrets;
+}
+
 static NMConnection *
 find_connection_by_path (GSList *connections, const char *path)
 {
@@ -277,10 +297,11 @@
 
 	for (iter = connections; iter; iter = g_slist_next (iter)) {
 		NMConnection *list_connection = NM_CONNECTION (iter->data);
-		const char *list_connection_path;
+		ConnectionData *cdata;
 
-		list_connection_path = g_object_get_data (G_OBJECT (list_connection), IFCFG_FILE_PATH_TAG);
-		if (list_connection_path && !strcmp (list_connection_path, path))
+		cdata = connection_data_get (list_connection);
+		g_assert (cdata);
+		if (cdata->ifcfg_path && !strcmp (cdata->ifcfg_path, path))
 			return list_connection;
 	}
 	return NULL;
@@ -303,19 +324,20 @@
 
 	if (!strncmp (filename, IFCFG_TAG, strlen (IFCFG_TAG))) {
 		NMConnection *new_connection;
-		const char *filepath;
 		NMConnection *existing;
+		ConnectionData *new_cdata;
 
 		new_connection = build_one_connection (priv->profile, filename);
 		if (!new_connection)
 			goto out;
 
-		filepath = g_object_get_data (G_OBJECT (new_connection), IFCFG_FILE_PATH_TAG);
-		g_assert (filepath);
+		new_cdata = connection_data_get (new_connection);
+		g_assert (new_cdata);
 
-		existing = find_connection_by_path (priv->connections, filepath);
+		existing = find_connection_by_path (priv->connections, new_cdata->ifcfg_path);
 		if (existing) {
 			GHashTable *new_settings;
+			ConnectionData *existing_cdata;
 
 			/* update the settings of the existing connection for this
 			 * ifcfg file and notify listeners that something has changed.
@@ -330,6 +352,9 @@
 				g_signal_emit_by_name (plugin, "connection-removed", existing);
 				g_object_unref (existing);
 			} else {
+				existing_cdata = connection_data_get (existing);
+				g_assert (existing_cdata);
+				connection_data_copy_secrets (new_cdata, existing_cdata);
 				g_signal_emit_by_name (plugin, "connection-updated", existing);
 			}
 			g_object_unref (new_connection);
@@ -365,6 +390,7 @@
 		                         evt.len > PATH_MAX ? PATH_MAX : evt.len,
 		                         NULL, NULL);
 
+g_message ("%s: path changed: %s", __func__, filename);
 		if (evt.wd == priv->profile_wd) {
 			if (!strcmp (filename, "network")) {
 				char *new_profile;
@@ -425,8 +451,6 @@
 	                            plugin);
 	g_io_channel_unref (channel);
 
-
-
 	return TRUE;
 }
 
@@ -441,8 +465,7 @@
 	if (!priv->profile)
 		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "could not determine network profile path.");
 
-	priv->ifd = sc_plugin_inotify_init (plugin, &error);
-	if (error) {
+	if (!sc_plugin_inotify_init (plugin, &error)) {
 		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    inotify error: %s",
 		              error->message ? error->message : "(unknown)");
 	}
@@ -507,6 +530,7 @@
 {
 	/* interface implementation */
 	system_config_interface_class->get_connections = get_connections;
+	system_config_interface_class->get_secrets = get_secrets;
 	system_config_interface_class->init = init;
 }
 

Modified: trunk/system-settings/src/dbus-settings.c
==============================================================================
--- trunk/system-settings/src/dbus-settings.c	(original)
+++ trunk/system-settings/src/dbus-settings.c	Thu Feb  7 20:11:31 2008
@@ -27,6 +27,7 @@
 #include <nm-setting-connection.h>
 
 #include "dbus-settings.h"
+#include "nm-system-config-interface.h"
 #include "nm-utils.h"
 
 static gchar *connection_settings_get_id (NMConnectionSettings *connection);
@@ -78,6 +79,11 @@
 	g_slice_free (GValue, value);
 }
 
+struct AddSecretsData {
+	GHashTable *plugin_secrets;
+	GHashTable *out_secrets;
+};
+
 static void
 add_one_secret_to_hash (NMSetting *setting,
                         const char *key,
@@ -85,7 +91,7 @@
                         gboolean secret,
                         gpointer user_data)
 {
-	GHashTable *secrets = (GHashTable *) user_data;
+	struct AddSecretsData *data = (struct AddSecretsData *) user_data;
 	const char *str_val;
 
 	if (!secret)
@@ -94,11 +100,11 @@
 	if (!G_VALUE_HOLDS (value, G_TYPE_STRING))
 		return;
 
-	str_val = g_object_get_data (G_OBJECT (setting), key);
+	str_val = g_hash_table_lookup (data->plugin_secrets, key);
 	if (!str_val)
 		return;
 
-	g_hash_table_insert (secrets, g_strdup (key), string_to_gvalue (str_val));
+	g_hash_table_insert (data->out_secrets, g_strdup (key), string_to_gvalue (str_val));
 }
 
 static void
@@ -110,9 +116,10 @@
 {
 	NMConnection *connection = NM_SYSCONFIG_CONNECTION_SETTINGS (sys_connection)->connection;
 	GError *error = NULL;
-	GHashTable *secrets;
 	NMSettingConnection *s_con;
 	NMSetting *setting;
+	NMSystemConfigInterface *plugin;
+	struct AddSecretsData sdata;
 
 	g_return_if_fail (NM_IS_CONNECTION (connection));
 	g_return_if_fail (setting_name != NULL);
@@ -122,10 +129,7 @@
 		g_set_error (&error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d - Connection didn't have requested setting '%s'.",
 		             __FILE__, __LINE__, setting_name);
-		g_warning (error->message);
-		dbus_g_method_return_error (context, error);
-		g_error_free (error);
-		return;
+		goto error;
 	}
 
 	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection,
@@ -136,26 +140,45 @@
 		             NM_SETTING_CONNECTION_SETTING_NAME
 		             "' setting , or the connection name was invalid.",
 		             __FILE__, __LINE__);
-		g_warning (error->message);
-		dbus_g_method_return_error (context, error);
-		g_error_free (error);
-		return;
+		goto error;
+	}
+
+	plugin = g_object_get_data (G_OBJECT (connection), NM_SS_PLUGIN_TAG);
+	if (!plugin) {
+		g_set_error (&error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d - Connection had no plugin to ask for secrets.",
+		             __FILE__, __LINE__);
+		goto error;
 	}
 
-	secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
-	nm_setting_enumerate_values (setting, add_one_secret_to_hash, secrets);
-	if (g_hash_table_size (secrets) == 0) {
+	sdata.plugin_secrets = nm_system_config_interface_get_secrets (plugin, connection, setting);
+	if (!sdata.plugin_secrets) {
+		g_set_error (&error, NM_SETTINGS_ERROR, 1,
+		             "%s.%d - Connection's plugin did not return a secrets hash.",
+		             __FILE__, __LINE__);
+		goto error;
+	}
+
+	sdata.out_secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
+	nm_setting_enumerate_values (setting, add_one_secret_to_hash, &sdata);
+	g_hash_table_unref (sdata.plugin_secrets);
+
+	if (g_hash_table_size (sdata.out_secrets) == 0) {
 		g_set_error (&error, NM_SETTINGS_ERROR, 1,
 		             "%s.%d - Secrets were found for setting '%s' but none"
 		             " were valid.", __FILE__, __LINE__, setting_name);
-		g_warning (error->message);
-		dbus_g_method_return_error (context, error);
-		g_error_free (error);
+		goto error;
 	} else {
-		dbus_g_method_return (context, secrets);
+		dbus_g_method_return (context, sdata.out_secrets);
 	}
 
-	g_hash_table_destroy (secrets);
+	g_hash_table_destroy (sdata.out_secrets);
+	return;
+
+error:
+	g_warning (error->message);
+	dbus_g_method_return_error (context, error);
+	g_error_free (error);
 }
 
 static void

Modified: trunk/system-settings/src/dbus-settings.h
==============================================================================
--- trunk/system-settings/src/dbus-settings.h	(original)
+++ trunk/system-settings/src/dbus-settings.h	Thu Feb  7 20:11:31 2008
@@ -19,9 +19,14 @@
  * (C) Copyright 2007 Red Hat, Inc.
  */
 
+#ifndef __DBUS_SETTINGS_H__
+#define __DBUS_SETTINGS_H__
+
 #include <nm-connection.h>
 #include <nm-settings.h>
 
+#define NM_SS_PLUGIN_TAG "nm-ss-plugin"
+
 typedef struct _NMSysconfigConnectionSettings NMSysconfigConnectionSettings;
 typedef struct _NMSysconfigConnectionSettingsClass NMSysconfigConnectionSettingsClass;
 
@@ -92,3 +97,4 @@
 void nm_sysconfig_settings_update_connection (NMSysconfigSettings *settings,
                                               NMConnection *connection);
 
+#endif  /* __DBUS_SETTINGS_H__ */

Modified: trunk/system-settings/src/main.c
==============================================================================
--- trunk/system-settings/src/main.c	(original)
+++ trunk/system-settings/src/main.c	Thu Feb  7 20:11:31 2008
@@ -40,9 +40,12 @@
 #include "dbus-settings.h"
 #include "nm-system-config-interface.h"
 
+#define NM_SS_CONNECTIONS_TAG "nm-ss-connections"
+
 typedef struct {
 	DBusConnection *connection;
 	DBusGConnection *g_connection;
+
 	DBusGProxy *bus_proxy;
 	gboolean started;
 
@@ -75,6 +78,11 @@
                      NMConnection *connection,
                      Application *app)
 {
+	GSList **connections;
+
+	connections = g_object_get_data (G_OBJECT (config), NM_SS_CONNECTIONS_TAG);
+	*connections = g_slist_append (*connections, connection);
+
 	nm_sysconfig_settings_add_connection (app->settings, connection, app->g_connection);
 }
 
@@ -83,6 +91,11 @@
                        NMConnection *connection,
                        Application *app)
 {
+	GSList **connections;
+
+	connections = g_object_get_data (G_OBJECT (config), NM_SS_CONNECTIONS_TAG);
+	*connections = g_slist_remove (*connections, connection);
+
 	nm_sysconfig_settings_remove_connection (app->settings, connection);
 }
 
@@ -214,15 +227,10 @@
 static void
 free_plugin_connections (gpointer data)
 {
-	GSList *connections = (GSList *) data;
+	GSList **connections = (GSList **) data;
 
-	g_slist_foreach (connections, (GFunc) g_object_unref, NULL);
-}
-
-static void
-add_connection_to_settings (gpointer data, gpointer user_data)
-{
-	connection_added_cb (NULL, NM_CONNECTION (data), (Application *) user_data);
+	g_slist_foreach (*connections, (GFunc) g_object_unref, NULL);
+	g_slist_free (*connections);
 }
 
 static gboolean
@@ -235,23 +243,30 @@
 
 	for (iter = app->plugins; iter; iter = g_slist_next (iter)) {
 		NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
-		GSList *connections;
+		GSList *plugin_connections, **connections;
+		GSList *elt;
 
-		connections = nm_system_config_interface_get_connections (plugin);
+		plugin_connections = nm_system_config_interface_get_connections (plugin);
+
+		connections = g_malloc0 (sizeof (GSList *));
+		g_object_set_data_full (G_OBJECT (plugin), NM_SS_CONNECTIONS_TAG,
+		                        connections, free_plugin_connections);
 
 		// FIXME: ensure connections from plugins loaded with a lower priority
 		// get rejected when they conflict with connections from a higher
 		// priority plugin.
 
-		g_slist_foreach (connections, (GFunc) g_object_ref, NULL);
-		g_slist_foreach (connections, (GFunc) add_connection_to_settings, app);
-		g_object_set_data_full (G_OBJECT (plugin), "connections",
-		                        connections, free_plugin_connections);
+		for (elt = plugin_connections; elt; elt = g_slist_next (elt)) {
+			g_object_ref (NM_CONNECTION (elt->data));
+			g_object_set_data (G_OBJECT (elt->data), NM_SS_PLUGIN_TAG, plugin);
+			connection_added_cb (NM_SYSTEM_CONFIG_INTERFACE (plugin), NM_CONNECTION (elt->data), app);
+		}
 	}
 
 	return FALSE;
 }
 
+
 /******************************************************************/
 
 static gboolean



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]