Re: [evolution-patches] all components, password serialisation patch




here's another try and fixing the behaviour, revert the other one first.

it snatches any pending ops on the same password after the dialogue is answered and broadcasts the same result to them all.

it would be simpler to just look up the password in ep_ask_password and return it directly, and change all of the re-asking logic in the callers, but then it could get into loops and so on, so it wouldn't work afterall.


On Tue, 2004-08-10 at 13:25 +0000, Not Zed wrote:

this seems to be the only way to fix the password serialisation problem across all components.

its more or less a movement of the mail's password stuff to e-password, including making it fully mt-safe, which greatly simplifies the mail's calls to it, and could probably simplify the async callbacks in other components too.

it isn't entirely the same as what the mailer had though, since it now also guarantees execution order even from (recursive) calls from the gui thread, so  i don't know if it hasn't added other problems.

it will gaurantee you never get more than 1 password dialogue up at a time, requests areprocessed in the order they come in, etc etc.

--
Michael Zucchi <notzed ximian com>
"born to die, live to work, it's all downhill from here"
Novell's Evolution and Free Software Developer
Index: addressbook/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/ChangeLog,v
retrieving revision 1.1805
diff -u -3 -r1.1805 ChangeLog
--- addressbook/ChangeLog	4 Aug 2004 15:23:13 -0000	1.1805
+++ addressbook/ChangeLog	11 Aug 2004 04:08:02 -0000
@@ -1,3 +1,8 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* gui/component/addressbook.c (addressbook_authenticate): e
+	passwords api change/reprompt if we need to.
+
 2004-08-04  Rodney Dawes  <dobey novell com>
 
 	* gui/widgets/eab-popup-control.c: #include <gtk/gtkvbox.h>
Index: addressbook/gui/component/addressbook.c
===================================================================
RCS file: /cvs/gnome/evolution/addressbook/gui/component/addressbook.c,v
retrieving revision 1.238
diff -u -3 -r1.238 addressbook.c
--- addressbook/gui/component/addressbook.c	12 Jul 2004 18:28:08 -0000	1.238
+++ addressbook/gui/component/addressbook.c	11 Aug 2004 04:08:02 -0000
@@ -168,9 +168,11 @@
 		char *prompt;
 		gboolean remember;
 		char *failed_auth;
+		guint32 flags = E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET;
 
 		if (previous_failure) {
 			failed_auth = _("Failed to authenticate.\n");
+			flags |= E_PASSWORDS_REPROMPT;
 		}
 		else {
 			failed_auth = "";
@@ -180,8 +182,8 @@
 					  failed_auth, e_source_peek_name (source), user);
 
 		remember = get_remember_password (source);
