about summary refs log tree commit diff
path: root/src/settings/plugins/keyfile/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins/keyfile/plugin.c')
-rw-r--r--src/settings/plugins/keyfile/plugin.c395
1 files changed, 109 insertions, 286 deletions
diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c
index 7f21e71e..e352e523 100644
--- a/src/settings/plugins/keyfile/plugin.c
+++ b/src/settings/plugins/keyfile/plugin.c
@@ -27,62 +27,51 @@
 #include <string.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 <nm-utils.h>
-#include <nm-config.h>
-#include <nm-logging.h>
+#include "nm-config.h"
+#include "nm-default.h"
 #include "nm-core-internal.h"
 
 #include "plugin.h"
-#include "nm-system-config-interface.h"
+#include "nm-settings-plugin.h"
 #include "nm-keyfile-connection.h"
 #include "writer.h"
-#include "common.h"
 #include "utils.h"
-#include "gsystem-local-alloc.h"
 
-static char *plugin_get_hostname (SCPluginKeyfile *plugin);
-static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
+static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface);
 
-G_DEFINE_TYPE_EXTENDED (SCPluginKeyfile, sc_plugin_keyfile, G_TYPE_OBJECT, 0,
-				    G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
-									  system_config_interface_init))
+G_DEFINE_TYPE_EXTENDED (SettingsPluginKeyfile, settings_plugin_keyfile, G_TYPE_OBJECT, 0,
+                        G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN,
+                                               settings_plugin_interface_init))
 
-#define SC_PLUGIN_KEYFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfilePrivate))
+#define SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SETTINGS_TYPE_PLUGIN_KEYFILE, SettingsPluginKeyfilePrivate))
 
 typedef struct {
 	GHashTable *connections;  /* uuid::connection */
 
 	gboolean initialized;
 	GFileMonitor *monitor;
-	guint monitor_id;
+	gulong monitor_id;
 
-	const char *conf_file;
-	GFileMonitor *conf_file_monitor;
-	guint conf_file_monitor_id;
-
-	char *hostname;
-
-	gboolean disposed;
-} SCPluginKeyfilePrivate;
+	NMConfig *config;
+} SettingsPluginKeyfilePrivate;
 
 static void
 connection_removed_cb (NMSettingsConnection *obj, gpointer user_data)
 {
-	g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (user_data)->connections,
+	g_hash_table_remove (SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (user_data)->connections,
 	                     nm_connection_get_uuid (NM_CONNECTION (obj)));
 }
 
 /* Monitoring */
 
 static void
-remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection)
+remove_connection (SettingsPluginKeyfile *self, NMKeyfileConnection *connection)
 {
 	gboolean removed;
 
@@ -93,7 +82,7 @@ remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection)
 	/* Removing from the hash table should drop the last reference */
 	g_object_ref (connection);
 	g_signal_handlers_disconnect_by_func (connection, connection_removed_cb, self);
-	removed = g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->connections,
+	removed = g_hash_table_remove (SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (self)->connections,
 	                               nm_connection_get_uuid (NM_CONNECTION (connection)));
 	nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection));
 	g_object_unref (connection);
@@ -102,9 +91,9 @@ remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection)
 }
 
 static NMKeyfileConnection *
-find_by_path (SCPluginKeyfile *self, const char *path)
+find_by_path (SettingsPluginKeyfile *self, const char *path)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (self);
 	GHashTableIter iter;
 	NMSettingsConnection *candidate = NULL;
 
@@ -150,7 +139,7 @@ find_by_path (SCPluginKeyfile *self, const char *path)
  * Returns: the updated connection.
  * */
 static NMKeyfileConnection *
-update_connection (SCPluginKeyfile *self,
+update_connection (SettingsPluginKeyfile *self,
                    NMConnection *source,
                    const char *full_path,
                    NMKeyfileConnection *connection,
@@ -158,7 +147,7 @@ update_connection (SCPluginKeyfile *self,
                    GHashTable *protected_connections,
                    GError **error)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (self);
 	NMKeyfileConnection *connection_new;
 	NMKeyfileConnection *connection_by_uuid;
 	GError *local = NULL;
@@ -274,7 +263,7 @@ update_connection (SCPluginKeyfile *self,
 		if (!source) {
 			/* Only raise the signal if we were called without source, i.e. if we read the connection from file.
 			 * Otherwise, we were called by add_connection() which does not expect the signal. */
-			g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection_new);
+			g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, connection_new);
 		}
 		return connection_new;
 	}
