Index: libedataserverui/e-passwords.c
===================================================================
--- libedataserverui/e-passwords.c	(revision 8117)
+++ libedataserverui/e-passwords.c	(working copy)
@@ -110,6 +110,92 @@ static EDList request_list = E_DLIST_INI
 static int idle_id;
 static int ep_online_state = TRUE;
 
+#define KEY_FILE_GROUP_PREFIX "Passwords-"
+static GKeyFile *key_file = NULL;
+
+static gchar *
+ep_key_file_get_filename (void)
+{
+	/* XXX It would be nice to someday move this data elsewhere, or else
+	 * fully migrate to GNOME Keyring or whatever software supercedes it.
+	 * Evolution is one of the few remaining GNOME-2 applications that
+	 * still uses the deprecated ~/.gnome2_private directory. */
+
+	return g_build_filename (g_get_home_dir (),
+		".gnome2_private", "Evolution", NULL);
+}
+
+static gchar *
+ep_key_file_get_group (const gchar *component)
+{
+	return g_strconcat (KEY_FILE_GROUP_PREFIX, component, NULL);
+}
+
+static gchar *
+ep_key_file_normalize_key (const gchar *key)
+{
+	/* XXX Previous code converted all slashes and equal signs in the
+	 * key to underscores for use with "gnome-config" functions.  While
+	 * it may not be necessary to convert slashes for use with GKeyFile,
+	 * and an equal sign was most likely never encountered in a key, we
+	 * continue to do the same for backward-compatibility. */
+
+	gchar *normalized_key, *cp;
+
+	normalized_key = g_strdup (key);
+	for (cp = normalized_key; *cp != '\0'; cp++)
+		if (*cp == '/' || *cp == '=')
+			*cp = '_';
+
+	return normalized_key;
+}
+
+static void
+ep_key_file_load (void)
+{
+	gchar *filename;
+	GError *error = NULL;
+
+	filename = ep_key_file_get_filename ();
+
+	if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+		goto exit;
+
+	g_key_file_load_from_file (
+		key_file, filename, G_KEY_FILE_KEEP_COMMENTS |
+		G_KEY_FILE_KEEP_TRANSLATIONS, &error);
+
+	if (error != NULL) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+exit:
+	g_free (filename);
+}
+
+static void
+ep_key_file_save (void)
+{
+	gchar *contents;
+	gchar *filename;
+	gsize length;
+	GError *error = NULL;
+
+	filename = ep_key_file_get_filename ();
+	contents = g_key_file_to_data (key_file, &length, NULL);
+
+	g_file_set_contents (filename, contents, length, &error);
+
+	if (error != NULL) {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_free (contents);
+	g_free (filename);
+}
+
 static gchar *
 ep_password_encode (const gchar *password)
 {
@@ -264,14 +350,20 @@ ep_clear_passwords_keyring(EPassMsg *msg
 static void
 ep_clear_passwords_file(EPassMsg *msg)
 {
-	char *path;
+	gchar *group;
+	GError *error = NULL;
 
-	path = g_strdup_printf ("/Evolution/Passwords-%s", msg->component);
+	group = ep_key_file_get_group (msg->component);
 
-	gnome_config_private_clean_section (path);
-	gnome_config_private_sync_file ("/Evolution");
+	g_key_file_remove_group (key_file, group, &error);
+	if (error == NULL)
+		ep_key_file_save ();
+	else {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
 
-	g_free (path);
+	g_free (group);
 
 	if (!msg->noreply)
 		e_msgport_reply(&msg->msg);
@@ -336,47 +428,24 @@ ep_forget_passwords_keyring(EPassMsg *ms
 static void
 ep_forget_passwords_file(EPassMsg *msg)
 {
-	void *it;
-	char *key;
+	gchar **groups;
+	gsize length, ii;
 
-	it = gnome_config_private_init_iterator_sections("/Evolution");
-	while ( (it = gnome_config_iterator_next(it, &key, NULL)) ) {
-		if (0 == strncmp(key, "Passwords-", 10)) {
-			char *section = g_strdup_printf("/Evolution/%s", key);
+	g_hash_table_remove_all (passwords);
 
-			gnome_config_private_clean_section (section);
-			g_free(section);
-		}
-		g_free(key);
+	groups = g_key_file_get_groups (key_file, &length);
+	for (ii = 0; ii < length; ii++) {
+		if (!g_str_has_prefix (groups[ii], KEY_FILE_GROUP_PREFIX))
+			continue;
+		g_key_file_remove_group (key_file, groups[ii], NULL);
 	}
-
-	gnome_config_private_sync_file ("/Evolution");
-
-	/* free up the session passwords */
-	g_hash_table_foreach_remove (passwords, free_entry, NULL);
+	ep_key_file_save ();
+	g_strfreev (groups);
 
 	if (!msg->noreply)
 		e_msgport_reply(&msg->msg);
 }
 
-static char *
-password_path (const char *component_name, const char *key)
-{
-	char *keycopy, *path;
-	int i;
-	keycopy = g_strdup (key);
-
-	for (i = 0; i < strlen (keycopy); i ++)
-		if (keycopy[i] == '/' || keycopy[i] =='=')
-			keycopy[i] = '_';
-	
-	path = g_strdup_printf ("/Evolution/Passwords-%s/%s", component_name, keycopy);
-
-	g_free (keycopy);
-
-	return path;
-}
-
 #ifdef WITH_GNOME_KEYRING
 static void
 ep_remember_password_keyring(EPassMsg *msg)
@@ -433,23 +502,25 @@ ep_remember_password_keyring(EPassMsg *m
 static void
 ep_remember_password_file(EPassMsg *msg)
 {
-	char *path, *pass64, *value;
+	gchar *group, *key, *password;
 
-	value = g_hash_table_lookup (passwords, msg->key);
-	if (value != NULL) {
-		/* add it to the on-disk cache of passwords */
-		path = password_path (msg->component, msg->key);
-		pass64 = ep_password_encode (value);
+	password = g_hash_table_lookup (passwords, msg->key);
+	if (password == NULL) {
+		g_warning ("Password for key \"%s\" not found", msg->key);
+		return;
+	}
 
-		gnome_config_private_set_string (path, pass64);
-		g_free (path);
-		g_free (pass64);
+	group = ep_key_file_get_group (msg->component);
+	key = ep_key_file_normalize_key (msg->key);
+	password = ep_password_encode (password);
 
-		/* now remove it from our session hash */
-		g_hash_table_remove (passwords, msg->key);
+	g_hash_table_remove (passwords, msg->key);
+	g_key_file_set_string (key_file, group, key, password);
+	ep_key_file_save ();
 
-		gnome_config_private_sync_file ("/Evolution");
-	}
+	g_free (group);
+	g_free (key);
+	g_free (password);
 
 	if (!msg->noreply)
 		e_msgport_reply(&msg->msg);
@@ -545,16 +616,25 @@ exit:
 static void
 ep_forget_password_file (EPassMsg *msg)
 {
-	char *path;
+	gchar *group, *key;
+	GError *error = NULL;
 
 	g_hash_table_remove (passwords, msg->key);
 
-	/* clear it in the on disk db */
-	path = password_path (msg->component, msg->key);
-	gnome_config_private_clean_key (path);
-	gnome_config_private_sync_file ("/Evolution");
-	g_free (path);
-	
+	group = ep_key_file_get_group (msg->component);
+	key = ep_key_file_normalize_key (msg->key);
+
+	g_key_file_remove_key (key_file, group, key, &error);
+	if (error == NULL)
+		ep_key_file_save ();
+	else {
+		g_warning ("%s", error->message);
+		g_error_free (error);
+	}
+
+	g_free (group);
+	g_free (key);
+
 	if (!msg->noreply)
 		e_msgport_reply(&msg->msg);
 }
@@ -643,24 +723,31 @@ ep_get_password_keyring (EPassMsg *msg)
 
 static void
 ep_get_password_file (EPassMsg *msg)
-{	
-	char *path, *passwd;
-	char *encoded = NULL;
+{
+	gchar *group, *key, *password;
+	GError *error = NULL;
 
-	passwd = g_hash_table_lookup (passwords, msg->key);
-	if (passwd) {
-		msg->password = g_strdup(passwd);
+	password = g_hash_table_lookup (passwords, msg->key);
+	if (password != NULL) {
+		msg->password = g_strdup (password);
+		return;
+	}
+
+	group = ep_key_file_get_group (msg->component);
+	key = ep_key_file_normalize_key (msg->key);
+
+	password = g_key_file_get_string (key_file, group, key, &error);
+	if (password != NULL) {
+		msg->password = ep_password_decode (password);
+		g_free (password);
 	} else {
-		/* not part of the session hash, look it up in the on disk db */
-		path = password_path (msg->component, msg->key);
-		encoded = gnome_config_private_get_string_with_default (path, NULL);
-		g_free (path);
-		if (encoded) {
-			msg->password = ep_password_decode (encoded);
-			g_free (encoded);
-		}
+		g_warning ("%s", error->message);
+		g_error_free (error);
 	}
 
+	g_free (group);
+	g_free (key);
+
 	if (!msg->noreply)
 		e_msgport_reply(&msg->msg);
 }
@@ -859,6 +946,16 @@ e_passwords_init (void)
 #ifdef ENABLE_THREADS
 		main_thread = pthread_self();
 #endif
+
+#ifdef WITH_GNOME_KEYRING
+		if (!gnome_keyring_is_available ()) {
+			key_file = g_key_file_new ();
+			ep_key_file_load ();
+		}
+#else
+		key_file = g_key_file_new ();
+		ep_key_file_load ();
+#endif
 	}
 
 	UNLOCK();