-		pass_dup = e_passwords_ask_password (prompt, component_name, uri, prompt, TRUE,
-						     E_PASSWORDS_REMEMBER_FOREVER, &remember,
+		pass_dup = e_passwords_ask_password (prompt, component_name, uri, prompt,
+						     flags, &remember,
 						     NULL);
 		if (remember != get_remember_password (source))
 			set_remember_password (source, remember);
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2479
diff -u -3 -r1.2479 ChangeLog
--- calendar/ChangeLog	9 Aug 2004 12:57:14 -0000	1.2479
+++ calendar/ChangeLog	11 Aug 2004 04:08:05 -0000
@@ -1,3 +1,8 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* gui/e-pub-utils.c (e_pub_publish): 
+	* common/authentication.c (auth_func_cb): epasswords api change.
+
 2004-08-06  JP Rosevear  <jpr ximian com>
  
  	Fixes #62452
Index: calendar/common/authentication.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/common/authentication.c,v
retrieving revision 1.6
diff -u -3 -r1.6 authentication.c
--- calendar/common/authentication.c	22 Jul 2004 03:02:08 -0000	1.6
+++ calendar/common/authentication.c	11 Aug 2004 04:08:05 -0000
@@ -45,8 +45,8 @@
 	password = e_passwords_get_password (component_name, key);
 	
 	if (!password)
-		password = e_passwords_ask_password (_("Enter password"), component_name, key, prompt, TRUE,
-						     E_PASSWORDS_REMEMBER_FOREVER, &remember,
+		password = e_passwords_ask_password (_("Enter password"), component_name, key, prompt,
+						     E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET, &remember,
 						     NULL);
 
 	return password;
Index: calendar/gui/e-pub-utils.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-pub-utils.c,v
retrieving revision 1.3
diff -u -3 -r1.3 e-pub-utils.c
--- calendar/gui/e-pub-utils.c	10 Apr 2004 21:31:37 -0000	1.3
+++ calendar/gui/e-pub-utils.c	11 Aug 2004 04:08:05 -0000
@@ -299,10 +299,10 @@
 			if (!password) {
 				prompt = g_strdup_printf (_("Enter the password for %s"), (gchar *)uri->location);
 				password = e_passwords_ask_password (_("Enter password"), 
-							     "Calendar", (gchar *)uri->location, 
-							     prompt, TRUE, 
-							   E_PASSWORDS_REMEMBER_FOREVER,
-							     &remember, NULL);
+								     "Calendar", (gchar *)uri->location, 
+								     prompt,
+								     E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET,
+								     &remember, NULL);
 
 				g_free (prompt);
 					
Index: camel/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/camel/ChangeLog,v
retrieving revision 1.2237
diff -u -3 -r1.2237 ChangeLog
--- camel/ChangeLog	6 Aug 2004 19:24:03 -0000	1.2237
+++ camel/ChangeLog	11 Aug 2004 04:08:07 -0000
@@ -1,3 +1,9 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* providers/groupwise/camel-gw-listener.c
+	(get_addressbook_names_from_server): fix for e_passwords api
+	change, and handle reprompting as well.
+
 2004-08-06  Jeffrey Stedfast  <fejj novell com>
 
 	* providers/imap4/camel-imap4-summary.c (untagged_fetch_all): Call
Index: camel/providers/groupwise/camel-gw-listener.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/groupwise/camel-gw-listener.c,v
retrieving revision 1.16
diff -u -3 -r1.16 camel-gw-listener.c
--- camel/providers/groupwise/camel-gw-listener.c	29 Jul 2004 06:46:26 -0000	1.16
+++ camel/providers/groupwise/camel-gw-listener.c	11 Aug 2004 04:08:09 -0000
@@ -381,6 +381,7 @@
 	char *uri;
 	const char *use_ssl;
 	const char *poa_address;
+	guint32 flags = E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET;
 
 	url = camel_url_new (source_url, NULL);
         if (url == NULL) {
@@ -406,8 +407,8 @@
 		prompt = g_strdup_printf (_("%sEnter password for %s (user %s)"),
                                           failed_auth, poa_address, url->user);
 		
-		password = e_passwords_ask_password (prompt, "Groupwise", key, prompt, TRUE,
-                                                     E_PASSWORDS_REMEMBER_FOREVER, &remember,
+		password = e_passwords_ask_password (prompt, "Groupwise", key, prompt,
+                                                     E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET, &remember,
 						     NULL);
 		g_free (prompt);
 		
@@ -415,6 +416,7 @@
 			break;
 		cnc = e_gw_connection_new (uri, url->user, password);
 		failed_auth = _("Failed to authenticate.\n");
+		flags |= E_PASSWORDS_REPROMPT;
 	} while (cnc == NULL);
 	
 	if (E_IS_GW_CONNECTION(cnc))  {
Index: e-util/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/e-util/ChangeLog,v
retrieving revision 1.476
diff -u -3 -r1.476 ChangeLog
--- e-util/ChangeLog	9 Aug 2004 16:47:03 -0000	1.476
+++ e-util/ChangeLog	11 Aug 2004 04:08:09 -0000
@@ -1,3 +1,13 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* e-passwords.c: Lots of changes.  The api is now fully
+	multi-thread safe, all calls are serialised internally, even
+	recursive main-loop calls.  One small change to the ask_password
+	call to add some new features required by the mailer and to clean
+	up some of the names.
+	(e_passwords_cancel): new procedure to cancel any outstanding
+	password requests, for when we need to go uninteractive.
+
 2004-08-09  Rodney Dawes  <dobey novell com>
 
 	* e-icon-factory.c (icon_foreach_remove): We must return TRUE here
Index: e-util/e-passwords.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-passwords.c,v
retrieving revision 1.18
diff -u -3 -r1.18 e-passwords.c
--- e-util/e-passwords.c	9 Mar 2004 21:10:42 -0000	1.18
+++ e-util/e-passwords.c	11 Aug 2004 04:08:10 -0000
@@ -22,40 +22,182 @@
  * USA.
  */
 
+/*
+ * This looks a lot more complicated than it is, and than you'd think
+ * it would need to be.  There is however, method to the madness.
+ *
+ * The code most cope with being called from any thread at any time,
+ * recursively from the main thread, and then serialising every
+ * request so that sane and correct values are always returned, and
+ * duplicate requests are never made.
+ *
+ * To this end, every call is marshalled and queued and a dispatch
+ * method invoked until that request is satisfied.  If mainloop
+ * recursion occurs, then the sub-call will necessarily return out of
+ * order, but will not be processed out of order.
+ */
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include "e-passwords.h"
 #include <string.h>
 #include <libgnome/gnome-config.h>
 #include <libgnome/gnome-i18n.h>
 #include <gtk/gtkentry.h>
-#include <gtk/gtkbox.h>
+#include <gtk/gtkvbox.h>
 #include <gtk/gtkcheckbutton.h>
 #include <gtk/gtkmessagedialog.h>
 
-static char *decode_base64 (char *base64);
+#include "e-passwords.h"
+#include "e-msgport.h"
+#include "widgets/misc/e-error.h"
+
+#ifndef ENABLE_THREADS
+#define ENABLE_THREADS (1)
+#endif
+
+#ifdef ENABLE_THREADS
+#include <pthread.h>
+
+static pthread_t main_thread;
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+#define LOCK() pthread_mutex_lock(&lock)
+#define UNLOCK() pthread_mutex_unlock(&lock)
+#else
+#define LOCK()
+#define UNLOCK()
+#endif
+
+struct _EPassMsg {
+	EMsg msg;
+
+	void (*dispatch)(struct _EPassMsg *);
+
+	/* input */
+	struct _GtkWindow *parent;	
+	const char *component;
+	const char *key;
+	const char *title;
+	const char *prompt;
+	const char *oldpass;
+	guint32 flags;
+
+	/* output */
+	gboolean *remember;
+	char *password;
+
+	/* work variables */
+	GtkWidget *entry;
+	GtkWidget *check;
+	int ismain:1;
+	int noreply:1;		/* supress replies; when calling
+				 * dispatch functions from others */
+};
+
+typedef struct _EPassMsg EPassMsg;
 
 static GHashTable *passwords = NULL;
+static GtkDialog *password_dialog;
+static EDList request_list = E_DLIST_INITIALISER(request_list);
+static int idle_id;
 
+static char *decode_base64 (char *base64);
 static int base64_encode_close(unsigned char *in, int inlen, gboolean break_lines, unsigned char *out, int *state, int *save);
 static int base64_encode_step(unsigned char *in, int len, gboolean break_lines, unsigned char *out, int *state, int *save);
 
-/**
- * e_passwords_init:
- *
- * Initializes the e_passwords routines. Must be called before any other
- * e_passwords_* function.
- **/
+static gboolean
+ep_idle_dispatch(void *data)
+{
+	EPassMsg *msg;
+
+	/* As soon as a password window is up we stop; it will
+	   re-invoke us when it has been closed down */
+	LOCK();
+	while (password_dialog == NULL && (msg = (EPassMsg *)e_dlist_remhead(&request_list))) {
+		UNLOCK();
+
+		msg->dispatch(msg);
+
+		LOCK();
+	}
+
+	idle_id = 0;
+	UNLOCK();
+
+	return FALSE;
+}
+
+static EPassMsg *
+ep_msg_new(void (*dispatch)(EPassMsg *))
+{
+	EPassMsg *msg;
+
+	e_passwords_init();
+
+	msg = g_malloc0(sizeof(*msg));
+	msg->dispatch = dispatch;
+	msg->msg.reply_port = e_msgport_new();
+#ifdef ENABLE_THREADS
+	msg->ismain = pthread_self() == main_thread;
+#else
+	msg->ismain = TRUE;
+#endif
+	return msg;
+}
+
+static void
+ep_msg_free(EPassMsg *msg)
+{
+	e_msgport_destroy(msg->msg.reply_port);
+	g_free(msg->password);
+	g_free(msg);
+}
+
 static void
-e_passwords_init ()
+ep_msg_send(EPassMsg *msg)
 {
-	if (passwords)
-		return;
+	int needidle = 0;
+
+	LOCK();
+	e_dlist_addtail(&request_list, (EDListNode *)&msg->msg);
+	if (!idle_id) {
+		if (!msg->ismain)
+			idle_id = g_idle_add(ep_idle_dispatch, NULL);
+		else
+			needidle = 1;
+	}
+	UNLOCK();
+
+	if (msg->ismain) {
+		EPassMsg *m;
+
+		if (needidle)
+			ep_idle_dispatch(NULL);
+		while ((m = (EPassMsg *)e_msgport_get(msg->msg.reply_port)) == NULL)
+			g_main_context_iteration(NULL, TRUE);
+		g_assert(m == msg);
+	} else {
+		e_msgport_wait(msg->msg.reply_port);
+		g_assert(e_msgport_get(msg->msg.reply_port) == &msg->msg);
+	}
+}
+
+/* the functions that actually do the work */
+static void
+ep_clear_passwords(EPassMsg *msg)
+{
+	char *path;
+
+	path = g_strdup_printf ("/Evolution/Passwords-%s", msg->component);
 
-	/* create the per-session hash table */
-	passwords = g_hash_table_new (g_str_hash, g_str_equal);
+	gnome_config_private_clean_section (path);
+	gnome_config_private_sync_file ("/Evolution");
+
+	g_free (path);
+
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
 }
 
 static gboolean
@@ -67,39 +209,12 @@
 	return TRUE;
 }
 
-/**
- * e_passwords_shutdown:
- *
- * Cleanup routine to call before exiting.
- **/
-void
-e_passwords_shutdown ()
-{
-	/* shouldn't need this really - everything is synchronous */
-	gnome_config_private_sync_file ("/Evolution");
-
-	if (passwords) {
-		/* and destroy our per session hash */
-		g_hash_table_foreach_remove (passwords, free_entry, NULL);
-		g_hash_table_destroy (passwords);
-		passwords = NULL;
-	}
-}
-
-
-/**
- * e_passwords_forget_passwords:
- *
- * Forgets all cached passwords, in memory and on disk.
- **/
-void
-e_passwords_forget_passwords ()
+static void
+ep_forget_passwords(EPassMsg *msg)
 {
 	void *it;
 	char *key;
 
-	e_passwords_init ();
-
 	it = gnome_config_private_init_iterator_sections("/Evolution");
 	while ( (it = gnome_config_iterator_next(it, &key, NULL)) ) {
 		if (0 == strncmp(key, "Passwords-", 10)) {
@@ -111,31 +226,13 @@
 		g_free(key);
 	}
 
-	/*gnome_config_private_clean_section ("/Evolution/Passwords-Mail");*/
 	gnome_config_private_sync_file ("/Evolution");
 
 	/* free up the session passwords */
 	g_hash_table_foreach_remove (passwords, free_entry, NULL);
-}
-
-/**
- * e_passwords_clear_component_passwords:
- *
- * Forgets all disk cached passwords.
- **/
-void
-e_passwords_clear_component_passwords (const char *component_name)
-{
-	char *path;
-
-	e_passwords_init ();
-
-	path = g_strdup_printf ("/Evolution/Passwords-%s", component_name);
-
-	gnome_config_private_clean_section (path);
-	gnome_config_private_sync_file ("/Evolution");
 
-	g_free (path);
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
 }
 
 static char *
@@ -156,42 +253,337 @@
 	return path;
 }
 
-/**
- * e_passwords_remember_password:
- * @key: the key
- *
- * Saves the password associated with @key to disk.
- **/
-void
-e_passwords_remember_password (const char *component_name, const char *key)
+static void
+ep_remember_password(EPassMsg *msg)
 {
 	gpointer okey, value;
 	char *path, *pass64;
 	int len, state, save;
 
-	e_passwords_init ();
+	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
+		/* add it to the on-disk cache of passwords */
+		path = password_path (msg->component, okey);
+
+		len = strlen (value);
+		pass64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
+		state = save = 0;
+		base64_encode_close (value, len, FALSE, pass64, &state, &save);
+
+		gnome_config_private_set_string (path, pass64);
+		g_free (path);
+		g_free (pass64);
 
-	if (!g_hash_table_lookup_extended (passwords, key, &okey, &value))
-		return;
+		/* now remove it from our session hash */
+		g_hash_table_remove (passwords, msg->key);
+		g_free (okey);
+		g_free (value);
 
-	/* add it to the on-disk cache of passwords */
-	path = password_path (component_name, okey);
+		gnome_config_private_sync_file ("/Evolution");
+	}
+
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
+}
 
-	len = strlen (value);
-	pass64 = g_malloc0 ((len + 2) * 4 / 3 + 1);
-	state = save = 0;
-	base64_encode_close (value, len, FALSE, pass64, &state, &save);
+static void
+ep_forget_password (EPassMsg *msg)
+{
+	gpointer okey, value;
+	char *path;
 
-	gnome_config_private_set_string (path, pass64);
+	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
+		g_hash_table_remove (passwords, msg->key);
+		memset (value, 0, strlen (value));
+		g_free (okey);
+		g_free (value);
+	}
+
+	/* clear it in the on disk db */
+	path = password_path (msg->component, msg->key);
+	gnome_config_private_clean_key (path);
+	gnome_config_private_sync_file ("/Evolution");
 	g_free (path);
-	g_free (pass64);
+	
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
+}
 
-	/* now remove it from our session hash */
-	g_hash_table_remove (passwords, key);
-	g_free (okey);
-	g_free (value);
+static void
+ep_get_password (EPassMsg *msg)
+{
+	char *path, *passwd;
+	char *encoded = NULL;
+
+	passwd = g_hash_table_lookup (passwords, msg->key);
+	if (passwd) {
+		msg->password = g_strdup(passwd);
+	} else {
+		/* not part of the session hash, look it up in the on disk db */
+		path = password_path (msg->component, msg->key);
+		encoded = gnome_config_private_get_string_with_default (path, NULL);
+		g_free (path);
+		if (encoded) {
+			msg->password = decode_base64 (encoded);
+			g_free (encoded);
+		}
+	}
+
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
+}
+
+static void
+ep_add_password (EPassMsg *msg)
+{
+	gpointer okey, value;
+
+	if (g_hash_table_lookup_extended (passwords, msg->key, &okey, &value)) {
+		g_hash_table_remove (passwords, msg->key);
+		g_free (okey);
+		g_free (value);
+	}
+
+	g_hash_table_insert (passwords, g_strdup (msg->key), g_strdup (msg->oldpass));
+
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
+}
+
+static void ep_ask_password(EPassMsg *msg);
+
+static void
+pass_response(GtkDialog *dialog, int response, void *data)
+{
+	EPassMsg *msg = data;
+	int type = msg->flags & E_PASSWORDS_REMEMBER_MASK;
+	EDList pending = E_DLIST_INITIALISER(pending);
+	EPassMsg *mw, *mn;
+
+	if (response == GTK_RESPONSE_OK) {
+		msg->password = g_strdup(gtk_entry_get_text((GtkEntry *)msg->entry));
+
+		if (type != E_PASSWORDS_REMEMBER_NEVER) {
+			int noreply = msg->noreply;
+
+			*msg->remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (msg->check));
+
+			msg->noreply = 1;
+
+			if (*msg->remember || type == E_PASSWORDS_REMEMBER_FOREVER) {
+				msg->oldpass = msg->password;
+				ep_add_password(msg);
+			}
+
+			if (*msg->remember && type == E_PASSWORDS_REMEMBER_FOREVER)
+				ep_remember_password(msg);
+
+			msg->noreply = noreply;
+		}
+	}
+
+	gtk_widget_destroy((GtkWidget *)dialog);
+	password_dialog = NULL;
+
+	/* ok, here things get interesting, we suck up any pending
+	 * operations on this specific password, and return the same
+	 * result or ignore other operations */
+
+	LOCK();
+	mw = (EPassMsg *)request_list.head;
+	mn = (EPassMsg *)mw->msg.ln.next;
+	while (mn) {
+		if ((mw->dispatch == ep_forget_password
+		     || mw->dispatch == ep_get_password
+		     || mw->dispatch == ep_ask_password)
+		    && (strcmp(mw->component, msg->component) == 0
+			&& strcmp(mw->key, msg->key) == 0)) {
+			e_dlist_remove((EDListNode *)mw);
+			mw->password = g_strdup(msg->password);
+			e_msgport_reply(&mw->msg);
+		}
+		mw = mn;
+		mn = (EPassMsg *)mn->msg.ln.next;
+	}
+	UNLOCK();
+
+	if (!msg->noreply)
+		e_msgport_reply(&msg->msg);
+
+	ep_idle_dispatch(NULL);
+}
+
+static void
+ep_ask_password(EPassMsg *msg)
+{
+	GtkWidget *vbox;
+	int type = msg->flags & E_PASSWORDS_REMEMBER_MASK;
+	int noreply = msg->noreply;
+
+	msg->noreply = 1;
+
+	/*password_dialog = (GtkDialog *)e_error_new(msg->parent, "mail:ask-session-password", msg->prompt, NULL);*/
+	password_dialog = (GtkDialog *)gtk_message_dialog_new (msg->parent,
+							       0,
+							       GTK_MESSAGE_QUESTION,
+							       GTK_BUTTONS_OK_CANCEL,
+							       msg->prompt);
+	gtk_window_set_title(GTK_WINDOW(password_dialog), msg->title);
+
+	gtk_dialog_set_has_separator(password_dialog, FALSE);
+	gtk_dialog_set_default_response(password_dialog, GTK_RESPONSE_OK);
+
+	vbox = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (password_dialog)->vbox), vbox, TRUE, FALSE, 0);
+	gtk_container_set_border_width((GtkContainer *)vbox, 6);
+	
+	msg->entry = gtk_entry_new ();
+	gtk_entry_set_visibility ((GtkEntry *)msg->entry, !(msg->flags & E_PASSWORDS_SECRET));
+	gtk_entry_set_activates_default((GtkEntry *)msg->entry, TRUE);
+	gtk_box_pack_start (GTK_BOX (vbox), msg->entry, TRUE, FALSE, 3);
+	gtk_widget_show (msg->entry);
+	gtk_widget_grab_focus (msg->entry);
+	
+	if ((msg->flags & E_PASSWORDS_REPROMPT)) {
+		ep_get_password(msg);
+		if (msg->password) {
+			gtk_entry_set_text ((GtkEntry *) msg->entry, msg->password);
+			g_free (msg->password);
+			msg->password = NULL;
+		}
+	}
+
+	/* static password, shouldn't be remembered between sessions,
+	   but will be remembered within the session beyond our control */
+	if (type != E_PASSWORDS_REMEMBER_NEVER) {
+		msg->check = gtk_check_button_new_with_mnemonic(type == E_PASSWORDS_REMEMBER_FOREVER
+								? _("_Remember this password")
+								: _("_Remember this password for the remainder of this session"));
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (msg->check), *msg->remember);
+		gtk_box_pack_start (GTK_BOX (vbox), msg->check, TRUE, FALSE, 3);
+		gtk_widget_show (msg->check);
+	}
+	
+	msg->noreply = noreply;
+
+	g_signal_connect(password_dialog, "response", G_CALLBACK (pass_response), msg);
+	gtk_widget_show((GtkWidget *)password_dialog);
+}
+
+
+/**
+ * e_passwords_init:
+ *
+ * Initializes the e_passwords routines. Must be called before any other
+ * e_passwords_* function.
+ **/
+void
+e_passwords_init (void)
+{
+	LOCK();
+
+	if (!passwords) {
+		/* create the per-session hash table */
+		passwords = g_hash_table_new (g_str_hash, g_str_equal);
+#ifdef ENABLE_THREADS
+		main_thread = pthread_self();
+#endif
+	}
+
+	UNLOCK();
+}
+
+/**
+ * e_passwords_cancel:
+ * 
+ * Cancel any outstanding password operations and close any dialogues
+ * currently being shown.
+ **/
+void
+e_passwords_cancel(void)
+{
+	EPassMsg *msg;
+
+	LOCK();
+	while ((msg = (EPassMsg *)e_dlist_remhead(&request_list)))
+		e_msgport_reply(&msg->msg);
+	UNLOCK();
+
+	if (password_dialog)
+		gtk_widget_destroy((GtkWidget *)password_dialog);
+}
 
