lazy-expunge-plugin.c revision 0b7a8f6c6d61d51d86adfbe56f0397dafd34960c
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* Copyright (c) 2006-2009 Dovecot authors, see the included COPYING file */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "lib.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "ioloop.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "array.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "str.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "seq-range-array.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "mkdir-parents.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "mail-storage-private.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "mail-search-build.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "mailbox-list-private.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "mail-namespace.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "lazy-expunge-plugin.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdlib.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <unistd.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <dirent.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <time.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define LAZY_EXPUNGE_CONTEXT(obj) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT(obj, lazy_expunge_mail_storage_module)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define LAZY_EXPUNGE_LIST_CONTEXT(obj) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT(obj, lazy_expunge_mailbox_list_module)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define LAZY_EXPUNGE_USER_CONTEXT(obj) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT(obj, lazy_expunge_mail_user_module)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define LAZY_EXPUNGE_MAIL_CONTEXT(obj) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT(obj, lazy_expunge_mail_module)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteenum lazy_namespace {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_NAMESPACE_EXPUNGE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_NAMESPACE_DELETE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_NAMESPACE_DELETE_EXPUNGE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_NAMESPACE_COUNT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct lazy_expunge_mail_user {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mail_user_module_context module_ctx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_namespace *lazy_ns[LAZY_NAMESPACE_COUNT];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *env;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct lazy_expunge_mailbox_list {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_list_module_context module_ctx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_list *expunge_list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned int internal_namespace:1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned int deleting:1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct lazy_expunge_transaction {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_transaction_module_context module_ctx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox *dest_box;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_transaction_context *dest_trans;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bool failed;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconst char *lazy_expunge_plugin_version = PACKAGE_VERSION;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic MODULE_CONTEXT_DEFINE_INIT(lazy_expunge_mail_storage_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mail_storage_module_register);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic MODULE_CONTEXT_DEFINE_INIT(lazy_expunge_mail_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mail_module_register);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic MODULE_CONTEXT_DEFINE_INIT(lazy_expunge_mailbox_list_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mailbox_list_module_register);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic MODULE_CONTEXT_DEFINE_INIT(lazy_expunge_mail_user_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &mail_user_module_register);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct mailbox *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortemailbox_open_or_create(struct mailbox_list *list, const char *name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char **error_r)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox *box;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_storage *storage;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte enum mail_error error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte box = mailbox_alloc(list, name, NULL, MAILBOX_FLAG_KEEP_RECENT |
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MAILBOX_FLAG_NO_INDEX_FILES);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_open(box) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_r = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return box;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_r = mail_storage_get_last_error(mailbox_get_storage(box),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (error != MAIL_ERROR_NOTFOUND) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* try creating and re-opening it. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte storage = mail_namespace_get_default_storage(list->ns);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_create(box, NULL, FALSE) < 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_open(box) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *error_r = mail_storage_get_last_error(mailbox_get_storage(box),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return box;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct mail_namespace *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteget_lazy_ns(struct mail_user *user, enum lazy_namespace type)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mail_user *luser = LAZY_EXPUNGE_USER_CONTEXT(user);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return luser->lazy_ns[type];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void lazy_expunge_mail_expunge(struct mail *_mail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_namespace *ns = _mail->box->list->ns;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_private *mail = (struct mail_private *)_mail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mail_module_context *mmail = LAZY_EXPUNGE_MAIL_CONTEXT(mail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_transaction *lt =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_EXPUNGE_CONTEXT(_mail->transaction);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_namespace *dest_ns;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_save_context *save_ctx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_ns = get_lazy_ns(ns->user, LAZY_NAMESPACE_EXPUNGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lt->dest_box == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt->dest_box = mailbox_open_or_create(dest_ns->list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _mail->box->name, &error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lt->dest_box == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_storage_set_critical(_mail->box->storage,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "lazy_expunge: Couldn't open expunge mailbox: "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s", error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt->failed = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_sync(lt->dest_box, 0, 0, NULL) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_storage_set_critical(_mail->box->storage,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "lazy_expunge: Couldn't sync expunge mailbox");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&lt->dest_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt->failed = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt->dest_trans = mailbox_transaction_begin(lt->dest_box,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MAILBOX_TRANSACTION_FLAG_EXTERNAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte save_ctx = mailbox_save_alloc(lt->dest_trans);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_save_copy_flags(save_ctx, _mail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte save_ctx->flags &= ~MAIL_DELETED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_copy(&save_ctx, _mail) < 0 && !_mail->expunged)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt->failed = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mmail->super.expunge(_mail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct mailbox_transaction_context *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelazy_expunge_transaction_begin(struct mailbox *box,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte enum mailbox_transaction_flags flags)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_module_context *mbox = LAZY_EXPUNGE_CONTEXT(box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_transaction_context *t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_transaction *lt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t = mbox->super.transaction_begin(box, flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt = i_new(struct lazy_expunge_transaction, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT_SET(t, lazy_expunge_mail_storage_module, lt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void lazy_expunge_transaction_free(struct lazy_expunge_transaction *lt)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lt->dest_trans != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_transaction_rollback(&lt->dest_trans);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lt->dest_box != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&lt->dest_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_free(lt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelazy_expunge_transaction_commit(struct mailbox_transaction_context *ctx,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_transaction_commit_changes *changes_r)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_module_context *mbox = LAZY_EXPUNGE_CONTEXT(ctx->box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_transaction *lt = LAZY_EXPUNGE_CONTEXT(ctx);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lt->dest_trans != NULL && !lt->failed) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_transaction_commit(&lt->dest_trans) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lt->failed = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (lt->failed) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mbox->super.transaction_rollback(ctx);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = mbox->super.transaction_commit(ctx, changes_r);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lazy_expunge_transaction_free(lt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelazy_expunge_transaction_rollback(struct mailbox_transaction_context *ctx)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_module_context *mbox = LAZY_EXPUNGE_CONTEXT(ctx->box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_transaction *lt = LAZY_EXPUNGE_CONTEXT(ctx);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mbox->super.transaction_rollback(ctx);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte lazy_expunge_transaction_free(lt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct mail *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelazy_expunge_mail_alloc(struct mailbox_transaction_context *t,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte enum mail_fetch_field wanted_fields,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_header_lookup_ctx *wanted_headers)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_module_context *mbox = LAZY_EXPUNGE_CONTEXT(t->box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mail_module_context *mmail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail *_mail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_private *mail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _mail = mbox->super.mail_alloc(t, wanted_fields, wanted_headers);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail = (struct mail_private *)_mail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mmail = p_new(mail->pool, union mail_module_context, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mmail->super = mail->v;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail->v.expunge = lazy_expunge_mail_expunge;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT_SET_SELF(mail, lazy_expunge_mail_module, mmail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return _mail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void lazy_expunge_mailbox_allocated(struct mailbox *box)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mailbox_list *llist =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_EXPUNGE_LIST_CONTEXT(box->list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte union mailbox_module_context *mbox;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (llist != NULL && !llist->internal_namespace) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mbox = p_new(box->pool, union mailbox_module_context, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mbox->super = box->v;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte box->v.transaction_begin = lazy_expunge_transaction_begin;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte box->v.transaction_commit = lazy_expunge_transaction_commit;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte box->v.transaction_rollback = lazy_expunge_transaction_rollback;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte box->v.mail_alloc = lazy_expunge_mail_alloc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mbox);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortemailbox_move(struct mailbox_list *src_list, const char *src_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_list *dest_list, const char **_dest_name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *dir, *origin, *dest_name = *_dest_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte enum mail_error error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mode_t mode;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gid_t gid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* make sure the destination root directory exists */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_list_get_dir_permissions(dest_list, NULL, &mode, &gid, &origin);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dir = mailbox_list_get_path(dest_list, NULL, MAILBOX_LIST_PATH_TYPE_DIR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mkdir_parents_chgrp(dir, mode, gid, origin) < 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno != EEXIST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_list_set_critical(src_list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "mkdir_parents(%s) failed: %m", dir);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (mailbox_list_rename_mailbox(src_list, src_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_list, dest_name, FALSE) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_list_get_last_error(src_list, &error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (error) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case MAIL_ERROR_EXISTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case MAIL_ERROR_NOTFOUND:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* mailbox is being deleted multiple times per second.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte update the filename. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_name = t_strdup_printf("%s-%04u", *_dest_name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uint32_t)random());
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *_dest_name = dest_name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortemailbox_move_all_mails(struct mailbox_list *list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *src_name, const char *dest_name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox *src_box, *dest_box;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_search_args *search_args;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_transaction_context *src_trans, *dest_trans;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_search_context *search_ctx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_save_context *save_ctx;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail *mail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *errstr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte enum mail_error error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_box = mailbox_alloc(list, dest_name, NULL, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_open(dest_box) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errstr = mail_storage_get_last_error(dest_box->storage, &error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_error("lazy_expunge: Couldn't open DELETE dest mailbox "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s: %s", dest_name, errstr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&dest_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_box = mailbox_alloc(list, src_name, NULL, MAILBOX_FLAG_KEEP_LOCKED);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_open(src_box) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errstr = mail_storage_get_last_error(src_box->storage, &error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&src_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&dest_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (error == MAIL_ERROR_NOTFOUND)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_error("lazy_expunge: Couldn't open DELETE source mailbox "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s: %s", src_name, errstr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte src_trans = mailbox_transaction_begin(src_box, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_trans = mailbox_transaction_begin(dest_box,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MAILBOX_TRANSACTION_FLAG_EXTERNAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte search_args = mail_search_build_init();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_search_build_add_all(search_args);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte search_ctx = mailbox_search_init(src_trans, search_args, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_search_args_unref(&search_args);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail = mail_alloc(src_trans, 0, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((ret = mailbox_search_next(search_ctx, mail)) > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte save_ctx = mailbox_save_alloc(dest_trans);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_save_copy_flags(save_ctx, mail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_copy(&save_ctx, mail) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!mail->expunged) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_free(&mail);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_search_deinit(&search_ctx) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void)mailbox_transaction_commit(&src_trans);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = mailbox_transaction_commit(&dest_trans);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_transaction_rollback(&dest_trans);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&src_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_close(&dest_box);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = mailbox_list_delete_mailbox(list, src_name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelazy_expunge_mailbox_list_delete(struct mailbox_list *list, const char *name)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mailbox_list *llist =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_EXPUNGE_LIST_CONTEXT(list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mail_namespace *expunge_ns, *dest_ns;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte enum mailbox_name_status status;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *destname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct tm *tm;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char timestamp[256];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (llist->internal_namespace || llist->deleting)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return llist->module_ctx.super.delete_mailbox(list, name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first do the normal sanity checks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(name, "INBOX") == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "INBOX can't be deleted.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mailbox_list_get_mailbox_name_status(list, name, &status) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (status == MAILBOX_NAME_INVALID) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_list_set_error(list, MAIL_ERROR_PARAMS,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Invalid mailbox name");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte expunge_ns = get_lazy_ns(list->ns->user, LAZY_NAMESPACE_EXPUNGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_ns = get_lazy_ns(list->ns->user, LAZY_NAMESPACE_DELETE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (expunge_ns == dest_ns) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if there are no expunged messages in this mailbox,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte we can simply rename the mailbox to the destination name */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte destname = name;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* destination mailbox name needs to contain a timestamp */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tm = localtime(&ioloop_time);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strftime(timestamp, sizeof(timestamp),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%Y%m%d-%H%M%S", tm) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_strocpy(timestamp, dec2str(ioloop_time),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof(timestamp));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte destname = t_strconcat(name, "-", timestamp, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first move the actual mailbox */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = mailbox_move(list, name, dest_ns->list, &destname)) < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (expunge_ns == dest_ns) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist->deleting = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void)mailbox_move_all_mails(dest_ns->list, destname, name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist->deleting = FALSE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* next move the expunged messages mailbox, if it exists */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_ns = get_lazy_ns(list->ns->user, LAZY_NAMESPACE_DELETE_EXPUNGE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (expunge_ns != dest_ns) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void)mailbox_move(expunge_ns->list, name,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dest_ns->list, &destname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void lazy_expunge_mail_namespace_storage_added(struct mail_namespace *ns)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct mailbox_list *list = ns->list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mail_user *luser =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_EXPUNGE_USER_CONTEXT(ns->user);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mailbox_list *llist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *const *p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if this is one of our internal namespaces, mark it as such before
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte quota plugin sees it */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = t_strsplit_spaces(luser->env, " ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < LAZY_NAMESPACE_COUNT && *p != NULL; i++, p++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(ns->prefix, *p) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ns->flags |= NAMESPACE_FLAG_NOQUOTA;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (luser != NULL && ns->type == NAMESPACE_PRIVATE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist = p_new(list->pool, struct lazy_expunge_mailbox_list, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist->module_ctx.super = list->v;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->v.delete_mailbox = lazy_expunge_mailbox_list_delete;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT_SET(list, lazy_expunge_mailbox_list_module,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortelazy_expunge_mail_namespaces_created(struct mail_namespace *namespaces)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mail_user *luser =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LAZY_EXPUNGE_USER_CONTEXT(namespaces->user);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mailbox_list *llist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *const *p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (luser == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte p = t_strsplit_spaces(luser->env, " ");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < LAZY_NAMESPACE_COUNT && *p != NULL; i++, p++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *name = *p;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luser->lazy_ns[i] =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_namespace_find_prefix(namespaces, name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (luser->lazy_ns[i] == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_fatal("lazy_expunge: Unknown namespace: '%s'", name);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we don't want to override these namespaces' expunge/delete
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte operations. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist = LAZY_EXPUNGE_LIST_CONTEXT(luser->lazy_ns[i]->list);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte llist->internal_namespace = TRUE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_fatal("lazy_expunge: No namespaces defined");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; i < LAZY_NAMESPACE_COUNT; i++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luser->lazy_ns[i] = luser->lazy_ns[i-1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void lazy_expunge_mail_user_created(struct mail_user *user)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct lazy_expunge_mail_user *luser;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *env;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte env = mail_user_plugin_getenv(user, "lazy_expunge");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (env != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luser = p_new(user->pool, struct lazy_expunge_mail_user, 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luser->module_ctx.super = user->v;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte luser->env = env;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte MODULE_CONTEXT_SET(user, lazy_expunge_mail_user_module, luser);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (user->mail_debug) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i_debug("lazy_expunge: No lazy_expunge setting - "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "plugin disabled");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct mail_storage_hooks lazy_expunge_mail_storage_hooks = {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte .mail_user_created = lazy_expunge_mail_user_created,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte .mail_namespaces_created = lazy_expunge_mail_namespaces_created,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte .mail_namespace_storage_added = lazy_expunge_mail_namespace_storage_added,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte .mailbox_allocated = lazy_expunge_mailbox_allocated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid lazy_expunge_plugin_init(struct module *module)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_storage_hooks_add(module, &lazy_expunge_mail_storage_hooks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid lazy_expunge_plugin_deinit(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mail_storage_hooks_remove(&lazy_expunge_mail_storage_hooks);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte