[evolution-data-server] Bug 610909 - IMAPX : password failure isn't reported properly Implement query auth types.



commit bf20c4794246ef3324c4acdcf9b59a02515d8a3b
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Fri Mar 12 03:51:52 2010 +0530

    Bug 610909 - IMAPX : password failure isn't reported properly
    Implement query auth types.

 camel/providers/imapx/camel-imapx-folder.c |   14 +-
 camel/providers/imapx/camel-imapx-server.c |  185 ++++++++++++++++++----------
 camel/providers/imapx/camel-imapx-server.h |    3 +-
 camel/providers/imapx/camel-imapx-store.c  |   64 +++++++---
 camel/providers/imapx/camel-imapx-utils.c  |    8 ++
 camel/providers/imapx/camel-imapx-utils.h  |    2 +-
 6 files changed, 183 insertions(+), 93 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index 00fc6f3..2b2552d 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -130,7 +130,7 @@ imapx_refresh_info (CamelFolder *folder, CamelException *ex)
 		return;
 
 	camel_service_connect((CamelService *)istore, ex);
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_refresh_info(istore->server, folder, ex);
 }
 
@@ -142,7 +142,7 @@ imapx_expunge (CamelFolder *folder, CamelException *ex)
 	if (CAMEL_OFFLINE_STORE (is)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (is->server && camel_imapx_server_connect (is->server, 1))
+	if (is->server && camel_imapx_server_connect (is->server, TRUE, ex))
 		camel_imapx_server_expunge(is->server, folder, ex);
 
 }
