NetworkManager r4018 - in trunk: . system-settings/plugins/keyfile
- From: dcbw svn gnome org
- To: svn-commits-list gnome org
- Subject: NetworkManager r4018 - in trunk: . system-settings/plugins/keyfile
- Date: Wed, 27 Aug 2008 03:09:14 +0000 (UTC)
Author: dcbw
Date: Wed Aug 27 03:09:14 2008
New Revision: 4018
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=4018&view=rev
Log:
2008-08-26 Dan Williams <dcbw redhat com>
* system-settings/plugins/keyfile/nm-keyfile-connection.c
- (update): Update filename of the connection if the connection id
was changed
* system-settings/plugins/keyfile/plugin.c
- (dir_changed): first pass at handling connection renames correctly
* system-settings/plugins/keyfile/writer.c
system-settings/plugins/keyfile/writer.h
- (write_connection): replace '/' with '*' when writing out the filename
from the connection id
Modified:
trunk/ChangeLog
trunk/system-settings/plugins/keyfile/nm-keyfile-connection.c
trunk/system-settings/plugins/keyfile/plugin.c
trunk/system-settings/plugins/keyfile/writer.c
trunk/system-settings/plugins/keyfile/writer.h
Modified: trunk/system-settings/plugins/keyfile/nm-keyfile-connection.c
==============================================================================
--- trunk/system-settings/plugins/keyfile/nm-keyfile-connection.c (original)
+++ trunk/system-settings/plugins/keyfile/nm-keyfile-connection.c Wed Aug 27 03:09:14 2008
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
#include <string.h>
#include <glib/gstdio.h>
@@ -31,8 +31,8 @@
g_return_val_if_fail (filename != NULL, NULL);
return (NMKeyfileConnection *) g_object_new (NM_TYPE_KEYFILE_CONNECTION,
- NM_KEYFILE_CONNECTION_FILENAME, filename,
- NULL);
+ NM_KEYFILE_CONNECTION_FILENAME, filename,
+ NULL);
}
const char *
@@ -51,14 +51,26 @@
static gboolean
update (NMExportedConnection *exported,
- GHashTable *new_settings,
- GError **error)
+ GHashTable *new_settings,
+ GError **error)
{
+ NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (exported);
gboolean success;
success = NM_EXPORTED_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->update (exported, new_settings, error);
- if (success)
- success = write_connection (nm_exported_connection_get_connection (exported), error);
+ if (success) {
+ NMConnection *connection;
+ char *filename = NULL;
+
+ connection = nm_exported_connection_get_connection (exported);
+ success = write_connection (connection, &filename, error);
+ if (success && filename && strcmp (priv->filename, filename)) {
+ /* Update the filename if it changed */
+ g_free (priv->filename);
+ priv->filename = filename;
+ } else
+ g_free (filename);
+ }
return success;
}
@@ -116,7 +128,7 @@
GError *error = NULL;
s_con->uuid = nm_utils_uuid_generate ();
- if (!write_connection (wrapped, &error)) {
+ if (!write_connection (wrapped, NULL, &error)) {
g_warning ("Couldn't update connection %s with a UUID: (%d) %s",
s_con->id, error ? error->code : 0,
error ? error->message : "unknown");
Modified: trunk/system-settings/plugins/keyfile/plugin.c
==============================================================================
--- trunk/system-settings/plugins/keyfile/plugin.c (original)
+++ trunk/system-settings/plugins/keyfile/plugin.c Wed Aug 27 03:09:14 2008
@@ -4,6 +4,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
+#include <string.h>
#include <gmodule.h>
#include <glib.h>
#include <glib/gstdio.h>
@@ -42,25 +43,10 @@
gboolean disposed;
} SCPluginKeyfilePrivate;
-static NMKeyfileConnection *
-read_one_connection (NMSystemConfigInterface *config, const char *filename)
-{
- SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
- NMKeyfileConnection *connection;
-
- connection = nm_keyfile_connection_new (filename);
- if (connection) {
- g_hash_table_insert (priv->hash,
- (gpointer) nm_keyfile_connection_get_filename (connection),
- g_object_ref (connection));
- }
-
- return connection;
-}
-
static void
read_connections (NMSystemConfigInterface *config)
{
+ SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config);
GDir *dir;
GError *err = NULL;
@@ -69,10 +55,16 @@
const char *item;
while ((item = g_dir_read_name (dir))) {
+ NMKeyfileConnection *connection;
char *full_path;
full_path = g_build_filename (KEYFILE_DIR, item, NULL);
- read_one_connection (config, full_path);
+ 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);
}
@@ -83,6 +75,45 @@
}
}
+typedef struct {
+ const char *uuid;
+ NMKeyfileConnection *found;
+} FindByUUIDInfo;
+
+static void
+find_by_uuid (gpointer key, gpointer data, gpointer user_data)
+{
+ NMKeyfileConnection *keyfile = NM_KEYFILE_CONNECTION (key);
+ FindByUUIDInfo *info = user_data;
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+
+ if (info->found)
+ return;
+
+ connection = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (keyfile));
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ if (s_con && s_con->uuid) {
+ if (!strcmp (info->uuid, s_con->uuid))
+ info->found = keyfile;
+ }
+}
+
+static gboolean
+update_connection_settings (NMExportedConnection *orig,
+ NMExportedConnection *new,
+ GError **error)
+{
+ GHashTable *settings;
+ gboolean success;
+
+ settings = nm_connection_to_hash (nm_exported_connection_get_connection (new));
+ success = nm_exported_connection_update (orig, settings, error);
+ g_hash_table_destroy (settings);
+
+ return success;
+}
+
/* Monitoring */
static void
@@ -103,8 +134,11 @@
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);
nm_exported_connection_signal_removed (NM_EXPORTED_CONNECTION (connection));
+ g_object_unref (connection);
}
break;
case G_FILE_MONITOR_EVENT_CREATED:
@@ -115,18 +149,75 @@
tmp = (NMExportedConnection *) nm_keyfile_connection_new (name);
if (tmp) {
- GHashTable *settings;
+ GError *error = NULL;
- settings = nm_connection_to_hash (nm_exported_connection_get_connection (tmp));
- nm_exported_connection_update (NM_EXPORTED_CONNECTION (connection), settings, NULL);
- g_hash_table_destroy (settings);
+ if (!update_connection_settings (NM_EXPORTED_CONNECTION (connection), tmp, &error)) {
+ g_warning ("%s: couldn't update connection settings: (%d) %s",
+ __func__, error ? error->code : 0,
+ error ? error->message : "unknown");
+ g_error_free (error);
+ }
g_object_unref (tmp);
}
} else {
/* New */
- connection = read_one_connection (config, name);
- if (connection)
- g_signal_emit_by_name (config, "connection-added", connection);
+ connection = nm_keyfile_connection_new (name);
+ if (connection) {
+ NMConnection *tmp;
+ NMSettingConnection *s_con;
+ NMKeyfileConnection *found = NULL;
+
+ /* Connection renames will show up as different files but with
+ * the same UUID. Try to find the original connection.
+ */
+ tmp = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
+ s_con = (NMSettingConnection *) nm_connection_get_setting (tmp, NM_TYPE_SETTING_CONNECTION);
+ if (s_con && s_con->uuid) {
+ FindByUUIDInfo info = { .found = NULL, .uuid = s_con->uuid };
+
+ g_hash_table_foreach (priv->hash, find_by_uuid, &info);
+ found = info.found;
+ }
+
+ /* A connection rename is treated just like an update except
+ * there's a bit more housekeeping with the hash table.
+ */
+ if (found) {
+ const char *old_filename = nm_keyfile_connection_get_filename (connection);
+ GError *error = NULL;
+
+ /* Removing from the hash table should drop the last reference,
+ * but of course we want to keep the connection around.
+ */
+ g_object_ref (found);
+ g_hash_table_remove (priv->hash, old_filename);
+
+ /* Updating settings should update the NMKeyfileConnection's
+ * filename property too.
+ */
+ if (!update_connection_settings (NM_EXPORTED_CONNECTION (found),
+ NM_EXPORTED_CONNECTION (connection),
+ &error)) {
+ g_warning ("%s: couldn't update connection settings: (%d) %s",
+ __func__, error ? error->code : 0,
+ error ? error->message : "unknown");
+ g_error_free (error);
+ }
+
+ /* Re-insert the connection back into the hash with the new filename */
+ g_hash_table_insert (priv->hash,
+ (gpointer) nm_keyfile_connection_get_filename (found),
+ found);
+
+ /* Get rid of the temporary connection */
+ g_object_unref (connection);
+ } else {
+ g_hash_table_insert (priv->hash,
+ (gpointer) nm_keyfile_connection_get_filename (connection),
+ connection);
+ g_signal_emit_by_name (config, "connection-added", connection);
+ }
+ }
}
break;
default:
@@ -186,7 +277,7 @@
NMConnection *connection,
GError **error)
{
- return write_connection (connection, error);
+ return write_connection (connection, NULL, error);
}
/* GObject */
Modified: trunk/system-settings/plugins/keyfile/writer.c
==============================================================================
--- trunk/system-settings/plugins/keyfile/writer.c (original)
+++ trunk/system-settings/plugins/keyfile/writer.c Wed Aug 27 03:09:14 2008
@@ -263,15 +263,38 @@
}
}
+char *
+writer_id_to_filename (const char *id)
+{
+ char *filename, *f;
+ const char *i = id;
+
+ f = filename = g_malloc0 (strlen (id) + 1);
+
+ /* Convert '/' to '*' */
+ while (*i) {
+ if (*i == '/')
+ *f++ = '*';
+ else
+ *f++ = *i;
+ i++;
+ }
+
+ return filename;
+}
+
gboolean
-write_connection (NMConnection *connection, GError **error)
+write_connection (NMConnection *connection, char **out_path, GError **error)
{
NMSettingConnection *s_con;
GKeyFile *key_file;
char *data;
gsize len;
gboolean success = FALSE;
- GError *err = NULL;
+ char *filename, *path;
+
+ if (out_path)
+ g_return_val_if_fail (*out_path == NULL, FALSE);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
if (!s_con)
@@ -279,30 +302,28 @@
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);
- if (chown (filename, 0, 0) < 0) {
- g_warning ("Error chowning '%s': %d", filename, errno);
- unlink (filename);
- } else
- success = TRUE;
-
- g_free (filename);
- }
-
- if (err) {
- g_warning ("Error while saving connection: %s", err->message);
- g_error_free (err);
+ data = g_key_file_to_data (key_file, &len, error);
+ if (!data)
+ goto out;
+
+ filename = writer_id_to_filename (s_con->id);
+ path = g_build_filename (KEYFILE_DIR, filename, NULL);
+ g_free (filename);
+
+ g_file_set_contents (path, data, len, error);
+ chmod (path, S_IRUSR | S_IWUSR);
+ if (chown (path, 0, 0) < 0) {
+ g_warning ("Error chowning '%s': %d", path, errno);
+ unlink (path);
+ } else {
+ if (out_path)
+ *out_path = g_strdup (path);
+ success = TRUE;
}
+ g_free (path);
+out:
g_free (data);
g_key_file_free (key_file);
-
return success;
}
Modified: trunk/system-settings/plugins/keyfile/writer.h
==============================================================================
--- trunk/system-settings/plugins/keyfile/writer.h (original)
+++ trunk/system-settings/plugins/keyfile/writer.h Wed Aug 27 03:09:14 2008
@@ -6,6 +6,8 @@
#include <glib.h>
#include <nm-connection.h>
-gboolean write_connection (NMConnection *connection, GError **error);
+gboolean write_connection (NMConnection *connection, char **out_path, GError **error);
+
+char *writer_id_to_filename (const char *id);
#endif /* _KEYFILE_PLUGIN_WRITER_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]