changeset 6748:d712370dfd14 HEAD

Added raw storage for opening single-mail files/streams as mailboxes.
author Timo Sirainen <tss@iki.fi>
date Thu, 08 Nov 2007 21:18:55 +0200
parents 0cee1cccd14c
children ced2ffbeef8b
files configure.in src/lib-storage/index/Makefile.am src/lib-storage/index/raw/Makefile.am src/lib-storage/index/raw/raw-mail.c src/lib-storage/index/raw/raw-storage.c src/lib-storage/index/raw/raw-storage.h src/lib-storage/index/raw/raw-sync.c src/lib-storage/index/raw/raw-sync.h src/lib-storage/index/raw/raw-transaction.c
diffstat 9 files changed, 615 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/configure.in	Thu Nov 08 21:18:10 2007 +0200
+++ b/configure.in	Thu Nov 08 21:18:55 2007 +0200
@@ -339,7 +339,7 @@
 		AC_MSG_ERROR([--with-storages needs storage list as parameter])
 	fi
 	mail_storages=`echo "$withval"|sed 's/,/ /g'` ],
-	mail_storages="maildir mbox dbox cydir")
+	mail_storages="maildir mbox dbox cydir raw")
 AC_SUBST(mail_storages)
 
 AC_ARG_WITH(sql-drivers,
@@ -1928,6 +1928,7 @@
 mbox_libs='$(top_builddir)/src/lib-storage/index/mbox/libstorage_mbox.a'
 dbox_libs='$(top_builddir)/src/lib-storage/index/dbox/libstorage_dbox.a'
 cydir_libs='$(top_builddir)/src/lib-storage/index/cydir/libstorage_cydir.a'
+raw_libs='$(top_builddir)/src/lib-storage/index/raw/libstorage_raw.a'
 index_libs='$(top_builddir)/src/lib-storage/index/libstorage_index.a $(top_builddir)/src/lib-index/libindex.a'
 
 deliver_storage="mbox"
@@ -2028,6 +2029,7 @@
 src/lib-storage/index/mbox/Makefile
 src/lib-storage/index/dbox/Makefile
 src/lib-storage/index/cydir/Makefile
+src/lib-storage/index/raw/Makefile
 src/lib-storage/register/Makefile
 src/auth/Makefile
 src/deliver/Makefile
--- a/src/lib-storage/index/Makefile.am	Thu Nov 08 21:18:10 2007 +0200
+++ b/src/lib-storage/index/Makefile.am	Thu Nov 08 21:18:55 2007 +0200
@@ -1,4 +1,4 @@
-SUBDIRS = maildir mbox dbox cydir
+SUBDIRS = maildir mbox dbox cydir raw
 
 noinst_LIBRARIES = libstorage_index.a
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/Makefile.am	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,26 @@
+noinst_LIBRARIES = libstorage_raw.a
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-mail \
+	-I$(top_srcdir)/src/lib-imap \
+	-I$(top_srcdir)/src/lib-index \
+	-I$(top_srcdir)/src/lib-storage \
+	-I$(top_srcdir)/src/lib-storage/index
+
+libstorage_raw_a_SOURCES = \
+	raw-mail.c \
+	raw-sync.c \
+	raw-storage.c \
+	raw-transaction.c
+
+headers = \
+	raw-storage.h \
+	raw-sync.h
+
+if INSTALL_HEADERS
+  pkginc_libdir=$(pkgincludedir)/src/lib-storage/index/raw
+  pkginc_lib_HEADERS = $(headers)
+else
+  noinst_HEADERS = $(headers)
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/raw-mail.c	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,109 @@
+/* Copyright (c) 2007 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "istream.h"
+#include "index-mail.h"
+#include "raw-storage.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+static int raw_mail_stat(struct mail *mail)
+{
+	struct raw_mailbox *mbox = (struct raw_mailbox *)mail->box;
+	const struct stat *st;
+
+	st = i_stream_stat(mbox->input, TRUE);
+	if (st == NULL) {
+		mail_storage_set_critical(mail->box->storage,
+					  "stat(%s) failed: %m", mbox->path);
+		return -1;
+	}
+
+	mbox->mtime = st->st_mtime;
+	mbox->ctime = st->st_ctime;
+	mbox->size = st->st_size;
+	return 0;
+}
+
+static int raw_mail_get_received_date(struct mail *_mail, time_t *date_r)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct raw_mailbox *mbox = (struct raw_mailbox *)_mail->box;
+
+	if (mbox->mtime == (time_t)-1) {
+		if (raw_mail_stat(_mail) < 0)
+			return -1;
+	}
+
+	*date_r = mail->data.received_date = mbox->mtime;
+	return 0;
+}
+
+static int raw_mail_get_save_date(struct mail *_mail, time_t *date_r)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct raw_mailbox *mbox = (struct raw_mailbox *)_mail->box;
+
+	if (mbox->ctime == (time_t)-1) {
+		if (raw_mail_stat(_mail) < 0)
+			return -1;
+	}
+
+	*date_r = mail->data.save_date = mbox->ctime;
+	return 0;
+}
+
+static int raw_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct raw_mailbox *mbox = (struct raw_mailbox *)_mail->box;
+
+	if (mbox->size == (uoff_t)-1) {
+		if (raw_mail_stat(_mail) < 0)
+			return -1;
+	}
+
+	*size_r = mail->data.physical_size = mbox->size;
+	return 0;
+}
+
+static int
+raw_mail_get_stream(struct mail *_mail, struct message_size *hdr_size,
+		    struct message_size *body_size, struct istream **stream_r)
+{
+	struct index_mail *mail = (struct index_mail *)_mail;
+	struct raw_mailbox *mbox = (struct raw_mailbox *)_mail->box;
+
+	if (mail->data.stream == NULL) {
+		i_stream_ref(mbox->input);
+		mail->data.stream = mbox->input;
+	}
+
+	return index_mail_init_stream(mail, hdr_size, body_size, stream_r);
+}
+
+struct mail_vfuncs raw_mail_vfuncs = {
+	index_mail_close,
+	index_mail_free,
+	index_mail_set_seq,
+	index_mail_set_uid,
+
+	index_mail_get_flags,
+	index_mail_get_keywords,
+	index_mail_get_parts,
+	index_mail_get_date,
+	raw_mail_get_received_date,
+	raw_mail_get_save_date,
+	index_mail_get_virtual_size,
+	raw_mail_get_physical_size,
+	index_mail_get_first_header,
+	index_mail_get_headers,
+	index_mail_get_header_stream,
+	raw_mail_get_stream,
+	index_mail_get_special,
+	index_mail_update_flags,
+	index_mail_update_keywords,
+	index_mail_expunge
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/raw-storage.c	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,307 @@
+/* Copyright (c) 2007 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "ioloop.h"
+#include "istream.h"
+#include "index-mail.h"
+#include "mail-copy.h"
+#include "raw-sync.h"
+#include "raw-storage.h"
+
+#define RAW_LIST_CONTEXT(obj) \
+	MODULE_CONTEXT(obj, raw_mailbox_list_module)
+
+extern struct mail_storage raw_storage;
+extern struct mailbox raw_mailbox;
+
+static MODULE_CONTEXT_DEFINE_INIT(raw_mailbox_list_module,
+				  &mailbox_list_module_register);
+
+static int raw_list_delete_mailbox(struct mailbox_list *list, const char *name);
+static int raw_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx,
+				    const char *dir, const char *fname,
+				    enum mailbox_list_file_type type,
+				    enum mailbox_info_flags *flags);
+
+static int
+raw_get_list_settings(struct mailbox_list_settings *list_set,
+		      const char *data, enum mail_storage_flags flags,
+		      const char **layout_r, const char **error_r)
+{
+	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
+
+	*layout_r = "fs";
+
+	memset(list_set, 0, sizeof(*list_set));
+	list_set->subscription_fname = RAW_SUBSCRIPTION_FILE_NAME;
+	list_set->maildir_name = "";
+
+	if (data == NULL || *data == '\0' || *data == ':') {
+		/* we won't do any guessing for this format. */
+		if (debug)
+			i_info("raw: mailbox location not given");
+		*error_r = "Root mail directory not given";
+		return -1;
+	}
+
+	if (debug)
+		i_info("raw: data=%s", data);
+	return mailbox_list_settings_parse(data, list_set, layout_r, NULL,
+					   error_r);
+}
+
+static struct mail_storage *raw_alloc(void)
+{
+	struct raw_storage *storage;
+	pool_t pool;
+
+	pool = pool_alloconly_create("raw storage", 512+256);
+	storage = p_new(pool, struct raw_storage, 1);
+	storage->storage = raw_storage;
+	storage->storage.pool = pool;
+
+	return &storage->storage;
+}
+
+static int raw_create(struct mail_storage *_storage, const char *data,
+		      const char **error_r)
+{
+	struct raw_storage *storage = (struct raw_storage *)_storage;
+	struct mailbox_list_settings list_set;
+	struct stat st;
+	const char *layout;
+
+	if (raw_get_list_settings(&list_set, data, _storage->flags,
+				  &layout, error_r) < 0)
+		return -1;
+	list_set.mail_storage_flags = &_storage->flags;
+	list_set.lock_method = &_storage->lock_method;
+
+	if (stat(list_set.root_dir, &st) < 0) {
+		if (errno != ENOENT) {
+			*error_r = t_strdup_printf("stat(%s) failed: %m",
+						   list_set.root_dir);
+		} else {
+			*error_r = t_strdup_printf(
+				"Root mail directory doesn't exist: %s",
+				list_set.root_dir);
+		}
+		return -1;
+	}
+
+	if (mailbox_list_alloc(layout, &_storage->list, error_r) < 0)
+		return -1;
+	storage->list_module_ctx.super = _storage->list->v;
+	_storage->list->v.iter_is_mailbox = raw_list_iter_is_mailbox;
+	_storage->list->v.delete_mailbox = raw_list_delete_mailbox;
+
+	MODULE_CONTEXT_SET_FULL(_storage->list, raw_mailbox_list_module,
+				storage, &storage->list_module_ctx);
+
+	/* finish list init after we've overridden vfuncs */
+	mailbox_list_init(_storage->list, _storage->ns, &list_set,
+			  mail_storage_get_list_flags(_storage->flags));
+	return 0;
+}
+
+static int
+raw_mailbox_open_input(struct mail_storage *storage, const char *name,
+		       const char *path, struct istream **input_r)
+{
+	int fd;
+
+	fd = open(path, O_RDONLY);
+	if (fd == -1) {
+		if (ENOTFOUND(errno)) {
+			mail_storage_set_error(storage, MAIL_ERROR_NOTFOUND,
+				T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
+		} else if (!mail_storage_set_error_from_errno(storage)) {
+			mail_storage_set_critical(storage,
+						  "open(%s) failed: %m", path);
+		}
+		return -1;
+	}
+	*input_r = i_stream_create_fd(fd, MAIL_READ_BLOCK_SIZE, TRUE);
+	return 0;
+}
+
+static struct mailbox *
+raw_mailbox_open(struct mail_storage *_storage, const char *name,
+		 struct istream *input, enum mailbox_open_flags flags)
+{
+	struct raw_storage *storage = (struct raw_storage *)_storage;
+	struct raw_mailbox *mbox;
+	const char *path;
+	pool_t pool;
+	bool stream = input != NULL;
+
+	flags |= MAILBOX_OPEN_READONLY | MAILBOX_OPEN_NO_INDEX_FILES;
+
+	path = mailbox_list_get_path(_storage->list, name,
+				     MAILBOX_LIST_PATH_TYPE_MAILBOX);
+	if (input != NULL)
+		i_stream_ref(input);
+	else {
+		if (raw_mailbox_open_input(_storage, name, path, &input) < 0)
+			return NULL;
+	}
+
+	pool = pool_alloconly_create("raw mailbox", 1024+512);
+	mbox = p_new(pool, struct raw_mailbox, 1);
+	mbox->ibox.box = raw_mailbox;
+	mbox->ibox.box.pool = pool;
+	mbox->ibox.storage = &storage->storage;
+	mbox->ibox.mail_vfuncs = &raw_mail_vfuncs;
+	mbox->ibox.index = index_storage_alloc(_storage, name, flags, NULL);
+
+	mbox->storage = storage;
+	mbox->path = p_strdup(pool, path);
+	mbox->input = input;
+
+	if (stream)
+		mbox->mtime = mbox->ctime = ioloop_time;
+	else
+		mbox->mtime = mbox->ctime = (time_t)-1;
+	mbox->size = (uoff_t)-1;
+
+	index_storage_mailbox_init(&mbox->ibox, name, flags, FALSE);
+	return &mbox->ibox.box;
+}
+
+static int raw_mailbox_close(struct mailbox *box)
+{
+	struct raw_mailbox *mbox = (struct raw_mailbox *)box;
+
+	i_stream_unref(&mbox->input);
+	return index_storage_mailbox_close(box);
+}
+
+static int raw_mailbox_create(struct mail_storage *storage,
+			      const char *name ATTR_UNUSED,
+			      bool directory ATTR_UNUSED)
+{
+	mail_storage_set_error(storage, MAIL_ERROR_NOTPOSSIBLE,
+			       "Raw mailbox creation isn't supported");
+	return -1;
+}
+
+static int raw_list_delete_mailbox(struct mailbox_list *list,
+				   const char *name ATTR_UNUSED)
+{
+	mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
+			       "Raw mailbox deletion isn't supported");
+	return -1;
+}
+
+static void raw_notify_changes(struct mailbox *box ATTR_UNUSED)
+{
+}
+
+static int raw_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx,
+				    const char *dir, const char *fname,
+				    enum mailbox_list_file_type type,
+				    enum mailbox_info_flags *flags_r)
+{
+	struct mail_storage *storage = RAW_LIST_CONTEXT(ctx->list);
+	const char *path;
+	struct stat st;
+	int ret = 1;
+
+	/* try to avoid stat() with these checks */
+	if (type == MAILBOX_LIST_FILE_TYPE_DIR) {
+		*flags_r = MAILBOX_NOSELECT | MAILBOX_CHILDREN;
+		return 1;
+	}
+	if (type != MAILBOX_LIST_FILE_TYPE_SYMLINK &&
+	    type != MAILBOX_LIST_FILE_TYPE_UNKNOWN &&
+	    (ctx->flags & MAILBOX_LIST_ITER_RETURN_NO_FLAGS) != 0) {
+		*flags_r = MAILBOX_NOINFERIORS;
+		return 1;
+	}
+
+	/* need to stat() then */
+	t_push();
+	path = t_strconcat(dir, "/", fname, NULL);
+	if (stat(path, &st) == 0) {
+		if (S_ISDIR(st.st_mode))
+			*flags_r = MAILBOX_NOSELECT | MAILBOX_CHILDREN;
+		else
+			*flags_r = MAILBOX_NOINFERIORS;
+	} else if (errno == EACCES || errno == ELOOP)
+		*flags_r = MAILBOX_NOSELECT;
+	else if (ENOTFOUND(errno)) {
+		*flags_r = MAILBOX_NONEXISTENT;
+		ret = 0;
+	} else {
+		mail_storage_set_critical(storage, "stat(%s) failed: %m", path);
+		ret = -1;
+	}
+	t_pop();
+
+	return ret;
+}
+
+static void raw_class_init(void)
+{
+	raw_transaction_class_init();
+}
+
+static void raw_class_deinit(void)
+{
+	raw_transaction_class_deinit();
+}
+
+struct mail_storage raw_storage = {
+	MEMBER(name) RAW_STORAGE_NAME,
+	MEMBER(mailbox_is_file) TRUE,
+
+	{
+		raw_class_init,
+		raw_class_deinit,
+		raw_alloc,
+		raw_create,
+		NULL,
+		NULL,
+		raw_mailbox_open,
+		raw_mailbox_create
+	}
+};
+
+struct mailbox raw_mailbox = {
+	MEMBER(name) NULL, 
+	MEMBER(storage) NULL, 
+
+	{
+		index_storage_is_readonly,
+		index_storage_allow_new_keywords,
+		raw_mailbox_close,
+		index_storage_get_status,
+		NULL,
+		NULL,
+		raw_storage_sync_init,
+		index_mailbox_sync_next,
+		index_mailbox_sync_deinit,
+		NULL,
+		raw_notify_changes,
+		index_transaction_begin,
+		index_transaction_commit,
+		index_transaction_rollback,
+		index_keywords_create,
+		index_keywords_free,
+		index_storage_get_uids,
+		index_mail_alloc,
+		index_header_lookup_init,
+		index_header_lookup_deinit,
+		index_storage_search_init,
+		index_storage_search_deinit,
+		index_storage_search_next_nonblock,
+		index_storage_search_next_update_seq,
+		NULL,
+		NULL,
+		NULL,
+		NULL,
+		mail_storage_copy,
+		index_storage_is_inconsistent
+	}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/raw-storage.h	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,33 @@
+#ifndef RAW_STORAGE_H
+#define RAW_STORAGE_H
+
+#include "index-storage.h"
+#include "mailbox-list-private.h"
+
+#define RAW_STORAGE_NAME "raw"
+#define RAW_SUBSCRIPTION_FILE_NAME "subscriptions"
+
+struct raw_storage {
+	struct mail_storage storage;
+	union mailbox_list_module_context list_module_ctx;
+};
+
+struct raw_mailbox {
+	struct index_mailbox ibox;
+	struct raw_storage *storage;
+
+	const char *path;
+	struct istream *input;
+
+	time_t mtime, ctime;
+	uoff_t size;
+
+	unsigned int synced:1;
+};
+
+extern struct mail_vfuncs raw_mail_vfuncs;
+
+void raw_transaction_class_init(void);
+void raw_transaction_class_deinit(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/raw-sync.c	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,58 @@
+/* Copyright (c) 2007 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "raw-storage.h"
+#include "raw-sync.h"
+
+static int raw_sync(struct raw_mailbox *mbox)
+{
+        struct mail_index_sync_ctx *index_sync_ctx;
+	struct mail_index_view *sync_view;
+	struct mail_index_transaction *trans;
+	uint32_t seq, uid_validity = ioloop_time;
+	enum mail_index_sync_flags sync_flags;
+
+	i_assert(!mbox->synced);
+
+	sync_flags = MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY;
+	if (!mbox->ibox.keep_recent)
+		sync_flags |= MAIL_INDEX_SYNC_FLAG_DROP_RECENT;
+
+	if (mail_index_sync_begin(mbox->ibox.index, &index_sync_ctx,
+				  &sync_view, &trans, sync_flags) < 0) {
+		mail_storage_set_index_error(&mbox->ibox);
+		return -1;
+	}
+
+	/* set our uidvalidity */
+	mail_index_update_header(trans,
+		offsetof(struct mail_index_header, uid_validity),
+		&uid_validity, sizeof(uid_validity), TRUE);
+
+	/* add our one and only message */
+	mail_index_append(trans, 1, &seq);
+	index_mailbox_set_recent_uid(&mbox->ibox, 1);
+
+	if (mail_index_sync_commit(&index_sync_ctx) < 0) {
+		mail_storage_set_index_error(&mbox->ibox);
+		return -1;
+	}
+	mbox->synced = TRUE;
+	return 0;
+}
+
+struct mailbox_sync_context *
+raw_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
+{
+	struct raw_mailbox *mbox = (struct raw_mailbox *)box;
+	int ret = 0;
+
+	if (!box->opened)
+		index_storage_mailbox_open(&mbox->ibox);
+
+	if (!mbox->synced)
+		ret = raw_sync(mbox);
+
+	return index_mailbox_sync_init(box, flags, ret < 0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/raw-sync.h	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,9 @@
+#ifndef RAW_SYNC_H
+#define RAW_SYNC_H
+
+struct mailbox;
+
+struct mailbox_sync_context *
+raw_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/raw/raw-transaction.c	Thu Nov 08 21:18:55 2007 +0200
@@ -0,0 +1,69 @@
+/* Copyright (c) 2007 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "raw-storage.h"
+
+struct raw_transaction_context {
+	struct index_transaction_context ictx;
+	union mail_index_transaction_module_context module_ctx;
+};
+
+static void (*next_hook_mail_index_transaction_created)
+	(struct mail_index_transaction *t) = NULL;
+
+static int
+raw_transaction_commit(struct mail_index_transaction *t,
+		       uint32_t *log_file_seq_r, uoff_t *log_file_offset_r)
+{
+	struct raw_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
+
+	return index_transaction_finish_commit(&mt->ictx, log_file_seq_r,
+					       log_file_offset_r);
+}
+
+static void raw_transaction_rollback(struct mail_index_transaction *t)
+{
+	struct raw_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
+
+	index_transaction_finish_rollback(&mt->ictx);
+}
+
+static void raw_transaction_created(struct mail_index_transaction *t)
+{
+	struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
+
+	/* index can be for mailbox list index, in which case box=NULL */
+	if (box != NULL &&
+	    strcmp(box->storage->name, RAW_STORAGE_NAME) == 0) {
+		struct raw_mailbox *raw = (struct raw_mailbox *)box;
+		struct raw_transaction_context *mt;
+
+		mt = i_new(struct raw_transaction_context, 1);
+		mt->ictx.trans = t;
+		mt->ictx.super = t->v;
+
+		t->v.commit = raw_transaction_commit;
+		t->v.rollback = raw_transaction_rollback;
+		MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
+		index_transaction_init(&mt->ictx, &raw->ibox);
+	}
+
+	if (next_hook_mail_index_transaction_created != NULL)
+		next_hook_mail_index_transaction_created(t);
+}
+
+void raw_transaction_class_init(void)
+{
+	next_hook_mail_index_transaction_created =
+		hook_mail_index_transaction_created;
+	hook_mail_index_transaction_created = raw_transaction_created;
+}
+
+void raw_transaction_class_deinit(void)
+{
+	i_assert(hook_mail_index_transaction_created ==
+		 raw_transaction_created);
+	hook_mail_index_transaction_created =
+		next_hook_mail_index_transaction_created;
+}