@@ -155,7 +155,7 @@ imapx_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 	if (CAMEL_OFFLINE_STORE (is)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (is->server && camel_imapx_server_connect (is->server, 1))
+	if (is->server && camel_imapx_server_connect (is->server, TRUE, ex))
 		camel_imapx_server_sync_changes (is->server, folder, ex);
 
 	/* Sync twice - make sure deleted flags are written out,
@@ -195,7 +195,7 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
 		if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 			return NULL;
 
-		if (istore->server && camel_imapx_server_connect (istore->server, 1)) {
+		if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex)) {
 			stream = camel_imapx_server_get_message(istore->server, folder, uid, ex);
 		} else {
 			camel_exception_setv(ex, 1, "not authenticated");
@@ -223,7 +223,7 @@ imapx_sync_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
 	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_sync_message (istore->server, folder, uid, ex);
 }
 
@@ -237,7 +237,7 @@ imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
 	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_copy_message (istore->server, source, dest, uids, delete_originals, ex);
 
 	imapx_refresh_info (dest, ex);
@@ -254,7 +254,7 @@ imapx_append_message(CamelFolder *folder, CamelMimeMessage *message, const Camel
 	if (appended_uid)
 		*appended_uid = NULL;
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_append_message(istore->server, folder, message, info, ex);
 }
 
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 74c52a3..1c57c78 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -1650,7 +1650,6 @@ imapx_command_run(CamelIMAPXServer *is, CamelIMAPXCommand *ic, CamelException *e
 	camel_imapx_command_close(ic);
 
 	QUEUE_LOCK(is);
-	g_assert(camel_dlist_empty(&is->active));
 	imapx_command_start(is, ic);
 	QUEUE_UNLOCK(is);
 
@@ -2097,12 +2096,12 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, CamelE
 	imapx_command_start (is, ic);
 }
 
-static void
-imapx_connect (CamelIMAPXServer *is, gint ssl_mode, gint try_starttls, CamelException *ex)
+gboolean
+imapx_connect_to_server (CamelIMAPXServer *is, CamelException *ex)
 {
 	CamelStream * tcp_stream = NULL;
 	CamelSockOptData sockopt;
-	gint ret;
+	gint ret, ssl_mode = 0;
 
 #ifdef HAVE_SSL
 	const gchar *mode;
@@ -2154,7 +2153,7 @@ imapx_connect (CamelIMAPXServer *is, gint ssl_mode, gint try_starttls, CamelExce
 	if (ex->id) {
 		e(printf ("Unable to connect %d %s \n", ex->id, ex->desc));
 		camel_object_unref(tcp_stream);
-		return;
+		return FALSE;
 	}
 
 	ret = camel_tcp_stream_connect(CAMEL_TCP_STREAM(tcp_stream), ai);
@@ -2167,7 +2166,7 @@ imapx_connect (CamelIMAPXServer *is, gint ssl_mode, gint try_starttls, CamelExce
 					_("Could not connect to %s (port %s): %s"),
 					is->url->host, serv, g_strerror(errno));
 		camel_object_unref(tcp_stream);
-		return;
+		return FALSE;
 	}
 
 	is->stream = (CamelIMAPXStream *) camel_imapx_stream_new(tcp_stream);
@@ -2186,14 +2185,19 @@ imapx_connect (CamelIMAPXServer *is, gint ssl_mode, gint try_starttls, CamelExce
 	camel_imapx_stream_gets (is->stream, &buffer, &len);
 	e(printf("Got greeting '%.*s'\n", len, buffer));
 
-	return;
-
 	ic = camel_imapx_command_new("CAPABILITY", NULL, "CAPABILITY");
 	imapx_command_run(is, ic, ex);
-	camel_imapx_command_free(ic);
 
-	if (camel_exception_is_set (ex))
+	if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
+		if (!camel_exception_is_set (ic->ex))
+			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "%s", ic->status->text);
+		else
+			camel_exception_xfer (ex, ic->ex);
+
+		camel_imapx_command_free(ic);
 		goto exit;
+	}
+	camel_imapx_command_free(ic);
 
 #ifdef HAVE_SSL
 	if (ssl_mode == 2)
@@ -2208,10 +2212,18 @@ imapx_connect (CamelIMAPXServer *is, gint ssl_mode, gint try_starttls, CamelExce
 
 		ic = camel_imapx_command_new ("STARTTLS", NULL, "STARTTLS");
 		imapx_command_run (is, ic, ex);
-		camel_imapx_command_free(ic);
+		
+		if (camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK) {
+			if (!camel_exception_is_set (ic->ex))
+				camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, "%s", ic->status->text);
+			else
+				camel_exception_xfer (ex, ic->ex);
 
-		if (camel_exception_is_set (ex))
+
+			camel_imapx_command_free(ic);
 			goto exit;
+		}
+		camel_imapx_command_free(ic);
 
 		if (camel_tcp_stream_ssl_enable_ssl (CAMEL_TCP_STREAM_SSL (tcp_stream)) == -1) {
 			camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
@@ -2227,9 +2239,16 @@ exit:
 		e(printf("Unable to connect %d %s \n", ex->id, ex->desc));
 		camel_object_unref (is->stream);
 		is->stream = NULL;
+		
+		if (is->cinfo) {
+			imapx_free_capability(is->cinfo);
+			is->cinfo = NULL;
+		}
 
-		return;
+		return FALSE;
 	}
+
+	return TRUE;
 }
 
 static void
@@ -2237,48 +2256,83 @@ imapx_reconnect (CamelIMAPXServer *is, CamelException *ex)
 {
 	CamelSasl *sasl;
 	CamelIMAPXCommand *ic;
-retry:
-	imapx_connect(is, 0, 0, ex);
-	if (camel_exception_is_set (ex))
-		return;
+	gchar *errbuf = NULL;
+	CamelService *service = (CamelService *) is->store;
+	const gchar *auth_domain = NULL;
+	gboolean authenticated = FALSE;
+
+	while (!authenticated) {
+		if (errbuf) {
+			/* We need to un-cache the password before prompting again */
+			camel_session_forget_password (is->session, service, auth_domain, "password", ex);
+			g_free (service->url->passwd);
+			service->url->passwd = NULL;
+			camel_exception_clear (ex);
+		}
 
