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. A bit ugly though.. :)
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