dovecot-2.0: Added pop3_save_uidl setting.

dovecot at dovecot.org dovecot at dovecot.org
Tue Sep 1 02:05:30 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/ecb05365f520
changeset: 9847:ecb05365f520
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 31 19:05:22 2009 -0400
description:
Added pop3_save_uidl setting.
When UIDLs are sent to client, save them to dovecot-uidlist. This allows
changing pop3_uidl_format without messages getting re-downloaded. It's also
useful with virtual POP3 INBOX when UIDLs are based on IMAP UIDs that may
not be as stable as in non-virtual INBOX.

diffstat:

13 files changed, 54 insertions(+), 4 deletions(-)
src/lib-storage/index/cydir/cydir-mail.c     |    1 +
src/lib-storage/index/dbox/dbox-mail.c       |    1 +
src/lib-storage/index/maildir/maildir-mail.c |   18 ++++++++++++++++++
src/lib-storage/index/mbox/mbox-mail.c       |    1 +
src/lib-storage/index/raw/raw-mail.c         |    1 +
src/lib-storage/mail-storage-private.h       |    1 +
src/lib-storage/mail-storage.h               |    2 ++
src/lib-storage/mail.c                       |    8 ++++++++
src/lib-storage/test-mail.c                  |    1 +
src/plugins/virtual/virtual-mail.c           |    8 ++++++++
src/pop3/pop3-commands.c                     |   13 +++++++++----
src/pop3/pop3-settings.c                     |    2 ++
src/pop3/pop3-settings.h                     |    1 +

diffs (242 lines):

diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/index/cydir/cydir-mail.c
--- a/src/lib-storage/index/cydir/cydir-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/index/cydir/cydir-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -145,6 +145,7 @@ struct mail_vfuncs cydir_mail_vfuncs = {
 	index_mail_update_keywords,
 	index_mail_update_modseq,
 	index_mail_update_uid,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/index/dbox/dbox-mail.c
--- a/src/lib-storage/index/dbox/dbox-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -416,6 +416,7 @@ struct mail_vfuncs dbox_mail_vfuncs = {
 	index_mail_update_keywords,
 	index_mail_update_modseq,
 	index_mail_update_uid,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -501,6 +501,23 @@ static void maildir_mail_update_uid(stru
 {
 	maildir_save_add_conflict(_mail->transaction, _mail->uid, new_uid);
 	index_mail_update_uid(_mail, new_uid);
+}
+
+static void maildir_update_pop3_uidl(struct mail *_mail, const char *uidl)
+{
+	struct maildir_mailbox *mbox = (struct maildir_mailbox *)_mail->box;
+	const char *fname;
+
+	if (maildir_mail_get_special(_mail, MAIL_FETCH_UIDL_FILE_NAME,
+				     &fname) == 0 &&
+	    strcmp(uidl, fname) == 0) {
+		/* special case optimization: empty UIDL means the same
+		   as base filename */
+		uidl = "";
+	}
+
+	maildir_uidlist_set_ext(mbox->uidlist, _mail->uid,
+				MAILDIR_UIDLIST_REC_EXT_POP3_UIDL, uidl);
 }
 
 static void maildir_mail_set_cache_corrupted(struct mail *_mail,
@@ -564,6 +581,7 @@ struct mail_vfuncs maildir_mail_vfuncs =
 	index_mail_update_keywords,
 	index_mail_update_modseq,
 	maildir_mail_update_uid,
+	maildir_update_pop3_uidl,
 	index_mail_expunge,
 	maildir_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/index/mbox/mbox-mail.c
--- a/src/lib-storage/index/mbox/mbox-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/index/mbox/mbox-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -375,6 +375,7 @@ struct mail_vfuncs mbox_mail_vfuncs = {
 	index_mail_update_keywords,
 	index_mail_update_modseq,
 	index_mail_update_uid,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/index/raw/raw-mail.c
--- a/src/lib-storage/index/raw/raw-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/index/raw/raw-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -136,6 +136,7 @@ struct mail_vfuncs raw_mail_vfuncs = {
 	index_mail_update_keywords,
 	index_mail_update_modseq,
 	index_mail_update_uid,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/mail-storage-private.h	Mon Aug 31 19:05:22 2009 -0400
@@ -296,6 +296,7 @@ struct mail_vfuncs {
 				struct mail_keywords *keywords);
 	void (*update_modseq)(struct mail *mail, uint64_t min_modseq);
 	void (*update_uid)(struct mail *mail, uint32_t new_uid);
+	void (*update_pop3_uidl)(struct mail *mail, const char *uidl);
 	void (*expunge)(struct mail *mail);
 	void (*set_cache_corrupted)(struct mail *mail,
 				    enum mail_fetch_field field);
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/mail-storage.h	Mon Aug 31 19:05:22 2009 -0400
@@ -657,6 +657,8 @@ void mail_update_modseq(struct mail *mai
 /* Update message's UID. The new UID must not be lower than next_uid at the
    commit time, otherwise the UID update fails and is just ignored. */
 void mail_update_uid(struct mail *mail, uint32_t new_uid);
+/* Update message's POP3 UIDL (if possible). */
+void mail_update_pop3_uidl(struct mail *mail, const char *uidl);
 /* Expunge this message. Sequence numbers don't change until commit. */
 void mail_expunge(struct mail *mail);
 /* Mark a cached field corrupted and have it recalculated. */
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/mail.c
--- a/src/lib-storage/mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -208,6 +208,14 @@ void mail_update_uid(struct mail *mail, 
 	struct mail_private *p = (struct mail_private *)mail;
 
 	p->v.update_uid(mail, new_uid);
+}
+
+void mail_update_pop3_uidl(struct mail *mail, const char *uidl)
+{
+	struct mail_private *p = (struct mail_private *)mail;
+
+	if (p->v.update_pop3_uidl != NULL)
+		p->v.update_pop3_uidl(mail, uidl);
 }
 
 void mail_expunge(struct mail *mail)
diff -r cf27080f3fcf -r ecb05365f520 src/lib-storage/test-mail.c
--- a/src/lib-storage/test-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/lib-storage/test-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -233,6 +233,7 @@ struct mail_vfuncs test_mail_vfuncs = {
 	test_mail_update_keywords,
 	test_mail_update_modseq,
 	test_mail_update_uid,
+	NULL,
 	test_mail_expunge,
 	test_mail_set_cache_corrupted,
 	test_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/plugins/virtual/virtual-mail.c
--- a/src/plugins/virtual/virtual-mail.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/plugins/virtual/virtual-mail.c	Mon Aug 31 19:05:22 2009 -0400
@@ -345,6 +345,13 @@ virtual_mail_get_special(struct mail *ma
 		return -1;
 	}
 	return 0;
+}
+
+static void virtual_mail_update_pop3_uidl(struct mail *mail, const char *uidl)
+{
+	struct virtual_mail *vmail = (struct virtual_mail *)mail;
+
+	mail_update_pop3_uidl(vmail->backend_mail, uidl);
 }
 
 static void virtual_mail_expunge(struct mail *mail)
@@ -399,6 +406,7 @@ struct mail_vfuncs virtual_mail_vfuncs =
 	index_mail_update_keywords,
 	index_mail_update_modseq,
 	index_mail_update_uid,
+	virtual_mail_update_pop3_uidl,
 	virtual_mail_expunge,
 	virtual_mail_set_cache_corrupted,
 	virtual_mail_get_index_mail
diff -r cf27080f3fcf -r ecb05365f520 src/pop3/pop3-commands.c
--- a/src/pop3/pop3-commands.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/pop3/pop3-commands.c	Mon Aug 31 19:05:22 2009 -0400
@@ -521,7 +521,7 @@ struct cmd_uidl_context {
 	unsigned int message;
 };
 
-static void pop3_get_uid(struct client *client, struct cmd_uidl_context *ctx,
+static bool pop3_get_uid(struct client *client, struct cmd_uidl_context *ctx,
 			 struct var_expand_table *tab, string_t *str)
 {
 	char uid_str[MAX_INT_STRLEN];
@@ -530,13 +530,13 @@ static void pop3_get_uid(struct client *
 	if (mail_get_special(ctx->mail, MAIL_FETCH_UIDL_BACKEND, &uidl) == 0 &&
 	    *uidl != '\0') {
 		str_append(str, uidl);
-		return;
+		return TRUE;
 	}
 
 	if (client->set->pop3_reuse_xuidl &&
 	    mail_get_first_header(ctx->mail, "X-UIDL", &uidl) > 0) {
 		str_append(str, uidl);
-		return;
+		return FALSE;
 	}
 
 	if ((client->uidl_keymask & UIDL_UID) != 0) {
@@ -562,6 +562,7 @@ static void pop3_get_uid(struct client *
 		}
 	}
 	var_expand(str, client->mail_set->pop3_uidl_format, tab);
+	return FALSE;
 }
 
 static bool list_uids_iter(struct client *client, struct cmd_uidl_context *ctx)
@@ -576,6 +577,7 @@ static bool list_uids_iter(struct client
 	struct var_expand_table *tab;
 	string_t *str;
 	int ret;
+	unsigned int uidl_pos;
 	bool found = FALSE;
 
 	tab = t_malloc(sizeof(static_tab));
@@ -595,7 +597,10 @@ static bool list_uids_iter(struct client
 		str_truncate(str, 0);
 		str_printfa(str, ctx->message == 0 ? "%u " : "+OK %u ",
 			    ctx->mail->seq);
-		pop3_get_uid(client, ctx, tab, str);
+		uidl_pos = str_len(str);
+		if (!pop3_get_uid(client, ctx, tab, str) &&
+		    client->set->pop3_save_uidl)
+			mail_update_pop3_uidl(ctx->mail, str_c(str) + uidl_pos);
 
 		ret = client_send_line(client, "%s", str_c(str));
 		if (ret < 0)
diff -r cf27080f3fcf -r ecb05365f520 src/pop3/pop3-settings.c
--- a/src/pop3/pop3-settings.c	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/pop3/pop3-settings.c	Mon Aug 31 19:05:22 2009 -0400
@@ -24,6 +24,7 @@ static struct setting_define pop3_settin
 	DEF(SET_BOOL, pop3_no_flag_updates),
 	DEF(SET_BOOL, pop3_enable_last),
 	DEF(SET_BOOL, pop3_reuse_xuidl),
+	DEF(SET_BOOL, pop3_save_uidl),
 	DEF(SET_BOOL, pop3_lock_session),
 	DEF(SET_STR, pop3_client_workarounds),
 	DEF(SET_STR, pop3_logout_format),
@@ -39,6 +40,7 @@ static struct pop3_settings pop3_default
 	MEMBER(pop3_no_flag_updates) FALSE,
 	MEMBER(pop3_enable_last) FALSE,
 	MEMBER(pop3_reuse_xuidl) FALSE,
+	MEMBER(pop3_save_uidl) FALSE,
 	MEMBER(pop3_lock_session) FALSE,
 	MEMBER(pop3_client_workarounds) "",
 	MEMBER(pop3_logout_format) "top=%t/%p, retr=%r/%b, del=%d/%m, size=%s"
diff -r cf27080f3fcf -r ecb05365f520 src/pop3/pop3-settings.h
--- a/src/pop3/pop3-settings.h	Mon Aug 31 17:21:37 2009 -0400
+++ b/src/pop3/pop3-settings.h	Mon Aug 31 19:05:22 2009 -0400
@@ -12,6 +12,7 @@ struct pop3_settings {
 	bool pop3_no_flag_updates;
 	bool pop3_enable_last;
 	bool pop3_reuse_xuidl;
+	bool pop3_save_uidl;
 	bool pop3_lock_session;
 	const char *pop3_client_workarounds;
 	const char *pop3_logout_format;


More information about the dovecot-cvs mailing list