dovecot-1.2: Added the concept of Global UIDs that are preserved...

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 7 22:34:03 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/6d51328896d6
changeset: 8077:6d51328896d6
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 07 15:33:52 2008 -0400
description:
Added the concept of Global UIDs that are preserved across copies.
They can be fetched, searched and specified for the save API. dbox format
supports them correctly, but with maildir the base filename is used so
maildir_copy_preserve_filename=yes is required to preserve GUIDs when copying.

diffstat:

21 files changed, 166 insertions(+), 45 deletions(-)
src/imap/imap-fetch.c                          |   24 ++++++++
src/lib-storage/index/cydir/cydir-save.c       |    1 
src/lib-storage/index/dbox/dbox-file-maildir.c |    7 ++
src/lib-storage/index/dbox/dbox-file.h         |    3 +
src/lib-storage/index/dbox/dbox-mail.c         |   67 ++++++++++++++----------
src/lib-storage/index/dbox/dbox-save.c         |   16 +++++
src/lib-storage/index/index-mail.c             |    2 
src/lib-storage/index/index-mail.h             |    1 
src/lib-storage/index/index-search.c           |    5 +
src/lib-storage/index/index-storage.c          |    6 ++
src/lib-storage/index/index-storage.h          |    1 
src/lib-storage/index/maildir/maildir-mail.c   |   12 ++--
src/lib-storage/index/maildir/maildir-save.c   |    1 
src/lib-storage/index/mbox/mbox-save.c         |    3 -
src/lib-storage/mail-copy.c                    |   12 ++--
src/lib-storage/mail-search-build.c            |    3 +
src/lib-storage/mail-search.h                  |    1 
src/lib-storage/mail-storage-private.h         |    3 -
src/lib-storage/mail-storage.c                 |   10 ++-
src/lib-storage/mail-storage.h                 |    7 ++
src/lib-storage/mail.c                         |   26 +++++++++

diffs (truncated from 539 to 300 lines):

diff -r bbfbc84f795c -r 6d51328896d6 src/imap/imap-fetch.c
--- a/src/imap/imap-fetch.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/imap/imap-fetch.c	Thu Aug 07 15:33:52 2008 -0400
@@ -22,7 +22,7 @@
 #define ENVELOPE_NIL_REPLY \
 	"(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)"
 
-#define IMAP_FETCH_HANDLER_COUNT 9
+#define IMAP_FETCH_HANDLER_COUNT 10
 extern const struct imap_fetch_handler
 	imap_fetch_default_handlers[IMAP_FETCH_HANDLER_COUNT];
 static buffer_t *fetch_handlers = NULL;
@@ -779,6 +779,27 @@ fetch_uid_init(struct imap_fetch_context
 	return TRUE;
 }
 
+static int fetch_guid(struct imap_fetch_context *ctx, struct mail *mail,
+		      void *context ATTR_UNUSED)
+{
+	const char *value;
+
+	if (mail_get_special(mail, MAIL_FETCH_GUID, &value) < 0)
+		return -1;
+
+	str_append(ctx->cur_str, "X-GUID ");
+	imap_quote_append_string(ctx->cur_str, value, FALSE);
+	return 1;
+}
+
+static bool
+fetch_guid_init(struct imap_fetch_context *ctx ATTR_UNUSED, const char *name,
+		const struct imap_arg **args ATTR_UNUSED)
+{
+	imap_fetch_add_handler(ctx, TRUE, FALSE, name, "", fetch_guid, NULL);
+	return TRUE;
+}
+
 static int fetch_x_mailbox(struct imap_fetch_context *ctx, struct mail *mail,
 			   void *context ATTR_UNUSED)
 {
@@ -811,5 +832,6 @@ imap_fetch_default_handlers[IMAP_FETCH_H
 	{ "MODSEQ", fetch_modseq_init },
 	{ "RFC822", fetch_rfc822_init },
 	{ "UID", fetch_uid_init },
+	{ "X-GUID", fetch_guid_init },
 	{ "X-MAILBOX", fetch_x_mailbox_init }
 };
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/cydir/cydir-save.c
--- a/src/lib-storage/index/cydir/cydir-save.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/cydir/cydir-save.c	Thu Aug 07 15:33:52 2008 -0400
@@ -216,6 +216,7 @@ int cydir_save_finish(struct mail_save_c
 				      _ctx->received_date, !ctx->failed);
 	i_stream_unref(&ctx->input);
 
+	index_save_context_free(_ctx);
 	return ctx->failed ? -1 : 0;
 }
 
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/dbox/dbox-file-maildir.c
--- a/src/lib-storage/index/dbox/dbox-file-maildir.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/dbox/dbox-file-maildir.c	Thu Aug 07 15:33:52 2008 -0400
@@ -40,12 +40,17 @@ const char *dbox_file_maildir_metadata_g
 {
 	struct stat st;
 	uoff_t size;
-	const char *value = NULL;
+	const char *p, *value = NULL;
 
 	switch (key) {
 	case DBOX_METADATA_FLAGS:
 	case DBOX_METADATA_KEYWORDS:
 		value = dbox_file_maildir_get_flags(file, key);
+		break;
+	case DBOX_METADATA_GUID:
+		p = strchr(file->fname, MAILDIR_INFO_SEP);
+		value = p == NULL ? file->fname :
+			t_strdup_until(file->fname, p);
 		break;
 	case DBOX_METADATA_RECEIVED_TIME:
 	case DBOX_METADATA_SAVE_TIME:
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/dbox/dbox-file.h
--- a/src/lib-storage/index/dbox/dbox-file.h	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/dbox/dbox-file.h	Thu Aug 07 15:33:52 2008 -0400
@@ -52,6 +52,9 @@ enum dbox_metadata_key {
 	/* Message flags in dbox_metadata_flags order. '0' = not set, anything
 	   else = set. Unknown flags should be preserved. */
 	DBOX_METADATA_FLAGS		= 'F',
+	/* Globally unique identifier for the message. Preserved when
+	   copying. */
+	DBOX_METADATA_GUID		= 'G',
 	/* Space separated list of keywords */
 	DBOX_METADATA_KEYWORDS		= 'K',
 	/* POP3 UIDL overriding the default format */
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/dbox/dbox-mail.c
--- a/src/lib-storage/index/dbox/dbox-mail.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/dbox/dbox-mail.c	Thu Aug 07 15:33:52 2008 -0400
@@ -178,39 +178,52 @@ static int dbox_mail_get_physical_size(s
 }
 
 static int
+dbox_get_cached_metadata(struct dbox_mail *mail, enum dbox_metadata_key key,
+			 enum index_cache_field cache_field,
+			 const char **value_r)
+{
+	struct index_mail *imail = &mail->imail;
+	const struct mail_cache_field *cache_fields = imail->ibox->cache_fields;
+	struct dbox_file *file;
+	const char *value;
+	string_t *str;
+
+	str = str_new(imail->data_pool, 64);
+	if (mail_cache_lookup_field(imail->trans->cache_view, str,
+				    imail->mail.mail.seq,
+				    cache_fields[cache_field].idx) > 0) {
+		*value_r = str_c(str);
+		return 0;
+	}
+
+	if (dbox_mail_metadata_seek(mail, &file) < 0)
+		return -1;
+
+	value = dbox_file_metadata_get(file, key);
+	if (value == NULL)
+		value = "";
+	index_mail_cache_add_idx(imail, cache_fields[cache_field].idx,
+				 value, strlen(value)+1);
+	*value_r = value;
+	return 0;
+}
+
+static int
 dbox_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
 		      const char **value_r)
 {
 	struct dbox_mail *mail = (struct dbox_mail *)_mail;
-	struct index_mail *imail = &mail->imail;
-	const unsigned int pop3_uidl_cache_field =
-		imail->ibox->cache_fields[MAIL_CACHE_POP3_UIDL].idx;
-	struct dbox_file *file;
-	const char *value;
-	string_t *str;
-
+
+	/* keep the UIDL in cache file, otherwise POP3 would open all
+	   mail files and read the metadata. same for GUIDs if they're
+	   used. */
 	switch (field) {
 	case MAIL_FETCH_UIDL_BACKEND:
-		/* keep the UIDL in cache file, otherwise POP3 would open all
-		   mail files and read the metadata */
-		str = str_new(imail->data_pool, 64);
-		if (mail_cache_lookup_field(imail->trans->cache_view, str,
-					    _mail->seq,
-					    pop3_uidl_cache_field) > 0) {
-			*value_r = str_c(str);
-			return 0;
-		}
-
-		if (dbox_mail_metadata_seek(mail, &file) < 0)
-			return -1;
-
-		value = dbox_file_metadata_get(file, DBOX_METADATA_POP3_UIDL);
-		if (value == NULL)
-			value = "";
-		index_mail_cache_add_idx(imail, pop3_uidl_cache_field,
-					 value, strlen(value)+1);
-		*value_r = value;
-		return 0;
+		return dbox_get_cached_metadata(mail, DBOX_METADATA_POP3_UIDL,
+						MAIL_CACHE_POP3_UIDL, value_r);
+	case MAIL_FETCH_GUID:
+		return dbox_get_cached_metadata(mail, DBOX_METADATA_GUID,
+						MAIL_CACHE_GUID, value_r);
 	default:
 		break;
 	}
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/dbox/dbox-save.c
--- a/src/lib-storage/index/dbox/dbox-save.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/dbox/dbox-save.c	Thu Aug 07 15:33:52 2008 -0400
@@ -178,6 +178,7 @@ static void dbox_save_write_metadata(str
 {
 	struct dbox_metadata_header metadata_hdr;
 	char space[DBOX_EXTRA_SPACE];
+	const char *guid;
 	string_t *str;
 	uoff_t vsize;
 
@@ -197,6 +198,10 @@ static void dbox_save_write_metadata(str
 	str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE,
 		    (unsigned long long)vsize);
 
+	guid = ctx->ctx.guid != NULL ? ctx->ctx.guid :
+		mail_generate_guid_string();
+	str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid);
+
 	/* flags */
 	str_append_c(str, DBOX_METADATA_FLAGS);
 	dbox_mail_metadata_flags_append(str, ctx->ctx.flags);
@@ -238,7 +243,7 @@ static int dbox_save_mail_write_header(s
 	return 0;
 }
 
-int dbox_save_finish(struct mail_save_context *_ctx)
+static int dbox_save_finish_write(struct mail_save_context *_ctx)
 {
 	struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
 	struct mail_storage *storage = &ctx->mbox->storage->storage;
@@ -288,6 +293,15 @@ int dbox_save_finish(struct mail_save_co
 		}
 		return 0;
 	}
+}
+
+int dbox_save_finish(struct mail_save_context *ctx)
+{
+	int ret;
+
+	ret = dbox_save_finish_write(ctx);
+	index_save_context_free(ctx);
+	return ret;
 }
 
 void dbox_save_cancel(struct mail_save_context *_ctx)
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/index-mail.c	Thu Aug 07 15:33:52 2008 -0400
@@ -33,6 +33,7 @@ struct mail_cache_field global_cache_fie
 	{ "imap.bodystructure", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
 	{ "imap.envelope", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
 	{ "pop3.uidl", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
+	{ "guid", 0, MAIL_CACHE_FIELD_STRING, 0, 0 },
 	{ "mime.parts", 0, MAIL_CACHE_FIELD_VARIABLE_SIZE, 0, 0 }
 };
 
@@ -1013,6 +1014,7 @@ int index_mail_get_special(struct mail *
 	case MAIL_FETCH_UIDL_FILE_NAME:
 	case MAIL_FETCH_UIDL_BACKEND:
 	case MAIL_FETCH_SEARCH_SCORE:
+	case MAIL_FETCH_GUID:
 		*value_r = "";
 		return 0;
 	case MAIL_FETCH_HEADER_MD5:
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/index-mail.h	Thu Aug 07 15:33:52 2008 -0400
@@ -19,6 +19,7 @@ enum index_cache_field {
 	MAIL_CACHE_IMAP_BODYSTRUCTURE,
 	MAIL_CACHE_IMAP_ENVELOPE,
 	MAIL_CACHE_POP3_UIDL,
+	MAIL_CACHE_GUID,
 	MAIL_CACHE_MESSAGE_PARTS,
 
 	MAIL_INDEX_CACHE_FIELD_COUNT
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/index-search.c
--- a/src/lib-storage/index/index-search.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/index-search.c	Thu Aug 07 15:33:52 2008 -0400
@@ -267,6 +267,10 @@ static int search_arg_match_cached(struc
 		else
 			return virtual_size > arg->value.size;
 
+	case SEARCH_GUID:
+		if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &str) < 0)
+			return -1;
+		return strcmp(str, arg->value.str) == 0;
 	case SEARCH_MAILBOX:
 		if (mail_get_special(ctx->mail, MAIL_FETCH_MAILBOX_NAME,
 				     &str) < 0)
@@ -1131,6 +1135,7 @@ static bool search_arg_is_static(struct 
 	case SEARCH_TEXT:
 	case SEARCH_BODY_FAST:
 	case SEARCH_TEXT_FAST:
+	case SEARCH_GUID:
 	case SEARCH_MAILBOX:
 		return TRUE;
 	}
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/index-storage.c	Thu Aug 07 15:33:52 2008 -0400
@@ -621,3 +621,9 @@ void index_keywords_free(struct mail_key
 {
 	mail_index_keywords_free(&keywords);
 }
+
+void index_save_context_free(struct mail_save_context *ctx)
+{
+	i_free_and_null(ctx->from_envelope);
+	i_free_and_null(ctx->guid);
+}
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h	Thu Aug 07 15:05:40 2008 -0400
+++ b/src/lib-storage/index/index-storage.h	Thu Aug 07 15:33:52 2008 -0400
@@ -189,6 +189,7 @@ int index_transaction_commit(struct mail
 			     uint32_t *first_saved_uid_r,
 			     uint32_t *last_saved_uid_r);
 void index_transaction_rollback(struct mailbox_transaction_context *t);
+void index_save_context_free(struct mail_save_context *ctx);
 
 bool index_keyword_array_cmp(const ARRAY_TYPE(keyword_indexes) *k1,
 			     const ARRAY_TYPE(keyword_indexes) *k2);
diff -r bbfbc84f795c -r 6d51328896d6 src/lib-storage/index/maildir/maildir-mail.c


More information about the dovecot-cvs mailing list