about summary refs log tree commit diff
path: root/src/settings/plugins/keyfile/writer.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-10-28 23:04:16 +0200
committerMichael Biebl <biebl@debian.org>2011-10-28 23:04:16 +0200
commit485d149fe80915d94ed49ea6c2c0552cf7a3e79a (patch)
tree6a48492b46b8c1e3df1c58626c28f05a978c61f7 /src/settings/plugins/keyfile/writer.c
parent263bf4c0c89bb88dc995acd9a6a2de9095fbd461 (diff)
Imported Upstream version 0.9.1.95 upstream/0.9.1.95
Diffstat (limited to 'src/settings/plugins/keyfile/writer.c')
-rw-r--r--src/settings/plugins/keyfile/writer.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
index 060093ce..db43b233 100644
--- a/src/settings/plugins/keyfile/writer.c
+++ b/src/settings/plugins/keyfile/writer.c
@@ -44,6 +44,7 @@
 #include <ctype.h>
 
 #include "nm-dbus-glib-types.h"
+#include "nm-glib-compat.h"
 #include "writer.h"
 #include "common.h"
 
@@ -483,6 +484,7 @@ ssid_writer (GKeyFile *file,
 	GByteArray *array;
 	const char *setting_name = nm_setting_get_name (setting);
 	gboolean new_format = TRUE;
+	unsigned int semicolons = 0;
 	int i, *tmp_array;
 	char *ssid;
 
@@ -501,11 +503,24 @@ ssid_writer (GKeyFile *file,
 			new_format = FALSE;
 			break;
 		}
+		if (c == ';')
+			semicolons++;
 	}
 
 	if (new_format) {
-		ssid = g_malloc0 (array->len + 1);
-		memcpy (ssid, array->data, array->len);
+		ssid = g_malloc0 (array->len + semicolons + 1);
+		if (semicolons == 0)
+			memcpy (ssid, array->data, array->len);
+		else {
+			/* Escape semicolons with backslashes to make strings
+			 * containing ';', such as '16;17;' unambiguous */
+			int j = 0;
+			for (i = 0; i < array->len; i++) {
+				if (array->data[i] == ';')
+					ssid[j++] = '\\';
+				ssid[j++] = array->data[i];
+			}
+		}
 		g_key_file_set_string (file, setting_name, key, ssid);
 		g_free (ssid);
 	} else {
@@ -876,7 +891,7 @@ write_setting_value (NMSetting *setting,
 	} else if (type == G_TYPE_BOOLEAN) {
 		g_key_file_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value));
 	} else if (type == G_TYPE_CHAR) {
-		g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_char (value));
+		g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_schar (value));
 	} else if (type == DBUS_TYPE_G_UCHAR_ARRAY) {
 		GByteArray *array;
 
@@ -993,15 +1008,27 @@ _internal_write_connection (NMConnection *connection,
 
 		path = g_strdup_printf ("%s/%s-%s", keyfile_dir, filename, nm_connection_get_uuid (connection));
 		if (g_file_test (path, G_FILE_TEST_EXISTS)) {
-			/* Hmm, this is odd. Give up. */
-			g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
-				         "%s.%d: could not find suitable keyfile file name (%s already used)",
-				         __FILE__, __LINE__, path);
-			g_free (path);
-			goto out;
+			if (existing_path == NULL || g_strcmp0 (path, existing_path) != 0) {
+				/* This should not happen. But, it actually occurs when
+				 * two connections have the same UUID, and one of the connections
+				 * is edited to contain the same ID as the other one.
+				 * Give up.
+				 */
+				g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,
+				                    "%s.%d: could not find suitable keyfile file name (%s already used)",
+				                    __FILE__, __LINE__, path);
+				g_free (path);
+				goto out;
+			}
 		}
 	}
 
+	/* In case of updating the connection and changing the file path,
+	 * we need to remove the old one, not to end up with two connections.
+	 */
+	if (existing_path != NULL && strcmp (path, existing_path) != 0)
+		unlink (existing_path);
+
 	g_file_set_contents (path, data, len, error);
 	if (chown (path, owner_uid, owner_grp) < 0) {
 		g_set_error (error, KEYFILE_PLUGIN_ERROR, 0,