]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
plugins: Remove expire plugin
authorJosef 'Jeff' Sipek <jeff.sipek@open-xchange.com>
Wed, 9 Dec 2020 14:42:19 +0000 (09:42 -0500)
committerJosef 'Jeff' Sipek <jeff.sipek@open-xchange.com>
Wed, 9 Dec 2020 14:42:19 +0000 (09:42 -0500)
The autoexpunge functionality should be used instead.

configure.ac
doc/example-config/dovecot-dict-sql.conf.ext
doc/example-config/dovecot.conf
src/plugins/Makefile.am
src/plugins/expire/Makefile.am [deleted file]
src/plugins/expire/doveadm-expire.c [deleted file]
src/plugins/expire/expire-plugin.c [deleted file]
src/plugins/expire/expire-plugin.h [deleted file]
src/plugins/expire/expire-set.c [deleted file]
src/plugins/expire/expire-set.h [deleted file]

index a55642e77a59a190ff3809654e7a732bbcc69505..6da8502ebbdb05804f2db10a1940fafa7f1bdca3 100644 (file)
@@ -889,7 +889,6 @@ src/util/Makefile
 src/plugins/Makefile
 src/plugins/acl/Makefile
 src/plugins/imap-acl/Makefile
-src/plugins/expire/Makefile
 src/plugins/fs-compress/Makefile
 src/plugins/fts/Makefile
 src/plugins/fts-lucene/Makefile
index a9a903f1ffa46453bf5374e8d3fbd419c431a1df..35aa107b91dc3522e801088ae0083fb9224a1d16 100644 (file)
@@ -21,21 +21,3 @@ map {
   username_field = username
   value_field = messages
 }
-
-# CREATE TABLE expires (
-#   username varchar(100) not null,
-#   mailbox varchar(255) not null,
-#   expire_stamp integer not null,
-#   primary key (username, mailbox)
-# );
-
-map {
-  pattern = shared/expire/$user/$mailbox
-  table = expires
-  value_field = expire_stamp
-
-  fields {
-    username = $user
-    mailbox = $mailbox
-  }
-}
index a99d8aa775c20428b52fdb289d98e97a9830e4da..b67e9eb4a424e60a561f466fb6d71806e04560bb 100644 (file)
@@ -89,7 +89,6 @@
 
 dict {
   #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
-  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
 }
 
 # Most of the actual configuration gets included below. The filenames are
index e88e3c425a3047c87d47ebe0f5a7d2950b62c2c7..ab0b9d14f8a9978deaab272fe54f0aed508fbd72 100644 (file)
@@ -21,7 +21,6 @@ endif
 SUBDIRS = \
        acl \
        imap-acl \
-       expire \
        fts \
        fts-squat \
        last-login \
