dovecot-1.2: Added initial support for shared mailboxes. Listing...

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 7 22:34:16 EEST 2008


details:   http://hg.dovecot.org/dovecot-1.2/rev/6dd0c6755afe
changeset: 8173:6dd0c6755afe
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Sep 07 22:34:11 2008 +0300
description:
Added initial support for shared mailboxes. Listing isn't supported yet.
Each user gets their own hidden namespace created automatically when they're
accessed the first time.

diffstat:

12 files changed, 619 insertions(+), 28 deletions(-)
configure.in                                  |    6 
src/lib-storage/index/Makefile.am             |    2 
src/lib-storage/index/shared/Makefile.am      |   23 ++
src/lib-storage/index/shared/shared-list.c    |  269 +++++++++++++++++++++++++
src/lib-storage/index/shared/shared-storage.c |  262 ++++++++++++++++++++++++
src/lib-storage/index/shared/shared-storage.h |   25 ++
src/lib-storage/mail-namespace.c              |   32 --
src/lib-storage/mail-storage.c                |    4 
src/lib-storage/mail-storage.h                |    2 
src/lib-storage/mail-user.c                   |   17 +
src/lib-storage/mail-user.h                   |    3 
src/lib-storage/register/Makefile.am          |    2 

diffs (truncated from 786 to 300 lines):

