aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2004-06-11 23:00:12 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2004-06-11 23:00:12 +0800
commit9c5abb70276da514cb6941348405de2fc1d3176b (patch)
tree6192e9738cf4350cb5203e0815c41c9b494b90dd /camel
parentff2a5e2ebf1ad4a458214502c24901d6e550bf62 (diff)
downloadgsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar
gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar.gz
gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar.bz2
gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar.lz
gsoc2013-evolution-9c5abb70276da514cb6941348405de2fc1d3176b.tar.xz
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/ChangeLog15
-rw-r--r--camel/providers/imap4/camel-imap4-folder.c34
-rw-r--r--camel/providers/imap4/camel-imap4-summary.c69
-rw-r--r--camel/providers/imap4/camel-imap4-summary.h2
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 {