diff options
Diffstat (limited to 'src/settings/nm-settings.c')
| -rw-r--r-- | src/settings/nm-settings.c | 116 |
1 files changed, 114 insertions, 2 deletions
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 1ead4f8b..96564605 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -49,6 +49,7 @@ #include <nm-setting-serial.h> #include <nm-setting-vpn.h> #include <nm-setting-wired.h> +#include <nm-setting-adsl.h> #include <nm-setting-wireless.h> #include <nm-setting-wireless-security.h> #include <nm-setting-bond.h> @@ -68,6 +69,7 @@ #include "plugins/keyfile/plugin.h" #include "nm-agent-manager.h" #include "nm-settings-utils.h" +#include "nm-connection-provider.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -110,6 +112,12 @@ static void impl_settings_save_hostname (NMSettings *self, static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); +static void connection_provider_init (NMConnectionProvider *cp_class); + +G_DEFINE_TYPE_EXTENDED (NMSettings, nm_settings, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION_PROVIDER, connection_provider_init)) + + typedef struct { NMDBusManager *dbus_mgr; DBusGConnection *bus; @@ -127,8 +135,6 @@ typedef struct { GSList *unmanaged_specs; } NMSettingsPrivate; -G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT) - #define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate)) enum { @@ -186,6 +192,7 @@ load_connections (NMSettings *self) unmanaged_specs_changed (NULL, self); g_signal_emit (self, signals[CONNECTIONS_LOADED], 0); + g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTIONS_LOADED); } void @@ -674,6 +681,7 @@ connection_removed (NMSettingsConnection *obj, gpointer user_data) /* Re-emit for listeners like NMPolicy */ g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection); + g_signal_emit_by_name (NM_SETTINGS (user_data), NM_CP_SIGNAL_CONNECTION_REMOVED, connection); g_object_unref (connection); } @@ -701,6 +709,7 @@ connection_updated (NMSettingsConnection *connection, gpointer user_data) signals[CONNECTION_UPDATED], 0, connection); + g_signal_emit_by_name (NM_SETTINGS (user_data), NM_CP_SIGNAL_CONNECTION_UPDATED, connection); } static void @@ -849,6 +858,7 @@ claim_connection (NMSettings *self, if (priv->connections_loaded) { /* Internal added signal */ g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); + g_signal_emit_by_name (self, NM_CP_SIGNAL_CONNECTION_ADDED, connection); /* Exported D-Bus signal */ g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); @@ -1621,6 +1631,100 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device) /***************************************************************/ +static gint +best_connection_sort (gconstpointer a, gconstpointer b, gpointer user_data) +{ + NMSettingsConnection *ac = (NMSettingsConnection *) a; + NMSettingsConnection *bc = (NMSettingsConnection *) b; + guint64 ats, bts; + + if (!ac && bc) + return -1; + else if (ac && !bc) + return 1; + else if (!ac && !bc) + return 0; + + g_assert (ac && bc); + + /* In the future we may use connection priorities in addition to timestamps */ + ats = nm_settings_connection_get_timestamp (ac); + bts = nm_settings_connection_get_timestamp (bc); + + if (ats < bts) + return -1; + else if (ats > bts) + return 1; + return 0; +} + +static GSList * +get_best_connections (NMConnectionProvider *provider, + guint max_requested, + const char *ctype1, + const char *ctype2, + NMConnectionFilterFunc func, + gpointer func_data) +{ + NMSettings *self = NM_SETTINGS (provider); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *sorted = NULL; + GHashTableIter iter; + NMSettingsConnection *connection; + guint added = 0; + guint64 oldest = 0; + + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) { + if (ctype1 && !nm_connection_is_type (NM_CONNECTION (connection), ctype1)) + continue; + if (ctype2 && !nm_connection_is_type (NM_CONNECTION (connection), ctype2)) + continue; + if (func && !func (provider, NM_CONNECTION (connection), func_data)) + continue; + + /* Don't bother with a connection that's older than the oldest one in the list */ + if ( max_requested + && added >= max_requested + && nm_settings_connection_get_timestamp (connection) <= oldest) + continue; + + /* List is sorted with oldest first */ + sorted = g_slist_insert_sorted_with_data (sorted, connection, best_connection_sort, NULL); + added++; + + if (max_requested && added > max_requested) { + /* Over the limit, remove the oldest one */ + sorted = g_slist_delete_link (sorted, sorted); + added--; + } + + oldest = nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (sorted->data)); + } + + return g_slist_reverse (sorted); +} + +static const GSList * +get_connections (NMConnectionProvider *provider) +{ + static GSList *list = NULL; + NMSettings *self = NM_SETTINGS (provider); + GHashTableIter iter; + NMSettingsConnection *connection; + + /* Lazily free the list with every call so we can keep it 'const' for callers */ + g_slist_free (list); + list = NULL; + + g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &connection)) + list = g_slist_prepend (list, connection); + return g_slist_reverse (list); +} + +/***************************************************************/ + NMSettings * nm_settings_new (const char *config_file, const char **plugins, @@ -1660,6 +1764,13 @@ nm_settings_new (const char *config_file, } static void +connection_provider_init (NMConnectionProvider *cp_class) +{ + cp_class->get_best_connections = get_best_connections; + cp_class->get_connections = get_connections; +} + +static void nm_settings_init (NMSettings *self) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); @@ -1873,6 +1984,7 @@ nm_settings_class_init (NMSettingsClass *class) dbus_g_error_domain_register (NM_SETTING_PPP_ERROR, NULL, NM_TYPE_SETTING_PPP_ERROR); dbus_g_error_domain_register (NM_SETTING_PPPOE_ERROR, NULL, NM_TYPE_SETTING_PPPOE_ERROR); dbus_g_error_domain_register (NM_SETTING_SERIAL_ERROR, NULL, NM_TYPE_SETTING_SERIAL_ERROR); + dbus_g_error_domain_register (NM_SETTING_ADSL_ERROR, NULL, NM_TYPE_SETTING_ADSL_ERROR); dbus_g_error_domain_register (NM_SETTING_VPN_ERROR, NULL, NM_TYPE_SETTING_VPN_ERROR); dbus_g_error_domain_register (NM_SETTING_WIRED_ERROR, NULL, NM_TYPE_SETTING_WIRED_ERROR); dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR); |