Patch: fix for imap_update_summary crash on AOL



	Hi,

	This patch adds a workaround for AOL IMAP server bug answering to
FETCH/SEARCH queries we use to get the list of uid's. When we request a
range of sequence numbers, the answer returns again all the sequences,
even the ones we had fetched previoulsly.

	With this code we simply ignore the sequence numbers we already have
fetched. This is enough to avoid the summary corruption we were getting
using AOL.

Changelog entry:
* libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.[ch]:
        * Added fetching aol specific imap capability.
* libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.[ch]:
        * Now we use FETCH instead of SEARCH for getting the UID's
          when the server is AOL.
        * Added an extra check in imap_get_uids. If server gives a list
          including sequence numbers we didn't request, we ignore them.
          This should fix the AOL problem fetching headers.


-- 
José Dapena Paz <jdapena igalia com>
Igalia
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(revision 3719)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.c	(working copy)
@@ -773,6 +773,7 @@
 	{ "CONVERT",		IMAP_CAPABILITY_CONVERT },
 	{ "LIST-EXTENDED",	IMAP_CAPABILITY_LISTEXT },
 	{ "COMPRESS=DEFLATE",	IMAP_CAPABILITY_COMPRESS },
+	{ "XAOL-NETMAIL",       IMAP_CAPABILITY_XAOLNETMAIL },
 	{ NULL, 0 }
 };
 
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h	(revision 3719)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-store.h	(working copy)
@@ -125,6 +125,7 @@
 #define IMAP_CAPABILITY_CONVERT			(1 << 18)
 #define IMAP_CAPABILITY_LISTEXT			(1 << 19)
 #define IMAP_CAPABILITY_COMPRESS		(1 << 20)
+#define IMAP_CAPABILITY_XAOLNETMAIL             (1 << 21)
 
 #define IMAP_PARAM_OVERRIDE_NAMESPACE		(1 << 0)
 #define IMAP_PARAM_CHECK_ALL			(1 << 1)
Index: libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
===================================================================
--- libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(revision 3719)
+++ libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c	(working copy)
@@ -181,6 +181,8 @@
 
 static void stop_gmsgstore_from_idle (CamelImapFolder *imap_folder);
 