diff -r c0a80d6b8ef6 -r 6dd0c6755afe configure.in
--- a/configure.in	Sun Sep 07 20:48:43 2008 +0300
+++ b/configure.in	Sun Sep 07 22:34:11 2008 +0300
@@ -362,12 +362,12 @@ AM_CONDITIONAL(BUILD_DELIVER, test "$wan
 
 AC_ARG_WITH(storages,
 [  --with-storages         Build with specified mail storage formats
-                          (maildir mbox dbox cydir raw)], [
+                          (maildir mbox dbox cydir shared raw)], [
 	if test "$withval" = "yes" -o "$withval" = "no"; then
 		AC_MSG_ERROR([--with-storages needs storage list as parameter])
 	fi
 	mail_storages=`echo "$withval"|sed 's/,/ /g'` ],
-	mail_storages="maildir mbox dbox cydir raw")
+	mail_storages="maildir mbox dbox cydir shared raw")
 AC_SUBST(mail_storages)
 
 AC_ARG_WITH(sql-drivers,
@@ -2238,6 +2238,7 @@ dbox_libs='$(top_builddir)/src/lib-stora
 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'
+shared_libs='$(top_builddir)/src/lib-storage/index/shared/libstorage_shared.a'
 CORE_LIBS='$(top_builddir)/src/lib-storage/index/libstorage_index.a $(top_builddir)/src/lib-storage/libstorage.a $(top_builddir)/src/lib-index/libindex.a'
 
 deliver_storage="raw"
@@ -2404,6 +2405,7 @@ src/lib-storage/index/dbox/Makefile
 src/lib-storage/index/dbox/Makefile
 src/lib-storage/index/cydir/Makefile
 src/lib-storage/index/raw/Makefile
+src/lib-storage/index/shared/Makefile
 src/lib-storage/register/Makefile
 src/auth/Makefile
 src/deliver/Makefile
diff -r c0a80d6b8ef6 -r 6dd0c6755afe src/lib-storage/index/Makefile.am
--- a/src/lib-storage/index/Makefile.am	Sun Sep 07 20:48:43 2008 +0300
+++ b/src/lib-storage/index/Makefile.am	Sun Sep 07 22:34:11 2008 +0300
@@ -1,4 +1,4 @@ SUBDIRS = maildir mbox dbox cydir raw
-SUBDIRS = maildir mbox dbox cydir raw
+SUBDIRS = maildir mbox dbox cydir raw shared
 
 noinst_LIBRARIES = libstorage_index.a
 
diff -r c0a80d6b8ef6 -r 6dd0c6755afe src/lib-storage/index/shared/Makefile.am
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/shared/Makefile.am	Sun Sep 07 22:34:11 2008 +0300
@@ -0,0 +1,23 @@
+noinst_LIBRARIES = libstorage_shared.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_shared_a_SOURCES = \
+	shared-list.c \
+	shared-storage.c
+
+headers = \
+	shared-storage.h
+
+if INSTALL_HEADERS
+  pkginc_libdir=$(pkgincludedir)/src/lib-storage/index/shared
+  pkginc_lib_HEADERS = $(headers)
+else
+  noinst_HEADERS = $(headers)
+endif
diff -r c0a80d6b8ef6 -r 6dd0c6755afe src/lib-storage/index/shared/shared-list.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib-storage/index/shared/shared-list.c	Sun Sep 07 22:34:11 2008 +0300
@@ -0,0 +1,269 @@
+/* Copyright (c) 2008 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mailbox-list-private.h"
+#include "shared-storage.h"
+
+struct shared_mailbox_list_iterate_context {
+	struct mailbox_list_iterate_context ctx;
+};
+
+extern struct mailbox_list shared_mailbox_list;
+
+static struct mailbox_list *shared_list_alloc(void)
+{
+	struct mailbox_list *list;
+	pool_t pool;
+
+	pool = pool_alloconly_create("shared list", 256);
+	list = p_new(pool, struct mailbox_list, 1);
+	*list = shared_mailbox_list;
+	list->pool = pool;
+	return list;
+}
+
+static void shared_list_deinit(struct mailbox_list *list)
+{
+	pool_unref(&list->pool);
+}
+
+static void shared_list_copy_error(struct mailbox_list *shared_list,
+				   struct mail_namespace *backend_ns)
+{
+	const char *str;
+	enum mail_error error;
+
+	str = mailbox_list_get_last_error(backend_ns->list, &error);
+	mailbox_list_set_error(shared_list, error, str);
+}
+
+static bool
+shared_is_valid_pattern(struct mailbox_list *list, const char *pattern)
+{
+	struct mail_namespace *ns;
+
+	if (shared_storage_get_namespace(list->ns->storage, &pattern, &ns) < 0)
+		return FALSE;
+	return mailbox_list_is_valid_pattern(ns->list, pattern);
+}
+
+static bool
+shared_is_valid_existing_name(struct mailbox_list *list, const char *name)
+{
+	struct mail_namespace *ns;
+
+	if (shared_storage_get_namespace(list->ns->storage, &name, &ns) < 0)
+		return FALSE;
+	return mailbox_list_is_valid_existing_name(ns->list, name);
+}
+
+static bool
+shared_is_valid_create_name(struct mailbox_list *list, const char *name)
+{
+	struct mail_namespace *ns;
+
+	if (shared_storage_get_namespace(list->ns->storage, &name, &ns) < 0)
+		return FALSE;
+	return mailbox_list_is_valid_create_name(ns->list, name);
+}
+
+static const char *
+shared_list_get_path(struct mailbox_list *list, const char *name,
+		     enum mailbox_list_path_type type)
+{
+	struct mail_namespace *ns;
+
+	if (list->ns->storage == NULL ||
+	    shared_storage_get_namespace(list->ns->storage, &name, &ns) < 0) {
+		switch (type) {
+		case MAILBOX_LIST_PATH_TYPE_DIR:
+		case MAILBOX_LIST_PATH_TYPE_MAILBOX:
+		case MAILBOX_LIST_PATH_TYPE_CONTROL:
+			break;
+		case MAILBOX_LIST_PATH_TYPE_INDEX:
+			/* we can safely say we don't use indexes */
+			return "";
+		}
+		i_panic("shared mailbox list: Can't return path for '%s'",
+			list->ns->prefix);
+	}
+	return mailbox_list_get_path(ns->list, name, type);
+}
+
+static int
+shared_list_get_mailbox_name_status(struct mailbox_list *list, const char *name,
+				    enum mailbox_name_status *status_r)
+{
+	struct mail_namespace *ns;
+	int ret;
+
+	if (shared_storage_get_namespace(list->ns->storage, &name, &ns) < 0)
+		return -1;
+	ret = mailbox_list_get_mailbox_name_status(ns->list, name, status_r);
+	if (ret < 0)
+		shared_list_copy_error(list, ns);
+	return ret;
+}
+
+static const char *
+shared_list_get_temp_prefix(struct mailbox_list *list, bool global ATTR_UNUSED)
+{
+	i_panic("shared mailbox list: Can't return a temp prefix for '%s'",
+		list->ns->prefix);
+	return NULL;
+}
+
+static const char *
+shared_list_join_refpattern(struct mailbox_list *list,
+			    const char *ref, const char *pattern)
+{
+	struct mail_namespace *ns;
+
+	if (*ref != '\0' &&
+	    shared_storage_get_namespace(list->ns->storage, &ref, &ns) == 0)
+		return mailbox_list_join_refpattern(ns->list, ref, pattern);
+
+	if (*ref == '\0' &&
+	    shared_storage_get_namespace(list->ns->storage, &pattern, &ns) == 0)
+		return mailbox_list_join_refpattern(ns->list, "", pattern);
+
+	/* fallback to default behavior */
+	if (*ref != '\0')
+		pattern = t_strconcat(ref, pattern, NULL);
+	return pattern;
+}
+
+static struct mailbox_list_iterate_context *
+shared_list_iter_init(struct mailbox_list *list, const char *const *patterns,
+		      enum mailbox_list_iter_flags flags)
+{
+	struct shared_mailbox_list_iterate_context *ctx;
+
+	ctx = i_new(struct shared_mailbox_list_iterate_context, 1);
+	ctx->ctx.list = list;
+	ctx->ctx.flags = flags;
+
+	/* FIXME */
+	return &ctx->ctx;
+}
+
+static const struct mailbox_info *
+shared_list_iter_next(struct mailbox_list_iterate_context *_ctx)
+{
+	struct shared_mailbox_list_iterate_context *ctx =
+		(struct shared_mailbox_list_iterate_context *)_ctx;
+
+	return NULL;
+}
+
+static int shared_list_iter_deinit(struct mailbox_list_iterate_context *_ctx)
+{
+	struct shared_mailbox_list_iterate_context *ctx =
+		(struct shared_mailbox_list_iterate_context *)_ctx;
+
+	i_free(ctx);
+	return -1;
+}
+
+static int shared_list_set_subscribed(struct mailbox_list *list,
+				      const char *name, bool set)
+{
+	struct mail_namespace *ns;
+	int ret;
+
+	if (shared_storage_get_namespace(list->ns->storage, &name, &ns) < 0)
+		return -1;
+	ret = mailbox_list_set_subscribed(ns->list, name, set);
+	if (ret < 0)
+		shared_list_copy_error(list, ns);
+	return ret;
+}
+
+static int
+shared_list_delete_mailbox(struct mailbox_list *list, const char *name)
+{
+	struct mail_namespace *ns;
+	int ret;
+
+	if (shared_storage_get_namespace(list->ns->storage, &name, &ns) < 0)
+		return -1;
+	ret = mailbox_list_delete_mailbox(ns->list, name);
+	if (ret < 0)
+		shared_list_copy_error(list, ns);
+	return ret;
+}
+
+static int shared_list_rename_get_ns(struct mailbox_list *list,
+				     const char **oldname, const char **newname,
+				     struct mail_namespace **ns_r)
+{
+	struct mail_namespace *old_ns, *new_ns;
+
+	if (shared_storage_get_namespace(list->ns->storage,
+					 oldname, &old_ns) < 0 ||
+	    shared_storage_get_namespace(list->ns->storage,
+					 newname, &new_ns) < 0)
+		return -1;
+	if (old_ns != new_ns) {
+		mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
+			"Can't rename mailboxes across storages");
+		return -1;
+	}
+	*ns_r = old_ns;
+	return 0;
+}
+
+static int shared_list_rename_mailbox(struct mailbox_list *list,
+				      const char *oldname, const char *newname)
+{
+	struct mail_namespace *ns;
+	int ret;
+
+	if (shared_list_rename_get_ns(list, &oldname, &newname, &ns) < 0)
+		return -1;
+	ret = mailbox_list_rename_mailbox(ns->list, oldname, newname);
+	if (ret < 0)
+		shared_list_copy_error(list, ns);


More information about the dovecot-cvs mailing list