From 9d1131ea41b921ed876bb29c0aa26da4cf6d9e31 Mon Sep 17 00:00:00 2001
From: Tambet Ingo <tambet@gmail.com>
Date: Thu, 23 Apr 2009 12:54:50 +0300
Subject: [PATCH] openSUSE merge.


diff --git a/system-settings/plugins/ifcfg-suse/Makefile.am b/system-settings/plugins/ifcfg-suse/Makefile.am
index 7f1043f..6fa6723 100644
--- a/system-settings/plugins/ifcfg-suse/Makefile.am
+++ b/system-settings/plugins/ifcfg-suse/Makefile.am
@@ -39,3 +39,46 @@ libnm_settings_plugin_ifcfg_suse_la_LIBADD += \
 	$(GIO_LIBS)
 endif
 
+BUILT_SOURCES = \
+	writer.h \
+	writer.c \
+	sha1.h \
+	sha1.c
+
+writer.h: $(top_srcdir)/system-settings/plugins/keyfile/io/writer.h
+	ln -s $< $@
+writer.c: $(top_srcdir)/system-settings/plugins/keyfile/io/writer.c
+	ln -s $< $@
+sha1.h: $(top_srcdir)/system-settings/src/sha1.h
+	ln -s $< $@
+sha1.c: $(top_srcdir)/system-settings/src/sha1.c
+	ln -s $< $@
+
+libexec_PROGRAMS = nm-opensuse-sysconfig-merge
+nm_opensuse_sysconfig_merge_SOURCES = \
+	parser.h \
+	parser.c \
+	sha1.h \
+	sha1.c \
+	shvar.h \
+	shvar.c \
+	writer.h \
+	writer.c \
+	nm-opensuse-sysconfig-merge.c
+
+nm_opensuse_sysconfig_merge_CPPFLAGS = \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	$(HAL_CFLAGS) \
+	-I$(top_srcdir)/include \
+	-I$(top_srcdir)/libnm-util \
+	-I$(top_srcdir)/libnm-glib \
+	-DSYSCONFDIR=\"$(sysconfdir)\" \
+	-DKEYFILE_DIR=\"$(sysconfdir)/NetworkManager/system-connections\"
+
+nm_opensuse_sysconfig_merge_LDADD = \
+	$(GLIB_LIBS) \
+	$(HAL_LIBS) \
+	$(DBUS_LIBS) \
+	$(top_builddir)/libnm-util/libnm-util.la \
+	$(top_builddir)/libnm-glib/libnm_glib.la
diff --git a/system-settings/plugins/ifcfg-suse/nm-opensuse-sysconfig-merge.c b/system-settings/plugins/ifcfg-suse/nm-opensuse-sysconfig-merge.c
new file mode 100644
index 0000000..617a935
--- /dev/null
+++ b/system-settings/plugins/ifcfg-suse/nm-opensuse-sysconfig-merge.c
@@ -0,0 +1,166 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include <string.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <libhal.h>
+#include <NetworkManager.h>
+#include <nm-connection.h>
+#include <nm-setting-ip4-config.h>
+
+#include "parser.h"
+#include "writer.h"
+
+#define CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
+#define CONF_DIR  SYSCONFDIR "/sysconfig/network"
+
+/* Connections */
+
+static NMDeviceType
+get_device_type (const char *iface)
+{
+    DBusGConnection *bus;
+    LibHalContext *hal_ctx;
+    DBusError error;
+    NMDeviceType type = NM_DEVICE_TYPE_UNKNOWN;
+
+    bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+    if (!bus) {
+        g_warning ("Could not connect to system bus.");
+        return type;
+    }
+
+    hal_ctx = libhal_ctx_new ();
+    libhal_ctx_set_dbus_connection (hal_ctx, dbus_g_connection_get_connection (bus));
+
+    dbus_error_init (&error);
+    if (libhal_ctx_init (hal_ctx, &error)) {
+        char **devices = NULL;
+        int num_devices = 0;
+
+        devices = libhal_manager_find_device_string_match (hal_ctx, "net.interface",
+                                                           iface, &num_devices, &error);
+
+        if (num_devices == 1) {
+            char *type_str;
+
+            type_str = libhal_device_get_property_string (hal_ctx, devices[0], "info.category", NULL);
+            if (type_str) {
+                if (!strcmp (type_str, "net.80203"))
+                    type = NM_DEVICE_TYPE_ETHERNET;
+                else if (!strcmp (type_str, "net.80211"))
+                    type = NM_DEVICE_TYPE_WIFI;
+                else
+                    g_warning ("Unsupported device type '%s'", type_str);
+
+                libhal_free_string (type_str);
+            }
+        } else
+            g_warning ("Device '%s' not found", iface);
+
+        if (devices)
+            libhal_free_string_array (devices);
+    } else
+        g_warning ("HAL initialization failed: %s", error.message);
+
+    if (dbus_error_is_set (&error))
+        dbus_error_free (&error);
+
+    libhal_ctx_shutdown (hal_ctx, NULL);
+    libhal_ctx_free (hal_ctx);
+
+    dbus_g_connection_unref (bus);
+
+    return type;
+}
+
+static NMConnection *
+read_connection (const char *iface, NMDeviceType type)
+{
+    NMConnection *connection;
+
+    connection = parse_ifcfg (iface, type);
+    if (connection) {
+        NMSettingIP4Config *ip4;
+
+        ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+        if (ip4 && !strcmp (nm_setting_ip4_config_get_method (ip4), NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) {
+            /* static IP connection, merge the default route and DNS information */
+
+            if (nm_setting_ip4_config_get_num_addresses (ip4) > 0)
+                nm_ip4_address_set_gateway (nm_setting_ip4_config_get_address (ip4, 0),
+                                            parser_parse_routes (CONF_DIR "/routes"));
+
+            parser_parse_resolv_conf (ip4, SYSCONFDIR "/resolv.conf");
+        }
+    }
+
+    return connection;
+}
+
+static void
+connections_merge (void)
+{
+    GDir *dir;
+
+    dir = g_dir_open (CONF_DIR, 0, NULL);
+    if (dir) {
+        const char *f;
+
+        while ((f = g_dir_read_name (dir)) != NULL) {
+            if (g_str_has_prefix (f, "ifcfg-") && 
+                strcmp (f, "ifcfg-lo") &&
+                !g_str_has_suffix (f, "~") &&
+                !g_str_has_suffix (f, ".bak")) {
+
+                const char *iface = f + 6;
+                NMDeviceType type = get_device_type (iface);
+
+                if (type != NM_DEVICE_TYPE_UNKNOWN) {
+                    NMConnection *connection;
+
+                    g_print ("Converting '%s' (interface: %s: type: %d)\n", f, iface, type);
+
+                    connection = read_connection (iface, type);
+                    if (connection) {
+                        char *path = NULL;
+                        GError *error = NULL;
+
+                        write_connection (connection, KEYFILE_DIR, 0, 0, &path, &error);
+                        if (error) {
+                            g_warning ("%s", error->message);
+                            g_error_free (error);
+                        }
+
+                        g_free (path);
+                        g_object_unref (connection);
+                    }
+                }
+            }
+        }
+
+        g_dir_close (dir);
+    } else
+        g_warning ("Could not open " CONF_DIR " directory");
+}
+
+/* */
+
+int
+main (int argc, char *argv[])
+{
+    int i;
+
+    g_type_init ();
+    g_set_prgname (argv[0]);
+
+    for (i = 1; i < argc; i++) {
+        const char *a = argv[i];
+
+        if (a && !strcmp (a, "--connections"))
+            connections_merge ();
+    }
+
+    return 0;
+}
diff --git a/system-settings/plugins/ifcfg-suse/parser.c b/system-settings/plugins/ifcfg-suse/parser.c
index e9fc57b..461a48f 100644
--- a/system-settings/plugins/ifcfg-suse/parser.c
+++ b/system-settings/plugins/ifcfg-suse/parser.c
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
+#include <netinet/in.h>
 #include <ctype.h>
 #include <sys/inotify.h>
 
@@ -50,6 +51,17 @@
 
 /* Common */
 
+static GQuark
+ifcfg_plugin_error_quark (void)
+{
+	static GQuark error_quark = 0;
+
+	if (G_UNLIKELY (error_quark == 0))
+		error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark");
+
+	return error_quark;
+}
+
 static gboolean
 get_int (const char *str, int *value)
 {
@@ -746,3 +758,60 @@ parser_parse_routes (const char *filename)
 
 	return route;
 }
+
+gboolean
+parser_parse_resolv_conf (NMSettingIP4Config *setting, const char *filename)
+{
+	GRegex *r;
+	GMatchInfo *match = NULL;
+	gchar *contents = NULL;
+	GError *error = NULL;
+	gsize len;
+
+	g_return_val_if_fail (NM_IS_SETTING_IP4_CONFIG (setting), FALSE);
+	g_return_val_if_fail (filename != NULL, FALSE);
+
+	if (!g_file_get_contents (filename, &contents, &len, &error)) {
+		g_warning ("Could not read %s: %s", filename, error ? error->message : "Unknown error");
+
+		if (error)
+			g_error_free (error);
+
+		return FALSE;
+	}
+
+	/* DNS */
+	r = g_regex_new ("^\\s*nameserver\\s+(\\S+)", G_REGEX_MULTILINE, 0, NULL);
+	g_regex_match_full (r, contents, len, 0, 0, &match, NULL);
+	while (g_match_info_matches (match)) {
+		struct in_addr addr = { 0 };
+		gchar *word = g_match_info_fetch (match, 1);
+
+		if (inet_aton (word, &addr) == 0)
+			g_warning ("Invalid DNS: %s", word);
+		else
+			nm_setting_ip4_config_add_dns (setting, addr.s_addr);
+
+		g_free (word);
+		g_match_info_next (match, NULL);
+	}
+	g_match_info_free (match);
+	g_regex_unref (r);
+
+	/* Searches*/
+	r = g_regex_new ("^\\s*search\\s+(\\S+)", G_REGEX_MULTILINE, 0, NULL);
+	g_regex_match_full (r, contents, len, 0, 0, &match, NULL);
+	while (g_match_info_matches (match)) {
+		gchar *word = g_match_info_fetch (match, 1);
+
+		nm_setting_ip4_config_add_dns_search (setting, word);
+		g_free (word);
+		g_match_info_next (match, NULL);
+	}
+	g_match_info_free (match);
+	g_regex_unref (r);
+
+	g_free (contents);
+
+	return TRUE;
+}
diff --git a/system-settings/plugins/ifcfg-suse/parser.h b/system-settings/plugins/ifcfg-suse/parser.h
index b216f77..f1dc16d 100644
--- a/system-settings/plugins/ifcfg-suse/parser.h
+++ b/system-settings/plugins/ifcfg-suse/parser.h
@@ -25,6 +25,7 @@
 #include <glib.h>
 #include <NetworkManager.h>
 #include <nm-connection.h>
+#include <nm-setting-ip4-config.h>
 
 #define IFCFG_TAG "ifcfg-"
 #define BAK_TAG ".bak"
@@ -33,5 +34,7 @@ NMConnection *parse_ifcfg (const char *iface, NMDeviceType type);
 gboolean parser_ignore_device (const char *iface);
 
 guint32        parser_parse_routes (const char *filename);
+gboolean       parser_parse_resolv_conf (NMSettingIP4Config *setting,
+					 const char *filename);
 
 #endif /* _PARSER_H_ */
diff --git a/system-settings/plugins/ifcfg-suse/plugin.c b/system-settings/plugins/ifcfg-suse/plugin.c
index 812cdf3..e35e871 100644
--- a/system-settings/plugins/ifcfg-suse/plugin.c
+++ b/system-settings/plugins/ifcfg-suse/plugin.c
@@ -26,8 +26,6 @@
 #include <glib-object.h>
 #include <glib/gi18n.h>
 #include <string.h>
-#include <sys/inotify.h>
-#include <unistd.h>
 
 #ifndef NO_GIO
 #include <gio/gio.h>
@@ -35,18 +33,17 @@
 #include <gfilemonitor/gfilemonitor.h>
 #endif
 
-#include <nm-setting-connection.h>
-#include <nm-setting-ip4-config.h>
-
 #include "plugin.h"
-#include "parser.h"
-#include "nm-suse-connection.h"
 #include "nm-system-config-interface.h"
 
 #define IFCFG_PLUGIN_NAME "ifcfg-suse"
-#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc.  To report bugs please use the NetworkManager mailing list."
+#define IFCFG_PLUGIN_INFO "(C) 2008 Novell, Inc.	To report bugs please use the NetworkManager mailing list."
 #define IFCFG_DIR SYSCONFDIR "/sysconfig/network"
 
+#define CONF_DIR  SYSCONFDIR "/sysconfig/network"
+#define CONF_DHCP CONF_DIR "/dhcp"
+#define HOSTNAME_FILE "/etc/HOSTNAME"
+
 static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
 
 G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
@@ -59,313 +56,151 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
 #define IFCFG_FILE_PATH_TAG "ifcfg-file-path"
 
 typedef struct {
-	DBusGConnection *dbus_connection;
-	NMSystemConfigHalManager *hal_manager;
-
-	gboolean initialized;
-	GHashTable *connections;
-	GHashTable *unmanaged_devices;
-
-	guint32 default_gw;
-	GFileMonitor *default_gw_monitor;
-	guint default_gw_monitor_id;
+	GFileMonitor *hostname_monitor;
+	char *hostname;
 } SCPluginIfcfgPrivate;
 
-GQuark
-ifcfg_plugin_error_quark (void)
-{
-	static GQuark error_quark = 0;
-
-	if (G_UNLIKELY (error_quark == 0))
-		error_quark = g_quark_from_static_string ("ifcfg-plugin-error-quark");
+typedef void (*FileChangedFn) (gpointer user_data);
 
-	return error_quark;
-}
-
-static void
-update_one_connection (gpointer key, gpointer val, gpointer user_data)
-{
-	NMExportedConnection *exported = NM_EXPORTED_CONNECTION (val);
-	NMConnection *connection;
-	NMSettingIP4Config *ip4_config;
-
-	connection = nm_exported_connection_get_connection (exported);
-	ip4_config = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-	if (!ip4_config)
-		return;
-
-	if (nm_setting_ip4_config_get_num_addresses (ip4_config)) {
-		/* suse only has one address per device */
-		NMIP4Address *ip4_address = nm_setting_ip4_config_get_address (ip4_config, 0);
-		SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (user_data);
-		GHashTable *settings;
-
-		if (nm_ip4_address_get_gateway (ip4_address) != priv->default_gw) {
-			nm_ip4_address_set_gateway (ip4_address, priv->default_gw);
-			settings = nm_connection_to_hash (connection);
-			nm_exported_connection_signal_updated (exported, settings);
-			g_hash_table_destroy (settings);
-		}
-	}
-}
-
-static void
-update_connections (SCPluginIfcfg *self)
-{
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-
-	g_hash_table_foreach (priv->connections, update_one_connection, self);
-}
+typedef struct {
+	FileChangedFn callback;
+	gpointer user_data;
+} FileMonitorInfo;
 
 static void
-routes_changed (GFileMonitor *monitor,
-			 GFile *file,
-			 GFile *other_file,
-			 GFileMonitorEvent event_type,
-			 gpointer user_data)
+file_changed (GFileMonitor *monitor,
+		    GFile *file,
+		    GFile *other_file,
+		    GFileMonitorEvent event_type,
+		    gpointer user_data)
 {
-	SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	char *filename;
-	guint32 new_gw;
+	FileMonitorInfo *info;
 
 	switch (event_type) {
 	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
 	case G_FILE_MONITOR_EVENT_DELETED:
-		filename = g_file_get_path (file);
-		new_gw = parser_parse_routes (filename);
-		g_free (filename);
-
-		if (priv->default_gw != new_gw) {
-			priv->default_gw = new_gw;
-			update_connections (self);
-		}
+		info = (FileMonitorInfo *) user_data;
+		info->callback (info->user_data);
 		break;
 	default:
 		break;
 	}
 }
 
-static void
-monitor_routes (SCPluginIfcfg *self, const char *filename)
+static GFileMonitor *
+monitor_file_changes (const char *filename,
+				  FileChangedFn callback,
+				  gpointer user_data)
 {
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
 	GFile *file;
 	GFileMonitor *monitor;
+	FileMonitorInfo *info;
 
 	file = g_file_new_for_path (filename);
 	monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
 	g_object_unref (file);
 
 	if (monitor) {
-		priv->default_gw_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (routes_changed), self);
-		priv->default_gw_monitor = monitor;
+		info = g_new0 (FileMonitorInfo, 1);
+		info->callback = callback;
+		info->user_data = user_data;
+		g_object_weak_ref (G_OBJECT (monitor), (GWeakNotify) g_free, info);
+		g_signal_connect (monitor, "changed", G_CALLBACK (file_changed), info);
 	}
-}
-
-static char *
-get_iface_by_udi (SCPluginIfcfg *self, const char *udi)
-{
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	DBusGProxy *proxy;
-	char *iface = NULL;
 
-	proxy = dbus_g_proxy_new_for_name (priv->dbus_connection,
-								"org.freedesktop.Hal",
-								udi,
-								"org.freedesktop.Hal.Device");
-
-	dbus_g_proxy_call_with_timeout (proxy, "GetPropertyString", 10000, NULL,
-							  G_TYPE_STRING, "net.interface", G_TYPE_INVALID,
-							  G_TYPE_STRING, &iface, G_TYPE_INVALID);
-	g_object_unref (proxy);
-
-	return iface;
+	return monitor;
 }
 