+/**
+ * e_passwords_shutdown:
+ *
+ * Cleanup routine to call before exiting.
+ **/
+void
+e_passwords_shutdown (void)
+{
+	/* shouldn't need this really - everything is synchronous */
 	gnome_config_private_sync_file ("/Evolution");
+
+	e_passwords_cancel();
+
+	if (passwords) {
+		/* and destroy our per session hash */
+		g_hash_table_foreach_remove (passwords, free_entry, NULL);
+		g_hash_table_destroy (passwords);
+		passwords = NULL;
+	}
+}
+
+/**
+ * e_passwords_forget_passwords:
+ *
+ * Forgets all cached passwords, in memory and on disk.
+ **/
+void
+e_passwords_forget_passwords (void)
+{
+	EPassMsg *msg = ep_msg_new(ep_forget_passwords);
+
+	ep_msg_send(msg);
+	ep_msg_free(msg);
+}
+
+/**
+ * e_passwords_clear_passwords:
+ *
+ * Forgets all disk cached passwords for the component.
+ **/
+void
+e_passwords_clear_passwords (const char *component_name)
+{
+	EPassMsg *msg = ep_msg_new(ep_clear_passwords);
+
+	msg->component = component_name;
+	ep_msg_send(msg);
+	ep_msg_free(msg);
+}
+
+/**
+ * e_passwords_remember_password:
+ * @key: the key
+ *
+ * Saves the password associated with @key to disk.
+ **/
+void
+e_passwords_remember_password (const char *component_name, const char *key)
+{
+	EPassMsg *msg;
+
+	g_return_if_fail(component_name != NULL);
+	g_return_if_fail(key != NULL);
+
+	msg = ep_msg_new(ep_remember_password);
+
+	msg->component = component_name;
+	msg->key = key;
+
+	ep_msg_send(msg);
+	ep_msg_free(msg);
 }
 
 /**
@@ -203,23 +595,18 @@
 void
 e_passwords_forget_password (const char *component_name, const char *key)
 {
-	gpointer okey, value;
-	char *path;
+	EPassMsg *msg;
 
-	e_passwords_init ();
+	g_return_if_fail(component_name != NULL);
+	g_return_if_fail(key != NULL);
 
-	if (g_hash_table_lookup_extended (passwords, key, &okey, &value)) {
-		g_hash_table_remove (passwords, key);
-		memset (value, 0, strlen (value));
-		g_free (okey);
-		g_free (value);
-	}
+	msg = ep_msg_new(ep_forget_password);
 
-	/* clear it in the on disk db */
-	path = password_path (component_name, key);
-	gnome_config_private_clean_key (path);
-	gnome_config_private_sync_file ("/Evolution");
-	g_free (path);
+	msg->component = component_name;
+	msg->key = key;
+
+	ep_msg_send(msg);
+	ep_msg_free(msg);
 }
 
 /**
@@ -232,28 +619,23 @@
 char *
 e_passwords_get_password (const char *component_name, const char *key)
 {
-	char *path, *passwd;
-	char *encoded = NULL;
+	EPassMsg *msg;
+	char *passwd;
 
-	e_passwords_init ();
-	
-	passwd = g_hash_table_lookup (passwords, key);
-	if (passwd)
-		return g_strdup (passwd);
-	
-	/* not part of the session hash, look it up in the on disk db */
-	path = password_path (component_name, key);
+	g_return_val_if_fail(component_name != NULL, NULL);
+	g_return_val_if_fail(key != NULL, NULL);
 
