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