-static void
-read_connection (SCPluginIfcfg *self, const char *udi, NMDeviceType dev_type)
+static gboolean
+hostname_is_dynamic (void)
 {
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	char *iface;
-
-	iface = get_iface_by_udi (self, udi);
-	if (iface) {
-		if (parser_ignore_device (iface)) {
-			g_hash_table_insert (priv->unmanaged_devices, g_strdup (udi), GINT_TO_POINTER (1));
-			g_signal_emit_by_name (self, "unmanaged-devices-changed");
-		} else {
-			NMSuseConnection *connection;
-
-			connection = nm_suse_connection_new (iface, dev_type);
-			if (connection) {
-				g_hash_table_insert (priv->connections, g_strdup (udi), connection);
-				g_signal_emit_by_name (self, "connection-added", connection);
-			}
+	GIOChannel *channel;
+	const char *pattern = "DHCLIENT_SET_HOSTNAME=";
+	char *str = NULL;
+	int pattern_len;
+	gboolean dynamic = FALSE;
+
+	channel = g_io_channel_new_file (CONF_DHCP, "r", NULL);
+	if (!channel)
+		return dynamic;
+
+	pattern_len = strlen (pattern);
+
+	while (g_io_channel_read_line (channel, &str, NULL, NULL, NULL) != G_IO_STATUS_EOF) {
+		if (!strncmp (str, pattern, pattern_len)) {
+			if (!strncmp (str + pattern_len, "\"yes\"", 5))
+				dynamic = TRUE;
+			break;
 		}
+		g_free (str);
 	}
 
-	g_free (iface);
-}
-
-static void
-read_connections_by_type (SCPluginIfcfg *self, NMDeviceType dev_type)
-{
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	GSList *list;
-	GSList *iter;
-
-	list = nm_system_config_hal_manager_get_devices_of_type (priv->hal_manager, dev_type);
-	for (iter = list; iter; iter = iter->next) {
-		read_connection (self, (char *) iter->data, dev_type);
-		g_free (iter->data);
-	}
-
-	g_slist_free (list);
-}
-
-static void
-device_added_cb (NMSystemConfigHalManager *hal_mgr,
-                 const char *udi,
-                 NMDeviceType dev_type,
-                 gpointer user_data)
-{
-	SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
+	g_io_channel_shutdown (channel, FALSE, NULL);
+	g_io_channel_unref (channel);
 
-	if (dev_type != NM_DEVICE_TYPE_ETHERNET && dev_type != NM_DEVICE_TYPE_WIFI)
-		return;
-
-	read_connection (self, udi, dev_type);
+	return dynamic;
 }
 
-static void
-device_removed_cb (NMSystemConfigHalManager *hal_mgr,
-                   const char *udi,
-                   NMDeviceType dev_type,
-                   gpointer user_data)
+static char *
+hostname_read ()
 {
-	SCPluginIfcfg *self = SC_PLUGIN_IFCFG (user_data);
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	NMExportedConnection *exported;
-
-	if (dev_type != NM_DEVICE_TYPE_ETHERNET && dev_type != NM_DEVICE_TYPE_WIFI)
-		return;
+	GIOChannel *channel;
+	char *hostname = NULL;
 
-	if (g_hash_table_remove (priv->unmanaged_devices, udi))
-		g_signal_emit_by_name (self, "unmanaged-devices-changed");
+	channel = g_io_channel_new_file (HOSTNAME_FILE, "r", NULL);
+	if (channel) {
+		g_io_channel_read_line (channel, &hostname, NULL, NULL, NULL);
+		g_io_channel_shutdown (channel, FALSE, NULL);
+		g_io_channel_unref (channel);
 
-	exported = (NMExportedConnection *) g_hash_table_lookup (priv->connections, udi);
-	if (exported) {
-		nm_exported_connection_signal_removed (exported);
-		g_hash_table_remove (priv->connections, udi);
+		if (hostname)
+			hostname = g_strchomp (hostname);
 	}
-}
 
-static void
-init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager)
-{
-	SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-
-	priv->hal_manager = g_object_ref (hal_manager);
-
-	g_signal_connect (priv->hal_manager, "device-added", G_CALLBACK (device_added_cb), self);
-	g_signal_connect (priv->hal_manager, "device-removed", G_CALLBACK (device_removed_cb), self);
+	return hostname;
 }
 
 static void
-get_connections_cb (gpointer key, gpointer val, gpointer user_data)
+hostname_changed (gpointer data)
 {
-	GSList **list = (GSList **) user_data;
+	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (data);
 
-	*list = g_slist_prepend (*list, val);
-}
-
-static GSList *
-get_connections (NMSystemConfigInterface *config)
-{
-	SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config);
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	GSList *list = NULL;
-
-	if (!priv->initialized) {
-		const char *filename;
-
-		read_connections_by_type (self, NM_DEVICE_TYPE_ETHERNET);
-		read_connections_by_type (self, NM_DEVICE_TYPE_WIFI);
-
-		filename = SYSCONFDIR"/sysconfig/network/routes";
-		monitor_routes (self, filename);
-		priv->default_gw = parser_parse_routes (filename);
-		if (priv->default_gw)
-			update_connections (self);
-
-		priv->initialized = TRUE;
-	}
-
-	g_hash_table_foreach (priv->connections, get_connections_cb, &list);
+	g_free (priv->hostname);
+	if (hostname_is_dynamic ())
+		priv->hostname = NULL;
+	else
+		priv->hostname = hostname_read ();
 
-	return list;
+	g_object_notify (G_OBJECT (data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
 }
 
 static void
-get_unamanged_devices_cb (gpointer key, gpointer val, gpointer user_data)
-{
-	GSList **list = (GSList **) key;
-
-	*list = g_slist_prepend (*list, g_strdup ((char *) key));
-}
-
-static GSList *
-get_unmanaged_devices (NMSystemConfigInterface *config)
+init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager)
 {
-	GSList *list = NULL;
+	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (config);
 
-	g_hash_table_foreach (SC_PLUGIN_IFCFG_GET_PRIVATE (config)->unmanaged_devices,
-					  get_unamanged_devices_cb, &list);
+	priv->hostname_monitor = monitor_file_changes (HOSTNAME_FILE, hostname_changed, config);
 
-	return list;
+	if (!hostname_is_dynamic ())
+		priv->hostname = hostname_read ();
 }
 
 static void
 sc_plugin_ifcfg_init (SCPluginIfcfg *self)
 {
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self);
-	GError *err = NULL;
-
-	priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
-	priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-	priv->dbus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
-	if (!priv->dbus_connection) {
-		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    dbus-glib error: %s",
-		              err->message ? err->message : "(unknown)");
-		g_error_free (err);
-	}
 }
 
 static void