-	encoded = gnome_config_private_get_string_with_default (path, NULL);
-	
-	g_free (path);
+	msg = ep_msg_new(ep_get_password);
+
+	msg->component = component_name;
+	msg->key = key;
+
+	ep_msg_send(msg);
+
+	passwd = msg->password;
+	msg->password = NULL;
+	ep_msg_free(msg);
 
-	if (!encoded)
-		return NULL;
-	
-	passwd = decode_base64 (encoded);
-	g_free (encoded);
-	
 	return passwd;
 }
 
@@ -268,28 +650,17 @@
 void
 e_passwords_add_password (const char *key, const char *passwd)
 {
-	gpointer okey, value;
+	EPassMsg *msg;
 
-	e_passwords_init ();
+	g_return_if_fail(key != NULL);
+	g_return_if_fail(passwd != NULL);
 
-	/* FIXME: shouldn't this be g_return_if_fail? */
-	if (!key || !passwd)
-		return;
-
-	if (g_hash_table_lookup_extended (passwords, key, &okey, &value)) {
-		g_hash_table_remove (passwords, key);
-		g_free (okey);
-		g_free (value);
-	}
+	msg = ep_msg_new(ep_add_password);
+	msg->key = key;
+	msg->oldpass = passwd;
 
-	g_hash_table_insert (passwords, g_strdup (key), g_strdup (passwd));
-}
-
-
-static void
-entry_activate (GtkEntry *entry, GtkDialog *dialog)
-{
-	gtk_dialog_response (dialog, GTK_RESPONSE_OK);
+	ep_msg_send(msg);
+	ep_msg_free(msg);
 }
 
 /**
@@ -316,75 +687,28 @@
 char *
 e_passwords_ask_password (const char *title, const char *component_name,
 			  const char *key,
-			  const char *prompt, gboolean secret,
-			  EPasswordsRememberType remember_type,
+			  const char *prompt,
+			  EPasswordsRememberType type,
 			  gboolean *remember,
 			  GtkWindow *parent)
 {
-	GtkWidget *dialog;
-	GtkWidget *check = NULL, *entry;
-	char *password;
-	int response;
-
-	dialog = gtk_message_dialog_new (parent,
-					 0,
-					 GTK_MESSAGE_QUESTION,
-					 GTK_BUTTONS_OK_CANCEL,
-					 prompt);
-
-	gtk_window_set_title (GTK_WINDOW (dialog), title);
-
-	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
-	/* Password entry */
-	entry = gtk_entry_new();
-	if (secret)
-		gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
-
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), 
-			    entry, FALSE, FALSE, 4);
-	gtk_widget_show (entry);
-	gtk_widget_grab_focus (entry);
-
-	g_signal_connect (entry, "activate",
-			  G_CALLBACK (entry_activate), dialog);
-
-	/* Remember the password? */
-	if (remember_type != E_PASSWORDS_DO_NOT_REMEMBER) {
-		const char *label;
-
-		if (remember_type == E_PASSWORDS_REMEMBER_FOREVER)
-			label = _("Remember this password");
-		else
-			label = _("Remember this password for the remainder of this session");
-		check = gtk_check_button_new_with_label (label);
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
-					      *remember);
+	char *passwd;
+	EPassMsg *msg = ep_msg_new(ep_ask_password);
 
