[evolution-data-server] Handle UIDNEXT and MODSEQ/HIGHESTMODSEQ information from server.



commit f6f7f867fa344ff5ae61820d56c529b304429af6
Author: David Woodhouse <David Woodhouse intel com>
Date:   Thu Jun 24 12:36:51 2010 +0100

    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.

 camel/providers/imapx/camel-imapx-folder.c   |    2 +
 camel/providers/imapx/camel-imapx-folder.h   |    2 +
 camel/providers/imapx/camel-imapx-server.c   |   12 ++++++++
 camel/providers/imapx/camel-imapx-server.h   |    4 ++-
 camel/providers/imapx/camel-imapx-tokens.txt |    3 ++
 camel/providers/imapx/camel-imapx-utils.c    |   38 ++++++++++++++++++++++++++
 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 987015a..5b32cdc 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -96,6 +96,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 ec0a802..9bbccea 100644
--- a/camel/providers/imapx/camel-imapx-folder.h
+++ b/camel/providers/imapx/camel-imapx-folder.h
@@ -59,6 +59,8 @@ 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 8e107d5..ec2d476 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -1507,6 +1507,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));
 			}
@@ -1553,9 +1555,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;
@@ -2258,6 +2266,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)
@@ -2323,10 +2333,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 956365a..eb2aad8 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -96,8 +96,10 @@ struct _CamelIMAPXServer {
 	CamelFolderChangeInfo *changes;
 	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 6a9abbd..d485018 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 62d4b7b..9845547 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)
 {
@@ -1440,6 +1466,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);
@@ -1530,6 +1560,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");
@@ -1668,6 +1703,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 a44abc6..f75174f 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 */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]