-dispose (GObject *object)
+finalize (GObject *object)
 {
 	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (object);
 
-	g_hash_table_destroy (priv->connections);
-	g_hash_table_destroy (priv->unmanaged_devices);
+	if (priv->hostname_monitor)
+		g_object_unref (priv->hostname_monitor);
 
-	if (priv->default_gw_monitor) {
-		if (priv->default_gw_monitor_id)
-			g_signal_handler_disconnect (priv->default_gw_monitor, priv->default_gw_monitor_id);
+	g_free (priv->hostname);
 
-		g_file_monitor_cancel (priv->default_gw_monitor);
-		g_object_unref (priv->default_gw_monitor);
-	}
-
-	if (priv->hal_manager)
-		g_object_unref (priv->hal_manager);
-
-	dbus_g_connection_unref (priv->dbus_connection);
-
-	G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
+	G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->finalize (object);
 }
 
 static void
@@ -380,10 +215,23 @@ get_property (GObject *object, guint prop_id,
 		g_value_set_string (value, IFCFG_PLUGIN_INFO);
 		break;
 	case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
-		g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE);
+		g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
+		break;
+	case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+		g_value_set_string (value, SC_PLUGIN_IFCFG_GET_PRIVATE (object)->hostname);
 		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+		    const GValue *value, GParamSpec *pspec)