+static const gchar *imap_search_request_string (CamelImapFolder *imap_folder);
+
 #ifdef G_OS_WIN32
 /* The strtok() in Microsoft's C library is MT-safe (but still uses
  * only one buffer pointer per thread, but for the use of strtok_r()
@@ -3189,7 +3191,7 @@
 
 
 static guint32
-imap_get_uids (CamelFolder *folder, CamelImapStore *store, CamelException *ex, GPtrArray *needheaders, int size)
+imap_get_uids (CamelFolder *folder, CamelImapStore *store, CamelException *ex, GPtrArray *needheaders, int greater_than, int size)
 {
 	char *resp = NULL;
 	CamelImapResponseType type;
@@ -3215,8 +3217,9 @@
 			}
 		} else {
 			GData *data = parse_fetch_response ((CamelImapFolder *)folder, resp);
+			int sequence = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE"));
 			char *uid = g_datalist_get_data (&data, "UID");
-			if (uid) {
+			if (sequence > greater_than && uid) {
 				g_ptr_array_add (needheaders, g_strdup (uid));
 				cnt++;
 			}
@@ -3242,6 +3245,19 @@
 
 }
 
+static const gchar *
+imap_search_request_string (CamelImapFolder *imap_folder)
+{
+	CamelImapStore *store = CAMEL_IMAP_STORE (CAMEL_FOLDER (imap_folder)->parent_store);
+
+	if (store->capabilities & IMAP_CAPABILITY_XAOLNETMAIL) {
+		return "UID FETCH %d:* (UID)";
+	} else {
+		return "UID SEARCH %d:* ALL";
+	}
+}
+
+
 static void
 imap_update_summary (CamelFolder *folder, int exists,
 		     CamelFolderChangeInfo *changes,
@@ -3303,7 +3319,8 @@
 	seq = camel_folder_summary_count (folder->summary);
 
 	if (!camel_imap_command_start (store, folder, ex,
-		"UID SEARCH %d:%d ALL", seq + 1, MAX (1, MIN (seq + 1 + nextn, exists))))
+				       imap_search_request_string ((CamelImapFolder *) folder), 
+				       seq + 1, MAX (1, MIN (seq + 1 + nextn, exists))))
 		{
 			if (camel_operation_cancel_check (NULL))
 				imap_folder->cancel_occurred = TRUE;
@@ -3315,7 +3332,7 @@
 
 	more = FALSE;
 	needheaders = g_ptr_array_new ();
-	cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq));
+	cnt = imap_get_uids (folder, store, ex, needheaders, seq, (exists - seq));
 
 	if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
 	{
@@ -3360,7 +3377,7 @@
 			return;
 		}
 
-		tcnt = cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq) - tcnt);
+		tcnt = cnt = imap_get_uids (folder, store, ex, needheaders, seq + tcnt, (exists - seq) - tcnt);
 
 		if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
 		{
@@ -3388,7 +3405,7 @@
 	if ((cnt < nextn) && more)
 	{
 		if (!camel_imap_command_start (store, folder, ex,
-			"UID SEARCH %d:* ALL", seq + 1 + cnt))
+					       imap_search_request_string ((CamelImapFolder *) folder), seq + 1 + cnt))
 			{
 				if (camel_operation_cancel_check (NULL))
 					imap_folder->cancel_occurred = TRUE;
@@ -3401,7 +3418,7 @@
 
 		camel_folder_summary_dispose_all (folder->summary);
 
-		cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq) - cnt);
+		cnt = imap_get_uids (folder, store, ex, needheaders, seq + cnt, (exists - seq) - cnt);
 
 		if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
 		{
@@ -3443,7 +3460,7 @@
 
 			camel_folder_summary_dispose_all (folder->summary);
 
-			tcnt = cnt = imap_get_uids (folder, store, ex, needheaders, (exists - seq) - tcnt);
+			tcnt = cnt = imap_get_uids (folder, store, ex, needheaders, seq + tcnt, (exists - seq) - tcnt);
 
 			if (cnt == 0 && camel_exception_get_id (ex) == CAMEL_EXCEPTION_USER_CANCEL)
 			{
@@ -3555,33 +3572,33 @@
 
 				  if (sequence > 0 && sequence <= exists && sequence != curlen)
 				  {
-					int r;
-					if (curlen > sequence)
-					{
-						for (r = curlen-1; r >= sequence -1; r--)
-						{
-							CamelMessageInfo *ri;
-							g_warning ("Problem with your local summary store (too much), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);
-							ri = g_ptr_array_index (folder->summary->messages, r);
-							if (ri) {
-								/* camel_folder_change_info_remove_uid (mchange, camel_message_info_uid (mi)); */
-								((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_EXPUNGED;
-								((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_FREED;
-								camel_folder_summary_remove (folder->summary, ri);
-							}
-						}
-					} else {
-						for (r=0; r < sequence - curlen - 1; r++)
-						{
-							CamelMessageInfo *ni = camel_message_info_clone (mi);
-							if (ni) {
-								g_warning ("Problem with your local summary store (too few), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);
-								camel_folder_summary_add (folder->summary, (CamelMessageInfo *)ni);
-								/* camel_folder_change_info_add_uid (mchanges, camel_message_info_uid (ni)); */
-							}
-						}
-					}
-					oosync = TRUE;
+				  	int r;
+				  	if (curlen > sequence)
+				  	{
+				  		for (r = curlen-1; r >= sequence -1; r--)
+				  		{
+				  			CamelMessageInfo *ri;
+				  			g_warning ("Problem with your local summary store (too much), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);
+				  			ri = g_ptr_array_index (folder->summary->messages, r);
+				  			if (ri) {
+				  				/* camel_folder_change_info_remove_uid (mchange, camel_message_info_uid (mi)); */
+				  				((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_EXPUNGED;
+				  				((CamelMessageInfoBase*)ri)->flags |= CAMEL_MESSAGE_FREED;
+				  				camel_folder_summary_remove (folder->summary, ri);
+				  			}
+				  		}
+				  	} else {
+				  		for (r=0; r < sequence - curlen - 1; r++)
+				  		{
+				  			CamelMessageInfo *ni = camel_message_info_clone (mi);
+				  			if (ni) {
+				  				g_warning ("Problem with your local summary store (too few), correcting: curlen=%d, r=%d, seq=%d\n", curlen, r, sequence);
+				  				camel_folder_summary_add (folder->summary, (CamelMessageInfo *)ni);
+				  				/* camel_folder_change_info_add_uid (mchanges, camel_message_info_uid (ni)); */
+				  			}
+				  		}
+				  	}
+				  	oosync = TRUE;
 				  }
 
 				  camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi);


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