summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2010-06-24 12:36:51 +0100
committerDavid Woodhouse <David.Woodhouse@intel.com>2010-06-28 13:43:58 +0100
commitce054b4a98626099bcd93780bc4041bfa0c58cd9 (patch)
tree29b1dd06dd70968b5e21d9dd4db40209ae422949
parent74510e17ab484b8a0f74d30cd8962d3d39a045e7 (diff)
downloadevolution-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.c2
-rw-r--r--camel/providers/imapx/camel-imapx-folder.h2
-rw-r--r--camel/providers/imapx/camel-imapx-server.c12
-rw-r--r--camel/providers/imapx/camel-imapx-server.h4
-rw-r--r--camel/providers/imapx/camel-imapx-tokens.txt3
-rw-r--r--camel/providers/imapx/camel-imapx-utils.c38
-rw-r--r--camel/providers/imapx/camel-imapx-utils.h11
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 */