+{
+	switch (prop_id) {
 	case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
-		g_value_set_string (value, "");
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -399,7 +247,8 @@ sc_plugin_ifcfg_class_init (SCPluginIfcfgClass *req_class)
 	g_type_class_add_private (req_class, sizeof (SCPluginIfcfgPrivate));
 
 	object_class->get_property = get_property;
-	object_class->dispose = dispose;
+	object_class->set_property = set_property;
+	object_class->finalize = finalize;
 
 	g_object_class_override_property (object_class,
 							    NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
@@ -422,8 +271,6 @@ 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->get_unmanaged_devices = get_unmanaged_devices;
 	system_config_interface_class->init = init;
 }
 
diff --git a/system-settings/plugins/ifcfg-suse/plugin.h b/system-settings/plugins/ifcfg-suse/plugin.h
index 08ed440..4a9575d 100644
--- a/system-settings/plugins/ifcfg-suse/plugin.h
+++ b/system-settings/plugins/ifcfg-suse/plugin.h
@@ -46,7 +46,5 @@ struct _SCPluginIfcfgClass {
 
 GType sc_plugin_ifcfg_get_type (void);
 
-GQuark ifcfg_plugin_error_quark (void);
-
 #endif	/* _PLUGIN_H_ */
 
diff --git a/system-settings/plugins/keyfile/io/writer.c b/system-settings/plugins/keyfile/io/writer.c
index bbf40c7..3851ea0 100644
--- a/system-settings/plugins/keyfile/io/writer.c
+++ b/system-settings/plugins/keyfile/io/writer.c
@@ -38,7 +38,8 @@
 
 #include "nm-dbus-glib-types.h"
 #include "writer.h"
-#include "reader.h"
+
+#define VPN_SECRETS_GROUP "vpn-secrets"
 
 static gboolean
 write_array_of_uint (GKeyFile *file,
-- 
1.6.0.2

