dovecot-1.1: Added wildcard support to expire plugin. Added a ne...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Mar 4 06:28:08 EET 2008
details: http://hg.dovecot.org/dovecot-1.1/rev/969656b58e7f
changeset: 7335:969656b58e7f
user: Timo Sirainen <tss at iki.fi>
date: Tue Mar 04 06:26:24 2008 +0200
description:
Added wildcard support to expire plugin. Added a new expire_altmove setting
which moves mails to alt directory with dbox instead of expunging them. Both
settings can be used simultaneously. Added --test parameter to expire-tool.
Fixed several bugs and did some optimizations.
diffstat:
5 files changed, 248 insertions(+), 142 deletions(-)
src/plugins/expire/Makefile.am | 1
src/plugins/expire/expire-env.c | 83 ++++++++++++++---
src/plugins/expire/expire-env.h | 14 +-
src/plugins/expire/expire-plugin.c | 120 ++++++++++---------------
src/plugins/expire/expire-tool.c | 172 ++++++++++++++++++++++++++----------
diffs (truncated from 705 to 300 lines):
diff -r ae8180a4febd -r 969656b58e7f src/plugins/expire/Makefile.am
--- a/src/plugins/expire/Makefile.am Tue Mar 04 06:24:44 2008 +0200
+++ b/src/plugins/expire/Makefile.am Tue Mar 04 06:26:24 2008 +0200
@@ -4,6 +4,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-dict \
-I$(top_srcdir)/src/lib-mail \
+ -I$(top_srcdir)/src/lib-imap \
-I$(top_srcdir)/src/lib-index \
-I$(top_srcdir)/src/lib-storage \
-I$(top_srcdir)/src/lib-storage/index \
diff -r ae8180a4febd -r 969656b58e7f src/plugins/expire/expire-env.c
--- a/src/plugins/expire/expire-env.c Tue Mar 04 06:24:44 2008 +0200
+++ b/src/plugins/expire/expire-env.c Tue Mar 04 06:26:24 2008 +0200
@@ -2,42 +2,70 @@
#include "lib.h"
#include "array.h"
+#include "imap-match.h"
#include "expire-env.h"
#include <stdlib.h>
+
+enum expire_type {
+ EXPIRE_TYPE_EXPUNGE,
+ EXPIRE_TYPE_ALTMOVE
+};
+
+struct expire_box {
+ const char *pattern;
+ struct imap_match_glob *glob;
+
+ enum expire_type type;
+ unsigned int expire_secs;
+};
struct expire_env {
pool_t pool;
ARRAY_DEFINE(expire_boxes, struct expire_box);
};
-struct expire_env *expire_env_init(const char *str)
+static void expire_env_parse(struct expire_env *env, const char *str,
+ enum expire_type type)
{
- struct expire_env *env;
struct expire_box box;
- pool_t pool;
char *const *names;
unsigned int len;
- pool = pool_alloconly_create("Expire pool", 512);
- env = p_new(pool, struct expire_env, 1);
- env->pool = pool;
+ if (str == NULL)
+ return;
- names = p_strsplit(pool, str, " ");
+ names = p_strsplit(env->pool, str, " ");
len = str_array_length((const char *const *)names);
- p_array_init(&env->expire_boxes, pool, len / 2);
+ p_array_init(&env->expire_boxes, env->pool, len / 2);
for (; *names != NULL; names += 2) {
if (names[1] == NULL) {
i_fatal("expire: Missing expire days for mailbox '%s'",
*names);
}
- box.name = *names;
- box.expire_secs = strtoul(names[1], NULL, 10) * 3600 * 24;
+ box.pattern = *names;
+ /* FIXME: hardcoded separator isn't very good */
+ box.glob = imap_match_init(env->pool, box.pattern, TRUE, '/');
+ box.type = type;
+ box.expire_secs = strtoul(names[1], NULL, 10)/* * 3600 * 24*/ * 10;//FIXME
+
array_append(&env->expire_boxes, &box, 1);
}
+}
+struct expire_env *expire_env_init(const char *expunges, const char *altmoves)
+{
+ struct expire_env *env;
+ pool_t pool;
+
+ pool = pool_alloconly_create("Expire pool", 512);
+ 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);
return env;
}
@@ -46,16 +74,41 @@ void expire_env_deinit(struct expire_env
pool_unref(&env->pool);
}
-const struct expire_box *expire_box_find(struct expire_env *env,
- const char *name)
+bool expire_box_find(struct expire_env *env, const char *name,
+ unsigned int *expunge_secs_r,
+ unsigned int *altmove_secs_r)
{
const struct expire_box *expire_boxes;
unsigned int i, count;
+ unsigned int secs, expunge_min = 0, altmove_min = 0;
expire_boxes = array_get(&env->expire_boxes, &count);
for (i = 0; i < count; i++) {
- if (strcmp(name, expire_boxes[i].name) == 0)
- return &expire_boxes[i];
+ if (imap_match(expire_boxes[i].glob, name) == IMAP_MATCH_YES) {
+ secs = expire_boxes[i].expire_secs;
+ i_assert(secs > 0);
+
+ switch (expire_boxes[i].type) {
+ case EXPIRE_TYPE_EXPUNGE:
+ if (expunge_min == 0 || expunge_min > secs)
+ expunge_min = secs;
+ break;
+ case EXPIRE_TYPE_ALTMOVE:
+ if (altmove_min == 0 || altmove_min > secs)
+ altmove_min = secs;
+ break;
+ }
+ }
}
- return NULL;
+ *expunge_secs_r = expunge_min;
+ *altmove_secs_r = altmove_min;
+ return expunge_min > 0 || altmove_min > 0;
}
+
+unsigned int expire_box_find_min_secs(struct expire_env *env, const char *name)
+{
+ unsigned int secs1, secs2;
+
+ (void)expire_box_find(env, name, &secs1, &secs2);
+ return secs1 < secs2 && secs1 != 0 ? secs1 : secs2;
+}
diff -r ae8180a4febd -r 969656b58e7f src/plugins/expire/expire-env.h
--- a/src/plugins/expire/expire-env.h Tue Mar 04 06:24:44 2008 +0200
+++ b/src/plugins/expire/expire-env.h Tue Mar 04 06:26:24 2008 +0200
@@ -3,15 +3,13 @@
struct expire_env;
-struct expire_box {
- const char *name;
- time_t expire_secs;
-};
-
-struct expire_env *expire_env_init(const char *str);
+struct expire_env *expire_env_init(const char *expunges, const char *altmoves);
void expire_env_deinit(struct expire_env *env);
-const struct expire_box *expire_box_find(struct expire_env *env,
- const char *name);
+bool expire_box_find(struct expire_env *env, const char *name,
+ unsigned int *expunge_secs_r,
+ unsigned int *altmove_secs_r);
+
+unsigned int expire_box_find_min_secs(struct expire_env *env, const char *name);
#endif
diff -r ae8180a4febd -r 969656b58e7f src/plugins/expire/expire-plugin.c
--- a/src/plugins/expire/expire-plugin.c Tue Mar 04 06:24:44 2008 +0200
+++ b/src/plugins/expire/expire-plugin.c Tue Mar 04 06:26:24 2008 +0200
@@ -3,6 +3,7 @@
#include "lib.h"
#include "ioloop.h"
#include "array.h"
+#include "str.h"
#include "dict.h"
#include "mail-namespace.h"
#include "index-mail.h"
@@ -33,9 +34,7 @@ struct expire_transaction_context {
struct expire_transaction_context {
union mailbox_transaction_module_context module_ctx;
- struct mail *mail;
- time_t first_save_time;
-
+ unsigned int saves:1;
unsigned int first_expunged:1;
};
@@ -56,7 +55,6 @@ expire_mailbox_transaction_begin(struct
t = xpr_box->module_ctx.super.transaction_begin(box, flags);
xt = i_new(struct expire_transaction_context, 1);
- xt->mail = mail_alloc(t, 0, NULL);
MODULE_CONTEXT_SET(t, expire_storage_module, xt);
return t;
@@ -67,21 +65,26 @@ static void first_nonexpunged_timestamp(
{
struct index_transaction_context *t =
(struct index_transaction_context *)_t;
- struct expire_transaction_context *xt = EXPIRE_CONTEXT(_t);
struct mail_index_view *view = t->trans_view;
const struct mail_index_header *hdr;
+ struct mail *mail;
uint32_t seq;
+
+ mail = mail_alloc(_t, 0, NULL);
/* find the first non-expunged mail. we're here because the first
mail was expunged, so don't bother checking it. */
hdr = mail_index_get_header(view);
for (seq = 2; seq <= hdr->messages_count; seq++) {
if (!mail_index_is_expunged(view, seq)) {
- mail_set_seq(xt->mail, seq);
- if (mail_get_save_date(xt->mail, stamp_r) == 0)
+ mail_set_seq(mail, seq);
+ if (mail_get_save_date(mail, stamp_r) == 0) {
+ mail_free(&mail);
return;
+ }
}
}
+ mail_free(&mail);
/* everything expunged */
*stamp_r = 0;
@@ -106,7 +109,6 @@ expire_mailbox_transaction_commit(struct
update_dict = TRUE;
}
- mail_free(&xt->mail);
if (xpr_box->module_ctx.super.
transaction_commit(t, uid_validity_r,
first_saved_uid_r, last_saved_uid_r) < 0) {
@@ -114,27 +116,33 @@ expire_mailbox_transaction_commit(struct
return -1;
}
- T_BEGIN {
+ if (xt->first_expunged || xt->saves) T_BEGIN {
const char *key, *value;
key = t_strconcat(DICT_PATH_SHARED, expire.username, "/",
mailbox_name, NULL);
- if (!xt->first_expunged) {
+ if (!xt->first_expunged && xt->saves) {
/* saved new mails. dict needs to be updated only if
this is the first mail in the database */
ret = dict_lookup(expire.db, pool_datastack_create(),
key, &value);
update_dict = ret == 0 || strtoul(value, NULL, 10) == 0;
- new_stamp = xt->first_save_time;
+ /* may not be exactly the first message's save time
+ but a few second difference doesn't matter */
+ new_stamp = ioloop_time;
}
if (update_dict) {
struct dict_transaction_context *dctx;
- new_stamp += xpr_box->expire_secs;
-
dctx = dict_transaction_begin(expire.db);
- dict_set(dctx, key, dec2str(new_stamp));
+ if (new_stamp == 0) {
+ /* everything expunged */
+ dict_unset(dctx, key);
+ } else {
+ new_stamp += xpr_box->expire_secs;
+ dict_set(dctx, key, dec2str(new_stamp));
+ }
dict_transaction_commit(dctx);
}
} T_END;
@@ -148,8 +156,6 @@ expire_mailbox_transaction_rollback(stru
struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
- mail_free(&xt->mail);
-
xpr_box->module_ctx.super.transaction_rollback(t);
i_free(xt);
}
@@ -190,41 +196,14 @@ expire_mail_alloc(struct mailbox_transac
return _mail;
}
-static void
-mail_set_save_time(struct mailbox_transaction_context *t, uint32_t seq)
-{
- struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
- struct index_transaction_context *it =
- (struct index_transaction_context *)t;
-
- if (xt->first_save_time == 0)
- xt->first_save_time = ioloop_time;
-
- mail_cache_add(it->cache_trans, seq, MAIL_CACHE_SAVE_DATE,
- &ioloop_time, sizeof(ioloop_time));
More information about the dovecot-cvs
mailing list