Matthew Barnes 3be76c
--- evolution-data-server-1.11.4/libedataserverui/e-passwords.h.e-passwords	2007-04-18 06:10:16.000000000 -0400
Matthew Barnes 3be76c
+++ evolution-data-server-1.11.4/libedataserverui/e-passwords.h	2007-06-18 16:19:44.000000000 -0400
Matthew Barnes ab6285
@@ -28,45 +28,65 @@
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 G_BEGIN_DECLS
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-/*
Matthew Barnes ab6285
-  initialization is now implicit when you call any of the functions
Matthew Barnes ab6285
-  below, although this is only correct if the functions are called
Matthew Barnes ab6285
-  from the main thread.
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-  e_passwords_shutdown should be called at exit time to synch the
Matthew Barnes ab6285
-  password on-disk storage, and to free up in-memory storage. */
Matthew Barnes ab6285
-void e_passwords_init (void);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-void        e_passwords_shutdown          (void);
Matthew Barnes ab6285
-void	    e_passwords_cancel(void);
Matthew Barnes ab6285
-void        e_passwords_set_online(int state);
Matthew Barnes ab6285
-void        e_passwords_remember_password (const char *component, const char *key);
Matthew Barnes ab6285
-void        e_passwords_add_password      (const char *key, const char *passwd);
Matthew Barnes ab6285
-char       *e_passwords_get_password      (const char *component, const char *key);
Matthew Barnes ab6285
-void        e_passwords_forget_password   (const char *component, const char *key);
Matthew Barnes ab6285
-void        e_passwords_forget_passwords  (void);
Matthew Barnes ab6285
-void        e_passwords_clear_passwords (const char *component);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
+/**
Matthew Barnes ab6285
+ * EPasswordsRememberType:
Matthew Barnes ab6285
+ * @E_PASSWORDS_REMEMBER_NEVER:
Matthew Barnes ab6285
+ * 	Do not remember the password.
Matthew Barnes ab6285
+ * @E_PASSWORDS_REMEMBER_SESSION:
Matthew Barnes ab6285
+ * 	Remember the password for this session only.
Matthew Barnes ab6285
+ * @E_PASSWORDS_REMEMBER_FOREVER:
Matthew Barnes ab6285
+ * 	Remember the password across multiple sessions.
Matthew Barnes ab6285
+ * @E_PASSWORDS_REMEMBER_MASK:
Matthew Barnes ab6285
+ * 	Mask value separates the mutually-exclusive values
Matthew Barnes ab6285
+ * 	of the enumeration from the flags.
Matthew Barnes ab6285
+ * @E_PASSWORDS_SECRET:
Matthew Barnes ab6285
+ * 	Do not show the password as it's being typed.
Matthew Barnes ab6285
+ * @E_PASSWORDS_REPROMPT:
Matthew Barnes ab6285
+ * 	Populate the dialog with the current password (if one exists).
Matthew Barnes ab6285
+ * @E_PASSWORDS_ONLINE:
Matthew Barnes ab6285
+ * 	Only prompt the user for a password if we're online.
Matthew Barnes ab6285
+ * @E_PASSWORDS_DISABLE_REMEMBER:
Matthew Barnes ab6285
+ * 	Disable the "remember password" option on the dialog.
Matthew Barnes ab6285
+ * @E_PASSWORDS_PASSPHRASE:
Matthew Barnes ab6285
+ * 	Ask for a passphrase instead of a password.
Matthew Barnes ab6285
+ **/
Matthew Barnes ab6285
 typedef enum {
Matthew Barnes ab6285
 	E_PASSWORDS_REMEMBER_NEVER,
Matthew Barnes ab6285
 	E_PASSWORDS_REMEMBER_SESSION,
Matthew Barnes ab6285
 	E_PASSWORDS_REMEMBER_FOREVER,
Matthew Barnes ab6285
 	E_PASSWORDS_REMEMBER_MASK = 0xf,
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* option bits */
Matthew Barnes ab6285
-	E_PASSWORDS_SECRET = 1<<8,
Matthew Barnes ab6285
-	E_PASSWORDS_REPROMPT = 1<<9,
Matthew Barnes ab6285
-	E_PASSWORDS_ONLINE = 1<<10, /* only ask if we're online */
Matthew Barnes ab6285
-	E_PASSWORDS_DISABLE_REMEMBER = 1<<11, /* disable the 'remember password' checkbox */
Matthew Barnes ab6285
-	E_PASSWORDS_PASSPHRASE = 1<<12, /* We are asking a passphrase */
Matthew Barnes ab6285
+	/* flags */
Matthew Barnes ab6285
+	E_PASSWORDS_SECRET           = 1 << 8,
Matthew Barnes ab6285
+	E_PASSWORDS_REPROMPT         = 1 << 9,
Matthew Barnes ab6285
+	E_PASSWORDS_ONLINE           = 1 << 10,
Matthew Barnes ab6285
+	E_PASSWORDS_DISABLE_REMEMBER = 1 << 11,
Matthew Barnes ab6285
+	E_PASSWORDS_PASSPHRASE       = 1 << 12,
Matthew Barnes ab6285
 } EPasswordsRememberType;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-char *      e_passwords_ask_password      (const char *title, 
Matthew Barnes ab6285
-					   const char*component_name, const char *key,
Matthew Barnes ab6285
-					   const char *prompt,
Matthew Barnes ab6285
-					   EPasswordsRememberType remember_type,
Matthew Barnes ab6285
-					   gboolean *remember,
Matthew Barnes ab6285
-					   GtkWindow *parent);
Matthew Barnes ab6285
+#ifndef EDS_DISABLE_DEPRECATED
Matthew Barnes ab6285
+void		e_passwords_init		(void);
Matthew Barnes ab6285
+void		e_passwords_shutdown		(void);
Matthew Barnes ab6285
+void		e_passwords_cancel		(void);
Matthew Barnes ab6285
+#endif
Matthew Barnes ab6285
+void		e_passwords_set_online		(gboolean online);
Matthew Barnes ab6285
+void		e_passwords_remember_password	(const gchar *component,
Matthew Barnes ab6285
+						 const gchar *key);
Matthew Barnes ab6285
+void		e_passwords_add_password	(const gchar *key,
Matthew Barnes ab6285
+						 const gchar *password);
Matthew Barnes ab6285
+gchar *		e_passwords_get_password	(const gchar *component,
Matthew Barnes ab6285
+						 const gchar *key);
Matthew Barnes ab6285
+void		e_passwords_forget_password	(const gchar *component,
Matthew Barnes ab6285
+						 const gchar *key);
Matthew Barnes ab6285
+void		e_passwords_forget_passwords	(void);
Matthew Barnes ab6285
+void		e_passwords_clear_passwords	(const gchar *component);
Matthew Barnes ab6285
+gchar *		e_passwords_ask_password	(const gchar *title, 
Matthew Barnes ab6285
+						 const gchar *component,
Matthew Barnes ab6285
+						 const gchar *key,
Matthew Barnes ab6285
+						 const gchar *prompt,
Matthew Barnes ab6285
+						 EPasswordsRememberType remember_type,
Matthew Barnes ab6285
+						 gboolean *remember,
Matthew Barnes ab6285
+						 GtkWindow *parent);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 G_END_DECLS
Matthew Barnes ab6285
 
Matthew Barnes 3be76c
--- evolution-data-server-1.11.4/libedataserverui/e-passwords.c.e-passwords	2007-06-17 23:25:35.000000000 -0400
Matthew Barnes 3be76c
+++ evolution-data-server-1.11.4/libedataserverui/e-passwords.c	2007-06-18 16:26:02.000000000 -0400
Matthew Barnes ab6285
@@ -23,18 +23,29 @@
Matthew Barnes ab6285
  */
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /*
Matthew Barnes ab6285
- * This looks a lot more complicated than it is, and than you'd think
Matthew Barnes ab6285
- * it would need to be.  There is however, method to the madness.
Matthew Barnes ab6285
+ * The threading model was changed in version 1.11.  Here's the details.
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
- * The code most cope with being called from any thread at any time,
Matthew Barnes ab6285
- * recursively from the main thread, and then serialising every
Matthew Barnes ab6285
- * request so that sane and correct values are always returned, and
Matthew Barnes ab6285
- * duplicate requests are never made.
Matthew Barnes ab6285
+ * We now use a dedicated "dispatcher" thread to process password messages.
Matthew Barnes ab6285
+ * The callback functions do not use synchronization guards when accessing
Matthew Barnes ab6285
+ * the password store, so those functions must only be called from the
Matthew Barnes ab6285
+ * dispatcher thread.
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
- * To this end, every call is marshalled and queued and a dispatch
Matthew Barnes ab6285
- * method invoked until that request is satisfied.  If mainloop
Matthew Barnes ab6285
- * recursion occurs, then the sub-call will necessarily return out of
Matthew Barnes ab6285
- * order, but will not be processed out of order.
Matthew Barnes ab6285
+ * Message processing behind a visible password dialog is the trickiest
Matthew Barnes ab6285
+ * part to get right.  We want to, at all costs, avoid repeatedly prompting
Matthew Barnes ab6285
+ * the user for the same password.  To that end, when the password dialog
Matthew Barnes ab6285
+ * for some key 'X' is visible, the dispatcher thread is blocked and
Matthew Barnes ab6285
+ * subsequent messages for key 'X' are expedited by redirecting them to a
Matthew Barnes ab6285
+ * special "express queue" [1].
Matthew Barnes ab6285
+ *
Matthew Barnes ab6285
+ * Once the password dialog is closed, all messages in the express queue
Matthew Barnes ab6285
+ * are either (depending on the user's response) cancelled or loaded with
Matthew Barnes ab6285
+ * the new password and returned to the sender.  The express queue is then
Matthew Barnes ab6285
+ * closed so that no new messages can enter, and the dispatcher thread
Matthew Barnes ab6285
+ * resumes its normal processing.
Matthew Barnes ab6285
+ *
Matthew Barnes ab6285
+ * [1] Yes, it's a stupid name, but it's the best I could think of.  It's
Matthew Barnes ab6285
+ *     somewhat analogous to an express lane on a freeway because messages
Matthew Barnes ab6285
+ *     get through faster.
Matthew Barnes ab6285
  */
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 #ifdef HAVE_CONFIG_H
Matthew Barnes 8edc3a
@@ -42,159 +53,381 @@
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 #include <string.h>
Matthew Barnes ab6285
-#include <libgnome/gnome-config.h>
Matthew Barnes ab6285
+#include <gtk/gtk.h>
Matthew Barnes ab6285
 #include <glib/gi18n-lib.h>
