dovecot: Added raw storage for opening single-mail files/streams...

dovecot at dovecot.org dovecot at dovecot.org
Thu Nov 8 21:26:01 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/d712370dfd14
changeset: 6748:d712370dfd14
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Nov 08 21:18:55 2007 +0200
description:
Added raw storage for opening single-mail files/streams as mailboxes.

diffstat:

9 files changed, 615 insertions(+), 2 deletions(-)
configure.in                                |    4 
src/lib-storage/index/Makefile.am           |    2 
src/lib-storage/index/raw/Makefile.am       |   26 ++
src/lib-storage/index/raw/raw-mail.c        |  109 +++++++++
src/lib-storage/index/raw/raw-storage.c     |  307 +++++++++++++++++++++++++++
src/lib-storage/index/raw/raw-storage.h     |   33 ++
src/lib-storage/index/raw/raw-sync.c        |   58 +++++
src/lib-storage/index/raw/raw-sync.h        |    9 
src/lib-storage/index/raw/raw-transaction.c |   69 ++++++

diffs (truncated from 676 to 300 lines):

diff -r 0cee1cccd14c -r d712370dfd14 configure.in
--- 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_ARG_WITH(storages,
 		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-stora
 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/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
diff -r 0cee1cccd14c -r d712370dfd14 src/lib-storage/index/Makefile.am
--- 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
+SUBDIRS = maildir mbox dbox cydir raw
 
 noinst_LIBRARIES = libstorage_index.a
 
diff -r 0cee1cccd14c -r d712370dfd14 src/lib-storage/index/raw/Makefile.am
--- /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
diff -r 0cee1cccd14c -r d712370dfd14 src/lib-storage/index/raw/raw-mail.c
--- /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
+};
diff -r 0cee1cccd14c -r d712370dfd14 src/lib-storage/index/raw/raw-storage.c
--- /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)) {


More information about the dovecot-cvs mailing list