NetworkManager r3475 - in trunk: . system-settings/plugins/ifcfg-fedora



Author: dcbw
Date: Wed Mar 19 03:08:32 2008
New Revision: 3475
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=3475&view=rev

Log:
2008-03-18  Dan Williams  <dcbw redhat com>

	* system-settings/plugins/ifcfg-fedora/parser.c
	  system-settings/plugins/ifcfg-fedora/parser.h
	  system-settings/plugins/ifcfg-fedora/plugin.c
		- Read settings from /etc/sysconfig/network-scripts/ instead of using
			profiles.  DNS servers and searches must now be stored in the ifcfg
			files themselves



Modified:
   trunk/ChangeLog
   trunk/system-settings/plugins/ifcfg-fedora/parser.c
   trunk/system-settings/plugins/ifcfg-fedora/parser.h
   trunk/system-settings/plugins/ifcfg-fedora/plugin.c

Modified: trunk/system-settings/plugins/ifcfg-fedora/parser.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/parser.c	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/parser.c	Wed Mar 19 03:08:32 2008
@@ -163,7 +163,8 @@
 static char *
 get_ifcfg_name (const char *file)
 {
-	char *basename = NULL;
+	char *ifcfg_name = NULL;
+	char *basename;
 	int len;
 
 	basename = g_path_get_basename (file);
@@ -187,11 +188,11 @@
 	if (should_ignore_file (basename, REJ_TAG))
 		goto error;
 
-	return g_strdup (basename + strlen (IFCFG_TAG));
+	ifcfg_name = g_strdup (basename + strlen (IFCFG_TAG));
 
 error:
 	g_free (basename);
-	return NULL;
+	return ifcfg_name;
 }
 
 static NMSetting *
@@ -230,87 +231,32 @@
 	return (NMSetting *) s_con;
 }
 