@@ -287,8 +276,8 @@ dir_changed (GFileMonitor *monitor,
              GFileMonitorEvent event_type,
              gpointer user_data)
 {
-	NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data);
-	SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+	NMSettingsPlugin *config = NM_SETTINGS_PLUGIN (user_data);
+	SettingsPluginKeyfile *self = SETTINGS_PLUGIN_KEYFILE (config);
 	NMKeyfileConnection *connection;
 	char *full_path;
 	gboolean exists;
@@ -307,12 +296,12 @@ dir_changed (GFileMonitor *monitor,
 	switch (event_type) {
 	case G_FILE_MONITOR_EVENT_DELETED:
 		if (!exists && connection)
-			remove_connection (SC_PLUGIN_KEYFILE (config), connection);
+			remove_connection (SETTINGS_PLUGIN_KEYFILE (config), connection);
 		break;
 	case G_FILE_MONITOR_EVENT_CREATED:
 	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
 		if (exists)
-			update_connection (SC_PLUGIN_KEYFILE (config), NULL, full_path, connection, TRUE, NULL, NULL);
+			update_connection (SETTINGS_PLUGIN_KEYFILE (config), NULL, full_path, connection, TRUE, NULL, NULL);
 		break;
 	default:
 		break;
@@ -322,51 +311,30 @@ dir_changed (GFileMonitor *monitor,
 }
 
 static void
-conf_file_changed (GFileMonitor *monitor,
-				   GFile *file,
-				   GFile *other_file,
-				   GFileMonitorEvent event_type,
-				   gpointer data)
+config_changed_cb (NMConfig *config,
+                   NMConfigData *config_data,
+                   NMConfigChangeFlags changes,
+                   NMConfigData *old_data,
+                   SettingsPluginKeyfile *self)
 {
-	SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (data);
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
-	char *tmp;
-
-	switch (event_type) {
-	case G_FILE_MONITOR_EVENT_DELETED:
-	case G_FILE_MONITOR_EVENT_CREATED:
-	case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
-		g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
-
-		/* hostname */
-		tmp = plugin_get_hostname (self);
-		if ((tmp && !priv->hostname)
-			|| (!tmp && priv->hostname)
-			|| (priv->hostname && tmp && strcmp (priv->hostname, tmp))) {
-
-			g_free (priv->hostname);
-			priv->hostname = tmp;
-			tmp = NULL;
-			g_object_notify (G_OBJECT (self), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
-		}
+	gs_free char *old_value = NULL, *new_value = NULL;
 
-		g_free (tmp);
+	old_value = nm_config_data_get_value (old_data, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, NM_CONFIG_GET_VALUE_TYPE_SPEC);
+	new_value = nm_config_data_get_value (config_data, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, NM_CONFIG_GET_VALUE_TYPE_SPEC);
 
-		break;
-	default:
-		break;
-	}
+	if (g_strcmp0 (old_value, new_value) != 0)
+		g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED);
 }
 
 static void
-setup_monitoring (NMSystemConfigInterface *config)
+setup_monitoring (NMSettingsPlugin *config)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (config);
 	GFile *file;
 	GFileMonitor *monitor;
 
 	if (nm_config_get_monitor_connection_files (nm_config_get ())) {
-		file = g_file_new_for_path (KEYFILE_DIR);
+		file = g_file_new_for_path (nm_keyfile_plugin_get_path ());
 		monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
 		g_object_unref (file);
 
@@ -376,16 +344,10 @@ setup_monitoring (NMSystemConfigInterface *config)
 		}
 	}
 
-	if (priv->conf_file) {
-		file = g_file_new_for_path (priv->conf_file);
-		monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
-		g_object_unref (file);
-
-		if (monitor) {
-			priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
-			priv->conf_file_monitor = monitor;
-		}
-	}
+	g_signal_connect (G_OBJECT (priv->config),
+	                  NM_CONFIG_SIGNAL_CONFIG_CHANGED,
+	                  G_CALLBACK (config_changed_cb),
+	                  config);
 }
 
 static GHashTable *
@@ -426,10 +388,10 @@ _sort_paths (const char **f1, const char **f2, GHashTable *paths)
 }
 
 static void