-	if (is->url->passwd == NULL) {
-		CamelException ex = { 0, NULL };
-		gchar *prompt = g_strdup_printf(_("%sPlease enter the IMAP password for %s %s"), "", is->url->user, is->url->host);
-		const gchar *auth_domain;
+		imapx_connect_to_server (is, ex);
+		if (camel_exception_is_set (ex))
+			goto exception;
 
-		auth_domain = camel_url_get_param (is->url, "auth-domain");
-		is->url->passwd = camel_session_get_password(is->session, (CamelService *)is->store,
-				auth_domain,
-				prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, &ex);
+		if (service->url->passwd == NULL) {
+			gchar *base_prompt;
+			gchar *full_prompt;
 
-		g_free(prompt);
-		if (ex.id) {
-			g_message ("Unable to connect %d ", ex.id);
-			return;
+			base_prompt = camel_session_build_password_prompt (
+					"IMAP", service->url->user, service->url->host);
+
+			if (errbuf != NULL)
+				full_prompt = g_strconcat (errbuf, base_prompt, NULL);
+			else
+				full_prompt = g_strdup (base_prompt);
+
+			auth_domain = camel_url_get_param (service->url, "auth-domain");
+			service->url->passwd = camel_session_get_password(is->session, (CamelService *)is->store,
+					auth_domain,
+					full_prompt, "password", CAMEL_SESSION_PASSWORD_SECRET, ex);
+
+			g_free (base_prompt);
+			g_free (full_prompt);
+			g_free (errbuf);
+			errbuf = NULL;
+
+			if (!service->url->passwd) {
+				camel_exception_set (ex, CAMEL_EXCEPTION_USER_CANCEL,
+						_("You did not enter a password."));
+				goto exception;
+			}
 		}
-	}
 
-	if (is->url->authmech
-			&& (sasl = camel_sasl_new("imap", is->url->authmech, NULL))) {
-		ic = camel_imapx_command_new("AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl);
-		camel_object_unref(sasl);
-	} else {
-		ic = camel_imapx_command_new("LOGIN", NULL, "LOGIN %s %s", is->url->user, is->url->passwd);
-	}
+		if (service->url->authmech
+				&& (sasl = camel_sasl_new("imap", service->url->authmech, NULL))) {
+			ic = camel_imapx_command_new("AUTHENTICATE", NULL, "AUTHENTICATE %A", sasl);
+			camel_object_unref(sasl);
+		} else {
+			ic = camel_imapx_command_new("LOGIN", NULL, "LOGIN %s %s", service->url->user, service->url->passwd);
+		}
 
-	// TODO freeing data?
-	imapx_command_run(is, ic, ex);
-	if (camel_exception_is_set (ex)) {
-		if (ic->status)
-			camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_CANT_AUTHENTICATE, "Login failed: %s", ic->status->text);
-		return;
-	}
+		imapx_command_run(is, ic, ex);
 
-	camel_imapx_command_free(ic);
-	if (camel_exception_is_set (ex))
-		goto exception;
+		if (!(camel_exception_is_set (ic->ex) || ic->status->result != IMAPX_OK))
+			authenticated = TRUE;
+		else {
+			/* If exception is set, it might be mostly due to cancellation and we would get an 
+			   io error, else re-prompt */
+			if (camel_exception_is_set (ic->ex)) {
+				camel_imapx_command_free(ic);
+				goto exception;
+			}
+
+			errbuf = g_markup_printf_escaped (
+					_("Unable to authenticate to IMAP server.\n%s\n\n"),
+					 ic->status->text);
+			camel_exception_clear (ex);
 
+		}
+		
+		camel_imapx_command_free(ic);
+	}
+	
 	/* After login we re-capa */
 	if (is->cinfo) {
 		imapx_free_capability(is->cinfo);
@@ -2294,7 +2348,11 @@ retry:
 
 	is->state = IMAPX_AUTHENTICATED;
 
-	is->use_idle = TRUE;
+	if (((CamelIMAPXStore *)is->store)->rec_options & IMAPX_USE_IDLE)
+		is->use_idle = TRUE;
+	else
+		is->use_idle = FALSE;
+	
 	if (imapx_idle_supported (is))
 		imapx_init_idle (is);
 
@@ -2330,13 +2388,11 @@ retry:
 		return;
 
 exception:
-	if (ex->id != CAMEL_EXCEPTION_USER_CANCEL) {
-		c(printf("Re Connection failed: %s\n", ex->desc));
-		imapx_disconnect (is);
-		g_usleep(1);
-		// camelexception_done?
-		camel_exception_clear (ex);
-		goto retry;
+	imapx_disconnect (is);
+	
+	if (is->cinfo) {
+		imapx_free_capability(is->cinfo);
+		is->cinfo = NULL;
 	}
 }
 
@@ -3760,9 +3816,6 @@ imapx_disconnect (CamelIMAPXServer *is)
 
 	g_static_rec_mutex_lock (&is->ostream_lock);
 
-	if (is->state == IMAPX_DISCONNECTED)
-		goto exit;
-
 	if (is->stream) {
 		if (camel_stream_close (is->stream->source) == -1)
 			ret = FALSE;
@@ -3792,9 +3845,13 @@ imapx_disconnect (CamelIMAPXServer *is)
 		is->literal = NULL;
 	}
 
+	if (is->cinfo) {
+		imapx_free_capability(is->cinfo);
+		is->cinfo = NULL;	
+	}
+
 	is->state = IMAPX_DISCONNECTED;
 
-exit:
 	g_static_rec_mutex_unlock (&is->ostream_lock);
 
 	return ret;
@@ -3802,24 +3859,22 @@ exit:
 
 /* Client commands */
 gboolean
-camel_imapx_server_connect(CamelIMAPXServer *is, gint state)
+camel_imapx_server_connect (CamelIMAPXServer *is, gboolean connect, CamelException *ex)
 {
 	gboolean ret = FALSE;
 
 	CAMEL_SERVICE_REC_LOCK (is->store, connect_lock);
-	if (state) {
-		CamelException ex = CAMEL_EXCEPTION_INITIALISER;
-
+	if (connect) {
 		if (is->state == IMAPX_AUTHENTICATED || is->state == IMAPX_SELECTED) {
 			ret = TRUE;
 			goto exit;
 		}
 
 		g_static_rec_mutex_lock (&is->ostream_lock);
-		imapx_reconnect (is, &ex);
+		imapx_reconnect (is, ex);
 		g_static_rec_mutex_unlock (&is->ostream_lock);
 
-		if (camel_exception_is_set (&ex)) {
+		if (camel_exception_is_set (ex)) {
 			ret = FALSE;
 			goto exit;
 		}
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index eba2adb..bf1d74c 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -111,7 +111,8 @@ struct _CamelIMAPXServerClass {
 CamelType               camel_imapx_server_get_type     (void);
 CamelIMAPXServer *camel_imapx_server_new(struct _CamelStore *store, struct _CamelURL *url);
 
-gboolean camel_imapx_server_connect(CamelIMAPXServer *is, gint state);
+gboolean camel_imapx_server_connect(CamelIMAPXServer *is, gint state, CamelException *ex);
+gboolean imapx_connect_to_server (CamelIMAPXServer *is, CamelException *ex);
 
 GPtrArray *camel_imapx_server_list(CamelIMAPXServer *is, const gchar *top, guint32 flags, CamelException *ex);
 
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index 6beb20d..68bfbb0 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -63,6 +63,7 @@
 #include "camel-imapx-server.h"
 #include "camel-imapx-summary.h"
 #include "camel-net-utils.h"
+#include "camel/camel-private.h"
 
 /* Specified in RFC 2060 section 2.1 */
 #define IMAP_PORT 143
@@ -152,20 +153,45 @@ imapx_construct(CamelService *service, CamelSession *session, CamelProvider *pro
 }
 
 extern CamelServiceAuthType camel_imapx_password_authtype;
-extern CamelServiceAuthType camel_imapx_apop_authtype;
 
-/* TODO implement */
 static GList *
 imapx_query_auth_types (CamelService *service, CamelException *ex)
 {
-	/*CamelIMAPXStore *store = CAMEL_IMAPX_STORE (service);*/
-	GList *types = NULL;
+	CamelIMAPXStore *istore = CAMEL_IMAPX_STORE (service);
+	CamelServiceAuthType *authtype;
+	GList *sasl_types, *t, *next;
+	gboolean connected;
+	
+	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+		camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+				     _("You must be working online to complete this operation"));
+		return NULL;
+	}
 
-        types = CAMEL_SERVICE_CLASS (parent_class)->query_auth_types (service, ex);
-	if (types == NULL)
+	CAMEL_SERVICE_REC_LOCK (istore, connect_lock);
+	
+	if (istore->server == NULL)
+		istore->server = camel_imapx_server_new((CamelStore *)istore, service->url);
+	
+	connected = istore->server->stream != NULL;
+	if (!connected)
+		connected = imapx_connect_to_server (istore->server, ex);
+	CAMEL_SERVICE_REC_UNLOCK (istore, connect_lock);
+	if (!connected)
 		return NULL;
 
-	return types;
+	sasl_types = camel_sasl_authtype_list (FALSE);
+	for (t = sasl_types; t; t = next) {
+		authtype = t->data;
+		next = t->next;
+
+		if (!g_hash_table_lookup (istore->server->cinfo->auth_types, authtype->authproto)) {
+			sasl_types = g_list_remove_link (sasl_types, t);
+			g_list_free_1 (t);
+		}
+	}
+
+	return g_list_prepend (sasl_types, &camel_imapx_password_authtype);
 }
 
 static gchar *
@@ -181,24 +207,24 @@ imapx_get_name (CamelService *service, gboolean brief)
 static gboolean
 imapx_connect (CamelService *service, CamelException *ex)
 {
-	CamelIMAPXStore *store = (CamelIMAPXStore *)service;
+	CamelIMAPXStore *istore = (CamelIMAPXStore *)service;
 
 	/* We never really are 'connected' or 'disconnected' */
-	if (store->server == NULL)
-		store->server = camel_imapx_server_new((CamelStore *)store, service->url);
+	if (istore->server == NULL)
+		istore->server = camel_imapx_server_new((CamelStore *)istore, service->url);
 
-	return camel_imapx_server_connect(store->server, 1);
+	return camel_imapx_server_connect (istore->server, TRUE, ex);
 }
 
 static gboolean
 imapx_disconnect (CamelService *service, gboolean clean, CamelException *ex)
 {
-	CamelIMAPXStore *store = CAMEL_IMAPX_STORE (service);
+	CamelIMAPXStore *istore = CAMEL_IMAPX_STORE (service);
 
 	CAMEL_SERVICE_CLASS (parent_class)->disconnect (service, clean, ex);
 
-	if (store->server)
-		camel_imapx_server_connect(store->server, 0);
+	if (istore->server)
+		camel_imapx_server_connect(istore->server, FALSE, ex);
 
 	return TRUE;
 }
@@ -245,7 +271,7 @@ imapx_noop (CamelStore *store, CamelException *ex)
 	if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_noop (istore->server, NULL, ex);
 }
 
@@ -506,7 +532,7 @@ imapx_subscribe_folder (CamelStore *store, const gchar *folder_name, gboolean em
 	if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_manage_subscription (istore->server, folder_name, TRUE, ex);
 
 	if (!camel_exception_is_set (ex))
@@ -521,7 +547,7 @@ imapx_unsubscribe_folder (CamelStore *store, const gchar *folder_name, gboolean
 	if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
 		return;
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_manage_subscription (istore->server, folder_name, FALSE, ex);
 	
 	if (!camel_exception_is_set (ex))
@@ -595,7 +621,7 @@ imapx_delete_folder (CamelStore *store, const gchar *folder_name, CamelException
 		return;
 	}
 
-	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+	if (istore->server && camel_imapx_server_connect (istore->server, TRUE, ex))
 		camel_imapx_server_delete_folder (istore->server, folder_name, ex);
 
 	if (!camel_exception_is_set (ex))
@@ -625,7 +651,7 @@ imapx_create_folder (CamelStore *store, const gchar *parent_name, const gchar *f
 		return NULL;
 	}
 	
-	if (!(istore->server && camel_imapx_server_connect (istore->server, 1)))
+	if (!(istore->server && camel_imapx_server_connect (istore->server, TRUE, ex)))
 		return NULL;
 
 	if (!parent_name)
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index 939ab4b..f220fd1 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -401,6 +401,7 @@ imapx_parse_capability(CamelIMAPXStream *stream, CamelException *ex)
 	struct _capability_info * cinfo;
 
 	cinfo = g_malloc0(sizeof(*cinfo));
+	cinfo->auth_types = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
 
 	/* FIXME: handle auth types */
 	while (!camel_exception_is_set (ex) && (tok = camel_imapx_stream_token(stream, &token, &len, ex)) != '\n') {
@@ -413,6 +414,12 @@ imapx_parse_capability(CamelIMAPXStream *stream, CamelException *ex)
 				p = token;
 				while ((c = *p))
 					*p++ = toupper(c);
+				if (!strncmp ((gchar *) token, "AUTH=", 5)) {
+					g_hash_table_insert (cinfo->auth_types,
+							g_strdup ((gchar *)token + 5),
+							GINT_TO_POINTER (1));
+					break;
+				}
 			case IMAPX_TOK_INT:
 				d(printf(" cap: '%s'\n", token));
 				for (i = 0; i < G_N_ELEMENTS (capa_table); i++)
@@ -440,6 +447,7 @@ imapx_parse_capability(CamelIMAPXStream *stream, CamelException *ex)
 
 void imapx_free_capability(struct _capability_info *cinfo)
 {
+	g_hash_table_destroy (cinfo->auth_types);
 	g_free(cinfo);
 }
 
diff --git a/camel/providers/imapx/camel-imapx-utils.h b/camel/providers/imapx/camel-imapx-utils.h
index 51f4ce0..cc73d9f 100644
--- a/camel/providers/imapx/camel-imapx-utils.h
+++ b/camel/providers/imapx/camel-imapx-utils.h
@@ -83,7 +83,7 @@ enum {
 
 struct _capability_info {
 	guint32 capa;
-	/* auth stuff here */
+	GHashTable *auth_types;
 };
 
 struct _capability_info *imapx_parse_capability(struct _CamelIMAPXStream *stream, CamelException *ex);



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