-#define SEARCH_TAG "search "
-#define NS_TAG "nameserver "
-
-void
-connection_update_from_resolv_conf (char **lines, NMSettingIP4Config *s_ip4)
+static void
+get_one_ip4_addr (shvarFile *ifcfg,
+                  const char *tag,
+                  guint32 *out_addr,
+                  GError **error)
 {
-	char **line;
+	char *value = NULL;
+	struct in_addr ip4_addr;
 
-	/* lines == NULL means clear out existing settings */
-	if (!lines) {
-		if (s_ip4->dns) {
-			g_array_free (s_ip4->dns, TRUE);
-			s_ip4->dns = NULL;
-		}
+	g_return_if_fail (ifcfg != NULL);
+	g_return_if_fail (tag != NULL);
+	g_return_if_fail (out_addr != NULL);
+	g_return_if_fail (error != NULL);
+	g_return_if_fail (*error == NULL);
 
-		g_slist_foreach (s_ip4->dns_search, (GFunc) g_free, NULL);
-		g_slist_free (s_ip4->dns_search);
-		s_ip4->dns_search = NULL;
+	value = svGetValue (ifcfg, tag);
+	if (!value)
 		return;
-	}
-
-	s_ip4->dns = g_array_new (FALSE, FALSE, sizeof (guint32));
-
-	for (line = lines; *line; line++) {
-		if (!strncmp (*line, SEARCH_TAG, strlen (SEARCH_TAG))) {
-			char **searches;
-
-			if (s_ip4->dns_search)
-				continue;
 
-			searches = g_strsplit (*line + strlen (SEARCH_TAG), " ", 0);
-			if (searches) {
-				char **item;
-				for (item = searches; *item; item++)
-					s_ip4->dns_search = g_slist_append (s_ip4->dns_search, *item);
-				g_free (searches);
-			}
-		} else if (!strncmp (*line, NS_TAG, strlen (NS_TAG))) {
-			char *pdns = g_strdup (*line + strlen (NS_TAG));
-			struct in_addr dns;
-
-			pdns = g_strstrip (pdns);
-			if (inet_pton (AF_INET, pdns, &dns)) {
-				g_array_append_val (s_ip4->dns, dns.s_addr);
-			} else
-				g_warning ("Invalid IP4 DNS server address '%s'", pdns);
-			g_free (pdns);
-		}
-	}
-
-	if (!s_ip4->dns->len) {
-		g_array_free (s_ip4->dns, TRUE);
-		s_ip4->dns = NULL;
+	if (inet_pton (AF_INET, value, &ip4_addr))
+		*out_addr = ip4_addr.s_addr;
+	else {
+		g_set_error (error, ifcfg_plugin_error_quark (), 0,
+		             "Invalid %s IP4 address '%s'", tag, value);
 	}
-}
-
-static void
-read_profile_resolv_conf (const char *dir, NMSettingIP4Config *s_ip4)
-{
-	char *file = NULL;
-	char *contents = NULL;
-	char **lines = NULL;
-
-	file = g_strdup_printf ("%s/resolv.conf", dir);
-	if (!file)
-		goto out;
-
-	if (!g_file_get_contents (file, &contents, NULL, NULL))
-		goto out;
-
-	lines = g_strsplit (contents, "\n", 0);
-	if (!lines || !*lines)
-		goto out;
-
-	connection_update_from_resolv_conf (lines, s_ip4);
-
-out:
-	if (lines)
-		g_strfreev (lines);
-	g_free (contents);
-	g_free (file);
+	g_free (value);
 }
 
 static NMSetting *
@@ -320,7 +266,7 @@
 	char *value = NULL;
 	NMSettingIP4Address tmp = { 0, 0, 0 };
 	char *method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
-	char *dir;
+	guint32 dns;
 
 	value = svGetValue (ifcfg, "BOOTPROTO");
 	if (value && (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp")))
@@ -331,44 +277,18 @@
 		goto done;
 	}
 
-	value = svGetValue (ifcfg, "IPADDR");
-	if (value) {
-		struct in_addr ip4_addr;
-		if (inet_pton (AF_INET, value, &ip4_addr))
-			tmp.address = ip4_addr.s_addr;
-		else {
-			g_set_error (error, ifcfg_plugin_error_quark (), 0,
-			             "Invalid IP4 address '%s'", value);
-			goto error;
-		}
-		g_free (value);
-	}
+	get_one_ip4_addr (ifcfg, "IPADDR", &tmp.address, error);
+	if (*error)
+		goto error;
 
-	value = svGetValue (ifcfg, "GATEWAY");
-	if (value) {
-		struct in_addr gw_addr;
-		if (inet_pton (AF_INET, value, &gw_addr))
-			tmp.gateway = gw_addr.s_addr;
-		else {
-			g_set_error (error, ifcfg_plugin_error_quark (), 0,
-			             "Invalid IP4 gateway '%s'", value);
-			goto error;
-		}
-		g_free (value);
-	}
+	get_one_ip4_addr (ifcfg, "GATEWAY", &tmp.gateway, error);
+	if (*error)
+		goto error;
+
+	get_one_ip4_addr (ifcfg, "NETMASK", &tmp.netmask, error);
+	if (*error)
+		goto error;
 
-	value = svGetValue (ifcfg, "NETMASK");
-	if (value) {
-		struct in_addr mask_addr;
-		if (inet_pton (AF_INET, value, &mask_addr))
-			tmp.netmask = mask_addr.s_addr;
-		else {
-			g_set_error (error, ifcfg_plugin_error_quark (), 0,
-			             "Invalid IP4 netmask '%s'", value);
-			goto error;
-		}
-		g_free (value);
-	}
 
 done:
 	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
@@ -382,14 +302,40 @@
 
 	/* No DNS for autoip */
 	if (g_ascii_strcasecmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTOIP)) {
-		dir = g_path_get_dirname (ifcfg->fileName);
-		if (dir) {
-			read_profile_resolv_conf (dir, s_ip4);
-			g_free (dir);
-		} else {
-			g_set_error (error, ifcfg_plugin_error_quark (), 0,
-			             "Not enough memory to parse resolv.conf");
+		s_ip4->dns = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+
+		get_one_ip4_addr (ifcfg, "DNS1", &dns, error);
+		if (*error)
+			goto error;
+		g_array_append_val (s_ip4->dns, dns);
+
+		get_one_ip4_addr (ifcfg, "DNS2", &dns, error);
+		if (*error)
 			goto error;
+		g_array_append_val (s_ip4->dns, dns);
+
+		get_one_ip4_addr (ifcfg, "DNS3", &dns, error);
+		if (*error)
+			goto error;
+		g_array_append_val (s_ip4->dns, dns);
+
+		if (s_ip4->dns && !s_ip4->dns->len) {
+			g_array_free (s_ip4->dns, TRUE);
+			s_ip4->dns = NULL;
+		}
+
+		/* DNS searches */
+		value = svGetValue (ifcfg, "DOMAIN_SEARCHES");
+		if (value) {
+			char **searches = NULL;
+
+			searches = g_strsplit (value, " ", 0);
+			if (searches) {
+				char **item;
+				for (item = searches; *item; item++)
+					s_ip4->dns_search = g_slist_append (s_ip4->dns_search, *item);
+				g_free (searches);
+			}
 		}
 	}
 
@@ -907,6 +853,13 @@
 			goto done;
 		}
 
+		if (!strcmp (device, "lo")) {
+			g_set_error (error, ifcfg_plugin_error_quark (), 0,
+			             "Ignoring loopback device config.");
+			g_free (device);
+			goto done;
+		}
+
 		/* Test wireless extensions */
 		if (!is_wireless_device (device, &is_wireless)) {
 			g_set_error (error, ifcfg_plugin_error_quark (), 0,

Modified: trunk/system-settings/plugins/ifcfg-fedora/parser.h
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/parser.h	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/parser.h	Wed Mar 19 03:08:32 2008
@@ -45,8 +45,6 @@
 
 NMConnection * parser_parse_file (const char *file, GError **error);
 
-void connection_update_from_resolv_conf (char **lines, NMSettingIP4Config *s_ip4);
-
 ConnectionData *connection_data_get (NMConnection *connection);
 ConnectionData *connection_data_add (NMConnection *connection, const char *ifcfg_path);
 void connection_data_copy_secrets (ConnectionData *from, ConnectionData *to);

Modified: trunk/system-settings/plugins/ifcfg-fedora/plugin.c
==============================================================================
--- trunk/system-settings/plugins/ifcfg-fedora/plugin.c	(original)
+++ trunk/system-settings/plugins/ifcfg-fedora/plugin.c	Wed Mar 19 03:08:32 2008
@@ -40,6 +40,8 @@
 #define IFCFG_PLUGIN_NAME "ifcfg-fedora"
 #define IFCFG_PLUGIN_INFO "(c) 2007 - 2008 Red Hat, Inc.  To report bugs please use the NetworkManager mailing list."
 
+#define IFCFG_DIR SYSCONFDIR"/sysconfig/network-scripts/"
+
 static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
 
 G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
@@ -53,10 +55,8 @@
 	gboolean initialized;
 	GSList *connections;
 
-	char *profile;
-
 	int ifd;
-	int profile_wd;
+	int wd;
 	GHashTable *watch_table;
 } SCPluginIfcfgPrivate;
 
@@ -72,25 +72,6 @@
 	return error_quark;
 }
 
-static char *
-get_current_profile_path (void)
-{
-	shvarFile *file;
-	char *buf, *path;
-
-	if (!(file = svNewFile (SYSCONFDIR"/sysconfig/network")))
-		return NULL;
-
-	buf = svGetValue (file, "CURRENT_PROFILE");
-	if (!buf)
-		buf = strdup ("default");
-	svCloseFile (file);
-
-	path = g_strdup_printf (SYSCONFDIR "/sysconfig/networking/profiles/%s/", buf);
-	g_free (buf);
-	return path;
-}
-
 #define AUTO_WIRED_STAMP_FILE SYSCONFDIR"/NetworkManager/auto-wired-stamp"
 #define AUTO_WIRED_FILE_NAME  _("Auto Wired")
 
@@ -162,17 +143,16 @@
 }
 
 static NMConnection *