-read_connections (NMSystemConfigInterface *config)
+read_connections (NMSettingsPlugin *config)
 {
-	SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
+	SettingsPluginKeyfile *self = SETTINGS_PLUGIN_KEYFILE (config);
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (self);
 	GDir *dir;
 	GError *error = NULL;
 	const char *item;
@@ -441,10 +403,10 @@ read_connections (NMSystemConfigInterface *config)
 	GPtrArray *filenames;
 	GHashTable *paths;
 
-	dir = g_dir_open (KEYFILE_DIR, 0, &error);
+	dir = g_dir_open (nm_keyfile_plugin_get_path (), 0, &error);
 	if (!dir) {
 		nm_log_warn (LOGD_SETTINGS, "keyfile: cannot read directory '%s': (%d) %s",
-		             KEYFILE_DIR,
+		             nm_keyfile_plugin_get_path (),
 		             error ? error->code : -1,
 		             error && error->message ? error->message : "(unknown)");
 		g_clear_error (&error);
@@ -457,7 +419,7 @@ read_connections (NMSystemConfigInterface *config)
 	while ((item = g_dir_read_name (dir))) {
 		if (nm_keyfile_plugin_utils_should_ignore_file (item))
 			continue;
-		g_ptr_array_add (filenames, g_build_filename (KEYFILE_DIR, item, NULL));
+		g_ptr_array_add (filenames, g_build_filename (nm_keyfile_plugin_get_path (), item, NULL));
 	}
 	g_dir_close (dir);
 
@@ -499,9 +461,9 @@ read_connections (NMSystemConfigInterface *config)
 /* Plugin */
 
 static GSList *
-get_connections (NMSystemConfigInterface *config)
+get_connections (NMSettingsPlugin *config)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (config);
 
 	if (!priv->initialized) {
 		setup_monitoring (config);
@@ -512,14 +474,14 @@ get_connections (NMSystemConfigInterface *config)
 }
 
 static gboolean
-load_connection (NMSystemConfigInterface *config,
+load_connection (NMSettingsPlugin *config,
                  const char *filename)
 {
-	SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+	SettingsPluginKeyfile *self = SETTINGS_PLUGIN_KEYFILE (config);
 	NMKeyfileConnection *connection;
-	int dir_len = strlen (KEYFILE_DIR);
+	int dir_len = strlen (nm_keyfile_plugin_get_path ());
 
-	if (   strncmp (filename, KEYFILE_DIR, dir_len) != 0
+	if (   strncmp (filename, nm_keyfile_plugin_get_path (), dir_len) != 0
 	    || filename[dir_len] != '/'
 	    || strchr (filename + dir_len + 1, '/') != NULL)
 		return FALSE;
@@ -533,157 +495,46 @@ load_connection (NMSystemConfigInterface *config,
 }
 
 static void
-reload_connections (NMSystemConfigInterface *config)
+reload_connections (NMSettingsPlugin *config)
 {
 	read_connections (config);
 }
 
 static NMSettingsConnection *
-add_connection (NMSystemConfigInterface *config,
+add_connection (NMSettingsPlugin *config,
                 NMConnection *connection,
                 gboolean save_to_disk,
                 GError **error)
 {
-	SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
+	SettingsPluginKeyfile *self = SETTINGS_PLUGIN_KEYFILE (config);
 	gs_free char *path = NULL;
 
 	if (save_to_disk) {
-		if (!nm_keyfile_plugin_write_connection (connection, NULL, &path, error))
+		if (!nm_keyfile_plugin_write_connection (connection, NULL, FALSE, &path, error))
 			return NULL;
 	}
 	return NM_SETTINGS_CONNECTION (update_connection (self, connection, path, NULL, FALSE, NULL, error));
 }
 
-static gboolean
-parse_key_file_allow_none (SCPluginKeyfilePrivate  *priv,
-                           GKeyFile                *key_file,
-                           GError                 **error)
-{
-	gboolean ret = FALSE;
-	GError *local_error = NULL;
-
-	if (!g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &local_error)) {
-		if (g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
-			g_clear_error (&local_error);
-		else {
-			g_propagate_prefixed_error (error, local_error,
-			                            "Error parsing file '%s': ",
-			                            priv->conf_file);
-			goto out;
-		}
-	}
-	ret = TRUE;
-
- out:
-	return ret;
-}
-
 static GSList *
-get_unmanaged_specs (NMSystemConfigInterface *config)
-{
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
-	GKeyFile *key_file;
-	GSList *specs = NULL;
-	GError *error = NULL;
-
-	if (!priv->conf_file)
-		return NULL;
-
-	key_file = nm_config_create_keyfile ();
-	if (parse_key_file_allow_none (priv, key_file, &error))
-		specs = nm_config_get_device_match_spec (key_file, NM_CONFIG_KEYFILE_GROUP_KEYFILE, "unmanaged-devices", NULL);
-
-	if (error) {
-		nm_log_warn (LOGD_SETTINGS, "keyfile: error getting unmanaged specs: %s", error->message);
-		g_error_free (error);
-	}
-	g_key_file_free (key_file);
-
-	return specs;
-}
-
-static char *
-plugin_get_hostname (SCPluginKeyfile *plugin)
-{
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
-	GKeyFile *key_file;
-	char *hostname = NULL;
-	GError *error = NULL;
-
-	if (!priv->conf_file)
-		return NULL;
-
-	key_file = g_key_file_new ();
-	if (!parse_key_file_allow_none (priv, key_file, &error))
-		goto out;
-
-	hostname = g_key_file_get_value (key_file, NM_CONFIG_KEYFILE_GROUP_KEYFILE, "hostname", NULL);
-
- out:
-	if (error) {
-		nm_log_warn (LOGD_SETTINGS, "keyfile: error getting hostname: %s", error->message);
-		g_error_free (error);
-	}
-	if (key_file)
-		g_key_file_free (key_file);
-
-	return hostname;
-}
-
-static gboolean
-plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
+get_unmanaged_specs (NMSettingsPlugin *config)
 {
-	gboolean ret = FALSE;
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
-	GKeyFile *key_file = NULL;
-	GError *error = NULL;
-	char *data = NULL;
-	gsize len;
-
-	if (!priv->conf_file) {
-		g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
-		             "Error saving hostname: no config file");
-		goto out;
-	}
-
-	g_free (priv->hostname);
-	priv->hostname = g_strdup (hostname);
-
-	key_file = g_key_file_new ();
-	if (!parse_key_file_allow_none (priv, key_file, &error))
-		goto out;
-
-	g_key_file_set_string (key_file, NM_CONFIG_KEYFILE_GROUP_KEYFILE, "hostname", hostname);
-
-	data = g_key_file_to_data (key_file, &len, &error);
-	if (!data)
-		goto out;
-
-	if (!g_file_set_contents (priv->conf_file, data, len, &error)) {
-		g_prefix_error (&error, "Error saving hostname: ");
-		goto out;
-	}
-
-	ret = TRUE;
-
- out:
-	if (error) {
-		nm_log_warn (LOGD_SETTINGS, "keyfile: error setting hostname: %s", error->message);
-		g_error_free (error);
-	}
-	g_free (data);
-	if (key_file)
-		g_key_file_free (key_file);
-
-	return ret;
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (config);
+	gs_free char *value = NULL;
+
+	value = nm_config_data_get_value (nm_config_get_data (priv->config),
+	                                  NM_CONFIG_KEYFILE_GROUP_KEYFILE,
+	                                  NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES,
+	                                  NM_CONFIG_GET_VALUE_TYPE_SPEC);
+	return nm_match_spec_split (value);
 }
 
 /* GObject */
 
 static void
-sc_plugin_keyfile_init (SCPluginKeyfile *plugin)
+settings_plugin_keyfile_init (SettingsPluginKeyfile *plugin)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
 
 	priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
 }
@@ -693,18 +544,14 @@ get_property (GObject *object, guint prop_id,
 		    GValue *value, GParamSpec *pspec)
 {
 	switch (prop_id) {
-	case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
+	case NM_SETTINGS_PLUGIN_PROP_NAME:
 		g_value_set_string (value, KEYFILE_PLUGIN_NAME);
 		break;
-	case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
+	case NM_SETTINGS_PLUGIN_PROP_INFO:
 		g_value_set_string (value, KEYFILE_PLUGIN_INFO);
 		break;
-	case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
-		g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS | 
-						  NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
-		break;
-	case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
-		g_value_set_string (value, SC_PLUGIN_KEYFILE_GET_PRIVATE (object)->hostname);
+	case NM_SETTINGS_PLUGIN_PROP_CAPABILITIES:
+		g_value_set_uint (value, NM_SETTINGS_PLUGIN_CAP_MODIFY_CONNECTIONS);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -716,15 +563,7 @@ static void
 set_property (GObject *object, guint prop_id,
 			  const GValue *value, GParamSpec *pspec)
 {
-	const char *hostname;
-
 	switch (prop_id) {
-	case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
-		hostname = g_value_get_string (value);
-		if (hostname && strlen (hostname) < 1)
-			hostname = NULL;
-		plugin_set_hostname (SC_PLUGIN_KEYFILE (object), hostname);
-		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -732,97 +571,81 @@ set_property (GObject *object, guint prop_id,
 }
 
 static void
-dispose (GObject *object)
+constructed (GObject *object)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (object);
-
-	if (priv->disposed)
-		goto out;
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (object);
+
+	priv->config = g_object_ref (nm_config_get ());
+	if (nm_config_data_has_value (nm_config_get_data_orig (priv->config),
+	                              NM_CONFIG_KEYFILE_GROUP_KEYFILE,
+	                              NM_CONFIG_KEYFILE_KEY_KEYFILE_HOSTNAME,
+	                              NM_CONFIG_GET_VALUE_RAW))
+		nm_log_warn (LOGD_SETTINGS, "keyfile: 'hostname' option is deprecated and has no effect");
+}
 
-	priv->disposed = TRUE;
+static void
+dispose (GObject *object)
+{
+	SettingsPluginKeyfilePrivate *priv = SETTINGS_PLUGIN_KEYFILE_GET_PRIVATE (object);
 
 	if (priv->monitor) {
-		if (priv->monitor_id)
-			g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
+		nm_clear_g_signal_handler (priv->monitor, &priv->monitor_id);
 
 		g_file_monitor_cancel (priv->monitor);
-		g_object_unref (priv->monitor);
-	}
-
-	if (priv->conf_file_monitor) {
-		if (priv->conf_file_monitor_id)
-			g_signal_handler_disconnect (priv->conf_file_monitor, priv->conf_file_monitor_id);
-
-		g_file_monitor_cancel (priv->conf_file_monitor);
-		g_object_unref (priv->conf_file_monitor);
+		g_clear_object (&priv->monitor);
 	}
 
-	g_free (priv->hostname);
-
 	if (priv->connections) {
 		g_hash_table_destroy (priv->connections);
 		priv->connections = NULL;
 	}
 
-out:
-	G_OBJECT_CLASS (sc_plugin_keyfile_parent_class)->dispose (object);
+	if (priv->config) {
+		g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, object);
+		g_clear_object (&priv->config);
+	}
+
+	G_OBJECT_CLASS (settings_plugin_keyfile_parent_class)->dispose (object);
 }
 
 static void
-sc_plugin_keyfile_class_init (SCPluginKeyfileClass *req_class)
+settings_plugin_keyfile_class_init (SettingsPluginKeyfileClass *req_class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (req_class);
 
-	g_type_class_add_private (req_class, sizeof (SCPluginKeyfilePrivate));
+	g_type_class_add_private (req_class, sizeof (SettingsPluginKeyfilePrivate));
 
+	object_class->constructed = constructed;
 	object_class->dispose = dispose;
 	object_class->get_property = get_property;
 	object_class->set_property = set_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);
+	                                  NM_SETTINGS_PLUGIN_PROP_NAME,
+	                                  NM_SETTINGS_PLUGIN_NAME);
 
 	g_object_class_override_property (object_class,
-	                                  NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES,
-	                                  NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES);
+	                                  NM_SETTINGS_PLUGIN_PROP_INFO,
+	                                  NM_SETTINGS_PLUGIN_INFO);
 
 	g_object_class_override_property (object_class,
-	                                  NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME,
-	                                  NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+	                                  NM_SETTINGS_PLUGIN_PROP_CAPABILITIES,
+	                                  NM_SETTINGS_PLUGIN_CAPABILITIES);
 }
 
 static void
-system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
+settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface)
 {
 	/* interface implementation */
-	system_config_interface_class->get_connections = get_connections;
-	system_config_interface_class->load_connection = load_connection;
-	system_config_interface_class->reload_connections = reload_connections;
-	system_config_interface_class->add_connection = add_connection;
-	system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs;
+	plugin_iface->get_connections = get_connections;
+	plugin_iface->load_connection = load_connection;
+	plugin_iface->reload_connections = reload_connections;
+	plugin_iface->add_connection = add_connection;
+	plugin_iface->get_unmanaged_specs = get_unmanaged_specs;
 }
 
 GObject *
 nm_settings_keyfile_plugin_new (void)
 {
-	static SCPluginKeyfile *singleton = NULL;
-	SCPluginKeyfilePrivate *priv;
-
-	if (!singleton) {
-		singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
-		priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton);
-
-		priv->conf_file = nm_config_data_get_config_main_file (nm_config_get_data (nm_config_get ()));
-
-		/* plugin_set_hostname() has to be called *after* priv->conf_file is set */
-		priv->hostname = plugin_get_hostname (singleton);
-	} else
-		g_object_ref (singleton);
-
-	return G_OBJECT (singleton);
+	return g_object_new (SETTINGS_TYPE_PLUGIN_KEYFILE, NULL);
 }