dovecot-1.2: Added pop3_save_uidl setting.

dovecot at dovecot.org dovecot at dovecot.org
Tue Sep 1 01:53:29 EEST 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/3eacb6bbd227
changeset: 9348:3eacb6bbd227
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 31 18:53:17 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:

17 files changed, 60 insertions(+), 4 deletions(-)
dovecot-example.conf                         |    4 ++++
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               |    1 +
src/lib-storage/mail.c                       |    8 ++++++++
src/master/mail-process.c                    |    2 ++
src/master/master-settings-defs.c            |    1 +
src/master/master-settings.c                 |    1 +
src/master/master-settings.h                 |    1 +
src/plugins/virtual/virtual-mail.c           |    8 ++++++++
src/pop3/commands.c                          |   12 ++++++++----
src/pop3/common.h                            |    1 +
src/pop3/main.c                              |    2 ++

diffs (288 lines):

diff -r a37fa30b0072 -r 3eacb6bbd227 dovecot-example.conf
--- a/dovecot-example.conf	Fri Aug 28 16:50:20 2009 -0400
+++ b/dovecot-example.conf	Mon Aug 31 18:53:17 2009 -0400
@@ -658,6 +658,10 @@ protocol pop3 {
   # idea to change this. %08Xu%08Xv should be pretty fail-safe.
   #
   #pop3_uidl_format = %08Xu%08Xv
+
+  # Permanently save UIDLs sent to POP3 clients, so pop3_uidl_format changes
+  # won't change those UIDLs. Currently this works only with Maildir.
+  #pop3_save_uidl = no
 
   # POP3 logout format string:
   #  %i - total number of bytes read from client
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/index/cydir/cydir-mail.c
--- a/src/lib-storage/index/cydir/cydir-mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/index/cydir/cydir-mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -142,6 +142,7 @@ struct mail_vfuncs cydir_mail_vfuncs = {
 	index_mail_get_special,
 	index_mail_update_flags,
 	index_mail_update_keywords,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/index/dbox/dbox-mail.c
--- a/src/lib-storage/index/dbox/dbox-mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/index/dbox/dbox-mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -304,6 +304,7 @@ struct mail_vfuncs dbox_mail_vfuncs = {
 	dbox_mail_get_special,
 	index_mail_update_flags,
 	index_mail_update_keywords,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/index/maildir/maildir-mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -489,6 +489,23 @@ static int maildir_mail_get_stream(struc
 	}
 
 	return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
+}
+
+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,
@@ -549,6 +566,7 @@ struct mail_vfuncs maildir_mail_vfuncs =
 	maildir_mail_get_special,
 	index_mail_update_flags,
 	index_mail_update_keywords,
+	maildir_update_pop3_uidl,
 	index_mail_expunge,
 	maildir_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/index/mbox/mbox-mail.c
--- a/src/lib-storage/index/mbox/mbox-mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/index/mbox/mbox-mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -363,6 +363,7 @@ struct mail_vfuncs mbox_mail_vfuncs = {
 	mbox_mail_get_special,
 	index_mail_update_flags,
 	index_mail_update_keywords,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/index/raw/raw-mail.c
--- a/src/lib-storage/index/raw/raw-mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/index/raw/raw-mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -134,6 +134,7 @@ struct mail_vfuncs raw_mail_vfuncs = {
 	raw_mail_get_special,
 	index_mail_update_flags,
 	index_mail_update_keywords,
+	NULL,
 	index_mail_expunge,
 	index_mail_set_cache_corrupted,
 	index_mail_get_index_mail
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/mail-storage-private.h	Mon Aug 31 18:53:17 2009 -0400
@@ -264,6 +264,7 @@ struct mail_vfuncs {
 			     enum mail_flags flags);
 	void (*update_keywords)(struct mail *mail, enum modify_type modify_type,
 				struct mail_keywords *keywords);
+	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 a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/mail-storage.h	Mon Aug 31 18:53:17 2009 -0400
@@ -623,6 +623,7 @@ void mail_update_flags(struct mail *mail
 /* Update message keywords. */
 void mail_update_keywords(struct mail *mail, enum modify_type modify_type,
 			  struct mail_keywords *keywords);
+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);
diff -r a37fa30b0072 -r 3eacb6bbd227 src/lib-storage/mail.c
--- a/src/lib-storage/mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/lib-storage/mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -190,6 +190,14 @@ void mail_update_keywords(struct mail *m
 	struct mail_private *p = (struct mail_private *)mail;
 
 	p->v.update_keywords(mail, modify_type, keywords);
+}
+
+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 a37fa30b0072 -r 3eacb6bbd227 src/master/mail-process.c
--- a/src/master/mail-process.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/master/mail-process.c	Mon Aug 31 18:53:17 2009 -0400
@@ -359,6 +359,8 @@ mail_process_set_environment(struct sett
 			env_put("POP3_NO_FLAG_UPDATES=1");
 		if (set->pop3_reuse_xuidl)
 			env_put("POP3_REUSE_XUIDL=1");
+		if (set->pop3_save_uidl)
+			env_put("POP3_SAVE_UIDL=1");
 		if (set->pop3_enable_last)
 			env_put("POP3_ENABLE_LAST=1");
 		if (set->pop3_lock_session)
diff -r a37fa30b0072 -r 3eacb6bbd227 src/master/master-settings-defs.c
--- a/src/master/master-settings-defs.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/master/master-settings-defs.c	Mon Aug 31 18:53:17 2009 -0400
@@ -121,6 +121,7 @@ static struct setting_def setting_defs[]
 	DEF_BOOL(pop3_no_flag_updates),
 	DEF_BOOL(pop3_enable_last),
 	DEF_BOOL(pop3_reuse_xuidl),
+	DEF_BOOL(pop3_save_uidl),
 	DEF_BOOL(pop3_lock_session),
 	DEF_STR(pop3_uidl_format),
 	DEF_STR(pop3_client_workarounds),
diff -r a37fa30b0072 -r 3eacb6bbd227 src/master/master-settings.c
--- a/src/master/master-settings.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/master/master-settings.c	Mon Aug 31 18:53:17 2009 -0400
@@ -287,6 +287,7 @@ struct settings default_settings = {
 	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_uidl_format) "%08Xu%08Xv",
 	MEMBER(pop3_client_workarounds) "",
diff -r a37fa30b0072 -r 3eacb6bbd227 src/master/master-settings.h
--- a/src/master/master-settings.h	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/master/master-settings.h	Mon Aug 31 18:53:17 2009 -0400
@@ -133,6 +133,7 @@ struct 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_uidl_format;
 	const char *pop3_client_workarounds;
diff -r a37fa30b0072 -r 3eacb6bbd227 src/plugins/virtual/virtual-mail.c
--- a/src/plugins/virtual/virtual-mail.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/plugins/virtual/virtual-mail.c	Mon Aug 31 18:53:17 2009 -0400
@@ -341,6 +341,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)
@@ -392,6 +399,7 @@ struct mail_vfuncs virtual_mail_vfuncs =
 	virtual_mail_get_special,
 	index_mail_update_flags,
 	index_mail_update_keywords,
+	virtual_mail_update_pop3_uidl,
 	virtual_mail_expunge,
 	virtual_mail_set_cache_corrupted,
 	virtual_mail_get_index_mail
diff -r a37fa30b0072 -r 3eacb6bbd227 src/pop3/commands.c
--- a/src/pop3/commands.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/pop3/commands.c	Mon Aug 31 18:53:17 2009 -0400
@@ -519,7 +519,7 @@ struct cmd_uidl_context {
 	unsigned int message;
 };
 
-static void pop3_get_uid(struct cmd_uidl_context *ctx,
+static bool pop3_get_uid(struct cmd_uidl_context *ctx,
 			 struct var_expand_table *tab, string_t *str)
 {
 	char uid_str[MAX_INT_STRLEN];
@@ -528,13 +528,13 @@ static void pop3_get_uid(struct cmd_uidl
 	if (mail_get_special(ctx->mail, MAIL_FETCH_UIDL_BACKEND, &uidl) == 0 &&
 	    *uidl != '\0') {
 		str_append(str, uidl);
-		return;
+		return TRUE;
 	}
 
 	if (reuse_xuidl &&
 	    mail_get_first_header(ctx->mail, "X-UIDL", &uidl) > 0) {
 		str_append(str, uidl);
-		return;
+		return FALSE;
 	}
 
 	if ((uidl_keymask & UIDL_UID) != 0) {
@@ -560,6 +560,7 @@ static void pop3_get_uid(struct cmd_uidl
 		}
 	}
 	var_expand(str, uidl_format, tab);
+	return FALSE;
 }
 
 static bool list_uids_iter(struct client *client, struct cmd_uidl_context *ctx)
@@ -574,6 +575,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));
@@ -593,7 +595,9 @@ 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(ctx, tab, str);
+		uidl_pos = str_len(str);
+		if (!pop3_get_uid(ctx, tab, str) && 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 a37fa30b0072 -r 3eacb6bbd227 src/pop3/common.h
--- a/src/pop3/common.h	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/pop3/common.h	Mon Aug 31 18:53:17 2009 -0400
@@ -19,6 +19,7 @@ extern struct ioloop *ioloop;
 extern struct ioloop *ioloop;
 extern enum client_workarounds client_workarounds;
 extern bool enable_last_command, no_flag_updates, reuse_xuidl, lock_session;
+extern bool save_uidl;
 extern const char *uidl_format, *logout_format;
 extern enum uidl_keys uidl_keymask;
 
diff -r a37fa30b0072 -r 3eacb6bbd227 src/pop3/main.c
--- a/src/pop3/main.c	Fri Aug 28 16:50:20 2009 -0400
+++ b/src/pop3/main.c	Mon Aug 31 18:53:17 2009 -0400
@@ -48,6 +48,7 @@ bool enable_last_command = FALSE;
 bool enable_last_command = FALSE;
 bool no_flag_updates = FALSE;
 bool reuse_xuidl = FALSE;
+bool save_uidl = FALSE;
 bool lock_session = FALSE;
 const char *uidl_format, *logout_format;
 enum uidl_keys uidl_keymask;
@@ -235,6 +236,7 @@ static bool main_init(void)
 	enable_last_command = getenv("POP3_ENABLE_LAST") != NULL;
 	no_flag_updates = getenv("POP3_NO_FLAG_UPDATES") != NULL;
 	reuse_xuidl = getenv("POP3_REUSE_XUIDL") != NULL;
+	save_uidl = getenv("POP3_SAVE_UIDL") != NULL;
 	lock_session = getenv("POP3_LOCK_SESSION") != NULL;
 
 	uidl_format = getenv("POP3_UIDL_FORMAT");


More information about the dovecot-cvs mailing list