-		gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
-				  check, TRUE, FALSE, 4);
-		gtk_widget_show (check);
-	}
-
-	response = gtk_dialog_run (GTK_DIALOG (dialog));
-
-	if (response == GTK_RESPONSE_OK) {
-		password = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
-		if (remember_type != E_PASSWORDS_DO_NOT_REMEMBER) {
-			*remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
-
-			if (*remember || remember_type == E_PASSWORDS_REMEMBER_FOREVER)
-				e_passwords_add_password (key, password);
-			if (*remember && remember_type == E_PASSWORDS_REMEMBER_FOREVER)
-				e_passwords_remember_password (component_name, key);
-		}
-	} else
-		password = NULL;
-
-	gtk_widget_destroy (dialog);
-
-	return password;
+	msg->title = title;
+	msg->component = component_name;
+	msg->key = key;
+	msg->prompt = prompt;
+	msg->flags = type;
+	msg->remember = remember;
+	msg->parent = parent;
+
+	ep_msg_send(msg);
+	passwd = msg->password;
+	msg->password = NULL;
+	ep_msg_free(msg);
+	
+	return passwd;
 }
 
 
Index: e-util/e-passwords.h
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-passwords.h,v
retrieving revision 1.8
diff -u -3 -r1.8 e-passwords.h
--- e-util/e-passwords.h	9 Dec 2002 21:39:41 -0000	1.8
+++ e-util/e-passwords.h	11 Aug 2004 04:08:10 -0000
@@ -28,28 +28,38 @@
 
 G_BEGIN_DECLS
 