-build_one_connection (const char *profile_path, const char *filename)
+build_one_connection (const char *path)
 {
 	NMConnection *connection;
 	GError *error = NULL;
 
-	g_return_val_if_fail (profile_path != NULL, NULL);
-	g_return_val_if_fail (filename != NULL, NULL);
+	g_return_val_if_fail (path != NULL, NULL);
 
-	PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename);
+	PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", path);
 
-	connection = parser_parse_file (filename, &error);
+	connection = parser_parse_file (path, &error);
 	if (connection) {
 		NMSettingConnection *s_con;
 
@@ -189,90 +169,50 @@
 }
 
 static NMConnection *
-handle_new_ifcfg (const char *profile_path,
-                  const char *file,
+handle_new_ifcfg (const char *basename,
                   const int inotify_fd,
                   GHashTable *watch_table)
 {
-	NMConnection *connection;
+	NMConnection *connection = NULL;
 	ConnectionData *cdata;
-	char *keys_file, *basename;
+	char *keys_file;
+	char *path;
 
-	connection = build_one_connection (profile_path, file);
-	if (!connection)
+	g_return_val_if_fail (basename != NULL, NULL);
+	g_return_val_if_fail (watch_table != NULL, NULL);
+
+	path = g_build_filename (IFCFG_DIR, basename, NULL);
+	if (!path) {
+		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "not enough memory for new connection.");
 		return NULL;
+	}
+
+	connection = build_one_connection (path);
+	if (!connection)
+		goto out;
 
 	/* Watch the file too so we can match up the watch descriptor with the
 	 * path we care about if the file is a hardlink.
 	 */
-	watch_path (file, inotify_fd, watch_table);
+	watch_path (path, inotify_fd, watch_table);
 
 	/* If there's a keys file watch that too */
-	basename = g_path_get_basename (file);
-	if (basename) {
-		keys_file = g_strdup_printf ("%s" KEYS_TAG "%s", profile_path, basename + strlen (IFCFG_TAG));
-		if (keys_file && g_file_test (keys_file, G_FILE_TEST_EXISTS))
-			watch_path (keys_file, inotify_fd, watch_table);
-		g_free (keys_file);
-		g_free (basename);
-	}
+	keys_file = g_strdup_printf (IFCFG_DIR KEYS_TAG "%s", basename + strlen (IFCFG_TAG));
+	if (keys_file && g_file_test (keys_file, G_FILE_TEST_EXISTS))
+		watch_path (keys_file, inotify_fd, watch_table);
+	g_free (keys_file);
 
 	cdata = connection_data_get (connection);
 	if (cdata->ignored) {
 		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' because "
-		              "NM_CONTROLLED was false.", file);
+		              "NM_CONTROLLED was false.", basename);
 	}
 
