dovecot-2.0: expire: Support per-user expire configuration.

dovecot at dovecot.org dovecot at dovecot.org
Tue Jul 7 21:19:12 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/1cf278c2fd63
changeset: 9563:1cf278c2fd63
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jul 07 14:19:05 2009 -0400
description:
expire: Support per-user expire configuration.

diffstat:

4 files changed, 110 insertions(+), 78 deletions(-)
src/plugins/expire/expire-env.c    |   31 ++++++--
src/plugins/expire/expire-env.h    |    6 +
src/plugins/expire/expire-plugin.c |   23 +++---
src/plugins/expire/expire-tool.c   |  128 +++++++++++++++++++-----------------

diffs (truncated from 386 to 300 lines):

diff -r 90f8e2d091b5 -r 1cf278c2fd63 src/plugins/expire/expire-env.c
--- a/src/plugins/expire/expire-env.c	Tue Jul 07 13:25:01 2009 -0400
+++ b/src/plugins/expire/expire-env.c	Tue Jul 07 14:19:05 2009 -0400
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "array.h"
 #include "imap-match.h"
+#include "mail-namespace.h"
 #include "expire-env.h"
 
 #include <stdlib.h>
@@ -25,11 +26,14 @@ struct expire_env {
 	ARRAY_DEFINE(expire_boxes, struct expire_box);
 };
 
-static void expire_env_parse(struct expire_env *env, const char *str,
-			     enum expire_type type)
+static void
+expire_env_parse(struct expire_env *env, struct mail_namespace *namespaces,
+		 const char *str, enum expire_type type)
 {
 	struct expire_box box;
+	struct mail_namespace *ns;
 	char *const *names;
+	const char *ns_name;
 	unsigned int len;
 
 	if (str == NULL)
@@ -46,8 +50,15 @@ static void expire_env_parse(struct expi
 		}
 
 		box.pattern = *names;
-		/* FIXME: hardcoded separator isn't very good */
-		box.glob = imap_match_init(env->pool, box.pattern, TRUE, '/');
+		ns_name = *names;
+		ns = mail_namespace_find(namespaces, &ns_name);
+		if (ns == NULL && *box.pattern != '*') {
+			i_warning("expire: No namespace found for mailbox: %s",
+				  box.pattern);
+		}
+
+		box.glob = imap_match_init(env->pool, box.pattern, TRUE,
+					   ns == NULL ? '/' : ns->sep);
 		box.type = type;
 		box.expire_secs = strtoul(names[1], NULL, 10) * 3600 * 24;
 
@@ -55,7 +66,8 @@ static void expire_env_parse(struct expi
 	}
 }
 