-/* initialization is now implicit when you call any of the functions
-   below (except _shutdown.).  e_passwords_shutdown should be called
-   at exit time to synch the password on-disk storage, and to free up
-   in-memory storage. */
-void        e_passwords_shutdown          (void);
+/*
+  initialization is now implicit when you call any of the functions
+  below, although this is only correct if the functions are called
+  from the main thread.
+
+  e_passwords_shutdown should be called at exit time to synch the
+  password on-disk storage, and to free up in-memory storage. */
+void e_passwords_init (void);
 
+void        e_passwords_shutdown          (void);
+void	    e_passwords_cancel(void);
 void        e_passwords_remember_password (const char *component, const char *key);
 void        e_passwords_add_password      (const char *key, const char *passwd);
 char       *e_passwords_get_password      (const char *component, const char *key);
 void        e_passwords_forget_password   (const char *component, const char *key);
 void        e_passwords_forget_passwords  (void);
-void        e_passwords_clear_component_passwords (const char *component);
+void        e_passwords_clear_passwords (const char *component);
 
 typedef enum {
-	E_PASSWORDS_DO_NOT_REMEMBER,
-	E_PASSWORDS_REMEMBER_FOR_SESSION,
-	E_PASSWORDS_REMEMBER_FOREVER
+	E_PASSWORDS_REMEMBER_NEVER,
+	E_PASSWORDS_REMEMBER_SESSION,
+	E_PASSWORDS_REMEMBER_FOREVER,
+	E_PASSWORDS_REMEMBER_MASK = 0xf,
+
+	/* option bits */
+	E_PASSWORDS_SECRET = 1<<8,
+	E_PASSWORDS_REPROMPT = 1<<9,
 } EPasswordsRememberType;
 
 char *      e_passwords_ask_password      (const char *title, 
 					   const char*component_name, const char *key,
-					   const char *prompt, gboolean secret,
+					   const char *prompt,
 					   EPasswordsRememberType remember_type,
 					   gboolean *remember,
 					   GtkWindow *parent);
Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.3429
diff -u -3 -r1.3429 ChangeLog
--- mail/ChangeLog	6 Aug 2004 17:36:01 -0000	1.3429
+++ mail/ChangeLog	11 Aug 2004 04:08:13 -0000
@@ -1,3 +1,14 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* mail-session.c (get_password): just call
+	e_passwords_ask_password directly.
+	(pass_activate, pass_response, request_password, do_get_pass)
+	(do_free_pass, main_forget_password): no longer required as
+	e_password now handles the magic, and is thread safe.
+
+	* mail-config.c (mail_config_write_on_exit): epasswords api
+	change.
+
 2004-06-08  Karsten Bräckelmann  <guenther rudersport de>
 
 	* em-format-html-display.c (smime_encrypt_table[4]): minor typo,
Index: mail/mail-config.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-config.c,v
retrieving revision 1.309
diff -u -3 -r1.309 mail-config.c
--- mail/mail-config.c	14 May 2004 18:21:03 -0000	1.309
+++ mail/mail-config.c	11 Aug 2004 04:08:13 -0000
@@ -440,7 +440,7 @@
 	g_object_unref (iter);
 	
 	/* then we clear out our component passwords */
-	e_passwords_clear_component_passwords ("Mail");
+	e_passwords_clear_passwords ("Mail");
 	
 	/* then we remember them */
 	iter = e_list_get_iterator ((EList *) config->accounts);
Index: mail/mail-session.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/mail-session.c,v
retrieving revision 1.96
diff -u -3 -r1.96 mail-session.c
--- mail/mail-session.c	17 Jun 2004 07:34:50 -0000	1.96
+++ mail/mail-session.c	11 Aug 2004 04:08:14 -0000
@@ -166,260 +166,89 @@
 
 /* ********************************************************************** */
 