+out:
+	g_free (path);
 	return connection;
 }
 
-static GSList *
-get_connections_for_profile (const char *profile_path,
-                             const int inotify_fd,
-                             GHashTable *watch_table)
-{
-	GSList *connections = NULL;
-	GDir *dir;
-	const char *item;
-	char *resolv_conf;
-
-	g_return_val_if_fail (profile_path != NULL, NULL);
-	g_return_val_if_fail (watch_table != NULL, NULL);
-
-	dir = g_dir_open (profile_path, 0, NULL);
-	if (!dir) {
-		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "couldn't access network profile directory '%s'.", profile_path);
-		return NULL;
-	}
-
-	while ((item = g_dir_read_name (dir))) {
-		NMConnection *connection;
-		char *ifcfg_file;
-
-		if (strncmp (item, IFCFG_TAG, strlen (IFCFG_TAG)))
-			continue;
-
-		ifcfg_file = g_build_filename (profile_path, item, NULL);
-
-		connection = handle_new_ifcfg (profile_path, ifcfg_file, inotify_fd, watch_table);
-		if (connection)
-			connections = g_slist_append (connections, connection);
-
-		g_free (ifcfg_file);
-	}
-	g_dir_close (dir);
-
-	watch_path (profile_path, inotify_fd, watch_table);
-
-	/* Watch resolv.conf too */
-	resolv_conf = g_strdup_printf ("%sresolv.conf", profile_path);
-	if (g_file_test (resolv_conf, G_FILE_TEST_EXISTS))
-		watch_path (resolv_conf, inotify_fd, watch_table);
-	g_free (resolv_conf);
-
-	return connections;
-}
-
 static void
 release_one_connection (gpointer item, gpointer user_data)
 {
@@ -313,9 +253,11 @@
 }
 
 static void
-reload_all_connections (SCPluginIfcfg *plugin)
+read_all_connections (SCPluginIfcfg *plugin)
 {
 	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+	GDir *dir;
+	const char *item;
 	GSList *iter;
 	gboolean have_wired = FALSE;
 
@@ -323,8 +265,22 @@
 
 	priv->watch_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
 
-	/* Add connections from the current profile */
-	priv->connections = get_connections_for_profile (priv->profile, priv->ifd, priv->watch_table);
+	dir = g_dir_open (IFCFG_DIR, 0, NULL);
+	if (dir) {
+		while ((item = g_dir_read_name (dir))) {
+			NMConnection *connection;
+
+			if (strncmp (item, IFCFG_TAG, strlen (IFCFG_TAG)))
+				continue;
+
+			connection = handle_new_ifcfg (item, priv->ifd, priv->watch_table);
+			if (connection)
+				priv->connections = g_slist_append (priv->connections, connection);
+		}
+		g_dir_close (dir);
+	} else {
+		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "couldn't access network config directory '" IFCFG_DIR "'.");
+	}
 
 	/* Check if we need to write out the auto wired connection */
 	for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
