[evolution-data-server] implement transfer_messages_to



commit 50f769972721a233c96134cd4932a7c2ed3c76cd
Author: Chenthill Palanisamy <pchenthill novell com>
Date:   Wed Feb 3 03:20:45 2010 +0530

    implement transfer_messages_to

 camel/providers/imapx/camel-imapx-folder.c   |   38 ++++++++-
 camel/providers/imapx/camel-imapx-server.c   |  114 ++++++++++++++++++++++++++
 camel/providers/imapx/camel-imapx-server.h   |    1 +
 camel/providers/imapx/camel-imapx-tokenise.h |   87 ++++++++++----------
 camel/providers/imapx/camel-imapx-tokens.txt |    1 +
 camel/providers/imapx/camel-imapx-utils.c    |   60 ++++++++++++++
 camel/providers/imapx/camel-imapx-utils.h    |    6 ++
 7 files changed, 259 insertions(+), 48 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index e8be652..b47c6dd 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -145,14 +145,17 @@ static void
 imapx_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
 {
 	CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+	
+	if (CAMEL_OFFLINE_STORE (is)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+		return;
+
+	if (is->server && camel_imapx_server_connect (is->server, 1))
+		camel_imapx_server_sync_changes (is->server, folder, ex);
 
 	/* Sync twice - make sure deleted flags are written out,
 	   then sync again incase expunge changed anything */
 	camel_exception_clear(ex);
 
-	if (is->server && camel_imapx_server_connect (is->server, 1))
-		camel_imapx_server_sync_changes (is->server, folder, ex);
-
 	if (is->server && expunge) {
 		camel_imapx_server_expunge(is->server, folder, ex);
 		camel_exception_clear(ex);
@@ -183,6 +186,9 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
 			return NULL;
 		}
 
+		if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+			return NULL;
+
 		if (istore->server && camel_imapx_server_connect (istore->server, 1)) {
 			stream = camel_imapx_server_get_message(istore->server, folder, uid, ex);
 		} else {
@@ -204,15 +210,36 @@ imapx_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
 	return msg;
 }
 
+
+static void
+imapx_transfer_messages_to (CamelFolder *source, GPtrArray *uids,
+		      CamelFolder *dest, GPtrArray **transferred_uids,
+		      gboolean delete_originals, CamelException *ex)
+{
+	CamelIMAPXStore *istore = (CamelIMAPXStore *) source->parent_store;
+
+	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+		return;
+		
+	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+		camel_imapx_server_copy_message (istore->server, source, dest, uids, delete_originals, ex);
+
+	imapx_refresh_info (dest, ex);
+}
+
 static void
 imapx_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, gchar **appended_uid, CamelException *ex)
 {
-	CamelIMAPXStore *is = (CamelIMAPXStore *)folder->parent_store;
+	CamelIMAPXStore *istore = (CamelIMAPXStore *)folder->parent_store;
+
+	if (CAMEL_OFFLINE_STORE (istore)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL)
+		return;
 
 	if (appended_uid)
 		*appended_uid = NULL;
 
-	camel_imapx_server_append_message(is->server, folder, message, info, ex);
+	if (istore->server && camel_imapx_server_connect (istore->server, 1))
+		camel_imapx_server_append_message(istore->server, folder, message, info, ex);
 }
 
 gchar *
@@ -356,6 +383,7 @@ imap_folder_class_init (CamelIMAPXFolderClass *klass)
 
 	((CamelFolderClass *)klass)->get_message = imapx_get_message;
 	((CamelFolderClass *)klass)->append_message = imapx_append_message;
+	((CamelFolderClass *)klass)->transfer_messages_to = imapx_transfer_messages_to;
 	((CamelFolderClass *)klass)->get_filename = imapx_get_filename;
 }
 
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index a56f167..5613240 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -71,6 +71,8 @@
 /* How many message headers to fetch at a time update summary for new messages*/
 #define BATCH_FETCH_COUNT 500
 
