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