summaryrefslogtreecommitdiff
path: root/system-settings/plugins/keyfile/plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'system-settings/plugins/keyfile/plugin.c')
-rw-r--r--system-settings/plugins/keyfile/plugin.c147
1 files changed, 109 insertions, 38 deletions
diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c
index 36f47ccdc5..da6456d983 100644
--- a/system-settings/plugins/keyfile/plugin.c
+++ b/system-settings/plugins/keyfile/plugin.c
@@ -16,13 +16,14 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008 - 2010 Red Hat, Inc.
*/
#include <config.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
+#include <netinet/ether.h>
#include <string.h>
#include <gmodule.h>
@@ -38,9 +39,8 @@
#include "nm-system-config-interface.h"
#include "nm-keyfile-connection.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."
+#include "common.h"
+#include "utils.h"
#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
@@ -74,31 +74,52 @@ read_connections (NMSystemConfigInterface *config)
{
SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
GDir *dir;
- GError *err = NULL;
+ GError *error = NULL;
+ const char *item;
+
+ dir = g_dir_open (KEYFILE_DIR, 0, &error);
+ if (!dir) {
+ PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Cannot read directory '%s': (%d) %s",
+ KEYFILE_DIR,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
- dir = g_dir_open (KEYFILE_DIR, 0, &err);
- if (dir) {
- const char *item;
+ while ((item = g_dir_read_name (dir))) {
+ NMKeyfileConnection *connection;
+ char *full_path;
- while ((item = g_dir_read_name (dir))) {
- NMKeyfileConnection *connection;
- char *full_path;
+ if (utils_should_ignore_file (item))
+ continue;
- full_path = g_build_filename (KEYFILE_DIR, item, NULL);
- connection = nm_keyfile_connection_new (full_path);
- if (connection) {
- g_hash_table_insert (priv->hash,
- (gpointer) nm_keyfile_connection_get_filename (connection),
- connection);
- }
- g_free (full_path);
- }
+ full_path = g_build_filename (KEYFILE_DIR, item, NULL);
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item);
+ connection = nm_keyfile_connection_new (full_path, &error);
+ if (connection) {
+ NMSettingConnection *s_con;
+ const char *cid;
- g_dir_close (dir);
- } else {
- g_warning ("Can not read directory '%s': %s", KEYFILE_DIR, err->message);
- g_error_free (err);
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+
+ cid = nm_setting_connection_get_id (s_con);
+ g_assert (cid);
+
+ g_hash_table_insert (priv->hash,
+ (gpointer) nm_keyfile_connection_get_filename (connection),
+ connection);
+
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", cid);
+ } else {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+ }
+ g_free (full_path);
}
+ g_dir_close (dir);
}
typedef struct {
@@ -148,28 +169,46 @@ update_connection_settings (NMKeyfileConnection *orig,
/* Monitoring */
static void
+remove_connection (SCPluginKeyfile *self,
+ NMKeyfileConnection *connection,
+ const char *name)
+{
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (name != NULL);
+
+ /* Removing from the hash table should drop the last reference */
+ g_object_ref (connection);
+ g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->hash, name);
+ g_signal_emit_by_name (connection, "removed");
+ g_object_unref (connection);
+}
+
+static void
dir_changed (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event_type,
- gpointer user_data)
+ 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;
NMKeyfileConnection *connection;
+ GError *error = NULL;
name = g_file_get_path (file);
+ if (utils_should_ignore_file (name)) {
+ g_free (name);
+ return;
+ }
+
connection = g_hash_table_lookup (priv->hash, name);
switch (event_type) {
case G_FILE_MONITOR_EVENT_DELETED:
if (connection) {
- /* Removing from the hash table should drop the last reference */
- g_object_ref (connection);
- g_hash_table_remove (priv->hash, name);
- g_signal_emit_by_name (connection, "removed");
- g_object_unref (connection);
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", name);
+ remove_connection (SC_PLUGIN_KEYFILE (config), connection, name);
}
break;
case G_FILE_MONITOR_EVENT_CREATED:
@@ -178,14 +217,27 @@ dir_changed (GFileMonitor *monitor,
/* Update */
NMKeyfileConnection *tmp;
- tmp = (NMKeyfileConnection *) nm_keyfile_connection_new (name);
+ tmp = nm_keyfile_connection_new (name, &error);
if (tmp) {
- update_connection_settings (connection, tmp);
+ if (!nm_connection_compare (NM_CONNECTION (connection),
+ NM_CONNECTION (tmp),
+ NM_SETTING_COMPARE_FLAG_EXACT)) {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name);
+ update_connection_settings (connection, tmp);
+ }
g_object_unref (tmp);
+ } else {
+ /* Error; remove the connection */
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
+ remove_connection (SC_PLUGIN_KEYFILE (config), connection, name);
}
} else {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name);
+
/* New */
- connection = nm_keyfile_connection_new (name);
+ connection = nm_keyfile_connection_new (name, &error);
if (connection) {
NMSettingConnection *s_con;
const char *connection_uuid;
@@ -234,6 +286,10 @@ dir_changed (GFileMonitor *monitor,
connection);
g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection);
}
+ } else {
+ PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s",
+ (error && error->message) ? error->message : "(unknown)");
+ g_clear_error (&error);
}
}
break;
@@ -363,8 +419,23 @@ get_unmanaged_specs (NMSystemConfigInterface *config)
udis = g_strsplit (str, ";", -1);
g_free (str);
- for (i = 0; udis[i] != NULL; i++)
- specs = g_slist_append (specs, udis[i]);
+ for (i = 0; udis[i] != NULL; i++) {
+ /* Verify unmanaged specification and add it to the list */
+ if (strlen (udis[i]) > 4 && !strncmp (udis[i], "mac:", 4) && ether_aton (udis[i] + 4)) {
+ char *p = udis[i];
+
+ /* To accept uppercase MACs in configuration file, we have to convert values to lowercase here.
+ * Unmanaged MACs in specs are always in lowercase. */
+ while (*p) {
+ *p = g_ascii_tolower (*p);
+ p++;
+ }
+ specs = g_slist_append (specs, udis[i]);
+ } else {
+ g_warning ("Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]);
+ g_free (udis[i]);
+ }
+ }
g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */
}