-static GtkDialog *password_dialog = NULL;
-static EDList password_list = E_DLIST_INITIALISER(password_list);
-
-struct _pass_msg {
-	struct _mail_msg msg;
-	
-	CamelSession *session;
-	CamelService *service;
-	const char *domain;
-	const char *prompt;
-	const char *item;
-	guint32 flags;
-	CamelException *ex;
-	
-	char *service_url;
-	char *key;
-
-	EAccountService *config_service;
-	GtkWidget *check;
-	GtkWidget *entry;
-	char *result;
-	int ismain;
-};
-
-static void do_get_pass(struct _mail_msg *mm);
-
-static void
-pass_activate (GtkEntry *entry, void *data)
+static char *
+get_password (CamelSession *session, CamelService *service, const char *domain,
+	      const char *prompt, const char *item, guint32 flags, CamelException *ex)
 {
-	if (password_dialog)
-		gtk_dialog_response (password_dialog, GTK_RESPONSE_OK);
-}
+	char *url;
+	char *ret = NULL;
+	EAccount *account = NULL;
+
+	url = service?camel_url_to_string(service->url, CAMEL_URL_HIDE_ALL):NULL;
+
+	if (!strcmp(item, "popb4smtp_uri")) {
+		/* not 100% mt safe, but should be ok */
+		if (url
+		    && (account = mail_config_get_account_by_transport_url(url)))
+			ret = g_strdup(account->source->url);
+	} else {
+		char *key = make_key(service, item);
+		EAccountService *config_service = NULL;
 
-static void
-pass_response (GtkDialog *dialog, int button, void *data)
-{
-	struct _pass_msg *m = data;
-	
-	switch (button) {
-	case GTK_RESPONSE_OK:
-	{
-		gboolean cache, remember;
-		
-		m->result = g_strdup (gtk_entry_get_text ((GtkEntry *) m->entry));
-		remember = cache = m->check ? gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m->check)) : FALSE;
-		
-		if (m->service_url) {
-			if (m->config_service) {
-				mail_config_service_set_save_passwd (m->config_service, cache);
-				
-				/* set `cache' to TRUE because people don't want to have to
-				   re-enter their passwords for this session even if they told
-				   us not to cache their passwords in the dialog...*sigh* */
-				cache = TRUE;
+		if (domain == NULL)
+			domain = "Mail";
+
+		ret = e_passwords_get_password(domain, key);
+		if (ret == NULL || (flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
+			guint32 eflags;
+			gboolean remember;
+			char *title;
+
+			if (url) {
+				if  ((account = mail_config_get_account_by_source_url(url)))
+					config_service = account->source;
+				else if ((account = mail_config_get_account_by_transport_url(url)))
+					config_service = account->transport;
 			}
-		} else {
-			/* we can't remember the password if it isn't for an account (pgp?) */
-			remember = FALSE;
-		}
-		
-		if (cache) {
-			/* cache the password for the session */
-			e_passwords_add_password (m->key, m->result);
-			
-			/* should we remember it between sessions? */
-			if (remember)
-				e_passwords_remember_password ("Mail", m->key);
-		}
-		break;
-	}
-	default:
-		camel_exception_set (m->ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled operation."));
-		break;
-	}
 
-	gtk_widget_destroy ((GtkWidget *) dialog);
+			remember = config_service?config_service->save_passwd:FALSE;
 
-	password_dialog = NULL;
-	e_msgport_reply ((EMsg *)m);
-	
-	if ((m = (struct _pass_msg *) e_dlist_remhead (&password_list)))
-		do_get_pass ((struct _mail_msg *) m);
-}
+			if (account)
+				title = g_strdup_printf (_("Enter Password for %s"), account->name);
+			else
+				title = g_strdup (_("Enter Password"));
 
-static void
-request_password (struct _pass_msg *m)
-{
-	EAccount *mca = NULL;
-	GtkWidget *vbox;
-	char *title;
-	
-	/* If we already have a password_dialog up, save this request till later */
-	if (!m->ismain && password_dialog) {
-		e_dlist_addtail (&password_list, (EDListNode *)m);
-		return;
-	}
-	
-	if (m->service_url) {
-		if ((mca = mail_config_get_account_by_source_url (m->service_url)))
-			m->config_service = mca->source;
-		else if ((mca = mail_config_get_account_by_transport_url (m->service_url)))
-			m->config_service = mca->transport;
-	}
-	
-	if (mca)
-		title = g_strdup_printf (_("Enter Password for %s"), mca->name);
-	else
-		title = g_strdup (_("Enter Password"));
-	
-	password_dialog = (GtkDialog *)e_error_new(NULL, "mail:ask-session-password", m->prompt, NULL);
-	gtk_window_set_title (GTK_WINDOW (password_dialog), title);
-	g_free (title);
-
-	vbox = gtk_vbox_new (FALSE, 6);
-	gtk_widget_show (vbox);
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (password_dialog)->vbox), vbox, TRUE, FALSE, 0);
-	gtk_container_set_border_width((GtkContainer *)vbox, 6);
-	
-	m->entry = gtk_entry_new ();
-	gtk_entry_set_visibility ((GtkEntry *) m->entry, !(m->flags & CAMEL_SESSION_PASSWORD_SECRET));
-	g_signal_connect (m->entry, "activate", G_CALLBACK (pass_activate), password_dialog);
-	gtk_box_pack_start (GTK_BOX (vbox), m->entry, TRUE, FALSE, 3);
-	gtk_widget_show (m->entry);
-	gtk_widget_grab_focus (m->entry);
-	
-	if ((m->flags & CAMEL_SESSION_PASSWORD_REPROMPT) && m->result) {
-		gtk_entry_set_text ((GtkEntry *) m->entry, m->result);
-		g_free (m->result);
-		m->result = NULL;
-	}
-
-	/* static password, shouldn't be remembered between sessions,
-	   but will be remembered within the session beyond our control */
-	if ((m->service_url == NULL || m->service != NULL)
-	    && (m->flags & CAMEL_SESSION_PASSWORD_STATIC) == 0) {
-		m->check = gtk_check_button_new_with_mnemonic (m->service_url ? _("_Remember this password")
-							       : _("_Remember this password for the remainder of this session"));
-		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m->check),
-					      m->config_service ? m->config_service->save_passwd : FALSE);
-		gtk_box_pack_start (GTK_BOX (vbox), m->check, TRUE, FALSE, 3);
-		gtk_widget_show (m->check);
-	}
-	
-	if (m->ismain) {
-		pass_response(password_dialog, gtk_dialog_run (password_dialog), m);
-	} else {
-		g_signal_connect (password_dialog, "response", G_CALLBACK (pass_response), m);
-		gtk_widget_show ((GtkWidget *) password_dialog);
-	}
-}
+			if ((flags & CAMEL_SESSION_PASSWORD_STATIC) != 0)
+				eflags = E_PASSWORDS_REMEMBER_NEVER;
+			else if (config_service == NULL)
+				eflags = E_PASSWORDS_REMEMBER_SESSION;
+			else
+				eflags = E_PASSWORDS_REMEMBER_FOREVER;
 
-static void
-do_get_pass(struct _mail_msg *mm)
-{
-	struct _pass_msg *m = (struct _pass_msg *)mm;
-	MailSession *mail_session = MAIL_SESSION (m->session);
-	
-	if (!strcmp (m->item, "popb4smtp_uri")) {
-		char *url = camel_url_to_string (m->service->url, 0);
-		EAccount *account = mail_config_get_account_by_transport_url (url);
-		
-		g_free(url);
-		if (account)
-			m->result = g_strdup(account->source->url);
-	} else if (m->key) {
-		m->result = e_passwords_get_password (m->domain?m->domain:"Mail", m->key);
-		if (m->result == NULL || (m->flags & CAMEL_SESSION_PASSWORD_REPROMPT)) {
-			if (mail_session->interactive) {
-				request_password(m);
-				return;
-			}
-		}
-	}
+			if (flags & CAMEL_SESSION_PASSWORD_REPROMPT)
+				eflags |= E_PASSWORDS_REPROMPT;
 
-	e_msgport_reply((EMsg *)mm);
-}
+			if (flags & CAMEL_SESSION_PASSWORD_SECRET)
+				eflags |= E_PASSWORDS_SECRET;
 
-static void
-do_free_pass(struct _mail_msg *mm)
-{
-	struct _pass_msg *m = (struct _pass_msg *)mm;
+			ret = e_passwords_ask_password(title, domain, key, prompt, eflags, &remember, NULL);
 
-	g_free(m->service_url);
-	g_free(m->key);
-}
+			g_free(title);
 
-static struct _mail_msg_op get_pass_op = {
-	NULL,
-	do_get_pass,
-	NULL,
-	do_free_pass,
-};
-
-static char *
-get_password (CamelSession *session, CamelService *service, const char *domain,
-	      const char *prompt, const char *item, guint32 flags, CamelException *ex)
-{
-	struct _pass_msg *m, *r;
-	EMsgPort *pass_reply;
-	char *ret;
-	
-	/* We setup an async request and send it off, and wait for it to return */
-	/* If we're really in main, we dont of course ...
-	   ... but this shouldn't be allowed because of locking issues */
-	pass_reply = e_msgport_new ();
-	m = mail_msg_new(&get_pass_op, pass_reply, sizeof(struct _pass_msg));
-	m->ismain = pthread_self() == mail_gui_thread;
-	m->session = session;
-	m->prompt = prompt;
-	m->flags = flags;
-	m->service = service;
-	m->domain = domain;
-	m->item = item;
-	m->ex = ex;
-	if (service)
-		m->service_url = camel_url_to_string (service->url, CAMEL_URL_HIDE_ALL);
-	m->key = make_key(service, item);
+			if (ret && config_service)
+				mail_config_service_set_save_passwd(config_service, remember);
+		}
 
