From bee138144b894e4a2bc2e81748ed3d40ae8f7cfd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 7 Feb 2008 20:11:31 +0000 Subject: [PATCH] 2008-02-07 Dan Williams * 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 git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3299 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 43 +++++++ system-settings/plugins/ifcfg-fedora/parser.c | 109 +++++++++++++++--- system-settings/plugins/ifcfg-fedora/parser.h | 9 ++ system-settings/plugins/ifcfg-fedora/plugin.c | 72 ++++++++---- system-settings/src/dbus-settings.c | 63 ++++++---- system-settings/src/dbus-settings.h | 6 + system-settings/src/main.c | 43 ++++--- 7 files changed, 269 insertions(+), 76 deletions(-) diff --git a/ChangeLog b/ChangeLog index dab6abe18..d524c8a4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +2008-02-07 Dan Williams + + * 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 + 2008-02-07 Dan Williams * system-settings/src/nm-system-config-interface.c diff --git a/system-settings/plugins/ifcfg-fedora/parser.c b/system-settings/plugins/ifcfg-fedora/parser.c index 8714ca0f5..cfca8ac79 100644 --- a/system-settings/plugins/ifcfg-fedora/parser.c +++ b/system-settings/plugins/ifcfg-fedora/parser.c @@ -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 @@ out: 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 @@ out: 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 @@ make_wireless_security_setting (shvarFile *ifcfg, // 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 @@ wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err 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 @@ wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err 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 @@ wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **error) 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 @@ wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **error) } 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; diff --git a/system-settings/plugins/ifcfg-fedora/parser.h b/system-settings/plugins/ifcfg-fedora/parser.h index aea3489e5..158745445 100644 --- a/system-settings/plugins/ifcfg-fedora/parser.h +++ b/system-settings/plugins/ifcfg-fedora/parser.h @@ -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_ */ diff --git a/system-settings/plugins/ifcfg-fedora/plugin.c b/system-settings/plugins/ifcfg-fedora/plugin.c index 253703286..9ec062603 100644 --- a/system-settings/plugins/ifcfg-fedora/plugin.c +++ b/system-settings/plugins/ifcfg-fedora/plugin.c @@ -25,8 +25,10 @@ #include #include #include +#include #include +#include #include "plugin.h" #include "parser.h" @@ -45,8 +47,6 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, #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 @@ find_watched_path (gpointer key, gpointer value, gpointer user_data) 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 @@ build_one_connection (const char *profile_path, const char *filename) 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 @@ reload_all_connections (SCPluginIfcfg *plugin) 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 @@ get_connections (NMSystemConfigInterface *config) 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 @@ find_connection_by_path (GSList *connections, const char *path) 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 @@ handle_profile_item_changed (SCPluginIfcfg *plugin, 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 @@ handle_profile_item_changed (SCPluginIfcfg *plugin, 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 @@ stuff_changed (GIOChannel *channel, GIOCondition cond, gpointer user_data) 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 @@ sc_plugin_inotify_init (SCPluginIfcfg *plugin, GError **error) plugin); g_io_channel_unref (channel); - - return TRUE; } @@ -441,8 +465,7 @@ init (NMSystemConfigInterface *config) 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 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c { /* interface implementation */ system_config_interface_class->get_connections = get_connections; + system_config_interface_class->get_secrets = get_secrets; system_config_interface_class->init = init; } diff --git a/system-settings/src/dbus-settings.c b/system-settings/src/dbus-settings.c index 642be6781..7c41be5ef 100644 --- a/system-settings/src/dbus-settings.c +++ b/system-settings/src/dbus-settings.c @@ -27,6 +27,7 @@ #include #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 @@ destroy_gvalue (gpointer data) 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 @@ add_one_secret_to_hash (NMSetting *setting, 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 @@ add_one_secret_to_hash (NMSetting *setting, 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 @@ connection_settings_get_secrets (NMConnectionSettings *sys_connection, { 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 @@ connection_settings_get_secrets (NMConnectionSettings *sys_connection, 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 @@ connection_settings_get_secrets (NMConnectionSettings *sys_connection, 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; } - 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) { + 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; + } + + 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 diff --git a/system-settings/src/dbus-settings.h b/system-settings/src/dbus-settings.h index bca096974..61d476a28 100644 --- a/system-settings/src/dbus-settings.h +++ b/system-settings/src/dbus-settings.h @@ -19,9 +19,14 @@ * (C) Copyright 2007 Red Hat, Inc. */ +#ifndef __DBUS_SETTINGS_H__ +#define __DBUS_SETTINGS_H__ + #include #include +#define NM_SS_PLUGIN_TAG "nm-ss-plugin" + typedef struct _NMSysconfigConnectionSettings NMSysconfigConnectionSettings; typedef struct _NMSysconfigConnectionSettingsClass NMSysconfigConnectionSettingsClass; @@ -92,3 +97,4 @@ void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings, void nm_sysconfig_settings_update_connection (NMSysconfigSettings *settings, NMConnection *connection); +#endif /* __DBUS_SETTINGS_H__ */ diff --git a/system-settings/src/main.c b/system-settings/src/main.c index 27b2b9372..e80348a9d 100644 --- a/system-settings/src/main.c +++ b/system-settings/src/main.c @@ -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 @@ connection_added_cb (NMSystemConfigInterface *config, 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 @@ connection_removed_cb (NMSystemConfigInterface *config, 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 @@ print_plugin_info (gpointer item, gpointer user_data) 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 @@ load_connections (gpointer user_data) 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