-struct expire_env *expire_env_init(const char *expunges, const char *altmoves)
+struct expire_env *expire_env_init(struct mail_namespace *namespaces,
+				   const char *expunges, const char *altmoves)
 {
 	struct expire_env *env;
 	pool_t pool;
@@ -64,13 +76,16 @@ struct expire_env *expire_env_init(const
 	env = p_new(pool, struct expire_env, 1);
 	env->pool = pool;
 
-	expire_env_parse(env, expunges, EXPIRE_TYPE_EXPUNGE);
-	expire_env_parse(env, altmoves, EXPIRE_TYPE_ALTMOVE);
+	expire_env_parse(env, namespaces, expunges, EXPIRE_TYPE_EXPUNGE);
+	expire_env_parse(env, namespaces, altmoves, EXPIRE_TYPE_ALTMOVE);
 	return env;
 }
 
-void expire_env_deinit(struct expire_env *env)
+void expire_env_deinit(struct expire_env **_env)
 {
+	struct expire_env *env = *_env;
+
+	*_env = NULL;
 	pool_unref(&env->pool);
 }
 
diff -r 90f8e2d091b5 -r 1cf278c2fd63 src/plugins/expire/expire-env.h
--- a/src/plugins/expire/expire-env.h	Tue Jul 07 13:25:01 2009 -0400
+++ b/src/plugins/expire/expire-env.h	Tue Jul 07 14:19:05 2009 -0400
@@ -4,9 +4,11 @@
 #define DICT_EXPIRE_PREFIX DICT_PATH_SHARED"expire/"
 
 struct expire_env;
+struct mail_namespace;
 
-struct expire_env *expire_env_init(const char *expunges, const char *altmoves);
-void expire_env_deinit(struct expire_env *env);
+struct expire_env *expire_env_init(struct mail_namespace *namespaces,
+				   const char *expunges, const char *altmoves);
+void expire_env_deinit(struct expire_env **env);
 
 bool expire_box_find(struct expire_env *env, const char *name,
 		     unsigned int *expunge_secs_r,
diff -r 90f8e2d091b5 -r 1cf278c2fd63 src/plugins/expire/expire-plugin.c
--- a/src/plugins/expire/expire-plugin.c	Tue Jul 07 13:25:01 2009 -0400
+++ b/src/plugins/expire/expire-plugin.c	Tue Jul 07 14:19:05 2009 -0400
@@ -44,7 +44,7 @@ const char *expire_plugin_version = PACK
 const char *expire_plugin_version = PACKAGE_VERSION;
 
 static void (*next_hook_mailbox_allocated)(struct mailbox *box);
-static void (*next_hook_mail_user_created)(struct mail_user *user);
+static void (*next_hook_mail_namespaces_created)(struct mail_namespace *ns);
 
 static MODULE_CONTEXT_DEFINE_INIT(expire_storage_module,
 				  &mail_storage_module_register);
@@ -282,13 +282,14 @@ static void expire_mail_user_deinit(stru
 	struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(user);
 
 	dict_deinit(&euser->db);
-	expire_env_deinit(euser->env);
+	expire_env_deinit(&euser->env);
 
 	euser->module_ctx.super.deinit(user);
 }
 
-static void expire_mail_user_created(struct mail_user *user)
-{
+static void expire_mail_namespaces_created(struct mail_namespace *ns)
+{
+	struct mail_user *user = ns->user;
 	struct expire_mail_user *euser;
 	const char *expunge_env, *altmove_env, *dict_uri, *service_name;
 
@@ -310,7 +311,7 @@ static void expire_mail_user_created(str
 		euser->module_ctx.super = user->v;
 		user->v.deinit = expire_mail_user_deinit;
 
-		euser->env = expire_env_init(expunge_env, altmove_env);
+		euser->env = expire_env_init(ns, expunge_env, altmove_env);
 		/* we're using only shared dictionary, the username
 		   doesn't matter. */
 		euser->db = dict_init(dict_uri, DICT_DATA_TYPE_UINT32, "",
@@ -321,8 +322,8 @@ static void expire_mail_user_created(str
 			MODULE_CONTEXT_SET(user, expire_mail_user_module, euser);
 	}
 
-	if (next_hook_mail_user_created != NULL)
-		next_hook_mail_user_created(user);
+	if (next_hook_mail_namespaces_created != NULL)
+		next_hook_mail_namespaces_created(ns);
 }
 
 void expire_plugin_init(void)
@@ -330,12 +331,12 @@ void expire_plugin_init(void)
 	next_hook_mailbox_allocated = hook_mailbox_allocated;
 	hook_mailbox_allocated = expire_mailbox_allocated;
 
-	next_hook_mail_user_created = hook_mail_user_created;
-	hook_mail_user_created = expire_mail_user_created;
+	next_hook_mail_namespaces_created = hook_mail_namespaces_created;
+	hook_mail_namespaces_created = expire_mail_namespaces_created;
 }
 
 void expire_plugin_deinit(void)
 {
 	hook_mailbox_allocated = next_hook_mailbox_allocated;
-	hook_mail_user_created = next_hook_mail_user_created;
-}
+	hook_mail_namespaces_created = next_hook_mail_namespaces_created;
+}
diff -r 90f8e2d091b5 -r 1cf278c2fd63 src/plugins/expire/expire-tool.c
--- a/src/plugins/expire/expire-tool.c	Tue Jul 07 13:25:01 2009 -0400
+++ b/src/plugins/expire/expire-tool.c	Tue Jul 07 14:19:05 2009 -0400
@@ -20,17 +20,59 @@ struct expire_context {
 	pool_t multi_user_pool;
 	struct mail_storage_service_multi_ctx *multi;
 	struct mail_user *mail_user;
+	struct expire_env *env;
 	bool testrun;
 };
 
+static int expire_init_user(struct expire_context *ctx, const char *user)
+{
+	struct mail_storage_service_input input;
+	struct mail_storage_service_multi_user *multi_user;
+	const char *expire, *expire_altmove, *errstr;
+	int ret;
+
+	i_set_failure_prefix(t_strdup_printf("expire-tool(%s): ", user));
+
+	memset(&input, 0, sizeof(input));
+	input.username = user;
+
+	p_clear(ctx->multi_user_pool);
+	ret = mail_storage_service_multi_lookup(ctx->multi, &input,
+						ctx->multi_user_pool,
+						&multi_user, &errstr);
+	if (ret <= 0) {
+		if (ret < 0 || ctx->testrun)
+			i_error("User lookup failed: %s", errstr);
+		return ret;
+	}
+	ret = mail_storage_service_multi_next(ctx->multi, multi_user,
+					      &ctx->mail_user, &errstr);
+	if (ret < 0) {
+		i_error("User init failed: %s", errstr);
+		return ret;
+	}
+
+	expire = mail_user_set_plugin_getenv(ctx->mail_user->set, "expire");
+	expire_altmove = mail_user_set_plugin_getenv(ctx->mail_user->set, 
+						     "expire_altmove");
+	if (expire == NULL && expire_altmove == NULL)
+		i_fatal("expire and expire_altmove settings not set");
+
+	ctx->env = expire_env_init(ctx->mail_user->namespaces,
+				   expire, expire_altmove);
+	return 1;
+}
+
+static void expire_deinit_user(struct expire_context *ctx)
+{
+	mail_user_unref(&ctx->mail_user);
+	expire_env_deinit(&ctx->env);
+}
+
 static int
 mailbox_delete_old_mails(struct expire_context *ctx, const char *user,
-			 const char *mailbox,
-			 unsigned int expunge_secs, unsigned int altmove_secs,
-			 time_t *oldest_r)
-{
-	struct mail_storage_service_input input;
-	struct mail_storage_service_multi_user *multi_user;
+			 const char *mailbox, time_t *next_expire_r)
+{
 	struct mail_namespace *ns;
 	struct mailbox *box;
 	struct mail_search_context *search_ctx;
@@ -38,37 +80,29 @@ mailbox_delete_old_mails(struct expire_c
 	struct mail_search_args *search_args;
 	struct mail *mail;
 	const char *ns_mailbox, *errstr;
+	unsigned int expunge_secs, altmove_secs;
 	time_t now, save_time;
 	enum mail_error error;
 	enum mail_flags flags;
 	int ret;
 
-	memset(&input, 0, sizeof(input));
-	input.username = user;
-
-	*oldest_r = 0;
+	*next_expire_r = 0;
 
 	if (ctx->mail_user != NULL &&
 	    strcmp(user, ctx->mail_user->username) != 0)
-		mail_user_unref(&ctx->mail_user);
+		expire_deinit_user(ctx);
 	if (ctx->mail_user == NULL) {
-		i_set_failure_prefix(t_strdup_printf("expire-tool(%s): ",
-						     user));
-		p_clear(ctx->multi_user_pool);
-		ret = mail_storage_service_multi_lookup(ctx->multi, &input,
-							ctx->multi_user_pool,
-							&multi_user, &errstr);
-		if (ret <= 0) {
-			if (ret < 0 || ctx->testrun)
-				i_error("User lookup failed: %s", errstr);
+		if ((ret = expire_init_user(ctx, user)) <= 0)
 			return ret;
-		}
-		ret = mail_storage_service_multi_next(ctx->multi, multi_user,
-						      &ctx->mail_user, &errstr);
-		if (ret < 0) {
-			i_error("User init failed: %s", errstr);
-			return ret;
-		}
+	}
+
+	if (!expire_box_find(ctx->env, mailbox, &expunge_secs, &altmove_secs)) {
+		/* we're no longer expunging old messages from here */
+		if (ctx->testrun) {
+			i_info("%s: mailbox '%s' removed from config",
+			       user, mailbox);
+		}
+		return 0;
 	}
 
 	ns_mailbox = mailbox;
@@ -140,7 +174,9 @@ mailbox_delete_old_mails(struct expire_c
 			}
 		} else {
 			/* first non-expired one. */
-			*oldest_r = save_time;
+			*next_expire_r = save_time +
+				(altmove_secs != 0 ?
+				 altmove_secs : expunge_secs);
 			break;
 		}
 	}
@@ -170,10 +206,8 @@ static void expire_run(struct master_ser
 	void **sets;
 	struct dict_transaction_context *trans;
 	struct dict_iterate_context *iter;
-	struct expire_env *env;
-	time_t oldest, expire_time;
-	unsigned int expunge_secs, altmove_secs;
-	const char *p, *key, *value, *expire, *expire_altmove, *expire_dict;
+	time_t next_expire, expire_time;


More information about the dovecot-cvs mailing list