@@ -337,7 +293,7 @@
 	}
 
 	if (!have_wired)
-		write_auto_wired_connection (priv->profile);
+		write_auto_wired_connection (IFCFG_DIR);
 }
 
 static GSList *
@@ -348,7 +304,7 @@
 	GSList *list = NULL, *iter;
 
 	if (!priv->initialized)
-		reload_all_connections (plugin);
+		read_all_connections (plugin);
 
 	for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
 		NMConnection *connection = NM_CONNECTION (iter->data);
@@ -445,9 +401,10 @@
 
 static void
 handle_connection_changed (SCPluginIfcfg *plugin,
-                           const char *filename)
+                           const char *basename)
 {
 	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
+	char *filename = NULL;
 	NMConnection *new_connection;
 	NMConnection *existing;
 	ConnectionData *new_cdata;
@@ -455,8 +412,22 @@
 	ConnectionData *existing_cdata;
 	gboolean remove = FALSE;
 
+	if (!strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG))) {
+		filename = g_strdup_printf (IFCFG_DIR "%s", basename);
+	} else if (!strncmp (basename, KEYS_TAG, strlen (KEYS_TAG))) {
+		filename = g_strdup_printf (IFCFG_DIR IFCFG_TAG "%s", basename + strlen (KEYS_TAG));
+	} else {
+		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "ignored event for '%s'.", basename);
+		return;
+	}
+
+	if (!filename) {
+		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "not enough memory to update connection.");
+		return;
+	}
+
 	/* Could return NULL if the connection got deleted */
-	new_connection = build_one_connection (priv->profile, filename);
+	new_connection = build_one_connection (filename);
 
 	existing = find_connection_by_path (priv->connections, filename);
 	if (!existing) {
@@ -471,6 +442,7 @@
 				g_signal_emit_by_name (plugin, "connection-added", new_connection);
 			}
 		}
+		g_free (filename);
 		return;
 	}
 
@@ -526,142 +498,57 @@
 		g_object_unref (existing);
 		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    removed connection");
 	}
-}
-
-static void
-handle_resolv_conf_changed (SCPluginIfcfg *plugin, const char *path)
-{
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
-	char *contents = NULL;
-	char **lines = NULL;
-	GSList *iter;
 
-	g_return_if_fail (path != NULL);
-
-	g_file_get_contents (path, &contents, NULL, NULL);
-	if (contents) {
-		lines = g_strsplit (contents, "\n", 0);
-		if (lines && !*lines) {
-			g_strfreev (lines);
-			lines = NULL;
-		}
-	}
-
-	if (lines) {
-		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Updating connections because %s changed.", path);
-	} else {
-		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Updating connections because %s was deleted.", path);
-	}
-
-	for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
-		NMConnection *connection = NM_CONNECTION (iter->data);
-		NMSettingIP4Config *s_ip4;
-
-		s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
-		if (s_ip4) {
-			ConnectionData *cdata;
-
-			cdata = connection_data_get (connection);
-			g_assert (cdata);
-
-			connection_update_from_resolv_conf (lines, s_ip4);
-
-			if (!cdata->ignored)
-				g_signal_emit_by_name (plugin, "connection-updated", connection);
-		}
-	}
-
-	if (lines)
-		g_strfreev (lines);
-	g_free (contents);
+	g_free (filename);
 }
 
 static void
-handle_profile_item_changed (SCPluginIfcfg *plugin, const char *path)
+handle_new_item (SCPluginIfcfg *plugin, const char *basename)
 {
 	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
-	char *basename;
-
-	g_return_if_fail (plugin != NULL);
-	g_return_if_fail (path != NULL);
+	NMConnection *connection;
+	ConnectionData *cdata;
+	char *ifcfgfile;
 
-	basename = g_path_get_basename (path);
-	if (!basename) {
-		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "not enough memory to parse connection change.");
+	if (!strncmp (basename, KEYS_TAG, strlen (KEYS_TAG))) {
+		ifcfgfile = g_strdup_printf (IFCFG_TAG "%s", basename + strlen (KEYS_TAG));
+		handle_connection_changed (plugin, ifcfgfile);
+		g_free (ifcfgfile);
 		return;
 	}
 
-	if (!strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG)))
-		handle_connection_changed (plugin, path);
-	else if (!strncmp (basename, KEYS_TAG, strlen (KEYS_TAG))) {
-		char *ifcfg;
-		
-		ifcfg = g_strdup_printf ("%s" IFCFG_TAG "%s", priv->profile, basename + strlen (KEYS_TAG));
-		if (ifcfg)
-			handle_connection_changed (plugin, ifcfg);
-		g_free (ifcfg);
-	} else if (!strcmp (basename, "resolv.conf"))
-		handle_resolv_conf_changed (plugin, path);
-
-	g_free (basename);
-}
-
-static void
-handle_profile_item_new (SCPluginIfcfg *plugin, const char *filename)
-{
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
-	char *path;
-
-	path = g_strdup_printf ("%s%s", priv->profile, filename);
-	if (!path)
+	if (strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG)))
 		return;
 
-	if (!strcmp (filename, "resolv.conf")) {
-		watch_path (path, priv->ifd, priv->watch_table);
-		handle_resolv_conf_changed (plugin, path);
-	} else if (!strncmp (filename, IFCFG_TAG, strlen (IFCFG_TAG))) {
-		NMConnection *connection;
-
-		connection = handle_new_ifcfg (priv->profile, path, priv->ifd, priv->watch_table);
-		if (connection) {
-			ConnectionData *cdata;
-
-			cdata = connection_data_get (connection);
-			g_assert (cdata);
-
-			/* new connection */
-			priv->connections = g_slist_append (priv->connections, connection);
-			if (!cdata->ignored) {
-				cdata->exported = TRUE;
-				g_signal_emit_by_name (plugin, "connection-added", connection);
-			}
-		}
-	}
-
-	g_free (path);
-}
-
-typedef struct {
-	gboolean found;
-	const char *path;
-} FindInfo;
+	/* New connection */
+	connection = handle_new_ifcfg (basename, priv->ifd, priv->watch_table);
+	if (!connection)
+		return;
 
-static void
-find_path_helper (gpointer key, gpointer data, gpointer user_data)
-{
-	FindInfo *info = (FindInfo *) user_data;
+	cdata = connection_data_get (connection);
+	g_assert (cdata);
 
-	if (!info->found && !strcmp (data, info->path))
-		info->found = TRUE;
+	/* new connection */
+	priv->connections = g_slist_append (priv->connections, connection);
+	if (!cdata->ignored) {
+		cdata->exported = TRUE;
+		g_signal_emit_by_name (plugin, "connection-added", connection);
+	}
 }
 
 static gboolean
-find_path (GHashTable *table, const char *path)
+should_ignore_file (const char *basename, const char *tag)
 {
-	FindInfo info = { FALSE, path };
+	int len, tag_len;
 
-	g_hash_table_foreach (table, find_path_helper, &info);
-	return info.found;
+	g_return_val_if_fail (basename != NULL, TRUE);
+	g_return_val_if_fail (tag != NULL, TRUE);
+
+	len = strlen (basename);
+	tag_len = strlen (tag);
+	if ((len > tag_len) && !strcasecmp (basename + len - tag_len, tag))
+		return TRUE;
+	return FALSE;
 }
 
 static gboolean
@@ -689,58 +576,41 @@
 		if (!path && !strlen (filename))
 			continue;
 