+#define MAX_COMMAND_LEN 1000
+
 extern gint camel_application_is_exiting;
 
 struct _uidset_state {
@@ -173,6 +175,7 @@ struct _refresh_info {
 enum {
 	IMAPX_JOB_GET_MESSAGE,
 	IMAPX_JOB_APPEND_MESSAGE,
+	IMAPX_JOB_COPY_MESSAGE,
 	IMAPX_JOB_REFRESH_INFO,
 	IMAPX_JOB_SYNC_CHANGES,
 	IMAPX_JOB_EXPUNGE,
@@ -240,6 +243,14 @@ struct _CamelIMAPXJob {
 			CamelMessageInfo *info;
 		} append_message;
 		struct {
+			CamelFolder *dest;
+			GPtrArray *uids;
+			gboolean delete_originals;
+			gint index;
+			gint last_index;
+			struct _uidset_state uidset;
+		} copy_messages;
+		struct {
 			gchar *pattern;
 			guint32 flags;
 			GHashTable *folders;
@@ -250,6 +261,8 @@ struct _CamelIMAPXJob {
 static void imapx_job_done (CamelIMAPXJob *job);
 static void imapx_run_job (CamelIMAPXServer *is, CamelIMAPXJob *job);
 static void imapx_job_fetch_new_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job);
+static void imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic);
+static gint imapx_refresh_info_uid_cmp(gconstpointer ap, gconstpointer bp);
 
 typedef struct _CamelIMAPXIdle CamelIMAPXIdle;
 struct _CamelIMAPXIdle {
@@ -2276,6 +2289,87 @@ imapx_job_get_message_start(CamelIMAPXServer *is, CamelIMAPXJob *job)
 /* ********************************************************************** */
 
 static void
+imapx_command_copy_messages_step_start (CamelIMAPXServer *is, CamelIMAPXJob *job, gint index)
+{
+	CamelIMAPXCommand *ic;
+	GPtrArray *uids = job->u.copy_messages.uids;
+	gint i = index;
+	
+	ic = camel_imapx_command_new ("COPY", job->folder->full_name, "UID COPY ");
+	ic->complete = imapx_command_copy_messages_step_done;
+	ic->job = job;
+	job->u.copy_messages.last_index = i;
+
+	for (;i < uids->len; i++) {
+		gint res;
+		const gchar *uid = (gchar *) g_ptr_array_index (uids, i);
+
+		res = imapx_uidset_add (&job->u.copy_messages.uidset, ic, uid);
+		if (res == 1) {
+			camel_imapx_command_add (ic, " %f", job->u.copy_messages.dest->full_name);
+			job->u.copy_messages.index = i;
+			imapx_command_queue (is, ic);
+			return;
+		}
+	}
+
+	job->u.copy_messages.index = i;
+	if (imapx_uidset_done (&job->u.copy_messages.uidset, ic)) {
+		camel_imapx_command_add (ic, " %s", job->u.copy_messages.dest->full_name);
+		imapx_command_queue (is, ic);
+		return;
+	}
+}
+
+static void
+imapx_command_copy_messages_step_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
+{
+	CamelIMAPXJob *job = ic->job;
+	gint i = job->u.copy_messages.index;
+	GPtrArray *uids = job->u.copy_messages.uids;
+	
+	if (camel_exception_is_set (ic->ex) || ic->status->result != IMAP_OK) {
+		if (!camel_exception_is_set (ic->ex))
+			camel_exception_set (job->ex, 1, "Error copying messages");
+		else
+			camel_exception_xfer (job->ex, ic->ex);
+
+		goto cleanup;
+	}
+
+	if (job->u.copy_messages.delete_originals) {
+		gint j;
+
+		for (j = job->u.copy_messages.last_index; j < i; j++)
+			camel_folder_delete_message (job->folder, uids->pdata [j]);
+	}
+
+	/* TODO copy the summary and cached messages to the new folder. We might need a sorted insert to avoid refreshing the dest folder */
+	if (ic->status->condition == IMAP_COPYUID) {
+		
+	}
+
+	if (i < uids->len) {
+		camel_imapx_command_free (ic);
+		imapx_command_copy_messages_step_start (is, job, i);
+	}
+
+cleanup:
+	imapx_job_done (job);
+	camel_imapx_command_free (ic);
+}
+
+static void
+imapx_job_copy_messages_start (CamelIMAPXServer *is, CamelIMAPXJob *job)
+{
+	g_ptr_array_sort (job->u.copy_messages.uids, (GCompareFunc) imapx_refresh_info_uid_cmp);
+	imapx_uidset_init(&job->u.copy_messages.uidset, 0, MAX_COMMAND_LEN);
+	imapx_command_copy_messages_step_start (is, job, 0);
+}
+
+/* ********************************************************************** */
+
+static void
 imapx_command_append_message_done (CamelIMAPXServer *is, CamelIMAPXCommand *ic)
 {
 	CamelIMAPXJob *job = ic->job;
@@ -3417,6 +3511,26 @@ camel_imapx_server_get_message(CamelIMAPXServer *is, CamelFolder *folder, const
 }
 
 void
+camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, CamelFolder *dest, GPtrArray *uids, gboolean delete_originals, CamelException *ex)
+{
+	CamelIMAPXJob *job;
+
+	job = g_malloc0(sizeof(*job));
+	job->pri = -60;
+	job->type = IMAPX_JOB_COPY_MESSAGE;
+	job->start = imapx_job_copy_messages_start;
+	job->folder = source;
+	job->u.copy_messages.dest = dest;
+	job->u.copy_messages.uids = uids;
+	job->u.copy_messages.delete_originals = delete_originals;
+	
+	camel_object_ref(source);
+	camel_object_ref (dest);
+
+	imapx_run_job (is, job);
+} 
+
+void
 camel_imapx_server_append_message(CamelIMAPXServer *is, CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *mi, CamelException *ex)
 {
 	gchar *uid = NULL, *tmp = NULL;
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index 856238d..bd984e5 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -114,6 +114,7 @@ void camel_imapx_server_expunge(CamelIMAPXServer *is, CamelFolder *folder, Camel
 void camel_imapx_server_noop (CamelIMAPXServer *is, CamelFolder *folder, CamelException *ex);
 
 CamelStream *camel_imapx_server_get_message(CamelIMAPXServer *is, CamelFolder *folder, const gchar *uid, struct _CamelException *ex);
+void camel_imapx_server_copy_message (CamelIMAPXServer *is, CamelFolder *source, CamelFolder *dest, GPtrArray *uids, gboolean delete_originals, CamelException *ex);
 void camel_imapx_server_append_message(CamelIMAPXServer *is, CamelFolder *folder, struct _CamelMimeMessage *message, const struct _CamelMessageInfo *mi, CamelException *ex);
 
 #endif /* _CAMEL_IMAPX_SERVER_H */
diff --git a/camel/providers/imapx/camel-imapx-tokenise.h b/camel/providers/imapx/camel-imapx-tokenise.h
index 249017a..954e4d4 100644
--- a/camel/providers/imapx/camel-imapx-tokenise.h
+++ b/camel/providers/imapx/camel-imapx-tokenise.h
@@ -31,7 +31,7 @@
 #line 3 "camel-imapx-tokens.txt"
 struct _imap_keyword {const gchar *name; camel_imapx_id_t id; };
 
-#define TOTAL_KEYWORDS 35
+#define TOTAL_KEYWORDS 36
 #define MIN_WORD_LENGTH 2
 #define MAX_WORD_LENGTH 14
 #define MIN_HASH_VALUE 5
@@ -45,10 +45,10 @@ __inline
 inline
 #endif
 #endif
-static guint
-imap_hash (register const gchar *str, register guint len)
+static unsigned int
+imap_hash (register const char *str, register unsigned int len)
 {
-  static guchar asso_values[] =
+  static unsigned char asso_values[] =
     {
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
@@ -56,8 +56,8 @@ imap_hash (register const gchar *str, register guint len)
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
-      57, 57, 57, 57, 57, 25, 15,  5, 20,  0,
-       5, 57,  5, 10, 57,  5, 30, 10, 25, 10,
+      57, 57, 57, 57, 57, 25, 15, 10, 20,  0,
+       5, 57,  5, 10, 57,  0, 30, 10, 25, 15,
        0, 57,  0, 25, 10, 10, 57, 57, 57,  5,
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
@@ -77,107 +77,108 @@ imap_hash (register const gchar *str, register guint len)
       57, 57, 57, 57, 57, 57, 57, 57, 57, 57,
       57, 57, 57, 57, 57, 57
     };
-  return len + asso_values[(guchar)str[len - 1]] + asso_values[(guchar)str[0]];
+  return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]];
 }
 
 #ifdef __GNUC__
 __inline
 #endif
 struct _imap_keyword *
-imap_tokenise_struct (register const gchar *str, register guint len)
+imap_tokenise_struct (register const char *str, register unsigned int len)
 {
   static struct _imap_keyword wordlist[] =
     {
       {""}, {""}, {""}, {""}, {""},
-#line 25 "camel-imapx-tokens.txt"
+#line 26 "camel-imapx-tokens.txt"
       {"PARSE",		IMAP_PARSE},
       {""},
-#line 14 "camel-imapx-tokens.txt"
+#line 15 "camel-imapx-tokens.txt"
       {"EXPUNGE",	IMAP_EXPUNGE},
-#line 12 "camel-imapx-tokens.txt"
+#line 13 "camel-imapx-tokens.txt"
       {"ENVELOPE",	IMAP_ENVELOPE},
       {""},
-#line 29 "camel-imapx-tokens.txt"
+#line 30 "camel-imapx-tokens.txt"
       {"READ-WRITE",	IMAP_READ_WRITE},
-#line 32 "camel-imapx-tokens.txt"
+#line 33 "camel-imapx-tokens.txt"
       {"RFC822.SIZE",	IMAP_RFC822_SIZE},
-#line 27 "camel-imapx-tokens.txt"
+#line 28 "camel-imapx-tokens.txt"
       {"PREAUTH",	IMAP_PREAUTH},
-#line 31 "camel-imapx-tokens.txt"
+#line 32 "camel-imapx-tokens.txt"
       {"RFC822.HEADER",	IMAP_RFC822_HEADER},
-#line 28 "camel-imapx-tokens.txt"
+#line 29 "camel-imapx-tokens.txt"
       {"READ-ONLY",	IMAP_READ_ONLY},
-#line 15 "camel-imapx-tokens.txt"
+#line 16 "camel-imapx-tokens.txt"
       {"FETCH",		IMAP_FETCH},
-#line 30 "camel-imapx-tokens.txt"
+#line 31 "camel-imapx-tokens.txt"
       {"RECENT",		IMAP_RECENT},
-#line 24 "camel-imapx-tokens.txt"
+#line 25 "camel-imapx-tokens.txt"
       {"OK",		IMAP_OK},
 #line 10 "camel-imapx-tokens.txt"
       {"BYE",		IMAP_BYE},
-#line 35 "camel-imapx-tokens.txt"
+#line 36 "camel-imapx-tokens.txt"
       {"TRYCREATE",	IMAP_TRYCREATE},
-#line 11 "camel-imapx-tokens.txt"
-      {"CAPABILITY",	IMAP_CAPABILITY},
-#line 33 "camel-imapx-tokens.txt"
+      {""},
+#line 34 "camel-imapx-tokens.txt"
       {"RFC822.TEXT",	IMAP_RFC822_TEXT},
-#line 17 "camel-imapx-tokens.txt"
+#line 18 "camel-imapx-tokens.txt"
       {"INTERNALDATE",	IMAP_INTERNALDATE},
       {""},
 #line 8 "camel-imapx-tokens.txt"
       {"BODY",		IMAP_BODY},
-      {""},
-#line 37 "camel-imapx-tokens.txt"
+#line 11 "camel-imapx-tokens.txt"
+      {"CAPABILITY",	IMAP_CAPABILITY},
+#line 38 "camel-imapx-tokens.txt"
       {"UIDVALIDITY",	IMAP_UIDVALIDITY},
-#line 39 "camel-imapx-tokens.txt"
+#line 40 "camel-imapx-tokens.txt"
       {"UIDNEXT",	IMAP_UIDNEXT},
 #line 9 "camel-imapx-tokens.txt"
       {"BODYSTRUCTURE",	IMAP_BODYSTRUCTURE},
       {""}, {""},
-#line 13 "camel-imapx-tokens.txt"
+#line 14 "camel-imapx-tokens.txt"
       {"EXISTS",		IMAP_EXISTS},
-#line 22 "camel-imapx-tokens.txt"
+#line 23 "camel-imapx-tokens.txt"
       {"NEWNAME",	IMAP_NEWNAME},
-#line 36 "camel-imapx-tokens.txt"
+#line 37 "camel-imapx-tokens.txt"
       {"UID",		IMAP_UID},
-#line 21 "camel-imapx-tokens.txt"
+#line 22 "camel-imapx-tokens.txt"
       {"NAMESPACE",	IMAP_NAMESPACE},
-#line 16 "camel-imapx-tokens.txt"
+#line 17 "camel-imapx-tokens.txt"
       {"FLAGS",		IMAP_FLAGS},
       {""},
-#line 23 "camel-imapx-tokens.txt"
-      {"NO",		IMAP_NO},
+#line 12 "camel-imapx-tokens.txt"
+      {"COPYUID",	IMAP_COPYUID},
 #line 7 "camel-imapx-tokens.txt"
       {"BAD",		IMAP_BAD},
-#line 26 "camel-imapx-tokens.txt"
+#line 27 "camel-imapx-tokens.txt"
       {"PERMANENTFLAGS",	IMAP_PERMANENTFLAGS},
 #line 5 "camel-imapx-tokens.txt"
       {"ALERT",          IMAP_ALERT},
-#line 38 "camel-imapx-tokens.txt"
+#line 39 "camel-imapx-tokens.txt"
       {"UNSEEN",		IMAP_UNSEEN},
-      {""},
-#line 20 "camel-imapx-tokens.txt"
+#line 24 "camel-imapx-tokens.txt"
+      {"NO",		IMAP_NO},
+#line 21 "camel-imapx-tokens.txt"
       {"MESSAGES",	IMAP_MESSAGES},
-#line 18 "camel-imapx-tokens.txt"
+#line 19 "camel-imapx-tokens.txt"
       {"LIST",		IMAP_LIST},
       {""}, {""}, {""}, {""},
-#line 19 "camel-imapx-tokens.txt"
+#line 20 "camel-imapx-tokens.txt"
       {"LSUB",		IMAP_LSUB},
       {""}, {""}, {""}, {""},
 #line 6 "camel-imapx-tokens.txt"
       {"APPENDUID",	IMAP_APPENDUID},
       {""},
-#line 34 "camel-imapx-tokens.txt"
+#line 35 "camel-imapx-tokens.txt"
       {"STATUS",		IMAP_STATUS}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
     {
-      register gint key = imap_hash (str, len);
+      register int key = imap_hash (str, len);
 
       if (key <= MAX_HASH_VALUE && key >= 0)
         {
-          register const gchar *s = wordlist[key].name;
+          register const char *s = wordlist[key].name;
 
           if (*str == *s && !strcmp (str + 1, s + 1))
             return &wordlist[key];
diff --git a/camel/providers/imapx/camel-imapx-tokens.txt b/camel/providers/imapx/camel-imapx-tokens.txt
index 04e5478..e84ecf7 100644
--- a/camel/providers/imapx/camel-imapx-tokens.txt
+++ b/camel/providers/imapx/camel-imapx-tokens.txt
@@ -9,6 +9,7 @@ BODY,		IMAP_BODY
 BODYSTRUCTURE,	IMAP_BODYSTRUCTURE
 BYE,		IMAP_BYE
 CAPABILITY,	IMAP_CAPABILITY
+COPYUID,	IMAP_COPYUID
 ENVELOPE,	IMAP_ENVELOPE
 EXISTS,		IMAP_EXISTS
 EXPUNGE,	IMAP_EXPUNGE
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index 5c0e16f..7cb7064 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -1502,6 +1502,56 @@ imap_parse_status_info (struct _CamelIMAPXStream *is, CamelException *ex)
 	return sinfo;
 }
 
+
+static void
+generate_uids_from_sequence (GPtrArray *uids, guint32 end_uid)
+{
+	guint32 uid = GPOINTER_TO_UINT (g_ptr_array_index (uids, uids->len - 1));
+	
+	uid++;
+	while (uid <= end_uid) {
+		g_ptr_array_add (uids, GUINT_TO_POINTER (uid));
+		uid++;
+	}
+}
+
+static GPtrArray *
+imap_parse_uids (CamelIMAPXStream *is, CamelException *ex)
+{
+	GPtrArray *uids = g_ptr_array_new ();
+	gboolean is_prev_number = FALSE, sequence = FALSE;
+	guchar *token;
+	guint len;
+	gint tok;
+
+	tok = camel_imapx_stream_token (is, &token, &len, ex);
+	while (tok != ']'|| !(is_prev_number && tok == IMAP_TOK_INT)) {
+		if (tok == ',') {
+			is_prev_number = FALSE;
+			sequence = FALSE;
+		} else if (tok == ':') {
+			sequence = TRUE;
+			is_prev_number = FALSE;
+		} else {
+			guint32 uid = strtoul ((char *) token, NULL, 10);
+
+			is_prev_number = TRUE;
+			sequence = FALSE;
+			
+			if (sequence)
+				generate_uids_from_sequence (uids, uid);
+			else
+				g_ptr_array_add (uids, GUINT_TO_POINTER (uid));
+		}
+		camel_imapx_stream_token (is, &token, &len, ex);
+	}
+
+	if (is_prev_number && tok == IMAP_TOK_INT)
+		camel_imapx_stream_ungettoken (is, tok, token, len);
+
+	return uids;
+}
+
 /* rfc 2060 section 7.1 Status Responses */
 /* shoudl this start after [ or before the [? token_unget anyone? */
 struct _status_info *
@@ -1557,6 +1607,11 @@ imap_parse_status(CamelIMAPXStream *is, CamelException *ex)
 				sinfo->u.appenduid.uidvalidity = camel_imapx_stream_number(is, ex);
 				sinfo->u.appenduid.uid = camel_imapx_stream_number(is, ex);
 				break;
+			case IMAP_COPYUID:
+				sinfo->u.copyuid.uidvalidity = camel_imapx_stream_number(is, ex);
+				sinfo->u.copyuid.uids = imap_parse_uids (is, ex);
+				sinfo->u.copyuid.copied_uids = imap_parse_uids (is, ex);
+				break;
 			case IMAP_NEWNAME:
 				/* the rfc doesn't specify the bnf for this */
 				camel_imapx_stream_astring(is, &token, ex);
@@ -1627,6 +1682,11 @@ imap_free_status(struct _status_info *sinfo)
 	case IMAP_NEWNAME:
 		g_free(sinfo->u.newname.oldname);
 		g_free(sinfo->u.newname.newname);
+		break;
+	case IMAP_COPYUID:
+		g_ptr_array_free (sinfo->u.copyuid.uids, FALSE);
+		g_ptr_array_free (sinfo->u.copyuid.copied_uids, FALSE);
+		break;
 	default:
 		break;
 	}
diff --git a/camel/providers/imapx/camel-imapx-utils.h b/camel/providers/imapx/camel-imapx-utils.h
index dcaddbe..f793cd6 100644
--- a/camel/providers/imapx/camel-imapx-utils.h
+++ b/camel/providers/imapx/camel-imapx-utils.h
@@ -20,6 +20,7 @@ typedef enum _camel_imapx_id_t {
 	IMAP_BODYSTRUCTURE,
 	IMAP_BYE,
 	IMAP_CAPABILITY,
+	IMAP_COPYUID,
 	IMAP_ENVELOPE,
 	IMAP_EXISTS,
 	IMAP_EXPUNGE,
@@ -151,6 +152,11 @@ struct _status_info {
 			guint32 uidvalidity;
 			guint32 uid;
 		} appenduid;
+		struct {
+			guint32 uidvalidity;
+			GPtrArray *uids;
+			GPtrArray *copied_uids;
+		} copyuid;
 	} u;
 
 	gchar *text;



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