Matthew Barnes ab6285
-#include <gtk/gtkversion.h>
Matthew Barnes ab6285
-#include <gtk/gtkentry.h>
Matthew Barnes ab6285
-#include <gtk/gtkvbox.h>
Matthew Barnes ab6285
-#include <gtk/gtkcheckbutton.h>
Matthew Barnes ab6285
-#include <gtk/gtkmessagedialog.h>
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 #include "e-passwords.h"
Matthew Barnes ab6285
-#include "libedataserver/e-msgport.h"
Matthew Barnes ab6285
+#include "libedataserver/e-flag.h"
Matthew Barnes ab6285
 #include "libedataserver/e-url.h"
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
 #ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
 #include <gnome-keyring.h>
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-#ifndef ENABLE_THREADS
Matthew Barnes ab6285
-#define ENABLE_THREADS (1)
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-#ifdef ENABLE_THREADS
Matthew Barnes ab6285
-#include <pthread.h>
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-static pthread_t main_thread;
Matthew Barnes ab6285
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
Matthew Barnes ab6285
-#define LOCK() pthread_mutex_lock(&lock)
Matthew Barnes ab6285
-#define UNLOCK() pthread_mutex_unlock(&lock)
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-#define LOCK()
Matthew Barnes ab6285
-#define UNLOCK()
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
+#define d(x)
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-#define d(x) x
Matthew Barnes ab6285
+typedef struct _EPassMsg EPassMsg;
Matthew Barnes ab6285
+typedef struct _EPassDialogData EPassDialogData;
Matthew Barnes ab6285
+typedef void (*EPassCallback) (EPassMsg *msg);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 struct _EPassMsg {
Matthew Barnes ab6285
-	EMsg msg;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	void (*dispatch)(struct _EPassMsg *);
Matthew Barnes ab6285
+	/* The 'expedite' flag indicates that the message
Matthew Barnes ab6285
+	 * is eligible for entry into the express queue. */
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* input */
Matthew Barnes ab6285
-	struct _GtkWindow *parent;	
Matthew Barnes ab6285
-	const char *component;
Matthew Barnes ab6285
-	const char *key;
Matthew Barnes ab6285
-	const char *title;
Matthew Barnes ab6285
-	const char *prompt;
Matthew Barnes ab6285
-	const char *oldpass;
Matthew Barnes ab6285
-	guint32 flags;
Matthew Barnes ab6285
+	/* dispatching */
Matthew Barnes ab6285
+	EPassCallback callback;
Matthew Barnes ab6285
+	gboolean expedite;
Matthew Barnes ab6285
+	EFlag *done;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* input/output */
Matthew Barnes ab6285
+	const gchar *component;
Matthew Barnes ab6285
+	const gchar *key;
Matthew Barnes ab6285
+	gchar *password;
Matthew Barnes ab6285
+	gpointer data;
Matthew Barnes ab6285
+};
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* output */
Matthew Barnes ab6285
-	gboolean *remember;
Matthew Barnes ab6285
-	char *password;
Matthew Barnes ab6285
+struct _EPassDialogData {
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* work variables */
Matthew Barnes ab6285
-	GtkWidget *entry;
Matthew Barnes ab6285
-	GtkWidget *check;
Matthew Barnes ab6285
-	guint ismain:1;
Matthew Barnes ab6285
-	guint noreply:1;	/* supress replies; when calling
Matthew Barnes ab6285
-				 * dispatch functions from others */
Matthew Barnes ab6285
+	/* settings */
Matthew Barnes ab6285
+	GtkWindow *parent;
Matthew Barnes ab6285
+	const gchar *title;
Matthew Barnes ab6285
+	const gchar *prompt;
Matthew Barnes ab6285
+	gint flags;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* input/output */
Matthew Barnes ab6285
+	gboolean remember;
Matthew Barnes ab6285
+	gint response;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* synchronization */
Matthew Barnes ab6285
+	EFlag *done;
Matthew Barnes ab6285
 };
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-typedef struct _EPassMsg EPassMsg;
Matthew Barnes ab6285
+/* Forward Declarations */
Matthew Barnes ab6285
+static void ep_msg_dispatch (EPassMsg *msg);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-static GHashTable *passwords = NULL;
Matthew Barnes ab6285
-static GtkDialog *password_dialog;
Matthew Barnes ab6285
-static EDList request_list = E_DLIST_INITIALISER(request_list);
Matthew Barnes ab6285
-static int idle_id;
Matthew Barnes ab6285
-static int ep_online_state = TRUE;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-static char *decode_base64 (char *base64);
Matthew Barnes ab6285
-static int base64_encode_close(unsigned char *in, int inlen, gboolean break_lines, unsigned char *out, int *state, int *save);
Matthew Barnes ab6285
-static int base64_encode_step(unsigned char *in, int len, gboolean break_lines, unsigned char *out, int *state, int *save);
Matthew Barnes ab6285
+static GThreadPool *dispatcher = NULL;
Matthew Barnes ab6285
+static GHashTable *password_cache = NULL;
Matthew Barnes ab6285
+static gboolean ep_online_state = TRUE;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-static gboolean
Matthew Barnes ab6285
-ep_idle_dispatch(void *data)
Matthew Barnes ab6285
+/* The queue's lock also guards the key. */
Matthew Barnes ab6285
+static const gchar *express_key = NULL;
Matthew Barnes ab6285
+static GAsyncQueue *express_queue = NULL;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+#define KEY_FILE_GROUP_PREFIX "Passwords-"
Matthew Barnes ab6285
+static GKeyFile *key_file = NULL;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static gchar *
Matthew Barnes ab6285
+ep_key_file_get_filename (void)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	EPassMsg *msg;
Matthew Barnes ab6285
+	/* XXX It would be nice to someday move this data elsewhere, or else
Matthew Barnes ab6285
+	 * fully migrate to GNOME Keyring or whatever software supercedes it.
Matthew Barnes ab6285
+	 * Evolution is one of the few remaining GNOME-2 applications that
Matthew Barnes ab6285
+	 * still uses the deprecated ~/.gnome2-private directory. */
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* As soon as a password window is up we stop; it will
Matthew Barnes ab6285
-	   re-invoke us when it has been closed down */
Matthew Barnes ab6285
-	LOCK();
Matthew Barnes ab6285
-	while (password_dialog == NULL && (msg = (EPassMsg *)e_dlist_remhead(&request_list))) {
Matthew Barnes ab6285
-		UNLOCK();
Matthew Barnes 3be76c
+	return g_build_filename (g_get_home_dir (),
Matthew Barnes 3be76c
+		".gnome2_private", "Evolution", NULL);
Matthew Barnes 3be76c
+}
Matthew Barnes 3be76c
 
