mail-autoexpunge.c revision 67c05b67130df470e2bf2619b2cef39fc972c69d
/* Copyright (c) 2015-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "file-create-locked.h"
#include "mailbox-list-iter.h"
#include "mail-storage-private.h"
#include "mail-namespace.h"
#include "mail-user.h"
#include "mail-autoexpunge.h"
#define AUTOEXPUNGE_LOCK_FNAME "dovecot.autoexpunge.lock"
static bool
{
struct file_create_settings lock_set;
bool created;
int ret;
return TRUE;
/* Try to lock the autoexpunging. If the lock already exists, another
process is already busy with expunging, so we don't have to do it.
The easiest place where to store the lock file to is the home
directory, but allow autoexpunging to work even if we can't get
it. The lock isn't really required; it 1) improves performance
so that multiple processes won't do the same work unnecessarily,
and 2) it helps to avoid duplicate mails being added with
lazy_expunge. */
/* home lookup failed - shouldn't really happen */
return TRUE;
}
if (ret == 0) {
i_warning("autoexpunge: User has no home directory, can't lock");
return TRUE;
}
const struct mail_storage_settings *mail_set =
/* another process is autoexpunging, so we don't
need to. */
return FALSE;
}
/* do autoexpunging anyway */
return TRUE;
}
return TRUE;
}
static int
unsigned int max_mails, unsigned int *expunged_count)
{
struct mailbox_transaction_context *t;
struct mailbox_metadata metadata;
const struct mail_index_header *hdr;
struct mailbox_status status;
const void *data;
unsigned int count = 0;
int ret = 0;
if ((unsigned int)ioloop_time < interval_time)
expire_time = 0;
else
/* first try to check quickly from mailbox list index if we should
bother opening this mailbox. */
/* autocreated mailbox doesn't exist yet */
return 0;
}
return -1;
}
return 0;
&metadata) < 0)
return -1;
return 0;
}
return -1;
t = mailbox_transaction_begin(box, 0);
mailbox_transaction_set_reason(t, "autoexpunge");
/* max_mails is still being reached -> expunge.
don't even check saved-dates before we're
below max_mails. */
count++;
} else if (interval_time == 0) {
/* only max_mails is used. nothing further to do. */
break;
break;
count++;
/* already expunged */
} else {
/* failed */
ret = -1;
break;
}
}
if (mailbox_transaction_commit(&t) < 0)
ret = -1;
else
*expunged_count += count;
return ret;
}
static void
unsigned int autoexpunge,
unsigned int autoexpunge_max_mails,
unsigned int *expunged_count)
{
/* autoexpunge is configured by admin, so we can safely ignore
any ACLs the user might normally have against expunging in
the mailbox. */
expunged_count) < 0) {
i_error("Failed to autoexpunge mailbox '%s': %s",
}
mailbox_free(&box);
}
static void
const struct mailbox_settings *set,
unsigned int *expunged_count)
{
struct mailbox_list_iterate_context *iter;
const struct mailbox_info *info;
const char *iter_name;
} T_END;
if (mailbox_list_iter_deinit(&iter) < 0) {
i_error("Failed to iterate autoexpunge mailboxes '%s': %s",
}
}
static bool
unsigned int *expunged_count)
{
struct mailbox_settings *const *box_set;
const char *vname;
return TRUE;
if ((*box_set)->autoexpunge == 0 &&
(*box_set)->autoexpunge_max_mails == 0)
continue;
return FALSE;
else {
else
}
}
return TRUE;
}
{
struct mail_namespace *ns;
unsigned int expunged_count = 0;
break;
}
}
return expunged_count;
}