diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2010-06-24 12:36:51 +0100 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-06-28 13:43:58 +0100 |
commit | ce054b4a98626099bcd93780bc4041bfa0c58cd9 (patch) | |
tree | 29b1dd06dd70968b5e21d9dd4db40209ae422949 | |
parent | 74510e17ab484b8a0f74d30cd8962d3d39a045e7 (diff) | |
download | evolution-data-server-ce054b4a98626099bcd93780bc4041bfa0c58cd9.tar.gz |
Handle UIDNEXT and MODSEQ/HIGHESTMODSEQ information from server.
UIDNEXT is useful for detecting when new messages have been added to a
folder, and (for servers which support it) MODSEQ is even more useful because
it lets us detect flags changes.
(cherry picked from commit f6f7f867fa344ff5ae61820d56c529b304429af6)
-rw-r--r-- | camel/providers/imapx/camel-imapx-folder.c | 2 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-folder.h | 2 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-server.c | 12 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-server.h | 4 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-tokens.txt | 3 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-utils.c | 38 | ||||
-rw-r--r-- | camel/providers/imapx/camel-imapx-utils.h | 11 |
7 files changed, 69 insertions, 3 deletions
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c index c62700576..3d9b0c048 100644 --- a/camel/providers/imapx/camel-imapx-folder.c +++ b/camel/providers/imapx/camel-imapx-folder.c @@ -108,6 +108,8 @@ camel_imapx_folder_new(CamelStore *store, const gchar *folder_dir, const gchar * ifolder->ignore_recent = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL); ifolder->exists_on_server = 0; ifolder->unread_on_server = 0; + ifolder->modseq_on_server = 0; + ifolder->uidnext_on_server = 0; istore = (CamelIMAPXStore *) store; if (!g_ascii_strcasecmp (folder_name, "INBOX")) { diff --git a/camel/providers/imapx/camel-imapx-folder.h b/camel/providers/imapx/camel-imapx-folder.h index 11979a7c0..ae7144a23 100644 --- a/camel/providers/imapx/camel-imapx-folder.h +++ b/camel/providers/imapx/camel-imapx-folder.h @@ -47,6 +47,8 @@ typedef struct _CamelIMAPXFolder { guint32 exists_on_server; guint32 unread_on_server; + guint64 modseq_on_server; + guint32 uidnext_on_server; /* hash table of UIDs to ignore as recent when updating folder */ GHashTable *ignore_recent; diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c index 437ec5587..a6e37e198 100644 --- a/camel/providers/imapx/camel-imapx-server.c +++ b/camel/providers/imapx/camel-imapx-server.c @@ -1510,6 +1510,8 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex) if (ifolder) { ifolder->unread_on_server = sinfo->unseen; ifolder->exists_on_server = sinfo->messages; + ifolder->modseq_on_server = sinfo->highestmodseq; + ifolder->uidnext_on_server = sinfo->uidnext; } else { c(printf("Received STATUS for unknown folder '%s'\n", sinfo->name)); } @@ -1557,9 +1559,15 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex) case IMAPX_UNSEEN: imap->unseen = sinfo->u.unseen; break; + case IMAPX_HIGHESTMODSEQ: + imap->highestmodseq = sinfo->u.highestmodseq; + break; case IMAPX_PERMANENTFLAGS: imap->permanentflags = sinfo->u.permanentflags; break; + case IMAPX_UIDNEXT: + imap->uidnext = sinfo->u.uidnext; + break; case IMAPX_ALERT: c(printf("ALERT!: %s\n", sinfo->text)); break; @@ -2247,6 +2255,8 @@ imapx_command_select_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic) } is->state = IMAPX_SELECTED; ifolder->exists_on_server = is->exists; + ifolder->modseq_on_server = is->highestmodseq; + ifolder->uidnext_on_server = is->uidnext; #if 0 /* This must trigger a complete index rebuild! */ if (is->uidvalidity && is->uidvalidity != ((CamelIMAPXSummary *)is->select_folder->summary)->uidvalidity) @@ -2307,10 +2317,12 @@ imapx_select (CamelIMAPXServer *is, CamelFolder *folder, gboolean forced, CamelE is->uidvalidity = 0; is->unseen = 0; + is->highestmodseq = 0; is->permanentflags = 0; is->exists = 0; is->recent = 0; is->mode = 0; + is->uidnext = 0; /* Hrm, what about reconnecting? */ is->state = IMAPX_INITIALISED; diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h index 1f0ed1070..2e3729a6e 100644 --- a/camel/providers/imapx/camel-imapx-server.h +++ b/camel/providers/imapx/camel-imapx-server.h @@ -79,8 +79,10 @@ struct _CamelIMAPXServer { struct _CamelFolderChangeInfo *changes; struct _CamelFolder *select_pending; guint32 permanentflags; - guint64 uidvalidity; guint32 unseen; + guint64 uidvalidity; + guint64 highestmodseq; + guint32 uidnext; guint32 exists; guint32 recent; guint32 mode; diff --git a/camel/providers/imapx/camel-imapx-tokens.txt b/camel/providers/imapx/camel-imapx-tokens.txt index 6a9abbd97..d48501865 100644 --- a/camel/providers/imapx/camel-imapx-tokens.txt +++ b/camel/providers/imapx/camel-imapx-tokens.txt @@ -17,13 +17,16 @@ EXISTS, IMAPX_EXISTS EXPUNGE, IMAPX_EXPUNGE FETCH, IMAPX_FETCH FLAGS, IMAPX_FLAGS +HIGHESTMODSEQ, IMAPX_HIGHESTMODSEQ INTERNALDATE, IMAPX_INTERNALDATE LIST, IMAPX_LIST LSUB, IMAPX_LSUB MESSAGES, IMAPX_MESSAGES +MODSEQ, IMAPX_MODSEQ NAMESPACE, IMAPX_NAMESPACE NEWNAME, IMAPX_NEWNAME NO, IMAPX_NO +NOMODSEQ, IMAPX_NOMODSEQ OK, IMAPX_OK PARSE, IMAPX_PARSE PERMANENTFLAGS, IMAPX_PERMANENTFLAGS diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c index c287cfcc2..431f11de5 100644 --- a/camel/providers/imapx/camel-imapx-utils.c +++ b/camel/providers/imapx/camel-imapx-utils.c @@ -1310,6 +1310,32 @@ imapx_parse_section(CamelIMAPXStream *is, CamelException *ex) return section; } +static guint64 +imapx_parse_modseq(CamelIMAPXStream *is, CamelException *ex) +{ + guint64 ret; + gint tok; + guint len; + guchar *token; + + + tok = camel_imapx_stream_token(is, &token, &len, ex); + if (tok != '(') { + camel_exception_set (ex, 1, "fetch: expecting '('"); + return 0; + } + ret = camel_imapx_stream_number(is, ex); + if (camel_exception_is_set(ex)) + return 0; + + tok = camel_imapx_stream_token(is, &token, &len, ex); + if (tok != ')') { + camel_exception_set (ex, 1, "fetch: expecting '('"); + return 0; + } + return ret; +} + void imapx_free_fetch(struct _fetch_info *finfo) { @@ -1442,6 +1468,10 @@ imapx_parse_fetch(CamelIMAPXStream *is, CamelException *ex) finfo->cinfo = imapx_parse_body(is, ex); finfo->got |= FETCH_CINFO; break; + case IMAPX_MODSEQ: + finfo->modseq = imapx_parse_modseq(is, ex); + finfo->got |= FETCH_MODSEQ; + break; case IMAPX_BODY: tok = camel_imapx_stream_token(is, &token, &len, ex); camel_imapx_stream_ungettoken(is, tok, token, len); @@ -1532,6 +1562,11 @@ imapx_parse_status_info (struct _CamelIMAPXStream *is, CamelException *ex) case IMAPX_UNSEEN: sinfo->unseen = camel_imapx_stream_number (is, ex); break; + case IMAPX_HIGHESTMODSEQ: + sinfo->highestmodseq = camel_imapx_stream_number (is, ex); + break; + case IMAPX_NOMODSEQ: + break; default: g_free (sinfo); camel_exception_set (ex, 1, "unknown status response"); @@ -1670,6 +1705,9 @@ imapx_parse_status(CamelIMAPXStream *is, CamelException *ex) case IMAPX_UNSEEN: sinfo->u.unseen = camel_imapx_stream_number(is, ex); break; + case IMAPX_HIGHESTMODSEQ: + sinfo->u.highestmodseq = camel_imapx_stream_number(is, ex); + break; case IMAPX_CAPABILITY: sinfo->u.cinfo = imapx_parse_capability(is, ex); break; diff --git a/camel/providers/imapx/camel-imapx-utils.h b/camel/providers/imapx/camel-imapx-utils.h index 43a836eb9..922f9bf58 100644 --- a/camel/providers/imapx/camel-imapx-utils.h +++ b/camel/providers/imapx/camel-imapx-utils.h @@ -27,13 +27,16 @@ typedef enum _camel_imapx_id_t { IMAPX_EXPUNGE, IMAPX_FETCH, IMAPX_FLAGS, + IMAPX_HIGHESTMODSEQ, IMAPX_INTERNALDATE, IMAPX_LIST, IMAPX_LSUB, IMAPX_MESSAGES, + IMAPX_MODSEQ, IMAPX_NAMESPACE, IMAPX_NEWNAME, IMAPX_NO, + IMAPX_NOMODSEQ, IMAPX_OK, IMAPX_PARSE, IMAPX_PERMANENTFLAGS, @@ -116,6 +119,7 @@ struct _fetch_info { guint32 size; /* RFC822.SIZE */ guint32 offset; /* start offset of a BODY[]<offset.length> request */ guint32 flags; /* FLAGS */ + guint64 modseq; /* MODSEQ */ struct _CamelFlag *user_flags; gchar *date; /* INTERNALDATE */ gchar *section; /* section for a BODY[section] request */ @@ -133,6 +137,7 @@ struct _fetch_info { #define FETCH_DATE (1<<8) #define FETCH_SECTION (1<<9) #define FETCH_UID (1<<10) +#define FETCH_MODSEQ (1<<11) struct _fetch_info *imapx_parse_fetch(struct _CamelIMAPXStream *is, CamelException *ex); void imapx_free_fetch(struct _fetch_info *finfo); @@ -142,7 +147,7 @@ void imapx_dump_fetch(struct _fetch_info *finfo); struct _status_info { camel_imapx_id_t result; /* ok/no/bad/preauth only, user_cancel - client response */ - camel_imapx_id_t condition; /* read-only/read-write/alert/parse/trycreate/newname/permanentflags/uidvalidity/unseen */ + camel_imapx_id_t condition; /* read-only/read-write/alert/parse/trycreate/newname/permanentflags/uidvalidity/unseen/highestmodseq */ union { struct { @@ -153,6 +158,7 @@ struct _status_info { guint64 uidvalidity; guint32 uidnext; guint32 unseen; + guint64 highestmodseq; struct { guint64 uidvalidity; guint32 uid; @@ -179,8 +185,9 @@ struct _state_info { guint32 messages; guint32 recent; guint32 uidnext; - guint64 uidvalidity; guint32 unseen; + guint64 uidvalidity; + guint64 highestmodseq; }; /* use g_free to free the return value */ |