[evolution-patches] imap fixes



a) create new resp-text-code handler where to handle [ALERT]. Easier to
add other handlers there if needed. resp-text-code handler is now called
from both tagged and untagged replies.

b) if server notifies of flag changes, update your own state

Applies cleanly for 1.4.5 too which I'm using now.

Index: camel-imap-command.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-command.c,v
retrieving revision 1.59
diff -u -r1.59 camel-imap-command.c
--- camel-imap-command.c	17 Jun 2003 03:20:59 -0000	1.59
+++ camel-imap-command.c	11 Jan 2004 06:50:19 -0000
@@ -39,6 +39,7 @@
 #include "camel-imap-store.h"
 #include "camel-imap-store-summary.h"
 #include "camel-imap-private.h"
+#include "camel-imap-summary.h"
 #include <camel/camel-exception.h>
 #include <camel/camel-private.h>
 #include <camel/camel-utf8.h>
@@ -269,6 +270,20 @@
 	return imap_read_response (store, ex);
 }
 
+static void camel_imap_command_handle_resp_code(CamelImapStore *store,
+						const char *respbuf)
+{
+	if (strncmp(respbuf, "ALERT] ", 7) == 0) {
+		char *msg;
+
+		/* for imap ALERT codes, account user host */
+		msg = g_strdup_printf(_("Alert from IMAP server %s %s:\n%s"),
+				      ((CamelService *)store)->url->user, ((CamelService *)store)->url->host, respbuf+7);
+		camel_session_alert_user(((CamelService *)store)->session, CAMEL_SESSION_ALERT_WARNING, msg, FALSE);
+		g_free(msg);
+	}
+}
+
 /**
  * camel_imap_command_response:
  * @store: the IMAP store
@@ -316,16 +331,11 @@
 		respbuf = imap_read_untagged (store, respbuf, ex);
 		if (!respbuf)
 			type = CAMEL_IMAP_RESPONSE_ERROR;
-		else if (!strncasecmp (respbuf, "* OK [ALERT]", 12)) {
-			char *msg;
-
-			/* for imap ALERT codes, account user host */
-			msg = g_strdup_printf(_("Alert from IMAP server %s %s:\n%s"),
-					      ((CamelService *)store)->url->user, ((CamelService *)store)->url->host, respbuf+12);
-			camel_session_alert_user(((CamelService *)store)->session, CAMEL_SESSION_ALERT_WARNING, msg, FALSE);
-			g_free(msg);
-		}
-		
+		else if (!strncasecmp (respbuf, "* OK [", 5) ||
+			 !strncasecmp (respbuf, "* NO [", 5))
+			camel_imap_command_handle_resp_code(store, respbuf+5);
+		else if (!strncasecmp (respbuf, "* BAD [", 6))
+			camel_imap_command_handle_resp_code(store, respbuf+6);
 		break;
 	case '+':
 		type = CAMEL_IMAP_RESPONSE_CONTINUATION;
@@ -379,8 +389,11 @@
 	if (*respbuf == '+')
 		return response;
 	p = strchr (respbuf, ' ');
-	if (p && !strncasecmp (p, " OK", 3))
+	if (p && !strncasecmp (p, " OK", 3)) {
+		if (p[3] == ' ' && p[4] == '[')
+			camel_imap_command_handle_resp_code(store, p+5);
 		return response;
+	}
 	
 	/* We should never get BAD, or anything else but +, OK, or NO
 	 * for that matter.
@@ -398,6 +411,13 @@
 	p += 3;
 	if (!*p++)
 		p = NULL;
+	else if (*p == '[') {
+		camel_imap_command_handle_resp_code(store, p+1);
+		while (*p != ']' && *p != '\0') p++;
+		if (*p == '\0')
+			p = NULL;
+	}
+
 	camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
 			      _("IMAP command failed: %s"),
 			      p ? p : _("Unknown error"));
@@ -527,6 +547,39 @@
 	return NULL;
 }
 
+static void
+camel_imap_response_update_flags(CamelImapStore *store, CamelFolder *folder,
+				 int number, char *resp, CamelFolderChangeInfo **changes)
+{
+	GData *data;
+	CamelMessageInfo *info;
+	CamelImapMessageInfo *iinfo;
+	guint32 flags;
+
+	info = camel_folder_summary_index (folder->summary, number-1);
+	iinfo = (CamelImapMessageInfo *)info;
+
+	data = camel_imap_parse_fetch_response (CAMEL_IMAP_FOLDER (folder), resp);
+	flags = GPOINTER_TO_UINT (g_datalist_get_data (&data, "FLAGS"));
+	g_datalist_clear (&data);
+
+	/* Update summary flags */
+	if (flags != iinfo->server_flags) {
+		guint32 server_set, server_cleared;
+
+		server_set = flags & ~iinfo->server_flags;
+		server_cleared = iinfo->server_flags & ~flags;
+
+		info->flags = (info->flags | server_set) & ~server_cleared;
+		iinfo->server_flags = flags;
+
+		if (*changes == NULL)
+			*changes = camel_folder_change_info_new();
+		camel_folder_change_info_change_uid(*changes, camel_message_info_uid (info));
+	}
+
+	camel_folder_summary_info_free (folder->summary, info);
+}
 
 /**
  * camel_imap_response_free:
@@ -541,6 +594,7 @@
 {
 	int i, number, exists = 0;
 	GArray *expunged = NULL;
+	CamelFolderChangeInfo *changes = NULL;
 	char *resp, *p;
 	
 	if (!response)
@@ -560,6 +614,17 @@
 								sizeof (int));
 				}
 				g_array_append_val (expunged, number);
+			} else if (!strncasecmp (p, " FETCH (", 8)) {
+				if (expunged != NULL) {
+					/* Update the summary */
+					camel_imap_folder_changed (response->folder,
+								   exists, expunged, NULL);
+					g_array_free (expunged, TRUE);
+					expunged = NULL;
+				}
+
+				camel_imap_response_update_flags(store, response->folder,
+								 number, p+8, &changes);
 			}
 		}
 		g_free (resp);
