lazy-expunge-plugin.c revision 9209a733e7448bbcdbe6d782dde8a9caab498d34
/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "array.h"
#include "str.h"
#include "seq-range-array.h"
#include "maildir-storage.h"
#include "mail-namespace.h"
#include "lazy-expunge-plugin.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <time.h>
#define LAZY_EXPUNGE_CONTEXT(obj) \
#define LAZY_EXPUNGE_LIST_CONTEXT(obj) \
enum lazy_namespace {
};
struct lazy_expunge_mailbox_list {
struct mail_storage *storage;
};
struct lazy_expunge_mail_storage {
bool internal_namespace;
};
struct lazy_expunge_transaction {
struct mailbox *expunge_box;
bool failed;
};
const char *lazy_expunge_plugin_version = PACKAGE_VERSION;
static void (*lazy_expunge_next_hook_mail_namespaces_created)
(struct mail_namespace *namespaces);
static void (*lazy_expunge_next_hook_mail_storage_created)
(struct mail_storage *storage);
static void (*lazy_expunge_next_hook_mailbox_list_created)
(struct mailbox_list *list);
static struct mailbox *
{
enum mail_error error;
return box;
if (error != MAIL_ERROR_NOTFOUND)
return NULL;
/* try creating it. */
return NULL;
/* and try opening again */
return box;
}
{
struct lazy_expunge_transaction *lt =
struct mail_storage *deststorage;
"lazy_expunge: Couldn't open expunge mailbox");
return;
}
}
}
static struct mailbox_transaction_context *
{
struct mailbox_transaction_context *t;
struct lazy_expunge_transaction *lt;
return t;
}
struct lazy_expunge_move_context {
unsigned int dir_len;
};
{
const char *p;
return 1;
}
struct lazy_expunge_transaction *lt)
{
struct mailbox_transaction_context *trans;
struct index_transaction_context *itrans;
struct lazy_expunge_move_context ctx;
unsigned int i, count;
const char *dir;
bool is_file;
int ret = 0;
&ctx) < 0) {
ret = -1;
break;
}
}
}
if (mailbox_transaction_commit(&trans, 0) < 0)
ret = -1;
return ret;
}
{
}
static int
enum mailbox_sync_flags flags,
{
int ret;
ret = -1;
} else {
}
return ret;
}
static void
{
}
static struct mail *
struct mailbox_header_lookup_ctx *wanted_headers)
{
union mail_module_context *mmail;
struct mail_private *mail;
return _mail;
}
static struct mailbox *
{
struct lazy_expunge_mail_storage *lstorage =
union mailbox_module_context *mbox;
return box;
return box;
}
{
unsigned int src_dirlen, dest_dirlen;
int ret = 0;
return 0;
if (!EDESTDIREXISTS(errno)) {
}
/* rename all the files separately */
"opendir(%s) failed: %m", srcdir);
return -1;
}
continue;
"rename(%s, %s) failed: %m",
ret = -1;
}
}
"closedir(%s) failed: %m", srcdir);
ret = -1;
}
if (ret == 0) {
"rmdir(%s) failed: %m", srcdir);
ret = -1;
}
}
return ret;
}
static int
{
const char *dest_name = *_dest_name;
return 0;
if (!EDESTDIREXISTS(errno)) {
return -1;
}
/* mailbox is being deleted multiple times per second.
update the filename. */
}
t_push();
}
}
t_pop();
*_dest_name = dest_name;
return 1;
}
static int
{
struct lazy_expunge_mailbox_list *llist =
struct lazy_expunge_mail_storage *lstorage;
struct mailbox_list *dest_list;
enum mailbox_name_status status;
const char *destname;
char timestamp[256];
int ret;
/* not a maildir storage */
}
if (lstorage->internal_namespace)
/* first do the normal sanity checks */
"INBOX can't be deleted.");
return -1;
}
return -1;
if (status == MAILBOX_NAME_INVALID) {
"Invalid mailbox name");
return -1;
}
/* destination mailbox name needs to contain a timestamp */
/* first move the actual mailbox */
return -1;
if (ret == 0) {
return -1;
}
/* next move the expunged messages mailbox, if it exists */
return 0;
}
{
struct lazy_expunge_mailbox_list *llist =
struct lazy_expunge_mail_storage *lstorage;
const char *const *p;
unsigned int i;
/* only maildir supported for now */
return;
/* if this is one of our internal storages, mark it as such before
quota plugin sees it */
t_push();
for (i = 0; i < LAZY_NAMESPACE_COUNT; i++, p++) {
break;
}
}
t_pop();
}
{
struct lazy_expunge_mailbox_list *llist;
}
static void
{
struct lazy_expunge_mail_storage *lstorage;
const char *const *p;
int i;
t_push();
for (i = 0; i < LAZY_NAMESPACE_COUNT; i++, p++) {
const char *name = *p;
lazy_namespaces[i] =
if (lazy_namespaces[i] == NULL)
i_fatal("lazy_expunge: Namespace must be in maildir "
"format: %s", name);
}
operations. */
}
t_pop();
}
void lazy_expunge_plugin_init(void)
{
return;
}
void lazy_expunge_plugin_deinit(void)
{
return;
}