diff options
author | Jeffrey Stedfast <fejj@ximian.com> | 2004-06-11 23:00:12 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2004-06-11 23:00:12 +0800 |
commit | 9c5abb70276da514cb6941348405de2fc1d3176b (patch) | |
tree | 6192e9738cf4350cb5203e0815c41c9b494b90dd /camel | |
parent | ff2a5e2ebf1ad4a458214502c24901d6e550bf62 (diff) | |
download | gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar.gz gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar.zst gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.zip |
Handle getting FLAGS even though we didn't request it (server can send us
2004-06-11 Jeffrey Stedfast <fejj@ximian.com>
* providers/imap4/camel-imap4-folder.c (untagged_fetch): Handle
getting FLAGS even though we didn't request it (server can send us
FLAGS info if another client changed them recently, for
example). Also fixed to handle the fact that not every bit of info
has to be in a single untagged FETCH response - it may come in
several untagged responses.
* providers/imap4/camel-imap4-summary.c (envelope_decode_address):
Decode the email address name token.
(envelope_decode_nstring): rfc2047 decode strings if requested.
(decode_envelope): Request that the subject string be rfc2047
decoded.
svn path=/trunk/; revision=26310
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 15 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-folder.c | 34 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-summary.c | 69 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-summary.h | 2 |
4 files changed, 90 insertions, 30 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index a67f634255..361ade4e40 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,18 @@ +2004-06-11 Jeffrey Stedfast <fejj@ximian.com> + + * providers/imap4/camel-imap4-folder.c (untagged_fetch): Handle + getting FLAGS even though we didn't request it (server can send us + FLAGS info if another client changed them recently, for + example). Also fixed to handle the fact that not every bit of info + has to be in a single untagged FETCH response - it may come in + several untagged responses. + + * providers/imap4/camel-imap4-summary.c (envelope_decode_address): + Decode the email address name token. + (envelope_decode_nstring): rfc2047 decode strings if requested. + (decode_envelope): Request that the subject string be rfc2047 + decoded. + 2004-06-11 Not Zed <NotZed@Ximian.com> * providers/local/camel-maildir-store.c (get_folder_info): if we diff --git a/camel/providers/imap4/camel-imap4-folder.c b/camel/providers/imap4/camel-imap4-folder.c index 006b214488..8570964360 100644 --- a/camel/providers/imap4/camel-imap4-folder.c +++ b/camel/providers/imap4/camel-imap4-folder.c @@ -616,9 +616,13 @@ imap4_refresh_info (CamelFolder *folder, CamelException *ex) static int untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_imap4_token_t *token, CamelException *ex) { + CamelFolderSummary *summary = ((CamelFolder *) engine->folder)->summary; CamelStream *fstream, *stream = ic->user_data; + CamelFolderChangeInfo *changes; + CamelIMAP4MessageInfo *iinfo; + CamelMessageInfo *info; CamelMimeFilter *crlf; - int left = 2; + guint32 flags; if (camel_imap4_engine_next_token (engine, token, ex) == -1) return -1; @@ -633,6 +637,9 @@ untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, if (camel_imap4_engine_next_token (engine, token, ex) == -1) goto exception; + if (token->token == ')' || token->token == '\n') + break; + if (token->token != CAMEL_IMAP4_TOKEN_ATOM) goto unexpected; @@ -657,24 +664,35 @@ untagged_fetch (CamelIMAP4Engine *engine, CamelIMAP4Command *ic, guint32 index, camel_stream_write_to_stream ((CamelStream *) engine->istream, fstream); camel_stream_flush (fstream); camel_object_unref (fstream); - - left--; } else if (!strcmp (token->v.atom, "UID")) { if (camel_imap4_engine_next_token (engine, token, ex) == -1) goto exception; if (token->token != CAMEL_IMAP4_TOKEN_NUMBER || token->v.number == 0) goto unexpected; + } else if (!strcmp (token->v.atom, "FLAGS")) { + /* even though we didn't request this bit of information, it might be + * given to us if another client recently changed the flags... */ + if (camel_imap4_parse_flags_list (engine, &flags, ex) == -1) + goto exception; - left--; + if ((info = camel_folder_summary_index (summary, index - 1))) { + iinfo = (CamelIMAP4MessageInfo *) info; + info->flags = camel_imap4_merge_flags (iinfo->server_flags, info->flags, flags); + iinfo->server_flags = flags; + + changes = camel_folder_change_info_new (); + camel_folder_change_info_change_uid (changes, camel_message_info_uid (info)); + camel_object_trigger_event (engine->folder, "folder_changed", changes); + camel_folder_change_info_free (changes); + + camel_folder_summary_info_free (summary, info); + } } else { /* wtf? */ fprintf (stderr, "huh? %s?...\n", token->v.atom); } - } while (left); - - if (camel_imap4_engine_next_token (engine, token, ex) == -1) - goto exception; + } while (1); if (token->token != ')') { fprintf (stderr, "expected ')' to close untagged FETCH response\n"); diff --git a/camel/providers/imap4/camel-imap4-summary.c b/camel/providers/imap4/camel-imap4-summary.c index fa7cd7778a..f5fec4d05e 100644 --- a/camel/providers/imap4/camel-imap4-summary.c +++ b/camel/providers/imap4/camel-imap4-summary.c @@ -105,6 +105,10 @@ camel_imap4_summary_init (CamelIMAP4Summary *summary, CamelIMAP4SummaryClass *kl CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_FLAGGED | CAMEL_MESSAGE_SEEN; folder_summary->message_info_size = sizeof (CamelIMAP4MessageInfo); + + summary->update_flags = TRUE; + summary->exists_changed = FALSE; + summary->uidvalidity_changed = FALSE; } static void @@ -156,8 +160,10 @@ imap4_header_save (CamelFolderSummary *summary, FILE *fout) static int envelope_decode_address (CamelIMAP4Engine *engine, GString *addrs, CamelException *ex) { + char *addr, *name = NULL, *user = NULL; + struct _camel_header_address *cia; camel_imap4_token_t token; - gboolean had_name = FALSE; + const char *domain = NULL; int part = 0; if (camel_imap4_engine_next_token (engine, &token, ex) == -1) @@ -184,25 +190,39 @@ envelope_decode_address (CamelIMAP4Engine *engine, GString *addrs, CamelExceptio case CAMEL_IMAP4_TOKEN_QSTRING: switch (part) { case 0: - g_string_append_printf (addrs, "\"%s\" <", token.v.qstring); - had_name = TRUE; + name = camel_header_decode_string (token.v.qstring, NULL); break; case 2: - g_string_append (addrs, token.v.qstring); + user = g_strdup (token.v.qstring); break; case 3: - g_string_append_printf (addrs, "@%s%s", token.v.qstring, had_name ? ">" : ""); + domain = token.v.qstring; break; } break; default: camel_imap4_utils_set_unexpected_token_error (ex, engine, &token); + g_free (name); + g_free (user); return -1; } part++; } while (part < 4); + addr = g_strdup_printf ("%s@%s", user, domain); + g_free (user); + + cia = camel_header_address_new_name (name, addr); + g_free (name); + g_free (addr); + + addr = camel_header_address_list_format (cia); + camel_header_address_unref (cia); + + g_string_append (addrs, addr); + g_free (addr); + if (camel_imap4_engine_next_token (engine, &token, ex) == -1) return -1; @@ -290,7 +310,7 @@ envelope_decode_date (CamelIMAP4Engine *engine, time_t *date, CamelException *ex } static int -envelope_decode_nstring (CamelIMAP4Engine *engine, char **nstring, CamelException *ex) +envelope_decode_nstring (CamelIMAP4Engine *engine, char **nstring, gboolean rfc2047, CamelException *ex) { camel_imap4_token_t token; @@ -302,10 +322,16 @@ envelope_decode_nstring (CamelIMAP4Engine *engine, char **nstring, CamelExceptio *nstring = NULL; break; case CAMEL_IMAP4_TOKEN_ATOM: - *nstring = g_strdup (token.v.atom); + if (rfc2047) + *nstring = camel_header_decode_string (token.v.atom, NULL); + else + *nstring = g_strdup (token.v.atom); break; case CAMEL_IMAP4_TOKEN_QSTRING: - *nstring = g_strdup (token.v.qstring); + if (rfc2047) + *nstring = camel_header_decode_string (token.v.qstring, NULL); + else + *nstring = g_strdup (token.v.qstring); break; default: camel_imap4_utils_set_unexpected_token_error (ex, engine, &token); @@ -365,7 +391,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t goto exception; /* subject */ - if (envelope_decode_nstring (engine, &nstring, ex) == -1) + if (envelope_decode_nstring (engine, &nstring, TRUE, ex) == -1) goto exception; camel_message_info_set_subject (info, nstring); @@ -400,7 +426,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t g_free (nstring); /* in-reply-to */ - if (envelope_decode_nstring (engine, &nstring, ex) == -1) + if (envelope_decode_nstring (engine, &nstring, FALSE, ex) == -1) goto exception; if (nstring != NULL) { @@ -409,7 +435,7 @@ decode_envelope (CamelIMAP4Engine *engine, CamelMessageInfo *info, camel_imap4_t } /* message-id */ - if (envelope_decode_nstring (engine, &nstring, ex) == -1) + if (envelope_decode_nstring (engine, &nstring, FALSE, ex) == -1) goto exception; if (nstring != NULL) { @@ -1062,18 +1088,20 @@ camel_imap4_summary_expunge (CamelFolderSummary *summary, int seqid) g_return_if_fail (CAMEL_IS_IMAP4_SUMMARY (summary)); - if (!(info = camel_folder_summary_index (summary, seqid - 1))) + seqid--; + if (!(info = camel_folder_summary_index (summary, seqid))) return; - imap4_summary->expunged_changed = TRUE; + imap4_summary->exists--; changes = camel_folder_change_info_new (); camel_folder_change_info_remove_uid (changes, camel_message_info_uid (info)); - camel_object_trigger_event (imap4_summary->folder, "folder_changed", changes); - camel_folder_change_info_free (changes); camel_folder_summary_info_free (summary, info); camel_folder_summary_remove_index (summary, seqid); + + camel_object_trigger_event (imap4_summary->folder, "folder_changed", changes); + camel_folder_change_info_free (changes); } @@ -1104,14 +1132,12 @@ camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException * engine = ((CamelIMAP4Store *) imap4_summary->folder->parent_store)->engine; - if (imap4_summary->expunged_changed && imap4_summary->exists_changed) { - if (imap4_summary->exists == camel_folder_summary_count (summary)) - imap4_summary->exists_changed = FALSE; - } - if (imap4_summary->uidvalidity_changed) { first = 1; - } else if (imap4_summary->exists_changed && imap4_summary->exists > 0) { + } else if (imap4_summary->update_flags || imap4_summary->exists_changed) { + /* this both updates flags and removes messages which + * have since been expunged from the server by another + * client */ scount = camel_folder_summary_count (summary); ic = imap4_summary_fetch_flags (summary, 1, scount); @@ -1151,6 +1177,7 @@ camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException * g_ptr_array_sort (summary->messages, (GCompareFunc) info_uid_sort); } + imap4_summary->update_flags = FALSE; imap4_summary->exists_changed = FALSE; imap4_summary->uidvalidity_changed = FALSE; diff --git a/camel/providers/imap4/camel-imap4-summary.h b/camel/providers/imap4/camel-imap4-summary.h index 9546a7923d..3bad898a6a 100644 --- a/camel/providers/imap4/camel-imap4-summary.h +++ b/camel/providers/imap4/camel-imap4-summary.h @@ -60,8 +60,8 @@ struct _CamelIMAP4Summary { guint32 uidvalidity; guint uidvalidity_changed:1; - guint expunged_changed; guint exists_changed:1; + guint update_flags:1; }; struct _CamelIMAP4SummaryClass { |