Matthew Barnes 3be76c
-		msg->dispatch(msg);
Matthew Barnes ab6285
+static gchar *
Matthew Barnes ab6285
+ep_key_file_get_group (const gchar *component)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	return g_strconcat (KEY_FILE_GROUP_PREFIX, component, NULL);
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static gchar *
Matthew Barnes ab6285
+ep_key_file_normalize_key (const gchar *key)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	/* XXX Previous code converted all slashes and equal signs in the
Matthew Barnes ab6285
+	 * key to underscores for use with "gnome-config" functions.  While
Matthew Barnes ab6285
+	 * it may not be necessary to convert slashes for use with GKeyFile,
Matthew Barnes ab6285
+	 * and an equal sign was most likely never encountered in a key, we
Matthew Barnes ab6285
+	 * continue to do the same for backward-compatibility. */
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	gchar *normalized_key, *cp;
Matthew Barnes 3be76c
+
Matthew Barnes ab6285
+	normalized_key = g_strdup (key);
Matthew Barnes ab6285
+	for (cp = normalized_key; *cp != '\0'; cp++)
Matthew Barnes ab6285
+		if (*cp == '/' || *cp == '=')
Matthew Barnes ab6285
+			*cp = '_';
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	return normalized_key;
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_key_file_load (void)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	gchar *filename;
Matthew Barnes ab6285
+	GError *error = NULL;
Matthew Barnes 3be76c
+
Matthew Barnes 3be76c
+	filename = ep_key_file_get_filename ();
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-		LOCK();
Matthew Barnes ab6285
+	if (!g_file_test (filename, G_FILE_TEST_EXISTS))
Matthew Barnes ab6285
+		goto exit;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	g_key_file_load_from_file (key_file, filename,
Matthew Barnes ab6285
+		G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
Matthew Barnes ab6285
+		&error);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	if (error != NULL) {
Matthew Barnes ab6285
+		g_warning ("%s", error->message);
Matthew Barnes ab6285
+		g_error_free (error);
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	idle_id = 0;
Matthew Barnes ab6285
-	UNLOCK();
Matthew Barnes ab6285
+exit:
Matthew Barnes ab6285
+	g_free (filename);
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	return FALSE;
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_key_file_save (void)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	gchar *contents;
Matthew Barnes ab6285
+	gchar *filename;
Matthew Barnes ab6285
+	gsize length;
Matthew Barnes ab6285
+	GError *error = NULL;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	filename = ep_key_file_get_filename ();
Matthew Barnes ab6285
+	contents = g_key_file_to_data (key_file, &length, NULL);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	g_file_set_contents (filename, contents, length, &error);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	if (error != NULL) {
Matthew Barnes ab6285
+		g_warning ("%s", error->message);
Matthew Barnes ab6285
+		g_error_free (error);
Matthew Barnes ab6285
+	}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	g_free (contents);
Matthew Barnes ab6285
+	g_free (filename);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-static EPassMsg *
Matthew Barnes ab6285
-ep_msg_new(void (*dispatch)(EPassMsg *))
Matthew Barnes ab6285
+static gchar *
Matthew Barnes ab6285
+ep_password_encode (const gchar *password)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	EPassMsg *msg;
Matthew Barnes ab6285
+	/* XXX The previous Base64 encoding function did not encode the
Matthew Barnes ab6285
+	 * password's trailing nul byte.  This makes decoding the Base64
Matthew Barnes ab6285
+	 * string into a nul-terminated password more difficult, but we
Matthew Barnes ab6285
+	 * continue to do it this way for backward-compatibility. */
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	gsize length = strlen (password);
Matthew Barnes ab6285
+	return g_base64_encode ((const guchar *) password, length);
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static gchar *
Matthew Barnes ab6285
+ep_password_decode (const gchar *encoded_password)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	/* XXX The previous Base64 encoding function did not encode the
Matthew Barnes ab6285
+	 * password's trailing nul byte, so we have to append a nul byte
Matthew Barnes ab6285
+	 * to the decoded data to make it a nul-terminated string. */
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	gchar *password;
Matthew Barnes ab6285
+	gsize length;
Matthew Barnes 3be76c
+
Matthew Barnes ab6285
+	password = (gchar *) g_base64_decode (encoded_password, &length);
Matthew Barnes ab6285
+	password = g_realloc (password, length + 1);
Matthew Barnes ab6285
+	password[length] = '\0';
Matthew Barnes 3be76c
+
Matthew Barnes ab6285
+	return password;
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static gpointer
Matthew Barnes ab6285
+ep_init (gpointer data)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	/* Initialize the data structures with unbounded lifetimes. */
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	dispatcher = g_thread_pool_new (
Matthew Barnes ab6285
+		(GFunc) ep_msg_dispatch, NULL, 1, FALSE, NULL);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	password_cache = g_hash_table_new_full (
Matthew Barnes ab6285
+		g_str_hash, g_str_equal, g_free, g_free);
Matthew Barnes 3be76c
 
Matthew Barnes 3be76c
-	e_passwords_init();
Matthew Barnes ab6285
+	express_queue = g_async_queue_new ();
Matthew Barnes 3be76c
 
Matthew Barnes 3be76c
-	msg = g_malloc0(sizeof(*msg));
Matthew Barnes 3be76c
-	msg->dispatch = dispatch;
Matthew Barnes 3be76c
-	msg->msg.reply_port = e_msgport_new();
Matthew Barnes 3be76c
-#ifdef ENABLE_THREADS
Matthew Barnes 3be76c
-	msg->ismain = pthread_equal(pthread_self(), main_thread);
Matthew Barnes ab6285
+#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
+	if (!gnome_keyring_is_available ()) {
Matthew Barnes ab6285
+		key_file = g_key_file_new ();
Matthew Barnes ab6285
+		ep_key_file_load ();
Matthew Barnes ab6285
+	}
Matthew Barnes ab6285
 #else
Matthew Barnes ab6285
-	msg->ismain = TRUE;
Matthew Barnes ab6285
+	key_file = g_key_file_new ();
Matthew Barnes ab6285
+	ep_key_file_load ();
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	return NULL;
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static EPassMsg *
Matthew Barnes ab6285
+ep_msg_new (EPassCallback callback, gboolean expedite)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	static GOnce once = G_ONCE_INIT;
Matthew Barnes ab6285
+	EPassMsg *msg;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	g_once (&once, ep_init, NULL);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	msg = g_slice_new0 (EPassMsg);
Matthew Barnes ab6285
+	msg->callback = callback;
Matthew Barnes ab6285
+	msg->expedite = expedite;
Matthew Barnes ab6285
+	msg->done = e_flag_new ();
Matthew Barnes ab6285
+
Matthew Barnes ab6285
 	return msg;
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_msg_free(EPassMsg *msg)
Matthew Barnes ab6285
+ep_msg_dispatch (EPassMsg *msg)
Matthew Barnes 8edc3a
+{
Matthew Barnes ab6285
+	msg->callback (msg);
Matthew Barnes ab6285
+	e_flag_set (msg->done);
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static gboolean
Matthew Barnes ab6285
+ep_msg_expedite (EPassMsg *msg)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	gboolean success = FALSE;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	g_async_queue_lock (express_queue);
Matthew Barnes ab6285
+	if (express_key != NULL && strcmp (msg->key, express_key) == 0) {
Matthew Barnes ab6285
+		g_async_queue_push_unlocked (express_queue, msg);
Matthew Barnes ab6285
+		success = TRUE;
Matthew Barnes ab6285
+	}
Matthew Barnes ab6285
+	g_async_queue_unlock (express_queue);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	return success;
Matthew Barnes 8edc3a
+}
Matthew Barnes 8edc3a
+
Matthew Barnes 8edc3a
+static void
Matthew Barnes ab6285
+ep_msg_send (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes 8edc3a
-	e_msgport_destroy(msg->msg.reply_port);
Matthew Barnes 8edc3a
-	g_free(msg->password);
Matthew Barnes 8edc3a
-	g_free(msg);
Matthew Barnes 3b4059
+	GMainContext *context;
Matthew Barnes 3b4059
+
Matthew Barnes 3b4059
+	context = g_main_context_default (); 
Matthew Barnes 3b4059
+
Matthew Barnes ab6285
+	/* Expedite flag requires a key. */
Matthew Barnes ab6285
+	g_assert (!msg->expedite || msg->key != NULL);
Matthew Barnes 3b4059
+
Matthew Barnes 3b4059
+	if (!(msg->expedite && ep_msg_expedite (msg)))
Matthew Barnes 3b4059
+		g_thread_pool_push (dispatcher, msg, NULL);
Matthew Barnes ab6285
+
Matthew Barnes 3b4059
+	/* Don't block the main loop. */
Matthew Barnes 3b4059
+	if (g_main_context_is_owner (context))
Matthew Barnes 3b4059
+		while (!e_flag_is_set (msg->done))
Matthew Barnes 3b4059
+			g_main_context_iteration (context, TRUE);
Matthew Barnes 3b4059
+	else
Matthew Barnes 3b4059
+		e_flag_wait (msg->done);
Matthew Barnes 8edc3a
 }
Matthew Barnes 8edc3a
 
Matthew Barnes 8edc3a
 static void
Matthew Barnes 8edc3a
-ep_msg_send(EPassMsg *msg)
Matthew Barnes ab6285
+ep_msg_free (EPassMsg *msg)
Matthew Barnes 3be76c
 {
Matthew Barnes 3be76c
-	int needidle = 0;
Matthew Barnes ab6285
+	e_flag_free (msg->done);
Matthew Barnes ab6285
+	g_slice_free (EPassMsg, msg);
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static EPassDialogData *
Matthew Barnes ab6285
+ep_dialog_data_new (GtkWindow *parent, const gchar *title,
Matthew Barnes ab6285
+                    const gchar *prompt, gboolean remember, gint flags)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	EPassDialogData *data;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	data = g_slice_new0 (EPassDialogData);
Matthew Barnes ab6285
+	data->done = e_flag_new ();
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	data->parent = parent;
Matthew Barnes ab6285
+	data->title = title;
Matthew Barnes ab6285
+	data->prompt = prompt;
Matthew Barnes ab6285
+	data->remember = remember;
Matthew Barnes ab6285
+	data->flags = flags;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	return data;
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_dialog_data_free (EPassDialogData *data)
Matthew Barnes ab6285
+{
Matthew Barnes ab6285
+	e_flag_free (data->done);
Matthew Barnes ab6285
+	g_slice_free (EPassDialogData, data);
Matthew Barnes ab6285
+}
Matthew Barnes 8edc3a
 
Matthew Barnes 8edc3a
-	LOCK();
Matthew Barnes 8edc3a
-	e_dlist_addtail(&request_list, (EDListNode *)&msg->msg);
Matthew Barnes 8edc3a
-	if (!idle_id) {
Matthew Barnes 8edc3a
-		if (!msg->ismain)
Matthew Barnes 8edc3a
-			idle_id = g_idle_add(ep_idle_dispatch, NULL);
Matthew Barnes 3be76c
+static gboolean
Matthew Barnes 3be76c
+ep_dialog_run (EPassMsg *msg)
Matthew Barnes 3be76c
+{
Matthew Barnes 3be76c
+	/* This function must run in the main thread. */
Matthew Barnes 3be76c
+
Matthew Barnes ab6285
+	EPassDialogData *data = msg->data;
Matthew Barnes ab6285
+	GtkBox *box;
Matthew Barnes ab6285
+	GtkWidget *dialog;
Matthew Barnes ab6285
+	GtkWidget *entry;
Matthew Barnes ab6285
+	GtkWidget *check_button = NULL;
Matthew Barnes ab6285
+	gboolean visible;
Matthew Barnes ab6285
+	gint remember;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	visible = !(data->flags & E_PASSWORDS_SECRET);
Matthew Barnes ab6285
+	remember = data->flags & E_PASSWORDS_REMEMBER_MASK;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* Create a standard message dialog. */
Matthew Barnes ab6285
+	dialog = gtk_message_dialog_new (
Matthew Barnes ab6285
+		data->parent, 0, GTK_MESSAGE_QUESTION,
Matthew Barnes ab6285
+		GTK_BUTTONS_OK_CANCEL, "%s", data->prompt);
Matthew Barnes ab6285
+	gtk_window_set_title (GTK_WINDOW (dialog), data->title);
Matthew Barnes ab6285
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	box = GTK_BOX (GTK_DIALOG (dialog)->vbox);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* Add a GtkEntry for the password. */
Matthew Barnes ab6285
+	entry = gtk_entry_new ();
Matthew Barnes ab6285
+	gtk_box_pack_start (box, entry, TRUE, FALSE, 3);
Matthew Barnes ab6285
+	gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
Matthew Barnes ab6285
+	gtk_entry_set_visibility (GTK_ENTRY (entry), visible);
Matthew Barnes ab6285
+	if (msg->password != NULL) {
Matthew Barnes ab6285
+		gtk_entry_set_text (GTK_ENTRY (entry), msg->password);
Matthew Barnes ab6285
+		g_free (msg->password);
Matthew Barnes ab6285
+		msg->password = NULL;
Matthew Barnes ab6285
+	}
Matthew Barnes ab6285
+	atk_object_set_description (
Matthew Barnes ab6285
+		gtk_widget_get_accessible (entry), data->prompt);
Matthew Barnes ab6285
+	gtk_widget_grab_focus (entry);
Matthew Barnes ab6285
+	gtk_widget_show (entry);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* Add a GtkCheckButton for the "remember" option. */
Matthew Barnes ab6285
+	if (remember != E_PASSWORDS_REMEMBER_NEVER) {
Matthew Barnes ab6285
+		if (data->flags & E_PASSWORDS_PASSPHRASE)
Matthew Barnes ab6285
+			check_button = gtk_check_button_new_with_mnemonic (
Matthew Barnes ab6285
+				(remember == E_PASSWORDS_REMEMBER_FOREVER) ?
Matthew Barnes ab6285
+				_("_Remember this passphrase") :
Matthew Barnes ab6285
+				_("_Remember this passphrase for the "
Matthew Barnes ab6285
+				"remainder of this session"));
Matthew Barnes ab6285
 		else
Matthew Barnes ab6285
-			needidle = 1;
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
-	UNLOCK();
Matthew Barnes ab6285
+			check_button = gtk_check_button_new_with_mnemonic (
Matthew Barnes ab6285
+				(remember == E_PASSWORDS_REMEMBER_FOREVER) ?
Matthew Barnes ab6285
+				_("_Remember this password") :
Matthew Barnes ab6285
+				_("_Remember this password for the "
Matthew Barnes ab6285
+				"remainder of this session"));
Matthew Barnes ab6285
+		gtk_box_pack_start (box, check_button, TRUE, FALSE, 3);
Matthew Barnes ab6285
+		gtk_toggle_button_set_active (
Matthew Barnes ab6285
+			GTK_TOGGLE_BUTTON (check_button), data->remember);
Matthew Barnes ab6285
+		if (data->flags & E_PASSWORDS_DISABLE_REMEMBER)
Matthew Barnes ab6285
+			gtk_widget_set_sensitive (check_button, FALSE);
Matthew Barnes ab6285
+		gtk_widget_show (check_button);
Matthew Barnes ab6285
+	}
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	/* Run the dialog and collect the results. */
Matthew Barnes ab6285
+	data->response = gtk_dialog_run (GTK_DIALOG (dialog));
Matthew Barnes ab6285
+	msg->password = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
Matthew Barnes ab6285
+	if (check_button != NULL)
Matthew Barnes ab6285
+		data->remember = gtk_toggle_button_get_active (
Matthew Barnes ab6285
+			GTK_TOGGLE_BUTTON (check_button));
Matthew Barnes ab6285
+	else
Matthew Barnes ab6285
+		data->remember = FALSE;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	if (msg->ismain) {
Matthew Barnes ab6285
-		EPassMsg *m;
Matthew Barnes ab6285
+	gtk_widget_destroy (dialog);
Matthew Barnes ab6285
+	e_flag_set (data->done);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-		if (needidle)
Matthew Barnes ab6285
-			ep_idle_dispatch(NULL);
Matthew Barnes ab6285
-		while ((m = (EPassMsg *)e_msgport_get(msg->msg.reply_port)) == NULL)
Matthew Barnes ab6285
-			g_main_context_iteration(NULL, TRUE);
Matthew Barnes ab6285
-		g_assert(m == msg);
Matthew Barnes ab6285
-	} else {
Matthew Barnes ab6285
-		EMsg *reply_msg = e_msgport_wait(msg->msg.reply_port);
Matthew Barnes ab6285
-		g_assert(reply_msg == &msg->msg);
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
+	return FALSE;
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-/* the functions that actually do the work */
Matthew Barnes ab6285
+/* The rest of these static functions must run in the dispatcher thread. */
Matthew Barnes ab6285
+
Matthew Barnes 8edc3a
 #ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_clear_passwords_keyring(EPassMsg *msg)
Matthew Barnes ab6285
+ep_clear_passwords_keyring (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
 	GnomeKeyringAttributeList *attributes;
Matthew Barnes ab6285
 	GnomeKeyringAttribute attribute;
Matthew Barnes 6efa8f
@@ -205,11 +438,8 @@ ep_clear_passwords_keyring(EPassMsg *msg
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 	result = gnome_keyring_get_default_keyring_sync (&default_keyring);
Matthew Barnes ab6285
 	if (!default_keyring) {
Matthew Barnes ab6285
-	        if (gnome_keyring_create_sync ("default", NULL) != GNOME_KEYRING_RESULT_OK) {
Matthew Barnes ab6285
-				if (!msg->noreply)
Matthew Barnes ab6285
-					e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
-				return;
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
+	        if (gnome_keyring_create_sync ("default", NULL) != GNOME_KEYRING_RESULT_OK)
Matthew Barnes ab6285
+			return;
Matthew Barnes ab6285
 	        default_keyring = g_strdup ("default");			
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
 
Matthew Barnes 6efa8f
@@ -239,38 +469,44 @@ ep_clear_passwords_keyring(EPassMsg *msg
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
 	
Matthew Barnes ab6285
 	g_free (default_keyring);
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
+
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_clear_passwords_file(EPassMsg *msg)
Matthew Barnes ab6285
+ep_clear_passwords_keyfile (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	char *path;
Matthew Barnes 3be76c
-
Matthew Barnes 3be76c
-	path = g_strdup_printf ("/Evolution/Passwords-%s", msg->component);
Matthew Barnes ab6285
+	gchar *group;
Matthew Barnes ab6285
+	GError *error = NULL;
Matthew Barnes ab6285
 
Matthew Barnes 3b4059
-	gnome_config_private_clean_section (path);
Matthew Barnes 3b4059
-	gnome_config_private_sync_file ("/Evolution");
Matthew Barnes 3be76c
+	group = ep_key_file_get_group (msg->component);
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-	g_free (path);
Matthew Barnes ab6285
+	g_key_file_remove_group (key_file, group, &error);
Matthew Barnes ab6285
+	if (error == NULL)
Matthew Barnes ab6285
+		ep_key_file_save ();
Matthew Barnes ab6285
+	else {
Matthew Barnes ab6285
+		g_warning ("%s", error->message);
Matthew Barnes ab6285
+		g_error_free (error);
Matthew Barnes ab6285
+	}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
+	g_free (group);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-static gboolean
Matthew Barnes ab6285
-free_entry (gpointer key, gpointer value, gpointer user_data)
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_clear_passwords (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	g_free (key);
Matthew Barnes ab6285
-	memset (value, 0, strlen (value));
Matthew Barnes ab6285
-	g_free (value);
Matthew Barnes ab6285
-	return TRUE;
Matthew Barnes 8edc3a
+#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
+	if (gnome_keyring_is_available ())
Matthew Barnes ab6285
+		ep_clear_passwords_keyring (msg);
Matthew Barnes ab6285
+	else
Matthew Barnes ab6285
+		ep_clear_passwords_keyfile (msg);
Matthew Barnes ab6285
+#else
Matthew Barnes ab6285
+	ep_clear_passwords_keyfile (msg);
Matthew Barnes ab6285
+#endif
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
 #ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_forget_passwords_keyring(EPassMsg *msg)
Matthew Barnes ab6285
+ep_forget_passwords_keyring (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
 	GnomeKeyringAttributeList *attributes;
Matthew Barnes ab6285
 	GnomeKeyringAttribute attribute;
Matthew Barnes 6efa8f
@@ -281,11 +517,8 @@ ep_forget_passwords_keyring(EPassMsg *ms
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 	result = gnome_keyring_get_default_keyring_sync (&default_keyring);
Matthew Barnes ab6285
 	if (!default_keyring) {
Matthew Barnes ab6285
-	        if (gnome_keyring_create_sync ("default", NULL) != GNOME_KEYRING_RESULT_OK) {
Matthew Barnes ab6285
-				if (!msg->noreply)
Matthew Barnes ab6285
-					e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
-				return;
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
+	        if (gnome_keyring_create_sync ("default", NULL) != GNOME_KEYRING_RESULT_OK)
Matthew Barnes ab6285
+			return;
Matthew Barnes ab6285
 	        default_keyring = g_strdup ("default");			
Matthew Barnes ab6285
 	}	
Matthew Barnes ab6285
 	d(g_print("Get Default %d\n", result));
Matthew Barnes 6efa8f
@@ -316,69 +549,54 @@ ep_forget_passwords_keyring(EPassMsg *ms
Matthew Barnes ab6285
 	g_free (default_keyring);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 	/* free up the session passwords */
Matthew Barnes ab6285
-	g_hash_table_foreach_remove (passwords, free_entry, NULL);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
+	g_hash_table_remove_all (password_cache);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_forget_passwords_file(EPassMsg *msg)
Matthew Barnes ab6285
+ep_forget_passwords_keyfile (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	void *it;
Matthew Barnes ab6285
-	char *key;
Matthew Barnes ab6285
+	gchar **groups;
Matthew Barnes ab6285
+	gsize length, ii;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	it = gnome_config_private_init_iterator_sections("/Evolution");
Matthew Barnes ab6285
-	while ( (it = gnome_config_iterator_next(it, &key, NULL)) ) {
Matthew Barnes ab6285
-		if (0 == strncmp(key, "Passwords-", 10)) {
Matthew Barnes ab6285
-			char *section = g_strdup_printf("/Evolution/%s", key);
Matthew Barnes ab6285
+	g_hash_table_remove_all (password_cache);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-			gnome_config_private_clean_section (section);
Matthew Barnes ab6285
-			g_free(section);
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-		g_free(key);
Matthew Barnes ab6285
+	groups = g_key_file_get_groups (key_file, &length);
Matthew Barnes ab6285
+	for (ii = 0; ii < length; ii++) {
Matthew Barnes ab6285
+		if (!g_str_has_prefix (groups[ii], KEY_FILE_GROUP_PREFIX))
Matthew Barnes ab6285
+			continue;
Matthew Barnes ab6285
+		g_key_file_remove_group (key_file, groups[ii], NULL);
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	gnome_config_private_sync_file ("/Evolution");
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	/* free up the session passwords */
Matthew Barnes ab6285
-	g_hash_table_foreach_remove (passwords, free_entry, NULL);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
+	ep_key_file_save ();
Matthew Barnes ab6285
+	g_strfreev (groups);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-static char *
Matthew Barnes ab6285
-password_path (const char *component_name, const char *key)
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_forget_passwords (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	char *keycopy, *path;
Matthew Barnes ab6285
-	int i;
Matthew Barnes ab6285
-	keycopy = g_strdup (key);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	for (i = 0; i < strlen (keycopy); i ++)
Matthew Barnes ab6285
-		if (keycopy[i] == '/' || keycopy[i] =='=')
Matthew Barnes ab6285
-			keycopy[i] = '_';
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	path = g_strdup_printf ("/Evolution/Passwords-%s/%s", component_name, keycopy);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	g_free (keycopy);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	return path;
Matthew Barnes 8edc3a
+#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
+	if (gnome_keyring_is_available ())
Matthew Barnes ab6285
+		ep_forget_passwords_keyring (msg);
Matthew Barnes ab6285
+	else
Matthew Barnes ab6285
+		ep_forget_passwords_keyfile (msg);
Matthew Barnes ab6285
+#else
Matthew Barnes ab6285
+	ep_forget_passwords_keyfile (msg);
Matthew Barnes ab6285
+#endif
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
 #ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_remember_password_keyring(EPassMsg *msg)
Matthew Barnes ab6285
+ep_remember_password_keyring (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	gpointer okey, value;
Matthew Barnes ab6285
+	gpointer value;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
Matthew Barnes ab6285
+	value = g_hash_table_lookup (password_cache, msg->key);
Matthew Barnes ab6285
+	if (value != NULL) {
Matthew Barnes ab6285
 		/* add it to the on-disk cache of passwords */
Matthew Barnes ab6285
 		GnomeKeyringAttributeList *attributes;
Matthew Barnes ab6285
 		GnomeKeyringAttribute attribute;
Matthew Barnes ab6285
 		GnomeKeyringResult result;
Matthew Barnes ab6285
-		EUri *uri = e_uri_new (okey);
Matthew Barnes ab6285
+		EUri *uri = e_uri_new (msg->key);
Matthew Barnes ab6285
 		guint32 item_id;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 		if (!strcmp (uri->protocol, "ldap") && !uri->user) {
Matthew Barnes 6efa8f
@@ -419,48 +637,48 @@ ep_remember_password_keyring(EPassMsg *m
Matthew Barnes ab6285
 	
Matthew Barnes ab6285
 		d(g_print("Remember %s: %d/%d\n", msg->key, result, item_id));
Matthew Barnes ab6285
 		/* now remove it from our session hash */
Matthew Barnes ab6285
-		g_hash_table_remove (passwords, msg->key);
Matthew Barnes ab6285
-		g_free (okey);
Matthew Barnes ab6285
-		g_free (value);
Matthew Barnes ab6285
+		g_hash_table_remove (password_cache, msg->key);
Matthew Barnes ab6285
 		
Matthew Barnes ab6285
 		e_uri_free (uri);
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_remember_password_file(EPassMsg *msg)
Matthew Barnes ab6285
+ep_remember_password_keyfile (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	gpointer okey, value;
Matthew Barnes ab6285
-	char *path, *pass64;
Matthew Barnes ab6285
-	int len, state, save;
Matthew Barnes 3be76c
+	gchar *group, *key, *password;
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
Matthew Barnes ab6285
-		/* add it to the on-disk cache of passwords */
Matthew Barnes ab6285
-		path = password_path (msg->component, okey);
Matthew Barnes 3be76c
+	password = g_hash_table_lookup (password_cache, msg->key);
Matthew Barnes 3be76c
+	if (password == NULL) {
Matthew Barnes 3be76c
+		g_warning ("Password for key \"%s\" not found", msg->key);
Matthew Barnes 3be76c
+		return;
Matthew Barnes 3be76c
+	}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-		len = strlen (value);
Matthew Barnes ab6285
-		pass64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
Matthew Barnes ab6285
-		state = save = 0;
Matthew Barnes ab6285
-		base64_encode_close (value, len, FALSE, (guchar *)pass64, &state, &save);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-		gnome_config_private_set_string (path, pass64);
Matthew Barnes ab6285
-		g_free (path);
Matthew Barnes ab6285
-		g_free (pass64);
Matthew Barnes 3be76c
+	group = ep_key_file_get_group (msg->component);
Matthew Barnes 3be76c
+	key = ep_key_file_normalize_key (msg->key);
Matthew Barnes 3be76c
+	password = ep_password_encode (password);
Matthew Barnes 3b4059
 
Matthew Barnes 3b4059
-		/* now remove it from our session hash */
Matthew Barnes 3b4059
-		g_hash_table_remove (passwords, msg->key);
Matthew Barnes 3b4059
-		g_free (okey);
Matthew Barnes 3b4059
-		g_free (value);
Matthew Barnes ab6285
+	g_hash_table_remove (password_cache, msg->key);
Matthew Barnes ab6285
+	g_key_file_set_string (key_file, group, key, password);
Matthew Barnes ab6285
+	ep_key_file_save ();
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-		gnome_config_private_sync_file ("/Evolution");
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
+	g_free (group);
Matthew Barnes ab6285
+	g_free (key);
Matthew Barnes ab6285
+	g_free (password);
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_remember_password (EPassMsg *msg)
Matthew Barnes ab6285
+{
Matthew Barnes 8edc3a
+#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
+	if (gnome_keyring_is_available ())
Matthew Barnes ab6285
+		ep_remember_password_keyring (msg);
Matthew Barnes ab6285
+	else
Matthew Barnes ab6285
+		ep_remember_password_keyfile (msg);
Matthew Barnes ab6285
+#else
Matthew Barnes ab6285
+	ep_remember_password_keyfile (msg);
Matthew Barnes ab6285
+#endif
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
 #ifdef WITH_GNOME_KEYRING
Matthew Barnes 6efa8f
@@ -472,7 +690,6 @@ ep_forget_password_keyring (EPassMsg *ms
Matthew Barnes ab6285
 	GnomeKeyringResult result;
Matthew Barnes ab6285
 	GList *matches = NULL, *tmp;	
Matthew Barnes ab6285
 	char *default_keyring = NULL;	
Matthew Barnes ab6285
-	gpointer okey, value;
Matthew Barnes ab6285
 	EUri *uri = e_uri_new (msg->key);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 	if (!strcmp (uri->protocol, "ldap") && !uri->user) {
Matthew Barnes 3be76c
@@ -486,12 +703,7 @@ ep_forget_password_keyring (EPassMsg *ms
Matthew Barnes ab6285
 		uri->user = keycopy;
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
 	    
Matthew Barnes ab6285
-	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
Matthew Barnes ab6285
-		g_hash_table_remove (passwords, msg->key);
Matthew Barnes ab6285
-		memset (value, 0, strlen (value));
Matthew Barnes ab6285
-		g_free (okey);
Matthew Barnes ab6285
-		g_free (value);
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
+	g_hash_table_remove (password_cache, msg->key);
Matthew Barnes ab6285
 
Matthew Barnes 3be76c
 	if (!uri->host && !uri->user)
Matthew Barnes ab6285
 		/* No need to remove from keyring for pass phrases */
Matthew Barnes 3be76c
@@ -563,36 +775,45 @@ ep_forget_password_keyring (EPassMsg *ms
Matthew Barnes ab6285
 	g_free (default_keyring);
Matthew Barnes 3be76c
 
Matthew Barnes 3be76c
 exit:
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes 3be76c
-
Matthew Barnes 3be76c
 	e_uri_free(uri);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_forget_password_file (EPassMsg *msg)
Matthew Barnes ab6285
+ep_forget_password_keyfile (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	gpointer okey, value;
Matthew Barnes ab6285
-	char *path;
Matthew Barnes ab6285
+	gchar *group, *key;
Matthew Barnes ab6285
+	GError *error = NULL;
Matthew Barnes 3be76c
+
Matthew Barnes 3be76c
+	g_hash_table_remove (password_cache, msg->key);
Matthew Barnes 3be76c
+
Matthew Barnes 3be76c
+	group = ep_key_file_get_group (msg->component);
Matthew Barnes 3be76c
+	key = ep_key_file_normalize_key (msg->key);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
Matthew Barnes ab6285
-		g_hash_table_remove (passwords, msg->key);
Matthew Barnes ab6285
-		memset (value, 0, strlen (value));
Matthew Barnes ab6285
-		g_free (okey);
Matthew Barnes ab6285
-		g_free (value);
Matthew Barnes ab6285
+	g_key_file_remove_key (key_file, group, key, &error);
Matthew Barnes ab6285
+	if (error == NULL)
Matthew Barnes ab6285
+		ep_key_file_save ();
Matthew Barnes ab6285
+	else {
Matthew Barnes ab6285
+		g_warning ("%s", error->message);
Matthew Barnes ab6285
+		g_error_free (error);
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* clear it in the on disk db */
Matthew Barnes ab6285
-	path = password_path (msg->component, msg->key);
Matthew Barnes ab6285
-	gnome_config_private_clean_key (path);
Matthew Barnes ab6285
-	gnome_config_private_sync_file ("/Evolution");
Matthew Barnes ab6285
-	g_free (path);
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
+	g_free (group);
Matthew Barnes ab6285
+	g_free (key);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
+static void
Matthew Barnes ab6285
+ep_forget_password (EPassMsg *msg)
Matthew Barnes ab6285
+{
Matthew Barnes 8edc3a
+#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
+	if (gnome_keyring_is_available ())
Matthew Barnes ab6285
+		ep_forget_password_keyring (msg);
Matthew Barnes ab6285
+	else
Matthew Barnes ab6285
+		ep_forget_password_keyfile (msg);
Matthew Barnes ab6285
+#else
Matthew Barnes ab6285
+	ep_forget_password_keyfile (msg);
Matthew Barnes ab6285
+#endif
Matthew Barnes ab6285
+}
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
 #ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
 static void
Matthew Barnes 3be76c
@@ -602,11 +823,11 @@ ep_get_password_keyring (EPassMsg *msg)
Matthew Barnes ab6285
 	GnomeKeyringAttributeList *attributes;
Matthew Barnes ab6285
 	GnomeKeyringAttribute attribute;
Matthew Barnes ab6285
 	GnomeKeyringResult result;
Matthew Barnes ab6285
-	GList *matches = NULL, *tmp;	
Matthew Barnes ab6285
+	GList *matches = NULL, *tmp;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	passwd = g_hash_table_lookup (passwords, msg->key);
Matthew Barnes ab6285
+	passwd = g_hash_table_lookup (password_cache, msg->key);
Matthew Barnes ab6285
 	if (passwd) {
Matthew Barnes ab6285
-		msg->password = g_strdup(passwd);
Matthew Barnes ab6285
+		msg->password = g_strdup (passwd);
Matthew Barnes ab6285
 	} else {
Matthew Barnes ab6285
 		EUri *uri = e_uri_new (msg->key);
Matthew Barnes ab6285
 		
Matthew Barnes 3be76c
@@ -681,284 +902,154 @@ ep_get_password_keyring (EPassMsg *msg)
Matthew Barnes ab6285
 		
Matthew Barnes 3be76c
 		e_uri_free (uri);
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
 }	
Matthew Barnes ab6285
 #endif
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-ep_get_password_file (EPassMsg *msg)
Matthew Barnes ab6285
+ep_get_password_keyfile (EPassMsg *msg)
Matthew Barnes ab6285
 {	
Matthew Barnes ab6285
-	char *path, *passwd;
Matthew Barnes ab6285
-	char *encoded = NULL;
Matthew Barnes ab6285
+	gchar *group, *key, *password;
Matthew Barnes ab6285
+	GError *error = NULL;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	passwd = g_hash_table_lookup (passwords, msg->key);
Matthew Barnes ab6285
-	if (passwd) {
Matthew Barnes ab6285
-		msg->password = g_strdup(passwd);
Matthew Barnes 3be76c
+	password = g_hash_table_lookup (password_cache, msg->key);
Matthew Barnes 3be76c
+	if (password != NULL) {
Matthew Barnes 3be76c
+		msg->password = g_strdup (password);
Matthew Barnes 3be76c
+		return;
Matthew Barnes 3be76c
+	}
Matthew Barnes 3be76c
+
Matthew Barnes 3be76c
+	group = ep_key_file_get_group (msg->component);
Matthew Barnes 3be76c
+	key = ep_key_file_normalize_key (msg->key);
Matthew Barnes 3be76c
+
Matthew Barnes 3be76c
+	password = g_key_file_get_string (key_file, group, key, &error);
Matthew Barnes 3be76c
+	if (password != NULL) {
Matthew Barnes 3be76c
+		msg->password = ep_password_decode (password);
Matthew Barnes 3be76c
+		g_free (password);
Matthew Barnes 3be76c
 	} else {
Matthew Barnes ab6285
-		/* not part of the session hash, look it up in the on disk db */
Matthew Barnes ab6285
-		path = password_path (msg->component, msg->key);
Matthew Barnes ab6285
-		encoded = gnome_config_private_get_string_with_default (path, NULL);
Matthew Barnes ab6285
-		g_free (path);
Matthew Barnes ab6285
-		if (encoded) {
Matthew Barnes ab6285
-			msg->password = decode_base64 (encoded);
Matthew Barnes ab6285
-			g_free (encoded);
Matthew Barnes ab6285
-		}
Matthew Barnes 3be76c
+		g_warning ("%s", error->message);
Matthew Barnes 3be76c
+		g_error_free (error);
Matthew Barnes ab6285
 	}
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes 3be76c
+	g_free (group);
Matthew Barnes 3be76c
+	g_free (key);
Matthew Barnes 3be76c
 }
Matthew Barnes ab6285
 
Matthew Barnes 3be76c
 static void
Matthew Barnes ab6285
-ep_add_password (EPassMsg *msg)
Matthew Barnes 3be76c
+ep_get_password (EPassMsg *msg)
Matthew Barnes 3be76c
 {
Matthew Barnes ab6285
-	gpointer okey, value;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
Matthew Barnes ab6285
-		g_hash_table_remove (passwords, msg->key);
Matthew Barnes ab6285
-		g_free (okey);
Matthew Barnes ab6285
-		g_free (value);
Matthew Barnes 3be76c
-	}
Matthew Barnes 3be76c
-
Matthew Barnes ab6285
-	g_hash_table_insert (passwords, g_strdup (msg->key), g_strdup (msg->oldpass));
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes 3be76c
+#ifdef WITH_GNOME_KEYRING
Matthew Barnes 3be76c
+	if (gnome_keyring_is_available ())
Matthew Barnes 3be76c
+		ep_get_password_keyring (msg);
Matthew Barnes 3be76c
+	else
Matthew Barnes 3be76c
+		ep_get_password_keyfile (msg);
Matthew Barnes 3be76c
+#else
Matthew Barnes 3be76c
+	ep_get_password_keyfile (msg);
Matthew Barnes 3be76c
+#endif
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-static void ep_ask_password(EPassMsg *msg);
Matthew Barnes ab6285
-
Matthew Barnes ab6285
 static void
Matthew Barnes ab6285
-pass_response(GtkDialog *dialog, int response, void *data)
Matthew Barnes 3be76c
+ep_add_password (EPassMsg *msg)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	EPassMsg *msg = data;
Matthew Barnes ab6285
-	int type = msg->flags & E_PASSWORDS_REMEMBER_MASK;
Matthew Barnes ab6285
-	EDList pending = E_DLIST_INITIALISER(pending);
Matthew Barnes ab6285
-	EPassMsg *mw, *mn;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (response == GTK_RESPONSE_OK) {
Matthew Barnes ab6285
-		msg->password = g_strdup(gtk_entry_get_text((GtkEntry *)msg->entry));
Matthew Barnes 3be76c
+	gchar *key = g_strdup (msg->key);
Matthew Barnes 3be76c
+	gchar *password = g_strdup (msg->password);
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-		if (type != E_PASSWORDS_REMEMBER_NEVER) {
Matthew Barnes ab6285
-			int noreply = msg->noreply;
Matthew Barnes 3be76c
+	g_hash_table_insert (password_cache, key, password);
Matthew Barnes 3be76c
+}
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-			*msg->remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (msg->check));
Matthew Barnes 3be76c
+static void
Matthew Barnes 3be76c
+ep_ask_password (EPassMsg *msg)
Matthew Barnes 3be76c
+{
Matthew Barnes 3be76c
+	EPassDialogData *data = msg->data;
Matthew Barnes 3be76c
+	gchar *password;
Matthew Barnes 3be76c
+	gint remember;
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-			msg->noreply = 1;
Matthew Barnes 3be76c
+	/* Open the express queue for this key.  This allows us to catch
Matthew Barnes 3be76c
+	 * incoming operations on this key while waiting for the user to
Matthew Barnes 3be76c
+	 * provide a password.  Once we have the password, immediately
Matthew Barnes 3be76c
+	 * process any messages in the express queue. */
Matthew Barnes 3be76c
+	g_async_queue_lock (express_queue);
Matthew Barnes 3be76c
+	express_key = msg->key;
Matthew Barnes 3be76c
+	g_async_queue_unlock (express_queue);
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-			if (*msg->remember || type == E_PASSWORDS_REMEMBER_FOREVER) {
Matthew Barnes ab6285
-				msg->oldpass = msg->password;
Matthew Barnes ab6285
-				ep_add_password(msg);
Matthew Barnes ab6285
-			}
Matthew Barnes 3be76c
-#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
-			if (*msg->remember && type == E_PASSWORDS_REMEMBER_FOREVER) {
Matthew Barnes ab6285
-				if (gnome_keyring_is_available())
Matthew Barnes ab6285
-					ep_remember_password_keyring(msg);
Matthew Barnes ab6285
-				else
Matthew Barnes ab6285
-					ep_remember_password_file(msg);
Matthew Barnes ab6285
-			}
Matthew Barnes 3be76c
-#else
Matthew Barnes ab6285
-			if (*msg->remember && type == E_PASSWORDS_REMEMBER_FOREVER)
Matthew Barnes ab6285
-				ep_remember_password_file(msg);				    
Matthew Barnes ab6285
-#endif				    
Matthew Barnes 3be76c
+	if (data->flags & E_PASSWORDS_REPROMPT)
Matthew Barnes 3be76c
+		ep_get_password (msg);
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-			msg->noreply = noreply;
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-	}
Matthew Barnes 3be76c
+	/* Run the password dialog in the main thread. */
Matthew Barnes 3be76c
+	g_idle_add ((GSourceFunc) ep_dialog_run, msg);
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-	gtk_widget_destroy((GtkWidget *)dialog);
Matthew Barnes ab6285
-	password_dialog = NULL;
Matthew Barnes 3be76c
+	/* Wait for the user to respond. */
Matthew Barnes 3be76c
+	e_flag_wait (data->done);
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-	/* ok, here things get interesting, we suck up any pending
Matthew Barnes ab6285
-	 * operations on this specific password, and return the same
Matthew Barnes ab6285
-	 * result or ignore other operations */
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	LOCK();
Matthew Barnes ab6285
-	mw = (EPassMsg *)request_list.head;
Matthew Barnes ab6285
-	mn = (EPassMsg *)mw->msg.ln.next;
Matthew Barnes ab6285
-	while (mn) {
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING		
Matthew Barnes ab6285
-		if ((mw->dispatch == (gnome_keyring_is_available() ? ep_forget_password_keyring : ep_forget_password_file)
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-		if ((mw->dispatch == ep_forget_password_file		     
Matthew Barnes 3be76c
-#endif
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING				     
Matthew Barnes ab6285
-		     || mw->dispatch == (gnome_keyring_is_available() ? ep_get_password_keyring : ep_get_password_file)
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-		     || mw->dispatch == ep_get_password_file		     
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
-		     || mw->dispatch == ep_ask_password)		    
Matthew Barnes ab6285
-		    && (strcmp(mw->component, msg->component) == 0
Matthew Barnes ab6285
-			&& strcmp(mw->key, msg->key) == 0)) {
Matthew Barnes ab6285
-			e_dlist_remove((EDListNode *)mw);
Matthew Barnes ab6285
-			mw->password = g_strdup(msg->password);
Matthew Barnes ab6285
-			e_msgport_reply(&mw->msg);
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-		mw = mn;
Matthew Barnes ab6285
-		mn = (EPassMsg *)mn->msg.ln.next;
Matthew Barnes 3be76c
+	/* If the user cancelled the dialog then we need to dispatch
Matthew Barnes 3be76c
+	 * any messages that we trapped in the express queue. */
Matthew Barnes 3be76c
+	if (data->response != GTK_RESPONSE_OK) {
Matthew Barnes 3be76c
+		g_async_queue_lock (express_queue);
Matthew Barnes 3be76c
+		express_key = NULL;
Matthew Barnes 3be76c
+		while ((msg = g_async_queue_try_pop_unlocked (express_queue)))
Matthew Barnes 3be76c
+			ep_msg_dispatch (msg);
Matthew Barnes 3be76c
+		g_async_queue_unlock (express_queue);
Matthew Barnes 3be76c
+		return;
Matthew Barnes 3be76c
 	}
Matthew Barnes ab6285
-	UNLOCK();
Matthew Barnes 3be76c
-
Matthew Barnes ab6285
-	if (!msg->noreply)
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	ep_idle_dispatch(NULL);
Matthew Barnes 3be76c
-}
Matthew Barnes 3be76c
-
Matthew Barnes 3be76c
-static void
Matthew Barnes ab6285
-ep_ask_password(EPassMsg *msg)
Matthew Barnes 3be76c
-{
Matthew Barnes ab6285
-	GtkWidget *vbox;
Matthew Barnes ab6285
-	int type = msg->flags & E_PASSWORDS_REMEMBER_MASK;
Matthew Barnes ab6285
-	guint noreply = msg->noreply;
Matthew Barnes ab6285
-	AtkObject *a11y;
Matthew Barnes 3be76c
+	remember = data->flags & E_PASSWORDS_REMEMBER_MASK;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	msg->noreply = 1;
Matthew Barnes 3be76c
+	if (remember == E_PASSWORDS_REMEMBER_NEVER)
Matthew Barnes 3be76c
+		goto cleanup;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/*password_dialog = (GtkDialog *)e_error_new(msg->parent, "mail:ask-session-password", msg->prompt, NULL);*/
Matthew Barnes ab6285
-	password_dialog = (GtkDialog *)gtk_message_dialog_new (msg->parent,
Matthew Barnes ab6285
-							       0,
Matthew Barnes ab6285
-							       GTK_MESSAGE_QUESTION,
Matthew Barnes ab6285
-							       GTK_BUTTONS_OK_CANCEL,
Matthew Barnes ab6285
-							       "%s", msg->prompt);
Matthew Barnes ab6285
-	gtk_window_set_title(GTK_WINDOW(password_dialog), msg->title);
Matthew Barnes 3be76c
+	if (data->remember || remember == E_PASSWORDS_REMEMBER_FOREVER)
Matthew Barnes 3be76c
+		ep_add_password (msg);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	gtk_widget_ensure_style (GTK_WIDGET (password_dialog));
Matthew Barnes ab6285
-	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (password_dialog)->vbox), 0);
Matthew Barnes ab6285
-	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (password_dialog)->action_area), 12);
Matthew Barnes ab6285
+	if (data->remember && remember == E_PASSWORDS_REMEMBER_FOREVER)
Matthew Barnes ab6285
+		ep_remember_password (msg);
Matthew Barnes ab6285
 
Matthew Barnes 3be76c
-	gtk_dialog_set_default_response(password_dialog, GTK_RESPONSE_OK);
Matthew Barnes 3be76c
+cleanup:
Matthew Barnes 3be76c
 
Matthew Barnes ab6285
-	vbox = gtk_vbox_new (FALSE, 12);
Matthew Barnes ab6285
-	gtk_widget_show (vbox);
Matthew Barnes ab6285
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (password_dialog)->vbox), vbox, TRUE, FALSE, 0);
Matthew Barnes ab6285
-	gtk_container_set_border_width((GtkContainer *)vbox, 12);
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	msg->entry = gtk_entry_new ();
Matthew Barnes 3be76c
+	password = g_strdup (msg->password);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	a11y = gtk_widget_get_accessible (msg->entry);
Matthew Barnes ab6285
-	atk_object_set_description (a11y, msg->prompt);
Matthew Barnes ab6285
-	gtk_entry_set_visibility ((GtkEntry *)msg->entry, !(msg->flags & E_PASSWORDS_SECRET));
Matthew Barnes ab6285
-	gtk_entry_set_activates_default((GtkEntry *)msg->entry, TRUE);
Matthew Barnes ab6285
-	gtk_box_pack_start (GTK_BOX (vbox), msg->entry, TRUE, FALSE, 3);
Matthew Barnes ab6285
-	gtk_widget_show (msg->entry);
Matthew Barnes ab6285
-	gtk_widget_grab_focus (msg->entry);
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	if ((msg->flags & E_PASSWORDS_REPROMPT)) {
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
-		if (gnome_keyring_is_available())
Matthew Barnes ab6285
-			ep_get_password_keyring(msg);
Matthew Barnes ab6285
-		else
Matthew Barnes ab6285
-			ep_get_password_file(msg);			
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-		ep_get_password_file(msg);
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
-		if (msg->password) {
Matthew Barnes ab6285
-			gtk_entry_set_text ((GtkEntry *) msg->entry, msg->password);
Matthew Barnes ab6285
-			g_free (msg->password);
Matthew Barnes ab6285
-			msg->password = NULL;
Matthew Barnes ab6285
-		}
Matthew Barnes 3be76c
+	/* Close the express queue and process any messages there. */
Matthew Barnes 3be76c
+	g_async_queue_lock (express_queue);
Matthew Barnes 3be76c
+	express_key = NULL;
Matthew Barnes 3be76c
+	while ((msg = g_async_queue_try_pop_unlocked (express_queue))) {
Matthew Barnes 3be76c
+		msg->password = g_strdup (password);
Matthew Barnes 3be76c
+		e_flag_set (msg->done);
Matthew Barnes 3be76c
 	}
Matthew Barnes 3be76c
+	g_async_queue_unlock (express_queue);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	/* static password, shouldn't be remembered between sessions,
Matthew Barnes ab6285
-	   but will be remembered within the session beyond our control */
Matthew Barnes ab6285
-	if (type != E_PASSWORDS_REMEMBER_NEVER) {
Matthew Barnes ab6285
-		if (msg->flags & E_PASSWORDS_PASSPHRASE) {
Matthew Barnes ab6285
-			msg->check = gtk_check_button_new_with_mnemonic(type == E_PASSWORDS_REMEMBER_FOREVER
Matthew Barnes ab6285
-									? _("_Remember this passphrase")
Matthew Barnes ab6285
-									: _("_Remember this passphrase for the remainder of this session"));
Matthew Barnes ab6285
-		} else {
Matthew Barnes ab6285
-			msg->check = gtk_check_button_new_with_mnemonic(type == E_PASSWORDS_REMEMBER_FOREVER
Matthew Barnes ab6285
-									? _("_Remember this password")
Matthew Barnes ab6285
-									: _("_Remember this password for the remainder of this session"));
Matthew Barnes ab6285
-			
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (msg->check), *msg->remember);
Matthew Barnes ab6285
-		gtk_box_pack_start (GTK_BOX (vbox), msg->check, TRUE, FALSE, 3);
Matthew Barnes ab6285
-		if ((msg->flags & E_PASSWORDS_DISABLE_REMEMBER))
Matthew Barnes ab6285
-			gtk_widget_set_sensitive(msg->check, FALSE);
Matthew Barnes ab6285
-		gtk_widget_show (msg->check);
Matthew Barnes 3be76c
-	}
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	msg->noreply = noreply;
Matthew Barnes 3be76c
-
Matthew Barnes ab6285
-	g_signal_connect(password_dialog, "response", G_CALLBACK (pass_response), msg);
Matthew Barnes ab6285
-	gtk_widget_show((GtkWidget *)password_dialog);
Matthew Barnes ab6285
+	g_free (password);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_init:
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
- * Initializes the e_passwords routines. Must be called before any other
Matthew Barnes ab6285
- * e_passwords_* function.
Matthew Barnes ab6285
+ * This function is here for backward-compatibility.  It does nothing.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
 e_passwords_init (void)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	LOCK();
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (!passwords) {
Matthew Barnes ab6285
-		/* create the per-session hash table */
Matthew Barnes ab6285
-		passwords = g_hash_table_new (g_str_hash, g_str_equal);
Matthew Barnes ab6285
-#ifdef ENABLE_THREADS
Matthew Barnes ab6285
-		main_thread = pthread_self();
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	UNLOCK();
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
- * e_passwords_cancel:
Matthew Barnes ab6285
- * 
Matthew Barnes ab6285
- * Cancel any outstanding password operations and close any dialogues
Matthew Barnes ab6285
- * currently being shown.
Matthew Barnes ab6285
+ * e_passwords_shutdown:
Matthew Barnes ab6285
+ *
Matthew Barnes ab6285
+ * This function is here for backward-compatibility.  It does nothing.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_cancel(void)
Matthew Barnes ab6285
+e_passwords_shutdown (void)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	EPassMsg *msg;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	LOCK();
Matthew Barnes ab6285
-	while ((msg = (EPassMsg *)e_dlist_remhead(&request_list)))
Matthew Barnes ab6285
-		e_msgport_reply(&msg->msg);
Matthew Barnes ab6285
-	UNLOCK();
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (password_dialog)
Matthew Barnes ab6285
-		gtk_dialog_response(password_dialog,GTK_RESPONSE_CANCEL);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
- * e_passwords_shutdown:
Matthew Barnes ab6285
- *
Matthew Barnes ab6285
- * Cleanup routine to call before exiting.
Matthew Barnes ab6285
+ * e_passwords_cancel:
Matthew Barnes ab6285
+ * 
Matthew Barnes ab6285
+ * This function is here for backward-compatibility.  It does nothing.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_shutdown (void)
Matthew Barnes ab6285
+e_passwords_cancel(void)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
-	/* shouldn't need this really - everything is synchronous */
Matthew Barnes ab6285
-	if (!gnome_keyring_is_available())
Matthew Barnes ab6285
-		gnome_config_private_sync_file ("/Evolution");
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-	gnome_config_private_sync_file ("/Evolution");
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
-	e_passwords_cancel();
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (passwords) {
Matthew Barnes ab6285
-		/* and destroy our per session hash */
Matthew Barnes ab6285
-		g_hash_table_foreach_remove (passwords, free_entry, NULL);
Matthew Barnes ab6285
-		g_hash_table_destroy (passwords);
Matthew Barnes ab6285
-		passwords = NULL;
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_set_online:
Matthew Barnes ab6285
- * @state: 
Matthew Barnes ab6285
+ * @online: 
Matthew Barnes ab6285
  * 
Matthew Barnes ab6285
  * Set the offline-state of the application.  This is a work-around
Matthew Barnes ab6285
  * for having the backends fully offline aware, and returns a
Matthew Barnes 3be76c
@@ -967,10 +1058,11 @@ e_passwords_shutdown (void)
Matthew Barnes ab6285
  * FIXME: This is not a permanent api, review post 2.0.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_set_online(int state)
Matthew Barnes ab6285
+e_passwords_set_online (gboolean online)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	ep_online_state = state;
Matthew Barnes ab6285
-	/* TODO: we could check that a request is open and close it, or maybe who cares */
Matthew Barnes ab6285
+	/* TODO We could check that a request is open and close it,
Matthew Barnes ab6285
+	 *      or maybe who cares */
Matthew Barnes ab6285
+	ep_online_state = online;
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes 3be76c
@@ -981,151 +1073,138 @@ e_passwords_set_online(int state)
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
 e_passwords_forget_passwords (void)
Matthew Barnes ab6285
 {
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING	
Matthew Barnes ab6285
-	EPassMsg *msg = ep_msg_new(gnome_keyring_is_available() ? ep_forget_passwords_keyring : ep_forget_passwords_file);
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-	EPassMsg *msg = ep_msg_new(ep_forget_passwords_file);
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes ab6285
-	ep_msg_free(msg);
Matthew Barnes ab6285
+	EPassMsg *msg;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	msg = ep_msg_new (ep_forget_passwords, FALSE);
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	ep_msg_send (msg);
Matthew Barnes ab6285
+	ep_msg_free (msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_clear_passwords:
Matthew Barnes ab6285
+ * @component: component name of the caller
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
  * Forgets all disk cached passwords for the component.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_clear_passwords (const char *component_name)
Matthew Barnes ab6285
+e_passwords_clear_passwords (const gchar *component)
Matthew Barnes ab6285
 {
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING	
Matthew Barnes ab6285
-	EPassMsg *msg = ep_msg_new(gnome_keyring_is_available() ? ep_clear_passwords_keyring : ep_clear_passwords_file);
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-	EPassMsg *msg = ep_msg_new(ep_clear_passwords_file);		
Matthew Barnes ab6285
-#endif
Matthew Barnes ab6285
+	EPassMsg *msg;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	msg->component = component_name;
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes ab6285
-	ep_msg_free(msg);
Matthew Barnes 3b4059
+	g_return_if_fail (component != NULL);
Matthew Barnes 3b4059
+
Matthew Barnes ab6285
+	msg = ep_msg_new (ep_clear_passwords, FALSE);
Matthew Barnes ab6285
+	msg->component = component;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	ep_msg_send (msg);
Matthew Barnes ab6285
+	ep_msg_free (msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_remember_password:
Matthew Barnes ab6285
+ * @component: component name of the caller
Matthew Barnes ab6285
  * @key: the key
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
  * Saves the password associated with @key to disk.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_remember_password (const char *component_name, const char *key)
Matthew Barnes ab6285
+e_passwords_remember_password (const gchar *component, const gchar *key)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
 	EPassMsg *msg;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	g_return_if_fail(component_name != NULL);
Matthew Barnes ab6285
-	g_return_if_fail(key != NULL);
Matthew Barnes ab6285
+	g_return_if_fail (component != NULL);
Matthew Barnes ab6285
+	g_return_if_fail (key != NULL);
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING
Matthew Barnes ab6285
-	msg = ep_msg_new(gnome_keyring_is_available() ? ep_remember_password_keyring : ep_remember_password_file);
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-	msg = ep_msg_new(ep_remember_password_file);
Matthew Barnes ab6285
-#endif	
Matthew Barnes ab6285
-	msg->component = component_name;
Matthew Barnes ab6285
+	msg = ep_msg_new (ep_remember_password, FALSE);
Matthew Barnes ab6285
+	msg->component = component;
Matthew Barnes ab6285
 	msg->key = key;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes ab6285
-	ep_msg_free(msg);
Matthew Barnes ab6285
+	ep_msg_send (msg);
Matthew Barnes ab6285
+	ep_msg_free (msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_forget_password:
Matthew Barnes ab6285
+ * @component: component name of the caller
Matthew Barnes ab6285
  * @key: the key
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
  * Forgets the password associated with @key, in memory and on disk.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_forget_password (const char *component_name, const char *key)
Matthew Barnes ab6285
+e_passwords_forget_password (const gchar *component, const gchar *key)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
 	EPassMsg *msg;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	g_return_if_fail(component_name != NULL);
Matthew Barnes ab6285
-	g_return_if_fail(key != NULL);
Matthew Barnes ab6285
+	g_return_if_fail (component != NULL);
Matthew Barnes ab6285
+	g_return_if_fail (key != NULL);
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING	
Matthew Barnes ab6285
-	msg = ep_msg_new(gnome_keyring_is_available() ? ep_forget_password_keyring : ep_forget_password_file);
Matthew Barnes ab6285
-#else	
Matthew Barnes ab6285
-	msg = ep_msg_new(ep_forget_password_file);
Matthew Barnes ab6285
-#endif	
Matthew Barnes ab6285
-	msg->component = component_name;
Matthew Barnes ab6285
+	msg = ep_msg_new (ep_forget_password, TRUE);
Matthew Barnes ab6285
+	msg->component = component;
Matthew Barnes ab6285
 	msg->key = key;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes ab6285
-	ep_msg_free(msg);
Matthew Barnes ab6285
+	ep_msg_send (msg);
Matthew Barnes ab6285
+	ep_msg_free (msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_get_password:
Matthew Barnes ab6285
+ * @component: component name of the caller
Matthew Barnes ab6285
  * @key: the key
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
  * Return value: the password associated with @key, or %NULL.  Caller
Matthew Barnes ab6285
  * must free the returned password.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 char *
Matthew Barnes ab6285
-e_passwords_get_password (const char *component_name, const char *key)
Matthew Barnes ab6285
+e_passwords_get_password (const gchar *component, const gchar *key)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
 	EPassMsg *msg;
Matthew Barnes ab6285
-	char *passwd;
Matthew Barnes 3b4059
+	char *password;
Matthew Barnes 3b4059
 
Matthew Barnes ab6285
-	g_return_val_if_fail(component_name != NULL, NULL);
Matthew Barnes ab6285
-	g_return_val_if_fail(key != NULL, NULL);
Matthew Barnes 3b4059
+	g_return_val_if_fail (component != NULL, NULL);
Matthew Barnes 3b4059
+	g_return_val_if_fail (key != NULL, NULL);
Matthew Barnes ab6285
 
Matthew Barnes 8edc3a
-#ifdef WITH_GNOME_KEYRING	
Matthew Barnes ab6285
-	msg = ep_msg_new(gnome_keyring_is_available() ? ep_get_password_keyring : ep_get_password_file);
Matthew Barnes ab6285
-#else
Matthew Barnes ab6285
-	msg = ep_msg_new(ep_get_password_file);
Matthew Barnes ab6285
-#endif	
Matthew Barnes 3b4059
-
Matthew Barnes ab6285
-	msg->component = component_name;
Matthew Barnes ab6285
+	msg = ep_msg_new (ep_get_password, TRUE);
Matthew Barnes ab6285
+	msg->component = component;
Matthew Barnes ab6285
 	msg->key = key;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes 3b4059
-
Matthew Barnes 3b4059
-	passwd = msg->password;
Matthew Barnes 3b4059
-	msg->password = NULL;
Matthew Barnes 3b4059
-	ep_msg_free(msg);
Matthew Barnes ab6285
+	ep_msg_send (msg);
Matthew Barnes ab6285
+	password = msg->password;
Matthew Barnes ab6285
+	ep_msg_free (msg);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	return passwd;
Matthew Barnes ab6285
+	return password;
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_add_password:
Matthew Barnes ab6285
  * @key: a key
Matthew Barnes ab6285
- * @passwd: the password for @key
Matthew Barnes ab6285
+ * @password: the password for @key
Matthew Barnes ab6285
  *
Matthew Barnes ab6285
  * This stores the @key/@passwd pair in the current session's password
Matthew Barnes ab6285
  * hash.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
 void
Matthew Barnes ab6285
-e_passwords_add_password (const char *key, const char *passwd)
Matthew Barnes ab6285
+e_passwords_add_password (const gchar *key, const gchar *password)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
 	EPassMsg *msg;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	g_return_if_fail(key != NULL);
Matthew Barnes ab6285
-	g_return_if_fail(passwd != NULL);
Matthew Barnes ab6285
+	g_return_if_fail (key != NULL);
Matthew Barnes ab6285
+	g_return_if_fail (password != NULL);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	msg = ep_msg_new(ep_add_password);
Matthew Barnes ab6285
+	msg = ep_msg_new (ep_add_password, FALSE);
Matthew Barnes ab6285
 	msg->key = key;
Matthew Barnes ab6285
-	msg->oldpass = passwd;
Matthew Barnes ab6285
+	msg->password = g_strdup (password);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes ab6285
-	ep_msg_free(msg);
Matthew Barnes ab6285
+	ep_msg_send (msg);
Matthew Barnes ab6285
+	g_free (msg->password);
Matthew Barnes ab6285
+	ep_msg_free (msg);
Matthew Barnes ab6285
 }
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /**
Matthew Barnes ab6285
  * e_passwords_ask_password:
Matthew Barnes ab6285
  * @title: title for the password dialog
Matthew Barnes ab6285
- * @component_name: the name of the component for which we're storing
Matthew Barnes ab6285
- * the password (e.g. Mail, Addressbook, etc.)
Matthew Barnes 6efa8f
- * @key: key to store the password under
Matthew Barnes ab6285
+ * @component: component name of the caller
Matthew Barnes 6efa8f
+ * @key: key to store the password under, or NULL
Matthew Barnes ab6285
  * @prompt: prompt string
Matthew Barnes c30bc7
  * @type: whether or not to offer to remember the password,
Matthew Barnes 3be76c
  * and for how long.
Matthew Barnes 3be76c
@@ -1140,241 +1219,44 @@ e_passwords_add_password (const char *ke
Matthew Barnes ab6285
  * return value is non-%NULL and @remember_type is not
Matthew Barnes ab6285
  * E_PASSWORDS_DO_NOT_REMEMBER.
Matthew Barnes ab6285
  **/
Matthew Barnes ab6285
-char *
Matthew Barnes ab6285
-e_passwords_ask_password (const char *title, const char *component_name,
Matthew Barnes ab6285
-			  const char *key,
Matthew Barnes ab6285
-			  const char *prompt,
Matthew Barnes ab6285
+gchar *
Matthew Barnes ab6285
+e_passwords_ask_password (const gchar *title,
Matthew Barnes ab6285
+			  const gchar *component,
Matthew Barnes ab6285
+			  const gchar *key,
Matthew Barnes ab6285
+			  const gchar *prompt,
Matthew Barnes ab6285
 			  EPasswordsRememberType type,
Matthew Barnes ab6285
-			  gboolean *remember,
Matthew Barnes ab6285
+			  gboolean *p_remember,
Matthew Barnes ab6285
 			  GtkWindow *parent)
Matthew Barnes ab6285
 {
Matthew Barnes ab6285
-	char *passwd;
Matthew Barnes ab6285
-	EPassMsg *msg = ep_msg_new(ep_ask_password);
Matthew Barnes ab6285
+	EPassMsg *msg;
Matthew Barnes ab6285
+	EPassDialogData *data;
Matthew Barnes ab6285
+	gboolean remember;
Matthew Barnes ab6285
+	gchar *password;
Matthew Barnes ab6285
+
Matthew Barnes ab6285
+	g_return_val_if_fail (title != NULL, NULL);
Matthew Barnes ab6285
+	g_return_val_if_fail (component != NULL, NULL);
Matthew Barnes ab6285
+	g_return_val_if_fail (prompt != NULL, NULL);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 	if ((type & E_PASSWORDS_ONLINE) && !ep_online_state)
Matthew Barnes ab6285
 		return NULL;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	msg->title = title;
Matthew Barnes ab6285
-	msg->component = component_name;
Matthew Barnes ab6285
-	msg->key = key;
Matthew Barnes ab6285
-	msg->prompt = prompt;
Matthew Barnes ab6285
-	msg->flags = type;
Matthew Barnes ab6285
-	msg->remember = remember;
Matthew Barnes ab6285
-	msg->parent = parent;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	ep_msg_send(msg);
Matthew Barnes ab6285
-	passwd = msg->password;
Matthew Barnes ab6285
-	msg->password = NULL;
Matthew Barnes ab6285
-	ep_msg_free(msg);
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	return passwd;
Matthew Barnes ab6285
-}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-static char *base64_alphabet =
Matthew Barnes ab6285
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-static unsigned char camel_mime_base64_rank[256] = {
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
Matthew Barnes ab6285
-	 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
Matthew Barnes ab6285
-	255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
Matthew Barnes ab6285
-	 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
Matthew Barnes ab6285
-	255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
Matthew Barnes ab6285
-	 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
Matthew Barnes ab6285
-};
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-/* call this when finished encoding everything, to
Matthew Barnes ab6285
-   flush off the last little bit */
Matthew Barnes ab6285
-static int
Matthew Barnes ab6285
-base64_encode_close(unsigned char *in, int inlen, gboolean break_lines, unsigned char *out, int *state, int *save)
Matthew Barnes ab6285
-{
Matthew Barnes ab6285
-	int c1, c2;
Matthew Barnes ab6285
-	unsigned char *outptr = out;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (inlen>0)
Matthew Barnes ab6285
-		outptr += base64_encode_step(in, inlen, break_lines, outptr, state, save);
Matthew Barnes ab6285
+	remember = (p_remember != NULL) ? *p_remember : FALSE;
Matthew Barnes ab6285
+	data = ep_dialog_data_new (parent, title, prompt, remember, type);
Matthew Barnes ab6285
 
Matthew Barnes ab6285
-	c1 = ((unsigned char *)save)[1];
Matthew Barnes ab6285
-	c2 = ((unsigned char *)save)[2];
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	switch (((char *)save)[0]) {
Matthew Barnes ab6285
-	case 2:
Matthew Barnes ab6285
-		outptr[2] = base64_alphabet[ ( (c2 &0x0f) << 2 ) ];
Matthew Barnes ab6285
-		g_assert(outptr[2] != 0);
Matthew Barnes ab6285
-		goto skip;
Matthew Barnes ab6285
-	case 1:
Matthew Barnes ab6285
-		outptr[2] = '=';
Matthew Barnes ab6285
-	skip:
Matthew Barnes ab6285
-		outptr[0] = base64_alphabet[ c1 >> 2 ];
Matthew Barnes ab6285
-		outptr[1] = base64_alphabet[ c2 >> 4 | ( (c1&0x3) << 4 )];
Matthew Barnes ab6285
-		outptr[3] = '=';
Matthew Barnes ab6285
-		outptr += 4;
Matthew Barnes ab6285
-		break;
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
-	if (break_lines)
Matthew Barnes ab6285
-		*outptr++ = '\n';
Matthew Barnes 6efa8f
+	msg = ep_msg_new (ep_ask_password, TRUE);
Matthew Barnes 6efa8f
+	msg->component = component;
Matthew Barnes 6efa8f
+	msg->key = (key != NULL) ? key : "";
Matthew Barnes 6efa8f
+	msg->data = data;
Matthew Barnes 6efa8f
 
Matthew Barnes ab6285
-	*save = 0;
Matthew Barnes ab6285
-	*state = 0;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	return outptr-out;
Matthew Barnes ab6285
-}
Matthew Barnes 6efa8f
+	ep_msg_send (msg);
Matthew Barnes 6efa8f
+	password = msg->password;
Matthew Barnes 6efa8f
+	remember = data->remember;
Matthew Barnes 6efa8f
+	ep_msg_free (msg);
Matthew Barnes 6efa8f
 
Matthew Barnes ab6285
-/*
Matthew Barnes ab6285
-  performs an 'encode step', only encodes blocks of 3 characters to the
Matthew Barnes ab6285
-  output at a time, saves left-over state in state and save (initialise to
Matthew Barnes ab6285
-  0 on first invocation).
Matthew Barnes ab6285
-*/
Matthew Barnes ab6285
-static int
Matthew Barnes ab6285
-base64_encode_step(unsigned char *in, int len, gboolean break_lines, unsigned char *out, int *state, int *save)
Matthew Barnes ab6285
-{
Matthew Barnes ab6285
-	register unsigned char *inptr, *outptr;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (len<=0)
Matthew Barnes ab6285
-		return 0;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	inptr = in;
Matthew Barnes ab6285
-	outptr = out;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (len + ((char *)save)[0] > 2) {
Matthew Barnes ab6285
-		unsigned char *inend = in+len-2;
Matthew Barnes ab6285
-		register int c1, c2, c3;
Matthew Barnes ab6285
-		register int already;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-		already = *state;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-		switch (((char *)save)[0]) {
Matthew Barnes ab6285
-		case 1:	c1 = ((unsigned char *)save)[1]; goto skip1;
Matthew Barnes ab6285
-		case 2:	c1 = ((unsigned char *)save)[1];
Matthew Barnes ab6285
-			c2 = ((unsigned char *)save)[2]; goto skip2;
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-		
Matthew Barnes ab6285
-		/* yes, we jump into the loop, no i'm not going to change it, it's beautiful! */
Matthew Barnes ab6285
-		while (inptr < inend) {
Matthew Barnes ab6285
-			c1 = *inptr++;
Matthew Barnes ab6285
-		skip1:
Matthew Barnes ab6285
-			c2 = *inptr++;
Matthew Barnes ab6285
-		skip2:
Matthew Barnes ab6285
-			c3 = *inptr++;
Matthew Barnes ab6285
-			*outptr++ = base64_alphabet[ c1 >> 2 ];
Matthew Barnes ab6285
-			*outptr++ = base64_alphabet[ c2 >> 4 | ( (c1&0x3) << 4 ) ];
Matthew Barnes ab6285
-			*outptr++ = base64_alphabet[ ( (c2 &0x0f) << 2 ) | (c3 >> 6) ];
Matthew Barnes ab6285
-			*outptr++ = base64_alphabet[ c3 & 0x3f ];
Matthew Barnes ab6285
-			/* this is a bit ugly ... */
Matthew Barnes ab6285
-			if (break_lines && (++already)>=19) {
Matthew Barnes ab6285
-				*outptr++='\n';
Matthew Barnes ab6285
-				already = 0;
Matthew Barnes ab6285
-			}
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-		((char *)save)[0] = 0;
Matthew Barnes ab6285
-		len = 2-(inptr-inend);
Matthew Barnes ab6285
-		*state = already;
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	if (len>0) {
Matthew Barnes ab6285
-		register char *saveout;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-		/* points to the slot for the next char to save */
Matthew Barnes ab6285
-		saveout = & (((char *)save)[1]) + ((char *)save)[0];
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-		/* len can only be 0 1 or 2 */
Matthew Barnes ab6285
-		switch(len) {
Matthew Barnes ab6285
-		case 2:	*saveout++ = *inptr++;
Matthew Barnes ab6285
-		case 1:	*saveout++ = *inptr++;
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-		((char *)save)[0]+=len;
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	return outptr-out;
Matthew Barnes ab6285
-}
Matthew Barnes 6efa8f
+	ep_dialog_data_free (data);
Matthew Barnes 6efa8f
 
Matthew Barnes 6efa8f
+	if (p_remember != NULL)
Matthew Barnes 6efa8f
+		*p_remember = remember;
Matthew Barnes 6efa8f
 
Matthew Barnes ab6285
-/**
Matthew Barnes ab6285
- * base64_decode_step: decode a chunk of base64 encoded data
Matthew Barnes ab6285
- * @in: input stream
Matthew Barnes ab6285
- * @len: max length of data to decode
Matthew Barnes ab6285
- * @out: output stream
Matthew Barnes ab6285
- * @state: holds the number of bits that are stored in @save
Matthew Barnes ab6285
- * @save: leftover bits that have not yet been decoded
Matthew Barnes ab6285
- *
Matthew Barnes ab6285
- * Decodes a chunk of base64 encoded data
Matthew Barnes ab6285
- **/
Matthew Barnes ab6285
-static int
Matthew Barnes ab6285
-base64_decode_step(unsigned char *in, int len, unsigned char *out, int *state, unsigned int *save)
Matthew Barnes ab6285
-{
Matthew Barnes ab6285
-	register unsigned char *inptr, *outptr;
Matthew Barnes ab6285
-	unsigned char *inend, c;
Matthew Barnes ab6285
-	register unsigned int v;
Matthew Barnes ab6285
-	int i;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	inend = in+len;
Matthew Barnes ab6285
-	outptr = out;
Matthew Barnes ab6285
-
Matthew Barnes ab6285
-	/* convert 4 base64 bytes to 3 normal bytes */
Matthew Barnes ab6285
-	v=*save;
Matthew Barnes ab6285
-	i=*state;
Matthew Barnes ab6285
-	inptr = in;
Matthew Barnes ab6285
-	while (inptr
Matthew Barnes ab6285
-		c = camel_mime_base64_rank[*inptr++];
Matthew Barnes ab6285
-		if (c != 0xff) {
Matthew Barnes ab6285
-			v = (v<<6) | c;
Matthew Barnes ab6285
-			i++;
Matthew Barnes ab6285
-			if (i==4) {
Matthew Barnes ab6285
-				*outptr++ = v>>16;
Matthew Barnes ab6285
-				*outptr++ = v>>8;
Matthew Barnes ab6285
-				*outptr++ = v;
Matthew Barnes ab6285
-				i=0;
Matthew Barnes ab6285
-			}
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-	}
Matthew Barnes 6efa8f
-
Matthew Barnes ab6285
-	*save = v;
Matthew Barnes ab6285
-	*state = i;
Matthew Barnes 6efa8f
-
Matthew Barnes ab6285
-	/* quick scan back for '=' on the end somewhere */
Matthew Barnes ab6285
-	/* fortunately we can drop 1 output char for each trailing = (upto 2) */
Matthew Barnes ab6285
-	i=2;
Matthew Barnes ab6285
-	while (inptr>in && i) {
Matthew Barnes ab6285
-		inptr--;
Matthew Barnes ab6285
-		if (camel_mime_base64_rank[*inptr] != 0xff) {
Matthew Barnes ab6285
-			if (*inptr == '=')
Matthew Barnes ab6285
-				outptr--;
Matthew Barnes ab6285
-			i--;
Matthew Barnes ab6285
-		}
Matthew Barnes ab6285
-	}
Matthew Barnes 6efa8f
-
Matthew Barnes ab6285
-	/* if i!= 0 then there is a truncation error! */
Matthew Barnes ab6285
-	return outptr-out;
Matthew Barnes ab6285
-}
Matthew Barnes 6efa8f
-
Matthew Barnes ab6285
-static char *
Matthew Barnes ab6285
-decode_base64 (char *base64)
Matthew Barnes ab6285
-{
Matthew Barnes ab6285
-	guchar *plain;
Matthew Barnes ab6285
-	char *pad = "==";
Matthew Barnes ab6285
-	int len, out, state;
Matthew Barnes ab6285
-	unsigned int save;
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	len = strlen (base64);
Matthew Barnes ab6285
-	plain = g_malloc0 (len);
Matthew Barnes ab6285
-	state = save = 0;
Matthew Barnes ab6285
-	out = base64_decode_step ((guchar *)base64, len, plain, &state, &save);
Matthew Barnes ab6285
-	if (len % 4) {
Matthew Barnes ab6285
-		base64_decode_step ((guchar *)pad, 4 - len % 4, plain + out,
Matthew Barnes ab6285
-				    &state, &save);
Matthew Barnes ab6285
-	}
Matthew Barnes ab6285
-	
Matthew Barnes ab6285
-	return (char *)plain;
Matthew Barnes ab6285
+	return password;
Matthew Barnes ab6285
 }
Matthew Barnes 3be76c
--- evolution-data-server-1.11.4/libedataserver/e-msgport.h.e-passwords	2007-04-18 06:10:18.000000000 -0400
Matthew Barnes 3be76c
+++ evolution-data-server-1.11.4/libedataserver/e-msgport.h	2007-06-18 16:19:44.000000000 -0400
Matthew Barnes 6efa8f
@@ -54,7 +54,7 @@ typedef struct _EMsgPort EMsgPort;
Matthew Barnes ab6285
 
Matthew Barnes ab6285
 /* header for any message */
Matthew Barnes ab6285
 typedef struct _EMsg {
Matthew Barnes ab6285
-	EDListNode ln;
Matthew Barnes ab6285
+	EDListNode ln;  /* deprecated */
Matthew Barnes ab6285
 	EMsgPort *reply_port;
Matthew Barnes ab6285
 	gint flags;
Matthew Barnes ab6285
 } EMsg;