-	if (m->ismain) {
-		do_get_pass((struct _mail_msg *)m);
-	} else {
-		extern EMsgPort *mail_gui_port2;
-		
-		e_msgport_put(mail_gui_port2, (EMsg *)m);
+		g_free(key);
 	}
-	
-	e_msgport_wait(pass_reply);
-	r = (struct _pass_msg *)e_msgport_get(pass_reply);
-	g_assert(m == r);
 
-	ret = m->result;
-	mail_msg_free(m);
-	e_msgport_destroy(pass_reply);
-	
+	g_free(url);
+
+	if (ret == NULL)
+		camel_exception_set(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled operation."));
+
 	return ret;
 }
 
 static void
-main_forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
+forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
 {
 	char *key = make_key (service, item);
-	
+
 	e_passwords_forget_password (domain?domain:"Mail", key);
-	
 	g_free (key);
 }
 
-static void
-forget_password (CamelSession *session, CamelService *service, const char *domain, const char *item, CamelException *ex)
-{
-	mail_call_main(MAIL_CALL_p_ppppp, (MailMainFunc)main_forget_password,
-		       session, service, domain, item, ex);
-}
-
 /* ********************************************************************** */
 
 static GtkDialog *message_dialog;
@@ -834,21 +663,10 @@
 		struct _user_message_msg *um;
 		
 		d(printf ("Gone non-interactive, checking for outstanding interactive tasks\n"));
+
+		e_passwords_cancel();
 		
-		/* clear out pending password requests */
-		while ((pm = (struct _pass_msg *) e_dlist_remhead (&password_list))) {
-			d(printf ("Flushing password request : %s\n", pm->prompt));
-			e_msgport_reply ((EMsg *) pm);
-		}
-		
-		/* destroy the current */
-		if (password_dialog) {
-			d(printf ("Destroying password dialogue\n"));
-			gtk_widget_destroy ((GtkWidget *) password_dialog);
-			password_dialog =  NULL;
-		}
-		
-		/* same for pending user messages */
+		/* flush/cancel pending user messages */
 		while ((um = (struct _user_message_msg *) e_dlist_remhead (&message_list))) {
 			d(printf ("Flusing message request: %s\n", um->prompt));
 			e_msgport_reply((EMsg *) um);
Index: shell/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/shell/ChangeLog,v
retrieving revision 1.1464
diff -u -3 -r1.1464 ChangeLog
--- shell/ChangeLog	1 Aug 2004 17:58:08 -0000	1.1464
+++ shell/ChangeLog	11 Aug 2004 04:08:14 -0000
@@ -1,3 +1,7 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* main.c (main): init epasswords.
+
 2004-08-01  Not Zed  <NotZed Ximian com>
  
  	* apps_evolution_shell.schemas.in.in: added last_version item.
Index: shell/main.c
===================================================================
RCS file: /cvs/gnome/evolution/shell/main.c,v
retrieving revision 1.159
diff -u -3 -r1.159 main.c
--- shell/main.c	18 Jun 2004 21:19:39 -0000	1.159
+++ shell/main.c	11 Aug 2004 04:08:14 -0000
@@ -27,6 +27,7 @@
 #include "e-util/e-dialog-utils.h"
 #include "e-util/e-gtk-utils.h"
 #include "e-util/e-bconf-map.h"
+#include "e-util/e-passwords.h"
 
 #include <e-util/e-icon-factory.h>
 #include "e-shell-constants.h"
@@ -537,7 +538,8 @@
 	glade_init ();
 	e_cursors_init ();
 	e_icon_factory_init ();
-	
+	e_passwords_init();
+
 	icon_list = e_icon_factory_get_icon_list ("stock_mail");
 	if (icon_list) {
 		gtk_window_set_default_icon_list (icon_list);
Index: smime/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/smime/ChangeLog,v
retrieving revision 1.38
diff -u -3 -r1.38 ChangeLog
--- smime/ChangeLog	2 Aug 2004 17:46:03 -0000	1.38
+++ smime/ChangeLog	11 Aug 2004 04:08:15 -0000
@@ -1,3 +1,8 @@
+2004-08-10  Not Zed  <NotZed Ximian com>
+
+	* gui/component.c (smime_pk11_passwd, smime_pk11_change_passwd): 
+	* lib/e-pkcs12.c (prompt_for_password): api change in e_passwords.
+
 2004-08-02  Jeffrey Stedfast  <fejj novell com>
 
 	* lib/e-pkcs12.c (prompt_for_password): Fixed to work for both LE
Index: smime/gui/component.c
===================================================================
RCS file: /cvs/gnome/evolution/smime/gui/component.c,v
retrieving revision 1.4
diff -u -3 -r1.4 component.c
--- smime/gui/component.c	24 Mar 2004 22:27:00 -0000	1.4
+++ smime/gui/component.c	11 Aug 2004 04:08:15 -0000
@@ -46,8 +46,8 @@
 	g_free (slot_name);
 
 	*passwd = e_passwords_ask_password (_("Enter password"), NULL, NULL,
-					    prompt, TRUE,
-					    E_PASSWORDS_DO_NOT_REMEMBER, NULL,
+					    prompt,
+					    E_PASSWORDS_REMEMBER_NEVER|E_PASSWORDS_SECRET, NULL,
 					    NULL);
 
 	g_free (prompt);
@@ -68,8 +68,8 @@
 		prompt = _("Enter new password for certificate database");
 
 		*passwd = e_passwords_ask_password (_("Enter new password"), NULL, NULL,
-						    prompt, TRUE,
-						    E_PASSWORDS_DO_NOT_REMEMBER, NULL,
+						    prompt,
+						    E_PASSWORDS_REMEMBER_NEVER|E_PASSWORDS_SECRET, NULL,
 						    NULL);
 	}
 	else {
Index: smime/lib/e-pkcs12.c
===================================================================
RCS file: /cvs/gnome/evolution/smime/lib/e-pkcs12.c,v
retrieving revision 1.5
diff -u -3 -r1.5 e-pkcs12.c
--- smime/lib/e-pkcs12.c	2 Aug 2004 17:46:03 -0000	1.5
+++ smime/lib/e-pkcs12.c	11 Aug 2004 04:08:15 -0000
@@ -217,8 +217,8 @@
 {
 	char *passwd;
 
-	passwd = e_passwords_ask_password (title, NULL, NULL, prompt, TRUE,
-					   E_PASSWORDS_DO_NOT_REMEMBER, NULL,
+	passwd = e_passwords_ask_password (title, NULL, NULL, prompt,
+					   E_PASSWORDS_REMEMBER_NEVER|E_PASSWORDS_SECRET, NULL,
 					   NULL);
 
 	if (passwd) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]