diff --git a/src/plugins/expire/Makefile.am b/src/plugins/expire/Makefile.am
deleted file mode 100644 (file)
index 567772b..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-doveadm_moduledir = $(moduledir)/doveadm
-
-AM_CPPFLAGS = \
-       -I$(top_srcdir)/src/lib \
-       -I$(top_srcdir)/src/lib-auth \
-       -I$(top_srcdir)/src/lib-dict \
-       -I$(top_srcdir)/src/lib-settings \
-       -I$(top_srcdir)/src/lib-master \
-       -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 \
-       -I$(top_srcdir)/src/doveadm
-
-NOPLUGIN_LDFLAGS =
-lib10_doveadm_expire_plugin_la_LDFLAGS = -module -avoid-version
-lib20_expire_plugin_la_LDFLAGS = -module -avoid-version
-
-module_LTLIBRARIES = \
-       lib20_expire_plugin.la
-
-lib20_expire_plugin_la_SOURCES = \
-       expire-set.c \
-       expire-plugin.c
-
-noinst_HEADERS = \
-       expire-set.h \
-       expire-plugin.h
-
-doveadm_module_LTLIBRARIES = \
-       lib10_doveadm_expire_plugin.la
-
-lib10_doveadm_expire_plugin_la_SOURCES = \
-       doveadm-expire.c
diff --git a/src/plugins/expire/doveadm-expire.c b/src/plugins/expire/doveadm-expire.c
deleted file mode 100644 (file)
index 492f305..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-/* Copyright (c) 2005-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "module-dir.h"
-#include "str.h"
-#include "hash.h"
-#include "dict.h"
-#include "imap-match.h"
-#include "expire-set.h"
-#include "mail-search.h"
-#include "doveadm-settings.h"
-#include "doveadm-mail.h"
-
-#define DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(obj) \
-       MODULE_CONTEXT_REQUIRE(obj, doveadm_expire_mail_cmd_module)
-
-enum expire_user_state {
-       EXPIRE_USER_STATE_NONEXISTENT = 0,
-       EXPIRE_USER_STATE_EXISTS = 1,
-       EXPIRE_USER_STATE_SEEN = 2
-};
-
-struct expire_query {
-       const char *mailbox;
-       struct imap_match_glob *glob;
-       time_t before_time;
-};
-
-struct doveadm_expire_mail_cmd_context {
-       union doveadm_mail_cmd_module_context module_ctx;
-
-       struct dict *dict;
-       struct dict_transaction_context *trans;
-       struct dict_iterate_context *iter;
-
-       /* username => enum expire_user_state */
-       HASH_TABLE(char *, void *) user_states;
-       ARRAY(struct expire_query) queries;
-       time_t oldest_before_time;
-       bool delete_nonexistent_users;
-};
-
-const char *doveadm_expire_plugin_version = DOVECOT_ABI_VERSION;
-
-void doveadm_expire_plugin_init(struct module *module);
-void doveadm_expire_plugin_deinit(void);
-
-static MODULE_CONTEXT_DEFINE_INIT(doveadm_expire_mail_cmd_module,
-                                 &doveadm_mail_cmd_module_register);
-static void (*next_hook_doveadm_mail_init)(struct doveadm_mail_cmd_context *ctx);
-
-static bool
-doveadm_expire_mail_match_mailbox(struct doveadm_expire_mail_cmd_context *ectx,
-                                 const char *mailbox, time_t oldest_savedate)
-{
-       const struct expire_query *query;
-
-       array_foreach(&ectx->queries, query) {
-               if (oldest_savedate >= query->before_time)
-                       continue;
-
-               if (query->glob == NULL) {
-                       if (strcmp(query->mailbox, mailbox) == 0)
-                               return TRUE;
-               } else {
-                       if (imap_match(query->glob, mailbox) == IMAP_MATCH_YES)
-                               return TRUE;
-               }
-       }
-       return FALSE;
-}
-
-static int
-doveadm_expire_mail_want(struct doveadm_mail_cmd_context *ctx,
-                        const char *dict_key, time_t oldest_savedate,
-                        const char **username_r)
-{
-       struct doveadm_expire_mail_cmd_context *ectx =
-               DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(ctx);
-       const char *username, *mailbox;
-       enum expire_user_state state;
-       char *orig_username;
-       void *value;
-
-       /* dict_key = DICT_EXPIRE_PREFIX<user>/<mailbox> */
-       username = dict_key + strlen(DICT_EXPIRE_PREFIX);
-       mailbox = strchr(username, '/');
-       if (mailbox == NULL) {
-               /* invalid record, ignore */
-               i_error("expire: Invalid key: %s", dict_key);
-               return -1;
-       }
-       username = t_strdup_until(username, mailbox++);
-
-       if (!hash_table_lookup_full(ectx->user_states, username,
-                                   &orig_username, &value)) {
-               /* user no longer exists, delete the record */
-               return -1;
-       }
-       state = POINTER_CAST_TO(value, enum expire_user_state);
-       switch (state) {
-       case EXPIRE_USER_STATE_NONEXISTENT:
-               i_unreached();
-       case EXPIRE_USER_STATE_EXISTS:
-               break;
-       case EXPIRE_USER_STATE_SEEN:
-               /* seen this user already, skip the record */
-               return 0;
-       }
-
-       if (!doveadm_expire_mail_match_mailbox(ectx, mailbox,
-                                              oldest_savedate)) {
-               /* this mailbox doesn't have any matching messages */
-               return 0;
-       }
-       state = EXPIRE_USER_STATE_SEEN;
-       hash_table_update(ectx->user_states, orig_username,
-                         POINTER_CAST(state));
-       *username_r = orig_username;
-       return 1;
-}
-
-static int
-doveadm_expire_mail_cmd_get_next_user(struct doveadm_mail_cmd_context *ctx,
-                                     const char **username_r)
-{
-       struct doveadm_expire_mail_cmd_context *ectx =
-               DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(ctx);
-       const char *key, *value, *error;
-       unsigned long oldest_savedate;
-       int ret;
-
-       while (dict_iterate(ectx->iter, &key, &value)) {
-               if (str_to_ulong(value, &oldest_savedate) < 0) {
-                       /* invalid record */
-                       i_error("expire: Invalid timestamp: %s", value);
-                       continue;
-               }
-               if ((time_t)oldest_savedate > ectx->oldest_before_time) {
-                       if (doveadm_debug) {
-                               i_debug("expire: Stopping iteration on key %s "
-                                       "(%lu > %"PRIdTIME_T")",
-                                       key, oldest_savedate,
-                                       ectx->oldest_before_time);
-                       }
-                       break;
-               }
-
-               T_BEGIN {
-                       ret = doveadm_expire_mail_want(ctx, key,
-                                                      oldest_savedate,
-                                                      username_r);
-               } T_END;
-               if (ret > 0)
-                       return 1;
-               if (ret < 0 && ectx->delete_nonexistent_users) {
-                       /* user has been deleted */
-                       dict_unset(ectx->trans, key);
-               }
-       }
-
-       /* finished */
-       if (dict_iterate_deinit(&ectx->iter, &error) < 0) {
-               i_error("Dictionary iteration failed: %s", error);
-               return -1;
-       }
-       return 0;
-}
-
-static const char *const *doveadm_expire_get_patterns(void)
-{
-       ARRAY_TYPE(const_string) patterns;
-       const char *str;
-       char set_name[6 + MAX_INT_STRLEN];
-       unsigned int i;
-
-       t_array_init(&patterns, 16);
-       str = doveadm_plugin_getenv("expire");
-       for (i = 2; str != NULL; i++) {
-               array_push_back(&patterns, &str);
-
-               if (i_snprintf(set_name, sizeof(set_name), "expire%u", i) < 0)
-                       i_unreached();
-               str = doveadm_plugin_getenv(set_name);
-       }
-       array_append_zero(&patterns);
-       return array_front(&patterns);
-}
-
-static bool
-doveadm_expire_get_or_mailboxes(struct doveadm_mail_cmd_context *ctx,
-                               const struct mail_search_arg *args,
-                               struct expire_query query)
-{
-       struct doveadm_expire_mail_cmd_context *ectx =
-               DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(ctx);
-       const struct mail_search_arg *arg;
-       unsigned int query_count;
-
-       query.mailbox = NULL;
-       query_count = array_count(&ectx->queries);
-       for (arg = args; arg != NULL; arg = arg->next) {
-               switch (arg->type) {
-               case SEARCH_MAILBOX_GLOB:
-                       query.glob = imap_match_init(ctx->pool, arg->value.str,
-                                                    TRUE, '/');
-                       /* fall through */
-               case SEARCH_MAILBOX:
-                       /* require mailbox to be in expire patterns */
-                       query.mailbox = p_strdup(ctx->pool, arg->value.str);
-                       array_push_back(&ectx->queries, &query);
-                       break;
-               default:
-                       /* there are something else besides mailboxes,
-                          can't optimize this. */
-                       array_delete(&ectx->queries, query_count,
-                                    array_count(&ectx->queries) - query_count);
-                       return FALSE;
-               }
-       }
-       return query.mailbox != NULL;
-}
-
-static bool
-doveadm_expire_analyze_and_query(struct doveadm_mail_cmd_context *ctx,
-                                const struct mail_search_arg *args)
-{
-       struct doveadm_expire_mail_cmd_context *ectx =
-               DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(ctx);
-       const struct mail_search_arg *arg;
-       struct expire_query query;
-       bool have_or = FALSE;
-
-       i_zero(&query);
-       query.before_time = (time_t)-1;
-
-       for (arg = args; arg != NULL; arg = arg->next) {
-               switch (arg->type) {
-               case SEARCH_OR:
-                       have_or = TRUE;
-                       break;
-               case SEARCH_MAILBOX_GLOB:
-                       query.glob = imap_match_init(ctx->pool, arg->value.str,
-                                                    TRUE, '/');
-                       /* fall through */
-               case SEARCH_MAILBOX:
-                       /* require mailbox to be in expire patterns */
-                       query.mailbox = p_strdup(ctx->pool, arg->value.str);
-                       break;
-               case SEARCH_BEFORE:
-                       if (arg->value.date_type != MAIL_SEARCH_DATE_TYPE_SAVED)
-                               break;
-                       if ((arg->value.search_flags &
-                            MAIL_SEARCH_ARG_FLAG_UTC_TIMES) == 0)
-                               break;
-                       query.before_time = arg->value.time;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if (query.before_time == (time_t)-1) {
-               /* no SAVEDBEFORE, can't optimize */
-               return FALSE;
-       }
-
-       if (query.mailbox != NULL) {
-               /* one mailbox */
-               array_push_back(&ectx->queries, &query);
-               return TRUE;
-       }
-
-       /* no MAILBOX, but check if one of the ORs lists mailboxes */
-       if (!have_or)
-               return FALSE;
-
-       for (arg = args; arg != NULL; arg = arg->next) {
-               if (arg->type == SEARCH_OR &&
-                   doveadm_expire_get_or_mailboxes(ctx, arg->value.subargs,
-                                                   query))
-                       return TRUE;
-       }
-       return FALSE;
-}
-
-static bool
-doveadm_expire_analyze_or_query(struct doveadm_mail_cmd_context *ctx,
-                               const struct mail_search_arg *args)
-{
-       const struct mail_search_arg *arg;
-
-       /* all of the subqueries must have mailbox and savedbefore */
-       for (arg = args; arg != NULL; arg = arg->next) {
-               if (arg->type != SEARCH_SUB)
-                       return FALSE;
-
-               if (!doveadm_expire_analyze_and_query(ctx, arg->value.subargs))
-                       return FALSE;
-       }
-       return TRUE;
-}
-
-static bool doveadm_expire_analyze_query(struct doveadm_mail_cmd_context *ctx)
-{
-       struct doveadm_expire_mail_cmd_context *ectx =
-               DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(ctx);
-       struct mail_search_arg *args = ctx->search_args->args;
-       struct expire_set *set;
-       const struct expire_query *queries;
-       unsigned int i, count;
-
-       i_assert(args != NULL);
-
-       /* we support two kinds of queries:
-
-          1) mailbox-pattern savedbefore <stamp> ...
-          2) or 2*(mailbox-pattern savedbefore <stamp> ...)
-
-          mailbox-pattern can be:
-
-          a) mailbox <name>
-          b) or 2*(mailbox <name>)
-       */
-       p_array_init(&ectx->queries, ctx->pool, 8);
-       if (!doveadm_expire_analyze_and_query(ctx, args) &&
-           (args->type != SEARCH_OR || args->next != NULL ||
-            !doveadm_expire_analyze_or_query(ctx, args->value.subargs))) {
-               if (doveadm_debug)
-                       i_debug("expire: Couldn't optimize search query");
-               return FALSE;
-       }
-
-       /* make sure all mailboxes match expire patterns */
-       set = expire_set_init(doveadm_expire_get_patterns());
-       queries = array_get(&ectx->queries, &count);
-       for (i = 0; i < count; i++) {
-               if (!expire_set_lookup(set, queries[i].mailbox)) {
-                       if (doveadm_debug) {
-                               i_debug("expire: Couldn't optimize search query: "
-                                       "mailbox %s not in expire database",
-                                       queries[i].mailbox);
-                       }
-                       break;
-               }
-       }
-       expire_set_deinit(&set);
-
-       return i == count;
-}
-
-static void doveadm_expire_mail_cmd_deinit(struct doveadm_mail_cmd_context *ctx)
-{
-       struct doveadm_expire_mail_cmd_context *ectx =
-               DOVEADM_EXPIRE_MAIL_CMD_CONTEXT(ctx);
-       const char *error;
-
-       if (ectx->iter != NULL) {
-               if (dict_iterate_deinit(&ectx->iter, &error) < 0)
-                       i_error("expire: Dictionary iteration failed: %s", error);
-       }
-       if (dict_transaction_commit(&ectx->trans, &error) < 0)
-               i_error("expire: Dictionary commit failed: %s", error);
-       dict_deinit(&ectx->dict);
-       hash_table_destroy(&ectx->user_states);
-
-       ectx->module_ctx.super.deinit(ctx);
-}
-
-static void doveadm_expire_mail_init(struct doveadm_mail_cmd_context *ctx)
-{
-       struct doveadm_expire_mail_cmd_context *ectx;
-       struct dict_settings dict_set;
-       struct dict *dict;
-       const struct expire_query *query;
-       const char *expire_dict, *username, *value, *error;
-       char *username_dup;
-       enum expire_user_state state;
-
-       if (ctx->search_args == NULL)
-               return;
-
-       expire_dict = doveadm_plugin_getenv("expire_dict");
-       if (expire_dict == NULL)
-               return;
-
-       /* doveadm proxying uses expire database only locally. the remote
-          doveadm handles each user one at a time (even though
-          iterate_single_user=FALSE) */
-       if (ctx->iterate_single_user || ctx->proxying) {
-               if (doveadm_debug) {
-                       i_debug("expire: Iterating only a single user, "
-                               "ignoring expire database");
-               }
-               return;
-       }
-
-       ectx = p_new(ctx->pool, struct doveadm_expire_mail_cmd_context, 1);
-       ectx->module_ctx.super = ctx->v;
-       value = doveadm_plugin_getenv("expire_keep_nonexistent_users");
-       ectx->delete_nonexistent_users =
-               value == NULL || strcmp(value, "yes") != 0;
-       MODULE_CONTEXT_SET(ctx, doveadm_expire_mail_cmd_module, ectx);
-
-       /* we can potentially optimize this query. see if the search args
-          are valid for optimization. */
-       if (!doveadm_expire_analyze_query(ctx))
-               return;
-
-       if (doveadm_debug)
-               i_debug("expire: Searching only users listed in expire database");
-
-       i_zero(&dict_set);
-       dict_set.value_type = DICT_DATA_TYPE_UINT32;
-       dict_set.username = "";
-       dict_set.base_dir = doveadm_settings->base_dir;
-       if (dict_init(expire_dict, &dict_set, &dict, &error) < 0) {
-               i_error("dict_init(%s) failed, not using it: %s",
-                       expire_dict, error);
-               return;
-       }
-
-       ectx->oldest_before_time = (time_t)-1;
-       array_foreach(&ectx->queries, query) {
-               if (ectx->oldest_before_time > query->before_time ||
-                   ectx->oldest_before_time == (time_t)-1)
-                       ectx->oldest_before_time = query->before_time;
-       }
-
-       ctx->v.deinit = doveadm_expire_mail_cmd_deinit;
-       ctx->v.get_next_user = doveadm_expire_mail_cmd_get_next_user;
-
-       hash_table_create(&ectx->user_states, ctx->pool, 0, str_hash, strcmp);
-       while (mail_storage_service_all_next(ctx->storage_service, &username) > 0) {
-               username_dup = p_strdup(ctx->pool, username);
-               state = EXPIRE_USER_STATE_EXISTS;
-               hash_table_insert(ectx->user_states, username_dup,
-                                 POINTER_CAST(state));
-       }
-
-       ectx->dict = dict;
-       ectx->trans = dict_transaction_begin(dict);
-       ectx->iter = dict_iterate_init(dict, DICT_EXPIRE_PREFIX,
-                                      DICT_ITERATE_FLAG_RECURSE |
-                                      DICT_ITERATE_FLAG_SORT_BY_VALUE);
-}
-
-void doveadm_expire_plugin_init(struct module *module ATTR_UNUSED)
-{
-       next_hook_doveadm_mail_init = hook_doveadm_mail_init;
-       hook_doveadm_mail_init = doveadm_expire_mail_init;
-}
-
-void doveadm_expire_plugin_deinit(void)
-{
-       i_assert(hook_doveadm_mail_init == doveadm_expire_mail_init);
-       hook_doveadm_mail_init = next_hook_doveadm_mail_init;
-}
diff --git a/src/plugins/expire/expire-plugin.c b/src/plugins/expire/expire-plugin.c
deleted file mode 100644 (file)
index 0a245ad..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
-
-/* There are several race conditions in this plugin, but they should be
-   happening pretty rarely and usually it's not a big problem if the results
-   are temporarily wrong. Fixing the races would likely be a lot of work,
-   so it's not really worth it. */
-
-#include "lib.h"
-#include "ioloop.h"
-#include "array.h"
-#include "str.h"
-#include "master-service.h"
-#include "dict.h"
-#include "mail-namespace.h"
-#include "index-mail.h"
-#include "index-storage.h"
-#include "expire-set.h"
-#include "expire-plugin.h"
-
-
-#define EXPIRE_CONTEXT(obj) \
-       MODULE_CONTEXT(obj, expire_storage_module)
-#define EXPIRE_CONTEXT_REQUIRE(obj) \
-       MODULE_CONTEXT_REQUIRE(obj, expire_storage_module)
-#define EXPIRE_MAIL_CONTEXT(obj) \
-       MODULE_CONTEXT_REQUIRE(obj, expire_mail_module)
-#define EXPIRE_USER_CONTEXT(obj) \
-       MODULE_CONTEXT_REQUIRE(obj, expire_mail_user_module)
-
-struct expire_mail_index_header {
-       uint32_t timestamp;
-};
-
-struct expire_mail_user {
-       union mail_user_module_context module_ctx;
-
-       struct dict *db;
-       struct expire_set *set;
-       bool expire_cache;
-};
-
-struct expire_mailbox {
-       union mailbox_module_context module_ctx;
-       uint32_t expire_ext_id;
-};
-
-struct expire_transaction_context {
-       union mailbox_transaction_module_context module_ctx;
-
-       bool saves:1;
-       bool first_expunged:1;
-};
-
-const char *expire_plugin_version = DOVECOT_ABI_VERSION;
-
-static MODULE_CONTEXT_DEFINE_INIT(expire_storage_module,
-                                 &mail_storage_module_register);
-static MODULE_CONTEXT_DEFINE_INIT(expire_mail_module, &mail_module_register);
-static MODULE_CONTEXT_DEFINE_INIT(expire_mail_user_module,
-                                 &mail_user_module_register);
-
-static struct mailbox_transaction_context *
-expire_mailbox_transaction_begin(struct mailbox *box,
-                                enum mailbox_transaction_flags flags,
-                                const char *reason)
-{
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT_REQUIRE(box);
-       struct mailbox_transaction_context *t;
-       struct expire_transaction_context *xt;
-
-       t = xpr_box->module_ctx.super.transaction_begin(box, flags, reason);
-       xt = i_new(struct expire_transaction_context, 1);
-
-       MODULE_CONTEXT_SET(t, expire_storage_module, xt);
-       return t;
-}
-
-static void first_save_timestamp(struct mailbox *box, time_t *stamp_r)
-{
-       struct mailbox_transaction_context *t;
-       const struct mail_index_header *hdr;
-       struct mail *mail;
-
-       *stamp_r = ioloop_time;
-
-       t = mailbox_transaction_begin(box, 0, __func__);
-       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(box->view);
-       if (hdr->messages_count > 0) {
-               mail_set_seq(mail, 1);
-               (void)mail_get_save_date(mail, stamp_r);
-       }
-       mail_free(&mail);
-       (void)mailbox_transaction_commit(&t);
-}
-
-static uint32_t expire_get_ext_id(struct mailbox *box)
-{
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT_REQUIRE(box);
-
-       if (xpr_box->expire_ext_id != (uint32_t)-1)
-               return xpr_box->expire_ext_id;
-
-       xpr_box->expire_ext_id =
-               mail_index_ext_register(box->index, "expire",
-                       sizeof(struct expire_mail_index_header), 0, 0);
-       return xpr_box->expire_ext_id;
-}
-
-static int expire_lookup(struct mailbox *box, const char *key,
-                        time_t *new_stamp_r)
-{
-       struct expire_mail_user *euser =
-               EXPIRE_USER_CONTEXT(box->storage->user);
-       const struct expire_mail_index_header *hdr;
-       const void *data;
-       size_t data_size;
-       const char *value, *error;
-       int ret;
-
-       /* default to ioloop_time for newly saved mails. it may not be exactly
-          the first message's save time, but a few seconds difference doesn't
-          matter */
-       *new_stamp_r = ioloop_time;
-
-       if (euser->expire_cache) {
-               mail_index_get_header_ext(box->view, expire_get_ext_id(box),
-                                         &data, &data_size);
-               if (data_size == sizeof(*hdr)) {
-                       hdr = data;
-                       if (hdr->timestamp == 0)
-                               return 0;
-                       /* preserve the original timestamp */
-                       *new_stamp_r = hdr->timestamp;
-                       return 1;
-               }
-               /* cache doesn't exist yet */
-       }
-
-       ret = dict_lookup(euser->db, pool_datastack_create(),
-                         key, &value, &error);
-       if (ret <= 0) {
-               if (ret < 0) {
-                       i_error("expire: dict_lookup(%s) failed: %s", key, error);
-                       return -1;
-               }
-               first_save_timestamp(box, new_stamp_r);
-               return 0;
-       }
-       return strcmp(value, "0") != 0 ? 1 : 0;
-}
-
-static void
-expire_update(struct mailbox *box, const char *key, time_t timestamp)
-{
-       struct expire_mail_user *euser =
-               EXPIRE_USER_CONTEXT(box->storage->user);
-       struct dict_transaction_context *dctx;
-       struct mail_index_transaction *trans;
-       struct expire_mail_index_header hdr;
-       const char *error;
-
-       dctx = dict_transaction_begin(euser->db);
-       dict_set(dctx, key, dec2str(timestamp));
-       if (dict_transaction_commit(&dctx, &error) < 0)
-               i_error("expire: dict commit failed: %s", error);
-       else if (euser->expire_cache) {
-               i_zero(&hdr);
-               hdr.timestamp = timestamp;
-
-               trans = mail_index_transaction_begin(box->view,
-                       MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
-               mail_index_update_header_ext(trans, expire_get_ext_id(box),
-                                            0, &hdr, sizeof(hdr));
-               if (mail_index_transaction_commit(&trans) < 0)
-                       i_error("expire: index transaction commit failed");
-       }
-}
-
-static void first_nonexpunged_timestamp(struct mailbox_transaction_context *t,
-                                       time_t *stamp_r)
-{
-       struct mail_index_view *view = t->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(mail, seq);
-                       if (mail_get_save_date(mail, stamp_r) >= 0)
-                               break;
-               }
-       }
-       mail_free(&mail);
-
-       if (seq > hdr->messages_count) {
-               /* everything expunged */
-               *stamp_r = 0;
-       }
-}
-
-static int
-expire_mailbox_transaction_commit(struct mailbox_transaction_context *t,
-                                 struct mail_transaction_commit_changes *changes_r)
-{
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT_REQUIRE(t->box);
-       struct expire_transaction_context *xt = EXPIRE_CONTEXT_REQUIRE(t);
-       struct mailbox *box = t->box;
-       time_t new_stamp = 0;
-       bool update_dict = FALSE;
-       int ret;
-
-       if (xt->first_expunged) {
-               /* first mail expunged. dict needs updating. */
-               first_nonexpunged_timestamp(t, &new_stamp);
-               if (new_stamp == 0 && xt->saves) {
-                       /* everything was expunged, but also within this
-                          transaction a new message was saved */
-                       new_stamp = ioloop_time;
-               }
-               e_debug(box->event, "expire: Expunging first message, "
-                       "updating timestamp to %ld", (long)new_stamp);
-               update_dict = TRUE;
-       }
-
-       if (xpr_box->module_ctx.super.transaction_commit(t, changes_r) < 0) {
-               i_free(xt);
-               return -1;
-       }
-       /* transaction is freed now */
-       t = NULL;
-
-       if (xt->first_expunged || xt->saves) T_BEGIN {
-               const char *key;
-
-               key = t_strconcat(DICT_EXPIRE_PREFIX,
-                                 box->storage->user->username, "/",
-                                 mailbox_get_vname(box), NULL);
-               if (xt->first_expunged) {
-                       /* new_stamp is already set */
-               } else {
-                       i_assert(xt->saves);
-                       /* saved new mails. dict needs to be updated only if
-                          this is the first mail in the database */
-                       ret = expire_lookup(box, key, &new_stamp);
-                       if (ret <= 0) {
-                               /* first time saving here with expire enabled.
-                                  also handle lookup errors by just assuming
-                                  it didn't exist */
-                               if (ret < 0) {
-                                       i_warning("expire: dict lookup failed, "
-                                                 "assuming update is needed");
-                               }
-                               update_dict = TRUE;
-                       } else {
-                               /* already exists */
-                       }
-                       if (update_dict) {
-                               e_debug(box->event, "expire: Saving first message, "
-                                       "updating timestamp to %ld", (long)new_stamp);
-                       }
-               }
-
-               if (update_dict)
-                       expire_update(box, key, new_stamp);
-       } T_END;
-       i_free(xt);
-       return 0;
-}
-
-static void
-expire_mailbox_transaction_rollback(struct mailbox_transaction_context *t)
-{
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT_REQUIRE(t->box);
-       struct expire_transaction_context *xt = EXPIRE_CONTEXT_REQUIRE(t);
-
-       xpr_box->module_ctx.super.transaction_rollback(t);
-       i_free(xt);
-}
-
-static void expire_mail_expunge(struct mail *_mail)
-{
-       struct mail_private *mail = (struct mail_private *)_mail;
-       union mail_module_context *xpr_mail = EXPIRE_MAIL_CONTEXT(mail);
-       struct expire_transaction_context *xt =
-               EXPIRE_CONTEXT_REQUIRE(_mail->transaction);
-
-       if (_mail->seq == 1) {
-               /* first mail expunged, database needs to be updated */
-               xt->first_expunged = TRUE;
-       }
-       xpr_mail->super.expunge(_mail);
-}
-
-static void expire_mail_allocated(struct mail *_mail)
-{
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(_mail->box);
-       struct mail_private *mail = (struct mail_private *)_mail;
-       struct mail_vfuncs *v = mail->vlast;
-       union mail_module_context *xpr_mail;
-
-       if (xpr_box == NULL)
-               return;
-
-       xpr_mail = p_new(mail->pool, union mail_module_context, 1);
-       xpr_mail->super = *v;
-       mail->vlast = &xpr_mail->super;
-
-       v->expunge = expire_mail_expunge;
-       MODULE_CONTEXT_SET_SELF(mail, expire_mail_module, xpr_mail);
-}
-
-static int expire_save_finish(struct mail_save_context *ctx)
-{
-       struct expire_transaction_context *xt =
-               EXPIRE_CONTEXT_REQUIRE(ctx->transaction);
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT_REQUIRE(ctx->transaction->box);
-
-       xt->saves = TRUE;
-       return xpr_box->module_ctx.super.save_finish(ctx);
-}
-
-static int
-expire_copy(struct mail_save_context *ctx, struct mail *mail)
-{
-       struct expire_transaction_context *xt =
-               EXPIRE_CONTEXT_REQUIRE(ctx->transaction);
-       struct expire_mailbox *xpr_box = EXPIRE_CONTEXT_REQUIRE(ctx->transaction->box);
-
-       xt->saves = TRUE;
-       return xpr_box->module_ctx.super.copy(ctx, mail);
-}
-
-static void expire_mailbox_allocate_init(struct mailbox *box)
-{
-       struct mailbox_vfuncs *v = box->vlast;
-       struct expire_mailbox *xpr_box;
-
-       xpr_box = p_new(box->pool, struct expire_mailbox, 1);
-       xpr_box->module_ctx.super = *v;
-       box->vlast = &xpr_box->module_ctx.super;
-       xpr_box->expire_ext_id = (uint32_t)-1;
-
-       v->transaction_begin = expire_mailbox_transaction_begin;
-       v->transaction_commit = expire_mailbox_transaction_commit;
-       v->transaction_rollback = expire_mailbox_transaction_rollback;
-       v->save_finish = expire_save_finish;
-       v->copy = expire_copy;
-
-       MODULE_CONTEXT_SET(box, expire_storage_module, xpr_box);
-}
-
-static void expire_mailbox_allocated(struct mailbox *box)
-{
-       struct expire_mail_user *euser =
-               EXPIRE_USER_CONTEXT(box->storage->user);
-
-       if (euser != NULL && expire_set_lookup(euser->set, box->vname))
-               expire_mailbox_allocate_init(box);
-}
-
-static void expire_mail_user_deinit(struct mail_user *user)
-{
-       struct expire_mail_user *euser = EXPIRE_USER_CONTEXT(user);
-
-       dict_deinit(&euser->db);
-       expire_set_deinit(&euser->set);
-
-       euser->module_ctx.super.deinit(user);
-}
-
-static const char *const *expire_get_patterns(struct mail_user *user)
-{
-       ARRAY_TYPE(const_string) patterns;
-       const char *str;
-       char set_name[6 + MAX_INT_STRLEN];
-       unsigned int i;
-
-       t_array_init(&patterns, 16);
-       str = mail_user_set_plugin_getenv(user->set, "expire");
-       for (i = 2; str != NULL; i++) {
-               array_push_back(&patterns, &str);
-
-               if (i_snprintf(set_name, sizeof(set_name), "expire%u", i) < 0)
-                       i_unreached();
-               str = mail_user_set_plugin_getenv(user->set, set_name);
-       }
-       array_append_zero(&patterns);
-       return array_front(&patterns);
-}
-
-static void expire_mail_user_created(struct mail_user *user)
-{
-       struct mail_user_vfuncs *v = user->vlast;
-       struct expire_mail_user *euser;
-       struct dict_settings dict_set;
-       struct dict *db;
-       const char *dict_uri, *error;
-
-       if (!mail_user_plugin_getenv_bool(user, "expire")) {
-               e_debug(user->event, "expire: No expire setting - plugin disabled");
-               return;
-       }
-
-       dict_uri = mail_user_plugin_getenv(user, "expire_dict");
-       if (dict_uri == NULL) {
-               i_error("expire plugin: expire_dict setting missing");
-               return;
-       }
-       /* we're using only shared dictionary, the username doesn't matter. */
-       i_zero(&dict_set);
-       dict_set.value_type = DICT_DATA_TYPE_UINT32;
-       dict_set.username = "";
-       dict_set.base_dir = user->set->base_dir;
-       if (dict_init(dict_uri, &dict_set, &db, &error) < 0) {
-               i_error("expire plugin: dict_init(%s) failed: %s",
-                       dict_uri, error);
-               return;
-       }
-
-       euser = p_new(user->pool, struct expire_mail_user, 1);
-       euser->module_ctx.super = *v;
-       user->vlast = &euser->module_ctx.super;
-       v->deinit = expire_mail_user_deinit;
-
-       euser->db = db;
-       euser->set = expire_set_init(expire_get_patterns(user));
-       euser->expire_cache = mail_user_plugin_getenv_bool(user, "expire_cache");
-       MODULE_CONTEXT_SET(user, expire_mail_user_module, euser);
-}
-
-static struct mail_storage_hooks expire_mail_storage_hooks = {
-       .mail_user_created = expire_mail_user_created,
-       .mailbox_allocated = expire_mailbox_allocated,
-       .mail_allocated = expire_mail_allocated
-};
-
-void expire_plugin_init(struct module *module)
-{
-       mail_storage_hooks_add(module, &expire_mail_storage_hooks);
-}
-
-void expire_plugin_deinit(void)
-{
-       mail_storage_hooks_remove(&expire_mail_storage_hooks);
-}
diff --git a/src/plugins/expire/expire-plugin.h b/src/plugins/expire/expire-plugin.h
deleted file mode 100644 (file)
index 9f46c0a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef EXPIRE_PLUGIN_H
-#define EXPIRE_PLUGIN_H
-
-void expire_plugin_init(struct module *module);
-void expire_plugin_deinit(void);
-
-#endif
diff --git a/src/plugins/expire/expire-set.c b/src/plugins/expire/expire-set.c
deleted file mode 100644 (file)
index f210c09..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2006-2018 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "imap-match.h"
-#include "expire-set.h"
-
-
-struct expire_set {
-       pool_t pool;
-       ARRAY(struct imap_match_glob *) globs;
-};
-
-struct expire_set *expire_set_init(const char *const *patterns)
-{
-       struct expire_set *set;
-       struct imap_match_glob *glob;
-       const char *const *pattern;
-       pool_t pool;
-
-       pool = pool_alloconly_create("Expire pool", 512);
-       set = p_new(pool, struct expire_set, 1);
-       set->pool = pool;
-       p_array_init(&set->globs, set->pool, 16);
-
-       for (pattern = patterns; *pattern != NULL; pattern++) {
-               glob = imap_match_init(set->pool, *pattern, TRUE, '/');
-               array_push_back(&set->globs, &glob);
-       }
-       return set;
-}
-
-void expire_set_deinit(struct expire_set **_set)
-{
-       struct expire_set *set = *_set;
-
-       *_set = NULL;
-       pool_unref(&set->pool);
-}
-
-bool expire_set_lookup(struct expire_set *set, const char *mailbox)
-{
-       struct imap_match_glob *const *globp;
-
-       array_foreach(&set->globs, globp) {
-               if (imap_match(*globp, mailbox) == IMAP_MATCH_YES)
-                       return TRUE;
-       }
-       return FALSE;
-}
diff --git a/src/plugins/expire/expire-set.h b/src/plugins/expire/expire-set.h
deleted file mode 100644 (file)
index 70f241b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef EXPIRE_SET_H
-#define EXPIRE_SET_H
-
-#define DICT_EXPIRE_PREFIX DICT_PATH_SHARED"expire/"
-
-struct expire_set *expire_set_init(const char *const *patterns);
-void expire_set_deinit(struct expire_set **set);
-
-bool expire_set_lookup(struct expire_set *set, const char *mailbox);
-
-#endif