expire-plugin.c revision af847e72564a35f75171b69d291375fdb4846673
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "lib.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "ioloop.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "array.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "str.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "dict.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "mail-namespace.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "index-mail.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "index-storage.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "expire-env.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include "expire-plugin.h"
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#include <stdlib.h>
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define EXPIRE_CONTEXT(obj) \
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen MODULE_CONTEXT(obj, expire_storage_module)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#define EXPIRE_MAIL_CONTEXT(obj) \
6e54fd2bedbbc0c6316eae8fb569eb9a96aa29abTimo Sirainen MODULE_CONTEXT(obj, expire_mail_module)
6e54fd2bedbbc0c6316eae8fb569eb9a96aa29abTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct expire {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct dict *db;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct expire_env *env;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *username;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen void (*next_hook_mail_storage_created)(struct mail_storage *storage);
009217abb57a24a4076092e8e4e165545747839eStephan Bosch};
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct expire_mailbox {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen union mailbox_module_context module_ctx;
85601125c9cae82957a57f7b02409c567a59300eTimo Sirainen time_t expire_secs;
85601125c9cae82957a57f7b02409c567a59300eTimo Sirainen unsigned int altmove:1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen};
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstruct expire_transaction_context {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen union mailbox_transaction_module_context module_ctx;
b7650f081ff781c39fe00a3b93375e5f2dd14236Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int saves:1;
bd4bbe6478a97e3fab77b05257dd1397c7c090eaTimo Sirainen unsigned int first_expunged:1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen};
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenconst char *expire_plugin_version = PACKAGE_VERSION;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct expire expire;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(expire_storage_module,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen &mail_storage_module_register);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic MODULE_CONTEXT_DEFINE_INIT(expire_mail_module, &mail_module_register);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic struct mailbox_transaction_context *
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenexpire_mailbox_transaction_begin(struct mailbox *box,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen enum mailbox_transaction_flags flags)
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen{
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(box);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct mailbox_transaction_context *t;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct expire_transaction_context *xt;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen t = xpr_box->module_ctx.super.transaction_begin(box, flags);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen xt = i_new(struct expire_transaction_context, 1);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen MODULE_CONTEXT_SET(t, expire_storage_module, xt);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen return t;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen}
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic void first_nonexpunged_timestamp(struct mailbox_transaction_context *_t,
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen time_t *stamp_r)
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen{
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct index_transaction_context *t =
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen (struct index_transaction_context *)_t;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct mail_index_view *view = t->trans_view;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen const struct mail_index_header *hdr;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen struct mail *mail;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen uint32_t seq;
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen mail = mail_alloc(_t, 0, NULL);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen /* find the first non-expunged mail. we're here because the first
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen mail was expunged, so don't bother checking it. */
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen hdr = mail_index_get_header(view);
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen for (seq = 2; seq <= hdr->messages_count; seq++) {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen if (!mail_index_is_expunged(view, seq)) {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen mail_set_seq(mail, seq);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (mail_get_save_date(mail, stamp_r) == 0)
b7650f081ff781c39fe00a3b93375e5f2dd14236Timo Sirainen break;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen mail_free(&mail);
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen if (seq > hdr->messages_count) {
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen /* everything expunged */
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen *stamp_r = 0;
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen }
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen}
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainen
ce28adabf2c47d3af9ef197787cdb5139424c69cTimo Sirainenstatic int
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenexpire_mailbox_transaction_commit(struct mailbox_transaction_context *t,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen uint32_t *uid_validity_r,
009217abb57a24a4076092e8e4e165545747839eStephan Bosch uint32_t *first_saved_uid_r,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen uint32_t *last_saved_uid_r)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen time_t new_stamp;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen bool update_dict = FALSE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen int ret;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (xpr_box->altmove) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* only moving mails - don't update the move stamps */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } else if (xt->first_expunged) {
009217abb57a24a4076092e8e4e165545747839eStephan Bosch /* first mail expunged. dict needs updating. */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen first_nonexpunged_timestamp(t, &new_stamp);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen update_dict = TRUE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (xpr_box->module_ctx.super.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen transaction_commit(t, uid_validity_r,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen first_saved_uid_r, last_saved_uid_r) < 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_free(xt);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return -1;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (xt->first_expunged || xt->saves) T_BEGIN {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen const char *key, *value;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen key = t_strconcat(DICT_EXPIRE_PREFIX, expire.username, "/",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen t->box->storage->ns->prefix,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen t->box->name, NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (!xt->first_expunged && xt->saves) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* saved new mails. dict needs to be updated only if
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen this is the first mail in the database */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ret = dict_lookup(expire.db, pool_datastack_create(),
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen key, &value);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen update_dict = ret == 0 ||
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen (ret > 0 && strtoul(value, NULL, 10) == 0);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* may not be exactly the first message's save time
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen but a few second difference doesn't matter */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen new_stamp = ioloop_time;
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen }
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen if (update_dict) {
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen struct dict_transaction_context *dctx;
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen dctx = dict_transaction_begin(expire.db);
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen if (new_stamp == 0) {
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen /* everything expunged */
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen dict_unset(dctx, key);
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen } else {
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen new_stamp += xpr_box->expire_secs;
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen dict_set(dctx, key, dec2str(new_stamp));
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen }
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen dict_transaction_commit(&dctx);
1055d8038122c4f4190d37d98fdff6791d1306f8Timo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen } T_END;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_free(xt);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return 0;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
009217abb57a24a4076092e8e4e165545747839eStephan Boschstatic void
009217abb57a24a4076092e8e4e165545747839eStephan Boschexpire_mailbox_transaction_rollback(struct mailbox_transaction_context *t)
7c925149e49f7cce41c90d562ff3835b66ddca29Timo Sirainen{
7c925149e49f7cce41c90d562ff3835b66ddca29Timo Sirainen struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
7c925149e49f7cce41c90d562ff3835b66ddca29Timo Sirainen struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen xpr_box->module_ctx.super.transaction_rollback(t);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_free(xt);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
85601125c9cae82957a57f7b02409c567a59300eTimo Sirainen
85601125c9cae82957a57f7b02409c567a59300eTimo Sirainenstatic void expire_mail_expunge(struct mail *_mail)
85601125c9cae82957a57f7b02409c567a59300eTimo Sirainen{
85601125c9cae82957a57f7b02409c567a59300eTimo Sirainen struct mail_private *mail = (struct mail_private *)_mail;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen union mail_module_context *xpr_mail = EXPIRE_MAIL_CONTEXT(mail);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct expire_transaction_context *xt =
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen EXPIRE_CONTEXT(_mail->transaction);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (_mail->seq == 1) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* first mail expunged, database needs to be updated */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen xt->first_expunged = TRUE;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen }
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen xpr_mail->super.expunge(_mail);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen}
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic struct mail *
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenexpire_mail_alloc(struct mailbox_transaction_context *t,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen enum mail_fetch_field wanted_fields,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mailbox_header_lookup_ctx *wanted_headers)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen{
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen union mail_module_context *xpr_mail;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail *_mail;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen struct mail_private *mail;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen _mail = xpr_box->module_ctx.super.
mail_alloc(t, wanted_fields, wanted_headers);
mail = (struct mail_private *)_mail;
xpr_mail = p_new(mail->pool, union mail_module_context, 1);
xpr_mail->super = mail->v;
mail->v.expunge = expire_mail_expunge;
MODULE_CONTEXT_SET_SELF(mail, expire_mail_module, xpr_mail);
return _mail;
}
static int expire_save_finish(struct mail_save_context *ctx)
{
struct expire_transaction_context *xt =
EXPIRE_CONTEXT(ctx->transaction);
struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(ctx->transaction->box);
xt->saves = TRUE;
return xpr_box->module_ctx.super.save_finish(ctx);
}
static int
expire_copy(struct mailbox_transaction_context *t, struct mail *mail,
enum mail_flags flags, struct mail_keywords *keywords,
struct mail *dest_mail)
{
struct expire_transaction_context *xt = EXPIRE_CONTEXT(t);
struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
xt->saves = TRUE;
return xpr_box->module_ctx.super.
copy(t, mail, flags, keywords, dest_mail);
}
static void
mailbox_expire_hook(struct mailbox *box, time_t expire_secs, bool altmove)
{
struct expire_mailbox *xpr_box;
xpr_box = p_new(box->pool, struct expire_mailbox, 1);
xpr_box->module_ctx.super = box->v;
box->v.transaction_begin = expire_mailbox_transaction_begin;
box->v.transaction_commit = expire_mailbox_transaction_commit;
box->v.transaction_rollback = expire_mailbox_transaction_rollback;
box->v.mail_alloc = expire_mail_alloc;
box->v.save_finish = expire_save_finish;
box->v.copy = expire_copy;
xpr_box->altmove = altmove;
xpr_box->expire_secs = expire_secs;
MODULE_CONTEXT_SET(box, expire_storage_module, xpr_box);
}
static struct mailbox *
expire_mailbox_open(struct mail_storage *storage, const char *name,
struct istream *input, enum mailbox_open_flags flags)
{
union mail_storage_module_context *xpr_storage =
EXPIRE_CONTEXT(storage);
struct mailbox *box;
string_t *vname;
unsigned int secs;
bool altmove;
box = xpr_storage->super.mailbox_open(storage, name, input, flags);
if (box != NULL) {
vname = t_str_new(128);
(void)mail_namespace_get_vname(storage->ns, vname, name);
secs = expire_box_find_min_secs(expire.env, str_c(vname),
&altmove);
if (secs != 0)
mailbox_expire_hook(box, secs, altmove);
}
return box;
}
static void expire_mail_storage_created(struct mail_storage *storage)
{
union mail_storage_module_context *xpr_storage;
xpr_storage =
p_new(storage->pool, union mail_storage_module_context, 1);
xpr_storage->super = storage->v;
storage->v.mailbox_open = expire_mailbox_open;
MODULE_CONTEXT_SET_SELF(storage, expire_storage_module, xpr_storage);
if (expire.next_hook_mail_storage_created != NULL)
expire.next_hook_mail_storage_created(storage);
}
void expire_plugin_init(void)
{
const char *expunge_env, *altmove_env, *dict_uri;
expunge_env = getenv("EXPIRE");
altmove_env = getenv("EXPIRE_ALTMOVE");
if (expunge_env != NULL || altmove_env != NULL) {
dict_uri = getenv("EXPIRE_DICT");
if (dict_uri == NULL)
i_fatal("expire plugin: expire_dict setting missing");
// FIXME: user should be per-mail_user?...
expire.username = getenv("USER");
expire.env = expire_env_init(expunge_env, altmove_env);
expire.db = dict_init(dict_uri, DICT_DATA_TYPE_UINT32, expire.username);
if (expire.db == NULL)
i_fatal("expire plugin: dict_init() failed");
expire.next_hook_mail_storage_created =
hook_mail_storage_created;
hook_mail_storage_created = expire_mail_storage_created;
}
}
void expire_plugin_deinit(void)
{
if (expire.db != NULL) {
hook_mail_storage_created =
expire.next_hook_mail_storage_created;
dict_deinit(&expire.db);
expire_env_deinit(expire.env);
}
}