expire-env.c revision e07bf3772a2bc075de4915ad0961beb8d083c22d
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "lib.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "array.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "imap-match.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "expire-env.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include <stdlib.h>
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenenum expire_type {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen EXPIRE_TYPE_EXPUNGE,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen EXPIRE_TYPE_ALTMOVE
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct expire_box {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const char *pattern;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct imap_match_glob *glob;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum expire_type type;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int expire_secs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct expire_env {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_t pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ARRAY_DEFINE(expire_boxes, struct expire_box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen};
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void expire_env_parse(struct expire_env *env, const char *str,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum expire_type type)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct expire_box box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen char *const *names;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int len;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (str == NULL)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen names = p_strsplit(env->pool, str, " ");
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen len = str_array_length((const char *const *)names);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen p_array_init(&env->expire_boxes, env->pool, len / 2);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (; *names != NULL; names += 2) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (names[1] == NULL) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_fatal("expire: Missing expire days for mailbox '%s'",
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen *names);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen box.pattern = *names;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* FIXME: hardcoded separator isn't very good */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen box.glob = imap_match_init(env->pool, box.pattern, TRUE, '/');
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen box.type = type;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen box.expire_secs = strtoul(names[1], NULL, 10) * 3600 * 24;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen array_append(&env->expire_boxes, &box, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct expire_env *expire_env_init(const char *expunges, const char *altmoves)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct expire_env *env;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_t pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool = pool_alloconly_create("Expire pool", 512);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen env = p_new(pool, struct expire_env, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen env->pool = pool;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen expire_env_parse(env, expunges, EXPIRE_TYPE_EXPUNGE);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen expire_env_parse(env, altmoves, EXPIRE_TYPE_ALTMOVE);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return env;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvoid expire_env_deinit(struct expire_env *env)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen pool_unref(&env->pool);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenbool expire_box_find(struct expire_env *env, const char *name,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int *expunge_secs_r,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int *altmove_secs_r)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen const struct expire_box *expire_boxes;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int i, count;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int secs, expunge_min = 0, altmove_min = 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen expire_boxes = array_get(&env->expire_boxes, &count);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen for (i = 0; i < count; i++) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (imap_match(expire_boxes[i].glob, name) == IMAP_MATCH_YES) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen secs = expire_boxes[i].expire_secs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_assert(secs > 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen switch (expire_boxes[i].type) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case EXPIRE_TYPE_EXPUNGE:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (expunge_min == 0 || expunge_min > secs)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen expunge_min = secs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen case EXPIRE_TYPE_ALTMOVE:
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (altmove_min == 0 || altmove_min > secs)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen altmove_min = secs;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen break;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen *expunge_secs_r = expunge_min;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen *altmove_secs_r = altmove_min;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return expunge_min > 0 || altmove_min > 0;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenunsigned int expire_box_find_min_secs(struct expire_env *env, const char *name,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen bool *altmove_r)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen unsigned int secs1, secs2;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen (void)expire_box_find(env, name, &secs1, &secs2);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (secs1 < secs2 && secs1 != 0) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen *altmove_r = FALSE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return secs1;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen } else {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen *altmove_r = TRUE;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return secs2;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen }
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen