[dovecot-cvs] dovecot/src/plugins/mbox-snarf .cvsignore, NONE, 1.1 Makefile.am, NONE, 1.1 mbox-snarf-plugin.c, NONE, 1.1 mbox-snarf-plugin.h, NONE, 1.1
tss at dovecot.org
tss at dovecot.org
Thu May 17 20:25:29 EEST 2007
Update of /var/lib/cvs/dovecot/src/plugins/mbox-snarf
In directory talvi:/tmp/cvs-serv16250/src/plugins/mbox-snarf
Added Files:
.cvsignore Makefile.am mbox-snarf-plugin.c mbox-snarf-plugin.h
Log Message:
Added mbox snarf plugin to move mails from /var/spool/mail to ~/mbox if it
exists.
--- NEW FILE: .cvsignore ---
*.la
*.lo
*.o
.deps
.libs
Makefile
Makefile.in
so_locations
--- NEW FILE: Makefile.am ---
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-index \
-I$(top_srcdir)/src/lib-storage
lib20_mbox_snarf_plugin_la_LDFLAGS = -module -avoid-version
module_LTLIBRARIES = \
lib20_mbox_snarf_plugin.la
lib20_mbox_snarf_plugin_la_SOURCES = \
mbox-snarf-plugin.c
noinst_HEADERS = \
mbox-snarf-plugin.h
install-exec-local:
for d in imap pop3; do \
$(mkdir_p) $(DESTDIR)$(moduledir)/$$d; \
rm -f $(DESTDIR)$(moduledir)/$$d/lib20_mbox_snarf_plugin.so; \
$(LN_S) ../lib20_mbox_snarf_plugin.so $(DESTDIR)$(moduledir)/$$d; \
done
--- NEW FILE: mbox-snarf-plugin.c ---
/* Copyright (C) 2007 Timo Sirainen */
#include "lib.h"
#include "array.h"
#include "home-expand.h"
#include "mail-search.h"
#include "mail-storage-private.h"
#include "mbox-snarf-plugin.h"
#include <stdlib.h>
#include <sys/stat.h>
#define MBOX_SNARF_CONTEXT(obj) \
MODULE_CONTEXT(obj, mbox_snarf_storage_module)
struct mbox_snarf_mail_storage {
union mail_storage_module_context module_ctx;
const char *snarf_inbox_path;
bool open_spool_inbox;
};
struct mbox_snarf_mailbox {
union mailbox_module_context module_ctx;
struct mailbox *spool_mbox;
};
const char *mbox_snarf_plugin_version = PACKAGE_VERSION;
static void (*mbox_snarf_next_hook_mail_storage_created)
(struct mail_storage *storage);
static MODULE_CONTEXT_DEFINE_INIT(mbox_snarf_storage_module,
&mail_storage_module_register);
static int sync_mailbox(struct mailbox *box)
{
struct mailbox_sync_context *ctx;
struct mailbox_sync_rec sync_rec;
ctx = mailbox_sync_init(box, MAILBOX_SYNC_FLAG_FULL_READ);
while (mailbox_sync_next(ctx, &sync_rec) > 0)
;
return mailbox_sync_deinit(&ctx, 0, NULL);
}
static int mbox_snarf(struct mailbox *srcbox, struct mailbox *destbox)
{
struct mail_search_arg search_arg;
struct mail_search_context *search_ctx;
struct mailbox_transaction_context *src_trans, *dest_trans;
struct mail *mail;
int ret;
if (sync_mailbox(srcbox) < 0)
return -1;
memset(&search_arg, 0, sizeof(search_arg));
search_arg.type = SEARCH_ALL;
src_trans = mailbox_transaction_begin(srcbox, 0);
dest_trans = mailbox_transaction_begin(destbox,
MAILBOX_TRANSACTION_FLAG_EXTERNAL);
search_ctx = mailbox_search_init(src_trans, NULL, &search_arg, NULL);
mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER |
MAIL_FETCH_STREAM_BODY, NULL);
while ((ret = mailbox_search_next(search_ctx, mail)) > 0) {
if (mail->expunged)
continue;
if (mailbox_copy(dest_trans, mail, 0, NULL, NULL) < 0) {
if (!mail->expunged) {
ret = -1;
break;
}
}
mail_expunge(mail);
}
mail_free(&mail);
if (mailbox_search_deinit(&search_ctx) < 0)
ret = -1;
/* commit the copied messages to the destination mailbox. if we crash
between that and between expunging the messages from the source
mailbox, we're left with duplicates. */
if (ret < 0)
mailbox_transaction_rollback(&dest_trans);
else if (mailbox_transaction_commit(&dest_trans, 0) < 0)
ret = -1;
if (ret < 0)
mailbox_transaction_rollback(&src_trans);
else {
if (mailbox_transaction_commit(&src_trans, 0) < 0)
ret = -1;
}
return ret;
}
static struct mailbox_sync_context *
mbox_snarf_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
{
struct mbox_snarf_mail_storage *mstorage =
MBOX_SNARF_CONTEXT(box->storage);
struct mbox_snarf_mailbox *mbox = MBOX_SNARF_CONTEXT(box);
if (mbox->spool_mbox == NULL) {
/* try to open the spool mbox */
mstorage->open_spool_inbox = TRUE;
mbox->spool_mbox =
mailbox_open(box->storage, "INBOX", NULL,
MAILBOX_OPEN_KEEP_RECENT |
MAILBOX_OPEN_NO_INDEX_FILES);
mstorage->open_spool_inbox = FALSE;
}
if (mbox->spool_mbox != NULL)
mbox_snarf(mbox->spool_mbox, box);
return mbox->module_ctx.super.sync_init(box, flags);
}
static struct mailbox *
mbox_snarf_mailbox_open(struct mail_storage *storage, const char *name,
struct istream *input, enum mailbox_open_flags flags)
{
struct mbox_snarf_mail_storage *mstorage =
MBOX_SNARF_CONTEXT(storage);
struct mailbox *box;
struct mbox_snarf_mailbox *mbox;
struct stat st;
enum mail_storage_flags old_flags = storage->flags;
bool use_snarfing = FALSE;
if (strcasecmp(name, "INBOX") == 0 && !mstorage->open_spool_inbox) {
if (stat(mstorage->snarf_inbox_path, &st) == 0) {
/* use ~/mbox as the INBOX */
name = mstorage->snarf_inbox_path;
use_snarfing = TRUE;
storage->flags |= MAIL_STORAGE_FLAG_FULL_FS_ACCESS;
} else if (errno != ENOENT) {
mail_storage_set_critical(storage,
"stat(%s) failed: %m",
mstorage->snarf_inbox_path);
}
}
box = mstorage->module_ctx.super.
mailbox_open(storage, name, input, flags);
storage->flags = old_flags;
if (box == NULL || !use_snarfing)
return box;
mbox = p_new(box->pool, struct mbox_snarf_mailbox, 1);
mbox->module_ctx.super = box->v;
box->v.sync_init = mbox_snarf_sync_init;
MODULE_CONTEXT_SET(box, mbox_snarf_storage_module, mbox);
return box;
}
static void mbox_snarf_mail_storage_created(struct mail_storage *storage)
{
struct mbox_snarf_mail_storage *mstorage;
if (mbox_snarf_next_hook_mail_storage_created != NULL)
mbox_snarf_next_hook_mail_storage_created(storage);
mstorage = p_new(storage->pool, struct mbox_snarf_mail_storage, 1);
mstorage->snarf_inbox_path =
p_strdup(storage->pool, home_expand(getenv("MBOX_SNARF")));
mstorage->module_ctx.super = storage->v;
storage->v.mailbox_open = mbox_snarf_mailbox_open;
MODULE_CONTEXT_SET(storage, mbox_snarf_storage_module, mstorage);
}
void mbox_snarf_plugin_init(void)
{
const char *path;
path = getenv("MBOX_SNARF");
if (path != NULL) {
mbox_snarf_next_hook_mail_storage_created =
hook_mail_storage_created;
hook_mail_storage_created = mbox_snarf_mail_storage_created;
}
}
void mbox_snarf_plugin_deinit(void)
{
if (getenv("MBOX_SNARF") != NULL) {
hook_mail_storage_created =
mbox_snarf_next_hook_mail_storage_created;
}
}
--- NEW FILE: mbox-snarf-plugin.h ---
#ifndef __MBOX_SNARF_PLUGIN_H
#define __MBOX_SNARF_PLUGIN_H
void mbox_snarf_plugin_init(void);
void mbox_snarf_plugin_deinit(void);
#endif
More information about the dovecot-cvs
mailing list