mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 02:35:25 +00:00
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. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3587 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
parent
bfa6b28b59
commit
e6a5d0be51
33
ChangeLog
33
ChangeLog
|
@ -1,3 +1,36 @@
|
|||
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.
|
||||
|
||||
2008-04-22 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
Patch from Charles R. Anderson (cra@wpi.edu)
|
||||
|
|
|
@ -308,6 +308,7 @@ system-settings/src/Makefile
|
|||
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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -107,6 +107,14 @@ static gboolean impl_exported_connection_get_id (NMExportedConnection *connectio
|
|||
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 @@ impl_exported_connection_get_id (NMExportedConnection *connection,
|
|||
{
|
||||
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 @@ impl_exported_connection_get_id (NMExportedConnection *connection,
|
|||
|
||||
static gboolean
|
||||
impl_exported_connection_get_settings (NMExportedConnection *connection,
|
||||
GHashTable **settings,
|
||||
GError **error)
|
||||
GHashTable **settings,
|
||||
GError **error)
|
||||
{
|
||||
NMExportedConnectionPrivate *priv;
|
||||
|
||||
|
@ -199,6 +207,32 @@ impl_exported_connection_get_settings (NMExportedConnection *connection,
|
|||
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,
|
||||
|
|
|
@ -37,6 +37,11 @@ typedef struct {
|
|||
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);
|
||||
|
|
|
@ -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
|
||||
|
|
28
system-settings/plugins/keyfile/Makefile.am
Normal file
28
system-settings/plugins/keyfile/Makefile.am
Normal file
|
@ -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
|
||||
|
310
system-settings/plugins/keyfile/plugin.c
Normal file
310
system-settings/plugins/keyfile/plugin.c
Normal file
|
@ -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);
|
||||
}
|
27
system-settings/plugins/keyfile/plugin.h
Normal file
27
system-settings/plugins/keyfile/plugin.h
Normal file
|
@ -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_ */
|
196
system-settings/plugins/keyfile/reader.c
Normal file
196
system-settings/plugins/keyfile/reader.c
Normal file
|
@ -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;
|
||||
}
|
11
system-settings/plugins/keyfile/reader.h
Normal file
11
system-settings/plugins/keyfile/reader.h
Normal file
|
@ -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 */
|
160
system-settings/plugins/keyfile/writer.c
Normal file
160
system-settings/plugins/keyfile/writer.c
Normal file
|
@ -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;
|
||||
}
|
11
system-settings/plugins/keyfile/writer.h
Normal file
11
system-settings/plugins/keyfile/writer.h
Normal file
|
@ -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 */
|
|
@ -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 @@ exported_connection_get_secrets (NMExportedConnection *sys_connection,
|
|||
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 @@ nm_sysconfig_exported_connection_new (NMConnection *connection,
|
|||
* 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 @@ static GPtrArray *
|
|||
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 @@ settings_finalize (GObject *object)
|
|||
|
||||
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 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_connection_added (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_sysconfig_settings_add_connection (NM_SYSCONFIG_SETTINGS (user_data), config, connection);
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_connection_removed (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
|
||||
|
||||
priv->in_plugin_signal_handler = TRUE;
|
||||
nm_sysconfig_settings_remove_connection (NM_SYSCONFIG_SETTINGS (user_data), connection);
|
||||
priv->in_plugin_signal_handler = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
plugin_connection_updated (NMSystemConfigInterface *config,
|
||||
NMConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data);
|
||||
|
||||
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
|
||||
unmanaged_devices_changed (NMSystemConfigInterface *config,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data);
|
||||
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
|
||||
g_hash_table_remove_all (priv->unmanaged_devices);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES);
|
||||
}
|
||||
|
||||
void
|
||||
nm_sysconfig_settings_add_plugin (NMSysconfigSettings *self,
|
||||
NMSystemConfigInterface *plugin)
|
||||
{
|
||||
NMSysconfigSettingsPrivate *priv;
|
||||
char *pname = NULL;
|
||||
char *pinfo = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
|
||||
g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin));
|
||||
|
||||
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
NMConnection *connection,
|
||||
DBusGConnection *g_connection)
|
||||
NMSystemConfigInterface *plugin,
|
||||
NMConnection *connection)
|
||||
{
|
||||
NMSysconfigSettingsPrivate *priv;
|
||||
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));
|
||||
|
||||
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__);
|
||||
if (find_existing_connection (self, connection)) {
|
||||
/* A plugin is lying to us */
|
||||
g_message ("Connection is already added, ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
priv->connections = g_slist_append (priv->connections, exported);
|
||||
exported = nm_sysconfig_exported_connection_new (connection, priv->g_connection);
|
||||
if (exported) {
|
||||
priv->connections = g_slist_append (priv->connections, exported);
|
||||
|
||||
nm_settings_signal_new_connection (NM_SETTINGS (self),
|
||||
NM_EXPORTED_CONNECTION (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__);
|
||||
}
|
||||
|
||||
static void
|
||||
remove_connection (NMSysconfigSettings *self,
|
||||
NMConnection *connection)
|
||||
void
|
||||
nm_sysconfig_settings_remove_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));
|
||||
|
||||
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;
|
||||
exported = find_existing_connection (self, connection);
|
||||
if (exported) {
|
||||
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
|
||||
|
||||
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;
|
||||
}
|
||||
priv->connections = g_slist_remove (priv->connections, exported);
|
||||
nm_exported_connection_signal_removed (exported);
|
||||
g_object_unref (exported);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
|
||||
NMConnection *connection)
|
||||
{
|
||||
remove_connection (settings, connection);
|
||||
}
|
||||
|
||||
void
|
||||
nm_sysconfig_settings_update_connection (NMSysconfigSettings *self,
|
||||
NMConnection *connection)
|
||||
NMConnection *connection)
|
||||
{
|
||||
NMSysconfigSettingsPrivate *priv;
|
||||
GHashTable *hash;
|
||||
GSList *iter;
|
||||
NMSysconfigExportedConnection *found = NULL;
|
||||
NMExportedConnection *exported;
|
||||
|
||||
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
|
||||
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;
|
||||
exported = find_existing_connection (self, connection);
|
||||
if (exported) {
|
||||
if (nm_connection_verify (connection)) {
|
||||
GHashTable *hash;
|
||||
|
||||
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (item));
|
||||
if (wrapped == connection) {
|
||||
found = item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
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__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the connection is no longer valid, it gets removed */
|
||||
if (!nm_connection_verify (connection)) {
|
||||
remove_connection (self, connection);
|
||||
return;
|
||||
}
|
||||
|
||||
hash = nm_connection_to_hash (connection);
|
||||
nm_exported_connection_signal_updated (NM_EXPORTED_CONNECTION (found), hash);
|
||||
g_hash_table_destroy (hash);
|
||||
}
|
||||
|
||||
GSList *
|
||||
nm_sysconfig_settings_get_connections (NMSysconfigSettings *self)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL);
|
||||
|
||||
return NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self)->connections;
|
||||
}
|
||||
|
||||
void
|
||||
nm_sysconfig_settings_update_unamanged_devices (NMSysconfigSettings *self,
|
||||
GSList *new_list)
|
||||
{
|
||||
NMSysconfigSettingsPrivate *priv;
|
||||
GSList *iter;
|
||||
|
||||
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
|
||||
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 @@ nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *self,
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 @@ struct _NMSysconfigSettingsClass
|
|||
|
||||
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);
|
||||
|
|
|
@ -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 @@ typedef struct {
|
|||
NMSysconfigSettings *settings;
|
||||
GMainLoop *loop;
|
||||
|
||||
GSList *plugins; /* In priority order */
|
||||
|
||||
GHashTable *wired_devices;
|
||||
} Application;
|
||||
|
||||
|
@ -84,71 +80,6 @@ plugins_error_quark (void)
|
|||
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 @@ find_plugin (GSList *list, const char *pname)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GSList *
|
||||
static gboolean
|
||||
load_plugins (Application *app, const char *plugins, GError **error)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
|
@ -180,7 +111,7 @@ load_plugins (Application *app, const char *plugins, GError **error)
|
|||
|
||||
plist = g_strsplit (plugins, ",", 0);
|
||||
if (!plist)
|
||||
return NULL;
|
||||
return FALSE;
|
||||
|
||||
for (pname = plist; *pname; pname++) {
|
||||
GModule *plugin;
|
||||
|
@ -225,44 +156,17 @@ load_plugins (Application *app, const char *plugins, GError **error)
|
|||
}
|
||||
|
||||
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_slist_foreach (list, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (list);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
free_plugin_connections (gpointer data)
|
||||
{
|
||||
GSList **connections = (GSList **) data;
|
||||
|
||||
g_slist_foreach (*connections, (GFunc) g_object_unref, NULL);
|
||||
g_slist_free (*connections);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -271,34 +175,6 @@ load_stuff (gpointer user_data)
|
|||
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 @@ add_default_dhcp_connection (gpointer user_data)
|
|||
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 @@ main (int argc, char **argv)
|
|||
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 @@ main (int argc, char **argv)
|
|||
|
||||
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);
|
||||
|
||||
|
|
|
@ -161,3 +161,35 @@ nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *confi
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,22 @@ struct _NMSystemConfigInterface {
|
|||
*/
|
||||
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 @@ GHashTable *nm_system_config_interface_get_secrets (NMSystemConfigInterface *con
|
|||
|
||||
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 */
|
||||
|
|
Loading…
Reference in a new issue