doveadm-expire.c revision 35283613d4c04ce18836e9fc431582c87b3710a0
/* Copyright (c) 2005-2012 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) \
enum expire_user_state {
};
struct expire_query {
const char *mailbox;
struct imap_match_glob *glob;
};
struct doveadm_expire_mail_cmd_context {
struct dict_transaction_context *trans;
struct dict_iterate_context *iter;
struct hash_table *users;
bool delete_nonexistent_users;
};
const char *doveadm_expire_plugin_version = DOVECOT_VERSION;
void doveadm_expire_plugin_deinit(void);
static bool
{
const struct expire_query *query;
continue;
return TRUE;
} else {
return TRUE;
}
}
return FALSE;
}
static int
const char **username_r)
{
struct doveadm_expire_mail_cmd_context *ectx =
enum expire_user_state state;
/* dict_key = DICT_EXPIRE_PREFIX<user>/<mailbox> */
/* invalid record, ignore */
return -1;
}
/* user no longer exists, delete the record */
return -1;
}
switch (state) {
i_unreached();
case EXPIRE_USER_STATE_EXISTS:
break;
case EXPIRE_USER_STATE_SEEN:
/* seen this user already, skip the record */
return 0;
}
oldest_savedate)) {
/* this mailbox doesn't have any matching messages */
return 0;
}
*username_r = key;
return 1;
}
static int
const char **username_r)
{
struct doveadm_expire_mail_cmd_context *ectx =
unsigned long oldest_savedate;
int ret;
/* invalid record */
continue;
}
if (doveadm_debug) {
i_debug("expire: Stopping iteration on key %s "
(long)ectx->oldest_before_time);
}
break;
}
T_BEGIN {
} T_END;
if (ret > 0)
return TRUE;
/* user has been deleted */
}
}
/* finished */
i_error("Dictionary iteration failed");
return -1;
}
return 0;
}
static const char *const *doveadm_expire_get_patterns(void)
{
const char *str;
char set_name[20];
unsigned int i;
}
(void)array_append_space(&patterns);
}
static bool
const struct mail_search_arg *args,
struct expire_query query)
{
struct doveadm_expire_mail_cmd_context *ectx =
const struct mail_search_arg *arg;
unsigned int query_count;
case SEARCH_MAILBOX_GLOB:
TRUE, '/');
/* fall through */
case SEARCH_MAILBOX:
/* require mailbox to be in expire patterns */
break;
default:
/* there are something else besides mailboxes,
can't optimize this. */
return FALSE;
}
}
}
static bool
const struct mail_search_arg *args)
{
struct doveadm_expire_mail_cmd_context *ectx =
const struct mail_search_arg *arg;
struct expire_query query;
case SEARCH_OR:
break;
case SEARCH_MAILBOX_GLOB:
TRUE, '/');
/* fall through */
case SEARCH_MAILBOX:
/* require mailbox to be in expire patterns */
break;
case SEARCH_BEFORE:
break;
MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0)
break;
break;
default:
break;
}
}
/* no SAVEDBEFORE, can't optimize */
return FALSE;
}
/* one mailbox */
return TRUE;
}
/* no MAILBOX, but check if one of the ORs lists mailboxes */
if (!have_or)
return FALSE;
query))
return TRUE;
}
return FALSE;
}
static time_t
const struct mail_search_arg *args)
{
const struct mail_search_arg *arg;
/* all of the subqueries must have mailbox and savedbefore */
return FALSE;
return FALSE;
}
return TRUE;
}
{
struct doveadm_expire_mail_cmd_context *ectx =
struct expire_set *set;
const struct expire_query *queries;
unsigned int i, count;
/* 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>)
*/
if (doveadm_debug)
i_debug("expire: Couldn't optimize search query");
return FALSE;
}
/* make sure all mailboxes match expire patterns */
for (i = 0; i < count; i++) {
if (doveadm_debug) {
i_debug("expire: Couldn't optimize search query: "
"mailbox %s not in expire database",
}
break;
}
}
return i == count;
}
{
struct doveadm_expire_mail_cmd_context *ectx =
i_error("Dictionary iteration failed");
}
}
{
struct doveadm_expire_mail_cmd_context *ectx;
const struct expire_query *query;
char *username_dup;
return;
if (expire_dict == NULL)
return;
if (ctx->iterate_single_user) {
if (doveadm_debug) {
i_debug("expire: Iterating only a single user, "
"ignoring expire database");
}
return;
}
/* 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");
return;
}
}
}
}
{
}
void doveadm_expire_plugin_deinit(void)
{
}