NetworkManager r3587 - in trunk: . introspection libnm-glib system-settings/plugins system-settings/plugins/keyfile system-settings/src
- From: tambeti svn gnome org
- To: svn-commits-list gnome org
- Subject: NetworkManager r3587 - in trunk: . introspection libnm-glib system-settings/plugins system-settings/plugins/keyfile system-settings/src
- Date: Tue, 22 Apr 2008 15:48:03 +0100 (BST)
Author: tambeti
Date: Tue Apr 22 14:48:02 2008
New Revision: 3587
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3587&view=rev
Log:
2008-04-22 Tambet Ingo <tambet gmail com>
Implement GKeyFile system settings plugin.
Implement writing system settings (currently supported only by GKeyFile plugin).
* system-settings/src/main.c:
* system-settings/src/dbus-settings.c: Move the communication with plugins
from main.c to dbus-settings.c. Makes it possible to talk to all registered
plugins for adding/updating/removing connections.
* system-settings/src/nm-system-config-interface.c
(nm_system_config_interface_add_connection): Implement
(nm_system_config_interface_update_connection): Implement.
(nm_system_config_interface_remove_connection): Implement.
* system-settings/plugins/keyfile/Makefile.am:
* system-settings/plugins/keyfile/plugin.[ch]:
* system-settings/plugins/keyfile/writer.[ch]:
* system-settings/plugins/keyfile/reader.[ch]: Implement.
* system-settings/plugins/Makefile.am: Add GKeyFile plugin.
* configure.in: Generate GKeyFile Makefile.
* libnm-glib/nm-settings.c (impl_exported_connection_get_id): Fix a memory
corruption, need to duplicate the returned string.
(impl_exported_connection_update): Implement.
(impl_exported_connection_delete): Implement.
* introspection/nm-settings-system.xml: Add "AddConnection" method.
* introspection/nm-exported-connection.xml: Add "Update" and "Delete" methods.
Added:
trunk/system-settings/plugins/keyfile/
trunk/system-settings/plugins/keyfile/Makefile.am
trunk/system-settings/plugins/keyfile/plugin.c
trunk/system-settings/plugins/keyfile/plugin.h
trunk/system-settings/plugins/keyfile/reader.c
trunk/system-settings/plugins/keyfile/reader.h
trunk/system-settings/plugins/keyfile/writer.c
trunk/system-settings/plugins/keyfile/writer.h
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/introspection/nm-exported-connection.xml
trunk/introspection/nm-settings-system.xml
trunk/libnm-glib/nm-settings.c
trunk/libnm-glib/nm-settings.h
trunk/system-settings/plugins/Makefile.am
trunk/system-settings/src/dbus-settings.c
trunk/system-settings/src/dbus-settings.h
trunk/system-settings/src/main.c
trunk/system-settings/src/nm-system-config-interface.c
trunk/system-settings/src/nm-system-config-interface.h
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Tue Apr 22 14:48:02 2008
@@ -308,6 +308,7 @@
system-settings/plugins/Makefile
system-settings/plugins/ifcfg-fedora/Makefile
system-settings/plugins/ifcfg-suse/Makefile
+system-settings/plugins/keyfile/Makefile
test/Makefile
test/test-common/Makefile
initscript/Makefile
Modified: trunk/introspection/nm-exported-connection.xml
==============================================================================
--- trunk/introspection/nm-exported-connection.xml (original)
+++ trunk/introspection/nm-exported-connection.xml Tue Apr 22 14:48:02 2008
@@ -18,6 +18,25 @@
</arg>
</method>
+ <method name="Update">
+ <tp:docstring>
+ Update the connection.
+ </tp:docstring>
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_exported_connection_update"/>
+ <arg name="properties" type="a{sa{sv}}" direction="in">
+ <tp:docstring>
+ New connection properties.
+ </tp:docstring>
+ </arg>
+ </method>
+
+ <method name="Delete">
+ <tp:docstring>
+ Delete the connection.
+ </tp:docstring>
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_exported_connection_delete"/>
+ </method>
+
<method name="GetSettings">
<tp:docstring>
Get the settings maps describing this object.
Modified: trunk/introspection/nm-settings-system.xml
==============================================================================
--- trunk/introspection/nm-settings-system.xml (original)
+++ trunk/introspection/nm-settings-system.xml Tue Apr 22 14:48:02 2008
@@ -6,6 +6,18 @@
Implemented by the system settings service to provide additional settings to NetworkManager.
</tp:docstring>
+ <method name="AddConnection">
+ <tp:docstring>
+ Add new connection.
+ </tp:docstring>
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection"/>
+ <arg name="connection" type="a{sa{sv}}" direction="in">
+ <tp:docstring>
+ Connection properties.
+ </tp:docstring>
+ </arg>
+ </method>
+
<property name="UnmanagedDevices" type="ao" access="read">
<tp:docstring>
The list of HAL UDIs of devices that should not be managed by NetworkManager.
Modified: trunk/libnm-glib/nm-settings.c
==============================================================================
--- trunk/libnm-glib/nm-settings.c (original)
+++ trunk/libnm-glib/nm-settings.c Tue Apr 22 14:48:02 2008
@@ -107,6 +107,14 @@
static gboolean impl_exported_connection_get_settings (NMExportedConnection *connection,
GHashTable **settings,
GError **error);
+
+static gboolean impl_exported_connection_update (NMExportedConnection *connection,
+ GHashTable *new_settings,
+ GError *err);
+
+static gboolean impl_exported_connection_delete (NMExportedConnection *connection,
+ GError *err);
+
static void impl_exported_connection_get_secrets (NMExportedConnection *connection,
const gchar *setting_name,
const gchar **hints,
@@ -169,7 +177,7 @@
{
g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), FALSE);
- *id = (gchar *) nm_exported_connection_get_id (connection);
+ *id = g_strdup (nm_exported_connection_get_id (connection));
if (!*id) {
g_set_error (error, NM_SETTINGS_ERROR, 1,
"%s.%d - Could not get connection ID.",
@@ -182,8 +190,8 @@
static gboolean
impl_exported_connection_get_settings (NMExportedConnection *connection,
- GHashTable **settings,
- GError **error)
+ GHashTable **settings,
+ GError **error)
{
NMExportedConnectionPrivate *priv;
@@ -199,6 +207,32 @@
return TRUE;
}
+static gboolean
+impl_exported_connection_update (NMExportedConnection *connection,
+ GHashTable *new_settings,
+ GError *err)
+{
+ if (EXPORTED_CONNECTION_CLASS (connection)->update)
+ EXPORTED_CONNECTION_CLASS (connection)->update (connection, new_settings);
+ else
+ nm_connection_replace_settings (NM_EXPORTED_CONNECTION_GET_PRIVATE (connection)->wrapped, new_settings);
+
+ nm_exported_connection_signal_updated (connection, new_settings);
+
+ return TRUE;
+}
+
+static gboolean
+impl_exported_connection_delete (NMExportedConnection *connection, GError *err)
+{
+ if (EXPORTED_CONNECTION_CLASS (connection)->delete)
+ EXPORTED_CONNECTION_CLASS (connection)->delete (connection);
+
+ nm_exported_connection_signal_removed (connection);
+
+ return TRUE;
+}
+
static void
impl_exported_connection_get_secrets (NMExportedConnection *connection,
const gchar *setting_name,
Modified: trunk/libnm-glib/nm-settings.h
==============================================================================
--- trunk/libnm-glib/nm-settings.h (original)
+++ trunk/libnm-glib/nm-settings.h Tue Apr 22 14:48:02 2008
@@ -37,6 +37,11 @@
gboolean request_new,
DBusGMethodInvocation *context);
+ void (*update) (NMExportedConnection *connection,
+ GHashTable *new_settings);
+
+ void (*delete) (NMExportedConnection *connection);
+
/* signals */
void (* updated) (NMExportedConnection *connection, GHashTable *settings);
void (* removed) (NMExportedConnection *connection);
Modified: trunk/system-settings/plugins/Makefile.am
==============================================================================
--- trunk/system-settings/plugins/Makefile.am (original)
+++ trunk/system-settings/plugins/Makefile.am Tue Apr 22 14:48:02 2008
@@ -1,11 +1,13 @@
+SUBDIRS=keyfile
+
if TARGET_REDHAT
-SUBDIRS=ifcfg-fedora
+SUBDIRS+=ifcfg-fedora
endif
if TARGET_SUSE
-SUBDIRS=ifcfg-suse
+SUBDIRS+=ifcfg-suse
endif
if TARGET_MANDRIVA
-SUBDIRS=ifcfg-fedora
+SUBDIRS+=ifcfg-fedora
endif
Added: trunk/system-settings/plugins/keyfile/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/Makefile.am Tue Apr 22 14:48:02 2008
@@ -0,0 +1,28 @@
+
+pkglib_LTLIBRARIES = libnm-settings-plugin-keyfile.la
+
+libnm_settings_plugin_keyfile_la_SOURCES = \
+ plugin.c \
+ plugin.h \
+ reader.c \
+ reader.h \
+ writer.c \
+ writer.h
+
+libnm_settings_plugin_keyfile_la_CPPFLAGS = \
+ $(GLIB_CFLAGS) \
+ $(GMODULE_CFLAGS) \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED \
+ -I${top_srcdir}/system-settings/src \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/libnm-util \
+ -DKEYFILE_DIR=\""$(sysconfdir)/NetworkManager/system_config"\"
+
+libnm_settings_plugin_keyfile_la_LDFLAGS = -module -avoid-version
+libnm_settings_plugin_keyfile_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ $(GIO_LIBS) \
+ $(top_builddir)/libnm-util/libnm-util.la
+
Added: trunk/system-settings/plugins/keyfile/plugin.c
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/plugin.c Tue Apr 22 14:48:02 2008
@@ -0,0 +1,310 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <gmodule.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
+#include <nm-connection.h>
+#include <nm-setting.h>
+#include <nm-setting-connection.h>
+
+#include "plugin.h"
+#include "nm-system-config-interface.h"
+#include "reader.h"
+#include "writer.h"
+
+#define KEYFILE_PLUGIN_NAME "keyfile"
+#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2008 Red Hat, Inc. To report bugs please use the NetworkManager mailing list."
+
+static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (SCPluginKeyfile, sc_plugin_keyfile, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
+ system_config_interface_init))
+
+#define SC_PLUGIN_KEYFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfilePrivate))
+
+typedef struct {
+ GHashTable *hash;
+
+ GFileMonitor *monitor;
+ guint monitor_id;
+
+ gboolean disposed;
+} SCPluginKeyfilePrivate;
+
+static NMConnection *
+read_one_connection (NMSystemConfigInterface *config, const char *filename)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ char *full_path;
+ NMConnection *connection = NULL;
+
+ full_path = g_build_filename (KEYFILE_DIR, filename, NULL);
+ connection = connection_from_file (full_path);
+ if (connection)
+ g_hash_table_insert (priv->hash, g_strdup (filename), connection);
+
+ g_free (full_path);
+
+ return connection;
+}
+
+static void
+read_connections (NMSystemConfigInterface *config)
+{
+ GDir *dir;
+ GError *err = NULL;
+
+ dir = g_dir_open (KEYFILE_DIR, 0, &err);
+ if (dir) {
+ const char *item;
+
+ while ((item = g_dir_read_name (dir)))
+ read_one_connection (config, item);
+
+ g_dir_close (dir);
+ } else {
+ g_warning ("Can not read directory '%s': %s", KEYFILE_DIR, err->message);
+ g_error_free (err);
+ }
+}
+
+static void
+delete_connection (NMSystemConfigInterface *config, NMConnection *connection)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ NMSettingConnection *s_con;
+ char *filename;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ if (!s_con)
+ return;
+
+ filename = g_build_filename (KEYFILE_DIR, s_con->id, NULL);
+
+ if (g_hash_table_lookup (priv->hash, s_con->id)) {
+ if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+ /* Monitoring takes care of the rest */
+ g_unlink (filename);
+ else
+ g_warning ("File '%s' does not exist", filename);
+ }
+
+ g_free (filename);
+}
+
+/* Monitoring */
+
+static void
+dir_changed (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data);
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ char *name;
+ NMConnection *connection;
+
+ name = g_file_get_basename (file);
+ connection = g_hash_table_lookup (priv->hash, name);
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_DELETED:
+ if (connection) {
+ g_hash_table_remove (priv->hash, name);
+ g_signal_emit_by_name (config, "connection-removed", connection);
+ }
+ break;
+ case G_FILE_MONITOR_EVENT_CREATED:
+ case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
+ if (connection) {
+ /* Update */
+ char *full_path;
+ NMConnection *tmp;
+
+ full_path = g_file_get_path (file);
+ tmp = connection_from_file (full_path);
+ g_free (full_path);
+
+ if (tmp) {
+ GHashTable *settings;
+
+ settings = nm_connection_to_hash (tmp);
+
+ if (nm_connection_replace_settings (connection, settings))
+ g_signal_emit_by_name (config, "connection-updated", connection);
+
+ g_hash_table_destroy (settings);
+ g_object_unref (tmp);
+ }
+ } else {
+ /* New */
+ connection = read_one_connection (config, name);
+ if (connection)
+ g_signal_emit_by_name (config, "connection-added", connection);
+ }
+ break;
+ default:
+ break;
+ }
+
+ g_free (name);
+}
+
+static void
+setup_monitoring (NMSystemConfigInterface *config)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ GFile *file;
+ GFileMonitor *monitor;
+
+ priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+
+ file = g_file_new_for_path (KEYFILE_DIR);
+ monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
+ g_object_unref (file);
+
+ if (monitor) {
+ priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), config);
+ priv->monitor = monitor;
+ }
+}
+
+static void
+hash_to_slist (gpointer key, gpointer value, gpointer user_data)
+{
+ GSList **list = (GSList **) user_data;
+
+ *list = g_slist_prepend (*list, value);
+}
+
+/* Plugin */
+
+static GSList *
+get_connections (NMSystemConfigInterface *config)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+ GSList *connections = NULL;
+
+ if (!priv->hash) {
+ setup_monitoring (config);
+ read_connections (config);
+ }
+
+ g_hash_table_foreach (priv->hash, hash_to_slist, &connections);
+
+ return connections;
+}
+
+static void
+add_connection (NMSystemConfigInterface *config, NMConnection *connection)
+{
+ write_connection (connection);
+}
+
+static void
+update_connection (NMSystemConfigInterface *config, NMConnection *connection)
+{
+ write_connection (connection);
+}
+
+static void
+remove_connection (NMSystemConfigInterface *config, NMConnection *connection)
+{
+ delete_connection (config, connection);
+}
+
+/* GObject */
+
+static void
+sc_plugin_keyfile_init (SCPluginKeyfile *plugin)
+{
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+ g_value_set_string (value, KEYFILE_PLUGIN_NAME);
+ break;
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+ g_value_set_string (value, KEYFILE_PLUGIN_INFO);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (object);
+
+ if (priv->disposed)
+ return;
+
+ priv->disposed = TRUE;
+
+ if (priv->monitor) {
+ if (priv->monitor_id)
+ g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+
+ g_file_monitor_cancel (priv->monitor);
+ g_object_unref (priv->monitor);
+ }
+
+ g_hash_table_destroy (priv->hash);
+
+ G_OBJECT_CLASS (sc_plugin_keyfile_parent_class)->dispose (object);
+}
+
+static void
+sc_plugin_keyfile_class_init (SCPluginKeyfileClass *req_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (req_class);
+
+ g_type_class_add_private (req_class, sizeof (SCPluginKeyfilePrivate));
+
+ object_class->dispose = dispose;
+ object_class->get_property = get_property;
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
+ NM_SYSTEM_CONFIG_INTERFACE_NAME);
+
+ g_object_class_override_property (object_class,
+ NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO);
+}
+
+static void
+system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+{
+ /* interface implementation */
+ system_config_interface_class->get_connections = get_connections;
+ system_config_interface_class->add_connection = add_connection;
+ system_config_interface_class->update_connection = update_connection;
+ system_config_interface_class->remove_connection = remove_connection;
+}
+
+G_MODULE_EXPORT GObject *
+nm_system_config_factory (void)
+{
+ static SCPluginKeyfile *singleton = NULL;
+
+ if (!singleton)
+ singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
+ else
+ g_object_ref (singleton);
+
+ return G_OBJECT (singleton);
+}
Added: trunk/system-settings/plugins/keyfile/plugin.h
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/plugin.h Tue Apr 22 14:48:02 2008
@@ -0,0 +1,27 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef _PLUGIN_H_
+#define _PLUGIN_H_
+
+#include <glib-object.h>
+
+#define SC_TYPE_PLUGIN_KEYFILE (sc_plugin_keyfile_get_type ())
+#define SC_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfile))
+#define SC_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfileClass))
+#define SC_IS_PLUGIN_KEYFILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_PLUGIN_KEYFILE))
+#define SC_IS_PLUGIN_KEYFILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SC_TYPE_PLUGIN_KEYFILE))
+#define SC_PLUGIN_KEYFILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfileClass))
+
+typedef struct {
+ GObject parent;
+} SCPluginKeyfile;
+
+typedef struct {
+ GObjectClass parent;
+} SCPluginKeyfileClass;
+
+GType sc_plugin_keyfile_get_type (void);
+
+GQuark keyfile_plugin_error_quark (void);
+
+#endif /* _PLUGIN_H_ */
Added: trunk/system-settings/plugins/keyfile/reader.c
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/reader.c Tue Apr 22 14:48:02 2008
@@ -0,0 +1,196 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dbus/dbus-glib.h>
+#include <nm-setting.h>
+
+#include "reader.h"
+
+#define DBUS_TYPE_G_ARRAY_OF_UINT (dbus_g_type_get_collection ("GArray", G_TYPE_UINT))
+#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT))
+
+static void
+read_one_setting_value (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ gboolean secret,
+ gpointer user_data)
+{
+ GKeyFile *file = (GKeyFile *) user_data;
+ GType type;
+ GError *err = NULL;
+
+ if (!g_key_file_has_key (file, setting->name, key, &err)) {
+ if (err) {
+ g_warning ("Error loading setting '%s' value: %s", setting->name, err->message);
+ g_error_free (err);
+ }
+
+ return;
+ }
+
+ type = G_VALUE_TYPE (value);
+
+ if (type == G_TYPE_STRING) {
+ char *str_val;
+
+ str_val = g_key_file_get_string (file, setting->name, key, NULL);
+ g_object_set (setting, key, str_val, NULL);
+ g_free (str_val);
+ } else if (type == G_TYPE_UINT) {
+ int int_val;
+
+ int_val = g_key_file_get_integer (file, setting->name, key, NULL);
+ if (int_val < 0)
+ g_warning ("Casting negative value (%i) to uint", int_val);
+ g_object_set (setting, key, int_val, NULL);
+ } else if (type == G_TYPE_INT) {
+ int int_val;
+
+ int_val = g_key_file_get_integer (file, setting->name, key, NULL);
+ g_object_set (setting, key, int_val, NULL);
+ } else if (type == G_TYPE_BOOLEAN) {
+ gboolean bool_val;
+
+ bool_val = g_key_file_get_boolean (file, setting->name, key, NULL);
+ g_object_set (setting, key, bool_val, NULL);
+ } else if (type == G_TYPE_CHAR) {
+ int int_val;
+
+ int_val = g_key_file_get_integer (file, setting->name, key, NULL);
+ if (int_val < G_MININT8 || int_val > G_MAXINT8)
+ g_warning ("Casting value (%i) to char", int_val);
+
+ g_object_set (setting, key, int_val, NULL);
+ } else if (type == G_TYPE_UINT64) {
+ char *tmp_str;
+ guint64 uint_val;
+
+ tmp_str = g_key_file_get_value (file, setting->name, key, NULL);
+ uint_val = g_ascii_strtoull (tmp_str, NULL, 10);
+ g_object_set (setting, key, uint_val, NULL);
+ } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
+ gint *tmp;
+ GByteArray *array;
+ gsize length;
+ int i;
+
+ tmp = g_key_file_get_integer_list (file, setting->name, key, &length, NULL);
+
+ array = g_byte_array_sized_new (length);
+ for (i = 0; i < length; i++) {
+ int val = tmp[i];
+ unsigned char v = (unsigned char) (val & 0xFF);
+
+ if (val < 0 || val > 255)
+ g_warning ("Value out of range for a byte value");
+ else
+ g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
+ }
+
+ g_object_set (setting, key, array, NULL);
+ g_byte_array_free (array, TRUE);
+ } else if (type == dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) {
+ gchar **sa;
+ gsize length;
+ int i;
+ GSList *list = NULL;
+
+ sa = g_key_file_get_string_list (file, setting->name, key, &length, NULL);
+ for (i = 0; i < length; i++)
+ list = g_slist_prepend (list, sa[i]);
+
+ list = g_slist_reverse (list);
+ g_object_set (setting, key, list, NULL);
+
+ g_slist_free (list);
+ g_strfreev (sa);
+ } else if (type == dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) {
+ /* FIXME */
+ g_warning ("Implement me");
+ } else if (type == DBUS_TYPE_G_UINT_ARRAY) {
+ gint *tmp;
+ GArray *array;
+ gsize length;
+ int i;
+
+ tmp = g_key_file_get_integer_list (file, setting->name, key, &length, NULL);
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length);
+ for (i = 0; i < length; i++)
+ g_array_append_val (array, tmp[i]);
+
+ g_object_set (setting, key, array, NULL);
+ g_array_free (array, TRUE);
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
+ /* FIXME */
+ g_warning ("Implement me");
+ } else {
+ g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
+ setting->name, key, G_VALUE_TYPE_NAME (value));
+ }
+}
+
+static NMSetting *
+read_setting (GKeyFile *file, const char *name)
+{
+ NMSetting *setting;
+
+ setting = nm_connection_create_setting (name);
+ if (setting) {
+ nm_setting_enumerate_values (setting, read_one_setting_value, file);
+ } else
+ g_warning ("Invalid setting name '%s'", name);
+
+ return setting;
+}
+
+NMConnection *
+connection_from_file (const char *filename)
+{
+ GKeyFile *key_file;
+ struct stat statbuf;
+ gboolean bad_owner, bad_permissions;
+ NMConnection *connection = NULL;
+ GError *err = NULL;
+
+ if (stat (filename, &statbuf) != 0 || !S_ISREG (statbuf.st_mode))
+ return NULL;
+
+ bad_owner = getuid () != statbuf.st_uid;
+ bad_permissions = statbuf.st_mode & 0077;
+
+ if (bad_owner || bad_permissions) {
+ g_warning ("Ignorning insecure configuration file '%s'", filename);
+ return NULL;
+ }
+
+ key_file = g_key_file_new ();
+ if (g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, &err)) {
+ gchar **groups;
+ gsize length;
+ int i;
+
+ connection = nm_connection_new ();
+
+ groups = g_key_file_get_groups (key_file, &length);
+ for (i = 0; i < length; i++) {
+ NMSetting *setting;
+
+ setting = read_setting (key_file, groups[i]);
+ if (setting)
+ nm_connection_add_setting (connection, setting);
+ }
+
+ g_strfreev (groups);
+ } else {
+ g_warning ("Error parsing file '%s': %s", filename, err->message);
+ g_error_free (err);
+ }
+
+ g_key_file_free (key_file);
+
+ return connection;
+}
Added: trunk/system-settings/plugins/keyfile/reader.h
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/reader.h Tue Apr 22 14:48:02 2008
@@ -0,0 +1,11 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef _KEYFILE_PLUGIN_READER_H
+#define _KEYFILE_PLUGIN_READER_H
+
+#include <glib.h>
+#include <nm-connection.h>
+
+NMConnection *connection_from_file (const char *filename);
+
+#endif /* _KEYFILE_PLUGIN_READER_H */
Added: trunk/system-settings/plugins/keyfile/writer.c
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/writer.c Tue Apr 22 14:48:02 2008
@@ -0,0 +1,160 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dbus/dbus-glib.h>
+#include <nm-setting.h>
+#include <nm-setting-connection.h>
+
+#include "writer.h"
+
+#define DBUS_TYPE_G_ARRAY_OF_UINT (dbus_g_type_get_collection ("GArray", G_TYPE_UINT))
+#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT))
+
+static void
+write_setting_value (NMSetting *setting,
+ const char *key,
+ const GValue *value,
+ gboolean secret,
+ gpointer user_data)
+{
+ GKeyFile *file = (GKeyFile *) user_data;
+ GType type;
+
+ type = G_VALUE_TYPE (value);
+
+ if (type == G_TYPE_STRING) {
+ const char *str;
+
+ str = g_value_get_string (value);
+ if (str)
+ g_key_file_set_string (file, setting->name, key, str);
+ } else if (type == G_TYPE_UINT)
+ g_key_file_set_integer (file, setting->name, key, (int) g_value_get_uint (value));
+ else if (type == G_TYPE_INT)
+ g_key_file_set_integer (file, setting->name, key, g_value_get_int (value));
+ else if (type == G_TYPE_UINT64) {
+ char *numstr;
+
+ numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value));
+ g_key_file_set_value (file, setting->name, key, numstr);
+ g_free (numstr);
+ } else if (type == G_TYPE_BOOLEAN) {
+ g_key_file_set_boolean (file, setting->name, key, g_value_get_boolean (value));
+ } else if (type == G_TYPE_CHAR) {
+ g_key_file_set_integer (file, setting->name, key, (int) g_value_get_char (value));
+ } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
+ GByteArray *array;
+
+ array = (GByteArray *) g_value_get_boxed (value);
+ if (array && array->len > 0) {
+ int *tmp_array;
+ int i;
+
+ tmp_array = g_new (gint, array->len);
+ for (i = 0; i < array->len; i++)
+ tmp_array[i] = (int) array->data[i];
+
+ g_key_file_set_integer_list (file, setting->name, key, tmp_array, array->len);
+ g_free (tmp_array);
+ }
+ } else if (type == dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) {
+ GSList *list;
+ GSList *iter;
+
+ list = (GSList *) g_value_get_boxed (value);
+ if (list) {
+ char **array;
+ int i = 0;
+
+ array = g_new (char *, g_slist_length (list));
+ for (iter = list; iter; iter = iter->next)
+ array[i++] = iter->data;
+
+ g_key_file_set_string_list (file, setting->name, key, (const gchar **const) array, i);
+ g_free (array);
+ }
+ } else if (type == dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) {
+ /* FIXME */
+ g_warning ("Implement me");
+ } else if (type == DBUS_TYPE_G_UINT_ARRAY) {
+ GArray *array;
+
+ array = (GArray *) g_value_get_boxed (value);
+ if (array && array->len > 0) {
+ int *tmp_array;
+ int i;
+
+ tmp_array = g_new (gint, array->len);
+ for (i = 0; i < array->len; i++)
+ tmp_array[i] = (int) array->data[i];
+
+ g_key_file_set_integer_list (file, setting->name, key, tmp_array, array->len);
+ g_free (tmp_array);
+ }
+ } else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
+ GPtrArray *array;
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (array && array->len > 0) {
+ int i, j;
+ int* list;
+
+ list = g_new (int, array->len * 3);
+
+ for (i = 0, j = 0; i < array->len; i++) {
+ GArray *tuple = g_ptr_array_index (array, i);
+
+ list[j++] = g_array_index (tuple, guint32, 0);
+ list[j++] = g_array_index (tuple, guint32, 1);
+ list[j++] = tuple->len == 3 ? g_array_index (tuple, guint32, 2) : 0;
+ }
+
+ g_key_file_set_integer_list (file, setting->name, key, list, j);
+ g_free (list);
+ }
+ } else
+ g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
+ setting->name, key, g_type_name (type));
+}
+
+gboolean
+write_connection (NMConnection *connection)
+{
+ NMSettingConnection *s_con;
+ GKeyFile *key_file;
+ char *data;
+ gsize len;
+ gboolean success = FALSE;
+ GError *err = NULL;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ if (!s_con)
+ return success;
+
+ key_file = g_key_file_new ();
+ nm_connection_for_each_setting_value (connection, write_setting_value, key_file);
+ data = g_key_file_to_data (key_file, &len, &err);
+
+ if (!err) {
+ char *filename;
+
+ filename = g_build_filename (KEYFILE_DIR, s_con->id, NULL);
+ g_file_set_contents (filename, data, len, &err);
+ chmod (filename, S_IRUSR | S_IWUSR);
+ chown (filename, 0, 0);
+
+ g_free (filename);
+ success = TRUE;
+ }
+
+ if (err) {
+ g_warning ("Error while saving connection: %s", err->message);
+ g_error_free (err);
+ }
+
+ g_free (data);
+ g_key_file_free (key_file);
+
+ return success;
+}
Added: trunk/system-settings/plugins/keyfile/writer.h
==============================================================================
--- (empty file)
+++ trunk/system-settings/plugins/keyfile/writer.h Tue Apr 22 14:48:02 2008
@@ -0,0 +1,11 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef _KEYFILE_PLUGIN_WRITER_H
+#define _KEYFILE_PLUGIN_WRITER_H
+
+#include <glib.h>
+#include <nm-connection.h>
+
+gboolean write_connection (NMConnection *connection);
+
+#endif /* _KEYFILE_PLUGIN_WRITER_H */
Modified: trunk/system-settings/src/dbus-settings.c
==============================================================================
--- trunk/system-settings/src/dbus-settings.c (original)
+++ trunk/system-settings/src/dbus-settings.c Tue Apr 22 14:48:02 2008
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
/* NetworkManager system settings service
*
* SÃren Sandmann <sandmann daimi au dk>
@@ -28,9 +30,10 @@
#include "nm-dbus-glib-types.h"
#include "dbus-settings.h"
-#include "nm-system-config-interface.h"
#include "nm-utils.h"
+#define NM_SS_PLUGIN_TAG "nm-ss-plugin"
+
static void exported_connection_get_secrets (NMExportedConnection *connection,
const gchar *setting_name,
const gchar **hints,
@@ -93,7 +96,7 @@
goto error;
}
- plugin = g_object_get_data (G_OBJECT (connection), NM_SS_PLUGIN_TAG);
+ plugin = g_object_get_data (G_OBJECT (sys_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.",
@@ -174,11 +177,21 @@
* NMSettings
*/
+static gboolean
+impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, GError **err);
+
#include "nm-settings-system-glue.h"
typedef struct {
+ DBusGConnection *g_connection;
+ NMSystemConfigHalManager *hal_mgr;
+
+ GSList *plugins;
+ gboolean connections_loaded;
GSList *connections;
GHashTable *unmanaged_devices;
+
+ gboolean in_plugin_signal_handler;
} NMSysconfigSettingsPrivate;
G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS);
@@ -204,12 +217,11 @@
list_connections (NMSettings *settings)
{
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings);
- NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GPtrArray *connections;
GSList *iter;
connections = g_ptr_array_new ();
- for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
+ for (iter = nm_sysconfig_settings_get_connections (self); iter; iter = g_slist_next (iter)) {
NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data);
NMConnection *connection;
char *path;
@@ -238,6 +250,12 @@
g_hash_table_destroy (priv->unmanaged_devices);
+ g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->plugins);
+
+ g_object_unref (priv->hal_mgr);
+ dbus_g_connection_unref (priv->g_connection);
+
G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
}
@@ -367,142 +385,296 @@
}
NMSysconfigSettings *
-nm_sysconfig_settings_new (DBusGConnection *g_conn)
+nm_sysconfig_settings_new (DBusGConnection *g_conn, NMSystemConfigHalManager *hal_mgr)
{
NMSysconfigSettings *settings;
+ NMSysconfigSettingsPrivate *priv;
- settings = g_object_new (nm_sysconfig_settings_get_type (), NULL);
+ g_return_val_if_fail (g_conn != NULL, NULL);
+ g_return_val_if_fail (hal_mgr != NULL, NULL);
+
+ settings = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL);
dbus_g_connection_register_g_object (g_conn, NM_DBUS_PATH_SETTINGS, G_OBJECT (settings));
+
+ priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings);
+ priv->g_connection = dbus_g_connection_ref (g_conn);
+ priv->hal_mgr = g_object_ref (hal_mgr);
+
return settings;
}
-void
-nm_sysconfig_settings_add_connection (NMSysconfigSettings *self,
- NMConnection *connection,
- DBusGConnection *g_connection)
+static void
+plugin_connection_added (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ gpointer user_data)
{
- NMSysconfigSettingsPrivate *priv;
- NMSysconfigExportedConnection *exported;
+ nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), config, connection);
+}
- g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_CONNECTION (connection));
+static void
+plugin_connection_removed (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ gpointer user_data)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- exported = nm_sysconfig_exported_connection_new (connection, g_connection);
- if (!exported) {
- g_warning ("%s: couldn't export the connection!", __func__);
- return;
- }
+ priv->in_plugin_signal_handler = TRUE;
+ nm_sysconfig_settings_remove_connection (NM_SYSCONFIG_SETTINGS (user_data), connection);
+ priv->in_plugin_signal_handler = FALSE;
+}
- priv->connections = g_slist_append (priv->connections, exported);
+static void
+plugin_connection_updated (NMSystemConfigInterface *config,
+ NMConnection *connection,
+ gpointer user_data)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
- nm_settings_signal_new_connection (NM_SETTINGS (self),
- NM_EXPORTED_CONNECTION (exported));
+ priv->in_plugin_signal_handler = TRUE;
+ nm_sysconfig_settings_update_connection (NM_SYSCONFIG_SETTINGS (user_data), connection);
+ priv->in_plugin_signal_handler = FALSE;
}
static void
-remove_connection (NMSysconfigSettings *self,
- NMConnection *connection)
+unmanaged_devices_changed (NMSystemConfigInterface *config,
+ gpointer user_data)
{
- NMSysconfigSettingsPrivate *priv;
+ NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data);
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter;
- g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_CONNECTION (connection));
+ g_hash_table_remove_all (priv->unmanaged_devices);
- priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
- NMSysconfigExportedConnection *item = NM_SYSCONFIG_EXPORTED_CONNECTION (iter->data);
- NMExportedConnection *exported = NM_EXPORTED_CONNECTION (item);
- NMConnection *wrapped;
-
- wrapped = nm_exported_connection_get_connection (exported);
-
- if (wrapped == connection) {
- priv->connections = g_slist_remove_link (priv->connections, iter);
- nm_exported_connection_signal_removed (exported);
- g_object_unref (item);
- g_slist_free (iter);
- break;
+ /* Ask all the plugins for their unmanaged devices */
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ GSList *udis = nm_system_config_interface_get_unmanaged_devices (NM_SYSTEM_CONFIG_INTERFACE (iter->data));
+ GSList *udi_iter;
+
+ for (udi_iter = udis; udi_iter; udi_iter = udi_iter->next) {
+ if (!g_hash_table_lookup (priv->unmanaged_devices, udi_iter->data)) {
+ g_hash_table_insert (priv->unmanaged_devices,
+ udi_iter->data,
+ GUINT_TO_POINTER (1));
+ } else
+ g_free (udi_iter->data);
}
+
+ g_slist_free (udis);
}
-}
-void
-nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
- NMConnection *connection)
-{
- remove_connection (settings, connection);
+ g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES);
}
void
-nm_sysconfig_settings_update_connection (NMSysconfigSettings *self,
- NMConnection *connection)
+nm_sysconfig_settings_add_plugin (NMSysconfigSettings *self,
+ NMSystemConfigInterface *plugin)
{
NMSysconfigSettingsPrivate *priv;
- GHashTable *hash;
- GSList *iter;
- NMSysconfigExportedConnection *found = NULL;
+ char *pname = NULL;
+ char *pinfo = NULL;
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
- g_return_if_fail (NM_IS_CONNECTION (connection));
+ g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin));
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
- NMSysconfigExportedConnection *item = NM_SYSCONFIG_EXPORTED_CONNECTION (iter->data);
- NMConnection *wrapped;
- wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (item));
- if (wrapped == connection) {
- found = item;
- break;
- }
+ priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin));
+
+ g_signal_connect (plugin, "connection-added", G_CALLBACK (plugin_connection_added), self);
+ g_signal_connect (plugin, "connection-removed", G_CALLBACK (plugin_connection_removed), self);
+ g_signal_connect (plugin, "connection-updated", G_CALLBACK (plugin_connection_updated), self);
+
+ g_signal_connect (plugin, "unmanaged-devices-changed", G_CALLBACK (unmanaged_devices_changed), self);
+
+ nm_system_config_interface_init (plugin, priv->hal_mgr);
+
+ g_object_get (G_OBJECT (plugin),
+ NM_SYSTEM_CONFIG_INTERFACE_NAME, &pname,
+ NM_SYSTEM_CONFIG_INTERFACE_INFO, &pinfo,
+ NULL);
+
+ g_message ("Loaded plugin %s: %s", pname, pinfo);
+ g_free (pname);
+ g_free (pinfo);
+}
+
+static void
+connection_updated (NMExportedConnection *sys_connection,
+ GHashTable *new_settings,
+ gpointer user_data)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
+ NMSystemConfigInterface *plugin;
+ NMConnection *connection;
+
+ if (priv->in_plugin_signal_handler)
+ return;
+
+ connection = nm_exported_connection_get_connection (sys_connection);
+ plugin = (NMSystemConfigInterface *) g_object_get_data (G_OBJECT (sys_connection), NM_SS_PLUGIN_TAG);
+
+ if (plugin) {
+ nm_system_config_interface_update_connection (plugin, connection);
+ } else {
+ GSList *iter;
+
+ for (iter = priv->plugins; iter; iter = iter->next)
+ nm_system_config_interface_update_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), connection);
}
+}
- if (!found) {
- g_warning ("%s: cannot update unknown connection", __func__);
+static void
+connection_removed (NMExportedConnection *sys_connection,
+ gpointer user_data)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
+ NMSystemConfigInterface *plugin;
+ NMConnection *connection;
+
+ if (priv->in_plugin_signal_handler)
return;
+
+ connection = nm_exported_connection_get_connection (sys_connection);
+ plugin = (NMSystemConfigInterface *) g_object_get_data (G_OBJECT (sys_connection), NM_SS_PLUGIN_TAG);
+
+ if (plugin) {
+ nm_system_config_interface_remove_connection (plugin, connection);
+ } else {
+ GSList *iter;
+
+ for (iter = priv->plugins; iter; iter = iter->next)
+ nm_system_config_interface_remove_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), connection);
}
+}
- /* If the connection is no longer valid, it gets removed */
- if (!nm_connection_verify (connection)) {
- remove_connection (self, connection);
+static NMExportedConnection *
+find_existing_connection (NMSysconfigSettings *self, NMConnection *connection)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
+ NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data);
+ NMConnection *wrapped = nm_exported_connection_get_connection (exported);
+
+ if (wrapped == connection)
+ return exported;
+ }
+
+ return NULL;
+}
+
+void
+nm_sysconfig_settings_add_connection (NMSysconfigSettings *self,
+ NMSystemConfigInterface *plugin,
+ NMConnection *connection)
+{
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ NMSysconfigExportedConnection *exported;
+
+ g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ if (find_existing_connection (self, connection)) {
+ /* A plugin is lying to us */
+ g_message ("Connection is already added, ignoring");
return;
}
- hash = nm_connection_to_hash (connection);
- nm_exported_connection_signal_updated (NM_EXPORTED_CONNECTION (found), hash);
- g_hash_table_destroy (hash);
+ exported = nm_sysconfig_exported_connection_new (connection, priv->g_connection);
+ if (exported) {
+ priv->connections = g_slist_append (priv->connections, exported);
+
+ g_signal_connect (exported, "updated", G_CALLBACK (connection_updated), self);
+ g_signal_connect (exported, "removed", G_CALLBACK (connection_removed), self);
+
+ if (plugin)
+ g_object_set_data (G_OBJECT (exported), NM_SS_PLUGIN_TAG, plugin);
+
+ nm_settings_signal_new_connection (NM_SETTINGS (self), NM_EXPORTED_CONNECTION (exported));
+ } else
+ g_warning ("%s: couldn't export the connection!", __func__);
}
-GSList *
-nm_sysconfig_settings_get_connections (NMSysconfigSettings *self)
+void
+nm_sysconfig_settings_remove_connection (NMSysconfigSettings *self,
+ NMConnection *connection)
{
- g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL);
+ NMExportedConnection *exported;
- return NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self)->connections;
+ g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ exported = find_existing_connection (self, connection);
+ if (exported) {
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+
+ priv->connections = g_slist_remove (priv->connections, exported);
+ nm_exported_connection_signal_removed (exported);
+ g_object_unref (exported);
+ }
}
void
-nm_sysconfig_settings_update_unamanged_devices (NMSysconfigSettings *self,
- GSList *new_list)
+nm_sysconfig_settings_update_connection (NMSysconfigSettings *self,
+ NMConnection *connection)
{
- NMSysconfigSettingsPrivate *priv;
- GSList *iter;
+ NMExportedConnection *exported;
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ exported = find_existing_connection (self, connection);
+ if (exported) {
+ if (nm_connection_verify (connection)) {
+ GHashTable *hash;
+
+ hash = nm_connection_to_hash (connection);
+ nm_exported_connection_signal_updated (exported, hash);
+ g_hash_table_destroy (hash);
+ } else
+ /* If the connection is no longer valid, it gets removed */
+ nm_sysconfig_settings_remove_connection (self, connection);
+ } else
+ g_warning ("%s: cannot update unknown connection", __func__);
+}
+
+GSList *
+nm_sysconfig_settings_get_connections (NMSysconfigSettings *self)
+{
+ NMSysconfigSettingsPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL);
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
- g_hash_table_remove_all (priv->unmanaged_devices);
- for (iter = new_list; iter; iter = g_slist_next (iter)) {
- if (!g_hash_table_lookup (priv->unmanaged_devices, iter->data)) {
- g_hash_table_insert (priv->unmanaged_devices,
- g_strdup (iter->data),
- GUINT_TO_POINTER (1));
+ if (!priv->connections_loaded) {
+ GSList *iter;
+
+ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
+ NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
+ GSList *plugin_connections;
+ GSList *elt;
+
+ plugin_connections = nm_system_config_interface_get_connections (plugin);
+
+ // FIXME: ensure connections from plugins loaded with a lower priority
+ // get rejected when they conflict with connections from a higher
+ // priority plugin.
+
+ for (elt = plugin_connections; elt; elt = g_slist_next (elt))
+ nm_sysconfig_settings_add_connection (self, plugin, NM_CONNECTION (elt->data));
+
+ g_slist_free (plugin_connections);
}
+
+ /* FIXME: Bad hack */
+ unmanaged_devices_changed (NULL, self);
+
+ priv->connections_loaded = TRUE;
}
- g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES);
+
+ return priv->connections;
}
gboolean
@@ -519,3 +691,36 @@
return TRUE;
}
+static gboolean
+impl_settings_add_connection (NMSysconfigSettings *self, GHashTable *hash, GError **err)
+{
+ NMConnection *connection;
+
+ connection = nm_connection_new_from_hash (hash);
+ if (connection) {
+ NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
+ GSList *iter;
+
+ /* Here's how it works:
+ 1) plugin writes a connection.
+ 2) plugin notices that a new connection is available for reading.
+ 3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal.
+ 4) NMSysconfigSettings receives the signal and adds it to it's connection list.
+
+ This does not work if none of the plugins is able to write, but that is sort of by design -
+ if the connection is not saved, it won't be available after reboot and that would be very
+ inconsistent. Perhaps we should fail this call here as well, but with multiple plugins,
+ it's not very clear which failures we can ignore and which ones we can't.
+ */
+
+ for (iter = priv->plugins; iter; iter = iter->next)
+ nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), connection);
+
+ g_object_unref (connection);
+ return TRUE;
+ } else {
+ /* Invalid connection hash */
+ /* FIXME: Set error */
+ return FALSE;
+ }
+}
Modified: trunk/system-settings/src/dbus-settings.h
==============================================================================
--- trunk/system-settings/src/dbus-settings.h (original)
+++ trunk/system-settings/src/dbus-settings.h Tue Apr 22 14:48:02 2008
@@ -25,7 +25,8 @@
#include <nm-connection.h>
#include <nm-settings.h>
-#define NM_SS_PLUGIN_TAG "nm-ss-plugin"
+#include "nm-system-config-interface.h"
+#include "nm-system-config-hal-manager.h"
typedef struct _NMSysconfigExportedConnection NMSysconfigExportedConnection;
typedef struct _NMSysconfigExportedConnectionClass NMSysconfigExportedConnectionClass;
@@ -85,11 +86,15 @@
GType nm_sysconfig_settings_get_type (void);
-NMSysconfigSettings *nm_sysconfig_settings_new (DBusGConnection *g_conn);
+NMSysconfigSettings *nm_sysconfig_settings_new (DBusGConnection *g_conn,
+ NMSystemConfigHalManager *hal_mgr);
+
+void nm_sysconfig_settings_add_plugin (NMSysconfigSettings *settings,
+ NMSystemConfigInterface *plugin);
void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings,
- NMConnection *connection,
- DBusGConnection *g_connection);
+ NMSystemConfigInterface *plugin,
+ NMConnection *connection);
void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
NMConnection *connection);
Modified: trunk/system-settings/src/main.c
==============================================================================
--- trunk/system-settings/src/main.c (original)
+++ trunk/system-settings/src/main.c Tue Apr 22 14:48:02 2008
@@ -47,8 +47,6 @@
#include "nm-system-config-hal-manager-private.h"
#include "nm-system-config-interface.h"
-#define NM_SS_CONNECTIONS_TAG "nm-ss-connections"
-
typedef struct {
DBusConnection *connection;
DBusGConnection *g_connection;
@@ -60,8 +58,6 @@
NMSysconfigSettings *settings;
GMainLoop *loop;
- GSList *plugins; /* In priority order */
-
GHashTable *wired_devices;
} Application;
@@ -84,71 +80,6 @@
return error_quark;
}
-
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-connection_updated_cb (NMSystemConfigInterface *config,
- NMConnection *connection,
- Application *app)
-{
- nm_sysconfig_settings_update_connection (app->settings, connection);
-}
-
-static void
-unmanaged_devices_changed_cb (NMSystemConfigInterface *config,
- Application *app)
-{
- GSList *udis = NULL, *temp, *iter;
-
- /* Ask all the plugins for their unmanaged devices */
- for (iter = app->plugins; iter; iter = g_slist_next (iter)) {
- temp = nm_system_config_interface_get_unmanaged_devices (NM_SYSTEM_CONFIG_INTERFACE (iter->data));
- udis = g_slist_concat (udis, temp);
- }
-
- nm_sysconfig_settings_update_unamanged_devices (app->settings, udis);
- g_slist_foreach (udis, (GFunc) g_free, NULL);
- g_slist_free (udis);
-}
-
-static void
-register_plugin (Application *app, NMSystemConfigInterface *plugin)
-{
- g_signal_connect (plugin, "connection-added", (GCallback) connection_added_cb, app);
- g_signal_connect (plugin, "connection-removed", (GCallback) connection_removed_cb, app);
- g_signal_connect (plugin, "connection-updated", (GCallback) connection_updated_cb, app);
-
- g_signal_connect (plugin, "unmanaged-devices-changed", (GCallback) unmanaged_devices_changed_cb, app);
-
- nm_system_config_interface_init (plugin, app->hal_mgr);
-}
-
static GObject *
find_plugin (GSList *list, const char *pname)
{
@@ -171,7 +102,7 @@
return NULL;
}
-static GSList *
+static gboolean
load_plugins (Application *app, const char *plugins, GError **error)
{
GSList *list = NULL;
@@ -180,7 +111,7 @@
plist = g_strsplit (plugins, ",", 0);
if (!plist)
- return NULL;
+ return FALSE;
for (pname = plist; *pname; pname++) {
GModule *plugin;
@@ -225,44 +156,17 @@
}
g_module_make_resident (plugin);
- g_object_set_data_full (obj, "nm-ss-plugin", plugin, (GDestroyNotify) g_module_close);
- register_plugin (app, NM_SYSTEM_CONFIG_INTERFACE (obj));
+ g_object_weak_ref (obj, (GWeakNotify) g_module_close, plugin);
+ nm_sysconfig_settings_add_plugin (app->settings, NM_SYSTEM_CONFIG_INTERFACE (obj));
list = g_slist_append (list, obj);
}
-
- g_strfreev (plist);
- return list;
-}
-static void
-print_plugin_info (gpointer item, gpointer user_data)
-{
- NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (item);
- char *pname;
- char *pinfo;
-
- g_object_get (G_OBJECT (plugin),
- NM_SYSTEM_CONFIG_INTERFACE_NAME,
- &pname,
- NULL);
-
- g_object_get (G_OBJECT (plugin),
- NM_SYSTEM_CONFIG_INTERFACE_INFO,
- &pinfo,
- NULL);
-
- g_message (" %s: %s", pname, pinfo);
- g_free (pname);
- g_free (pinfo);
-}
+ g_strfreev (plist);
-static void
-free_plugin_connections (gpointer data)
-{
- GSList **connections = (GSList **) data;
+ g_slist_foreach (list, (GFunc) g_object_unref, NULL);
+ g_slist_free (list);
- g_slist_foreach (*connections, (GFunc) g_object_unref, NULL);
- g_slist_free (*connections);
+ return TRUE;
}
static gboolean
@@ -271,34 +175,6 @@
Application *app = (Application *) user_data;
GSList *devs, *iter;
- g_return_val_if_fail (app != NULL, FALSE);
-
- for (iter = app->plugins; iter; iter = g_slist_next (iter)) {
- NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
- GSList *plugin_connections, **connections;
- GSList *elt;
-
- 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.
-
- 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);
- }
-
- g_slist_free (plugin_connections);
- }
-
- unmanaged_devices_changed_cb (NULL, app);
-
/* Grab wired devices to make default DHCP connections for them if needed */
devs = nm_system_config_hal_manager_get_devices_of_type (app->hal_mgr, DEVICE_TYPE_802_3_ETHERNET);
for (iter = devs; iter; iter = g_slist_next (iter))
@@ -480,9 +356,8 @@
g_byte_array_append (s_wired->mac_address, info->mac->data, ETH_ALEN);
nm_connection_add_setting (info->connection, NM_SETTING (s_wired));
- nm_sysconfig_settings_add_connection (info->app->settings,
- info->connection,
- info->app->g_connection);
+ nm_sysconfig_settings_add_connection (info->app->settings, NULL, info->connection);
+
return FALSE;
ignore:
@@ -782,27 +657,23 @@
if (!dbus_init (app))
return -1;
- app->settings = nm_sysconfig_settings_new (app->g_connection);
+ app->hal_mgr = nm_system_config_hal_manager_get (app->g_connection);
+ app->settings = nm_sysconfig_settings_new (app->g_connection, app->hal_mgr);
app->wired_devices = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, wired_device_info_destroy);
- app->hal_mgr = nm_system_config_hal_manager_get (app->g_connection);
g_signal_connect (G_OBJECT (app->hal_mgr), "device-added",
G_CALLBACK (device_added_cb), app);
g_signal_connect (G_OBJECT (app->hal_mgr), "device-removed",
G_CALLBACK (device_removed_cb), app);
/* Load the plugins; fail if a plugin is not found. */
- app->plugins = load_plugins (app, plugins, &error);
+ load_plugins (app, plugins, &error);
if (error) {
- g_slist_foreach (app->plugins, (GFunc) g_object_unref, NULL);
- g_slist_free (app->plugins);
g_warning ("Error: %d - %s", error->code, error->message);
return -1;
}
g_free (plugins);
- g_message ("Loaded plugins:");
- g_slist_foreach (app->plugins, print_plugin_info, NULL);
g_idle_add (load_stuff, app);
@@ -810,9 +681,6 @@
g_hash_table_destroy (app->wired_devices);
- g_slist_foreach (app->plugins, (GFunc) g_object_unref, NULL);
- g_slist_free (app->plugins);
-
g_object_unref (app->settings);
g_object_unref (app->hal_mgr);
Modified: trunk/system-settings/src/nm-system-config-interface.c
==============================================================================
--- trunk/system-settings/src/nm-system-config-interface.c (original)
+++ trunk/system-settings/src/nm-system-config-interface.c Tue Apr 22 14:48:02 2008
@@ -161,3 +161,35 @@
return NULL;
}
+void
+nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
+ NMConnection *connection)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection)
+ NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection);
+}
+
+void
+nm_system_config_interface_update_connection (NMSystemConfigInterface *config,
+ NMConnection *connection)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->update_connection)
+ NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->update_connection (config, connection);
+}
+
+void
+nm_system_config_interface_remove_connection (NMSystemConfigInterface *config,
+ NMConnection *connection)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->remove_connection)
+ NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->remove_connection (config, connection);
+}
Modified: trunk/system-settings/src/nm-system-config-interface.h
==============================================================================
--- trunk/system-settings/src/nm-system-config-interface.h (original)
+++ trunk/system-settings/src/nm-system-config-interface.h Tue Apr 22 14:48:02 2008
@@ -99,6 +99,22 @@
*/
GSList * (*get_unmanaged_devices) (NMSystemConfigInterface *config);
+ /*
+ * Add a new connection.
+ */
+ void (*add_connection) (NMSystemConfigInterface *config, NMConnection *connection);
+
+ /*
+ * Update the connection.
+ */
+ void (*update_connection) (NMSystemConfigInterface *config, NMConnection *connection);
+
+ /*
+ * Remove the connection.
+ */
+ void (*remove_connection) (NMSystemConfigInterface *config, NMConnection *connection);
+
+
/* Signals */
/* Emitted when a new connection has been found by the plugin */
@@ -127,6 +143,15 @@
GSList *nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config);
+void nm_system_config_interface_add_connection (NMSystemConfigInterface *config,
+ NMConnection *connection);
+
+void nm_system_config_interface_update_connection (NMSystemConfigInterface *config,
+ NMConnection *connection);
+
+void nm_system_config_interface_remove_connection (NMSystemConfigInterface *config,
+ NMConnection *connection);
+
G_END_DECLS
#endif /* NM_SYSTEM_CONFIG_INTERFACE_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]