@@ -576,10 +641,16 @@
 			if (expunged)
 				g_array_free (expunged, TRUE);
 		}
-		
+
+		if (changes) {
+			camel_object_trigger_event(CAMEL_OBJECT (response->folder),
+						   "folder_changed", changes);
+			camel_folder_change_info_free(changes);
+		}
+
 		camel_object_unref (CAMEL_OBJECT (response->folder));
 	}
-	
+
 	g_free (response);
 	CAMEL_SERVICE_UNLOCK (store, connect_lock);
 }
Index: camel-imap-folder.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-folder.c,v
retrieving revision 1.310
diff -u -r1.310 camel-imap-folder.c
--- camel-imap-folder.c	9 Jan 2004 06:26:44 -0000	1.310
+++ camel-imap-folder.c	11 Jan 2004 06:50:22 -0000
@@ -128,8 +128,6 @@
 
 static CamelObjectClass *parent_class;
 
-static GData *parse_fetch_response (CamelImapFolder *imap_folder, char *msg_att);
-
 static void
 camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
 {
@@ -363,7 +361,7 @@
 			if (uid != 0 || val != count || strncasecmp (resp, " FETCH (", 8) != 0)
 				continue;
 			
-			fetch_data = parse_fetch_response (imap_folder, resp + 7);
+			fetch_data = camel_imap_parse_fetch_response (imap_folder, resp + 7);
 			uid = strtoul (g_datalist_get_data (&fetch_data, "UID"), NULL, 10);
 			g_datalist_clear (&fetch_data);
 		}
@@ -575,7 +573,7 @@
 		char *uid;
 		guint32 flags;
 		
-		data = parse_fetch_response (imap_folder, resp);
+		data = camel_imap_parse_fetch_response (imap_folder, resp);
 		g_free (resp);
 		if (!data)
 			continue;
@@ -1965,7 +1963,7 @@
 		}
 		
 		for (i = 0, body = NULL; i < response->untagged->len; i++) {
-			fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
+			fetch_data = camel_imap_parse_fetch_response (imap_folder, response->untagged->pdata[i]);
 			if (fetch_data) {
 				found_uid = g_datalist_get_data (&fetch_data, "UID");
 				body = g_datalist_get_data (&fetch_data, "BODY");
@@ -2223,7 +2221,7 @@
 	messages = g_ptr_array_new ();
 	while ((type = camel_imap_command_response (store, &resp, ex)) ==
 	       CAMEL_IMAP_RESPONSE_UNTAGGED) {
-		data = parse_fetch_response (imap_folder, resp);
+		data = camel_imap_parse_fetch_response (imap_folder, resp);
 		g_free (resp);
 		if (!data)
 			continue;
@@ -2299,7 +2297,7 @@
 			
 			while ((type = camel_imap_command_response (store, &resp, ex))
 			       == CAMEL_IMAP_RESPONSE_UNTAGGED) {
-				data = parse_fetch_response (imap_folder, resp);
+				data = camel_imap_parse_fetch_response (imap_folder, resp);
 				g_free (resp);
 				if (!data)
 					continue;
@@ -2574,7 +2572,7 @@
 	}
 	
 	for (i = 0; i < response->untagged->len; i++) {
-		fetch_data = parse_fetch_response (imap_folder, response->untagged->pdata[i]);
+		fetch_data = camel_imap_parse_fetch_response (imap_folder, response->untagged->pdata[i]);
 		found_uid = g_datalist_get_data (&fetch_data, "UID");
 		stream = g_datalist_get_data (&fetch_data, "BODY_PART_STREAM");
 		if (found_uid && stream && !strcmp (uid, found_uid))
@@ -2596,8 +2594,8 @@
 	return stream;
 }
 
-static GData *
-parse_fetch_response (CamelImapFolder *imap_folder, char *response)
+GData *
+camel_imap_parse_fetch_response (CamelImapFolder *imap_folder, char *response)
 {
 	GData *data = NULL;
 	char *start, *part_spec = NULL, *body = NULL, *uid = NULL, *idate = NULL;
Index: camel-imap-folder.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/providers/imap/camel-imap-folder.h,v
retrieving revision 1.41
diff -u -r1.41 camel-imap-folder.h
--- camel-imap-folder.h	9 Jan 2004 06:26:45 -0000	1.41
+++ camel-imap-folder.h	11 Jan 2004 06:50:22 -0000
@@ -75,6 +75,9 @@
 void camel_imap_folder_changed (CamelFolder *folder, int exists,
 				GArray *expunged, CamelException *ex);
 
+GData *camel_imap_parse_fetch_response (CamelImapFolder *imap_folder,
+					char *msg_att);
+
 CamelStream *camel_imap_folder_fetch_data (CamelImapFolder *imap_folder,
 					   const char *uid,
 					   const char *section_text,

Attachment: signature.asc
Description: This is a digitally signed message part



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