-		if (evt.wd == priv->profile_wd) {
-			char *basename;
-
-			basename = g_path_get_basename (filename);
-
-			if (basename && !strcmp (basename, "network")) {
-				char *new_profile;
-
-				new_profile = get_current_profile_path ();
-				if (!new_profile) {
-					/* No new profile */
-					clear_all_connections (plugin);
-				} else if (!priv->profile || strcmp (new_profile, priv->profile)) {
-					/* Valid new profile */
-					g_free (priv->profile);
-					priv->profile = g_strdup (new_profile);
-					reload_all_connections (plugin);
-				}
-				g_free (new_profile);
+		if (evt.wd == priv->wd) {
+			if (   strncmp (filename, IFCFG_TAG, strlen (IFCFG_TAG))
+			    && strncmp (filename, KEYS_TAG, strlen (KEYS_TAG)))
+				continue;
+
+			/* ignore some files */
+			if (   should_ignore_file (filename, BAK_TAG)
+			    || should_ignore_file (filename, TILDE_TAG)
+			    || should_ignore_file (filename, ORIG_TAG)
+			    || should_ignore_file (filename, REJ_TAG))
+				continue;
+
+			if (evt.mask & (IN_CREATE | IN_MOVED_TO)) {
+				handle_new_item (plugin, filename);
+			} else if (evt.mask & (IN_DELETE | IN_MOVED_FROM)) {
+				/* Remove connection */
+				handle_connection_changed (plugin, filename);
+			} else if (evt.mask & IN_CLOSE_WRITE) {
+				/* Updated connection */
+				handle_connection_changed (plugin, filename);
 			}
-			g_free (basename);
 		} else {
-			char *fullpath;
-			gboolean path_found, delete = FALSE;
+			/* Track deletions and moves of the file itself */
+			if (   (evt.mask & IN_DELETE_SELF)
+			    || ((evt.mask & IN_MOVE_SELF) && path && !g_file_test (path, G_FILE_TEST_EXISTS))) {
+				char *basename;
 
-			/* If the item was deleted, stop tracking its watch */
-			if (evt.mask & (IN_DELETE | IN_DELETE_SELF))
-				delete = TRUE;
-
-			/* Track moves out of the profile directory */
-			if (   (evt.mask & IN_MOVE_SELF)
-			    && path
-			    && strcmp (path, priv->profile)
-			    && !strncmp (path, priv->profile, strlen (priv->profile))
-			    && !g_file_test (path, G_FILE_TEST_EXISTS))
-				delete = TRUE;
-
-			if (delete) {
 				inotify_rm_watch (priv->ifd, evt.wd);
 				g_hash_table_remove (priv->watch_table, GINT_TO_POINTER (evt.wd));
-			}
-
-			fullpath = g_strdup_printf ("%s%s", priv->profile, filename);
-			path_found = find_path (priv->watch_table, fullpath);
 
-			if (strlen (filename) && !strcmp (path, priv->profile) && !path_found) {
-				/* Some file appeared */
-				handle_profile_item_new (plugin, filename);
-			} else {
-				handle_profile_item_changed (plugin, path_found ? fullpath : path);
+				/* Remove connection */
+				basename = g_path_get_basename (path);
+				handle_connection_changed (plugin, basename);
+				g_free (basename);
 			}
-			g_free (fullpath);
 		}
 	}
 
@@ -762,19 +632,26 @@
 		return FALSE;
 	}
 
-	wd = inotify_add_watch (ifd, SYSCONFDIR "/sysconfig/", IN_CLOSE_WRITE);
+	wd = inotify_add_watch (ifd, IFCFG_DIR, 
+	                        IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MOVE);
 	if (wd == -1) {
 		g_set_error (error, ifcfg_plugin_error_quark (), 0,
-		             "Couldn't monitor %s", SYSCONFDIR "/sysconfig/");
+		             "Couldn't monitor " IFCFG_DIR);
 		close (ifd);
 		return FALSE;
 	}
 
 	priv->ifd = ifd;
-	priv->profile_wd = wd;
+	priv->wd = wd;
 
 	/* Watch the inotify descriptor for file/directory change events */
 	channel = g_io_channel_unix_new (ifd);
+	if (!channel) {
+		g_set_error (error, ifcfg_plugin_error_quark (), 0,
+		             "Couldn't create new GIOChannel");
+		close (ifd);
+		return FALSE;
+	}
 	g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
 	g_io_channel_set_encoding (channel, NULL, NULL); 
 
@@ -791,13 +668,8 @@
 init (NMSystemConfigInterface *config)
 {
 	SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
-	SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
 	GError *error = NULL;
 
-	priv->profile = get_current_profile_path ();
-	if (!priv->profile)
-		PLUGIN_WARN (IFCFG_PLUGIN_NAME, "could not determine network profile path.");
-
 	if (!sc_plugin_inotify_init (plugin, &error)) {
 		PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "    inotify error: %s",
 		              error->message ? error->message : "(unknown)");
@@ -813,6 +685,8 @@
 static void
 dispose (GObject *object)
 {
+	clear_all_connections (SC_PLUGIN_IFCFG (object));
+
 	G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]