]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Added "none" mailbox list driver.
authorTimo Sirainen <tss@iki.fi>
Mon, 5 Apr 2010 01:49:17 +0000 (04:49 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 5 Apr 2010 01:49:17 +0000 (04:49 +0300)
Fixed the most obvious crashes when using the driver.

--HG--
branch : HEAD

src/lib-storage/index/index-storage.c
src/lib-storage/list/Makefile.am
src/lib-storage/list/mailbox-list-none.c [new file with mode: 0644]
src/lib-storage/mail-storage.c
src/lib-storage/mailbox-list.c
src/lib-storage/mailbox-list.h
src/lib-storage/register/Makefile.am

index 5837ff4f6e7e190c3c7fb07511567ca32cbf778c..40cc2ce46744f42b573550df5ddf40a16e622190 100644 (file)
@@ -39,7 +39,7 @@ int index_list_create_missing_index_dir(struct mailbox_list *list,
                                         MAILBOX_LIST_PATH_TYPE_MAILBOX);
        index_dir = mailbox_list_get_path(list, name,
                                          MAILBOX_LIST_PATH_TYPE_INDEX);
-       if (strcmp(index_dir, root_dir) == 0 || *index_dir == '\0')
+       if (*index_dir == '\0' || strcmp(index_dir, root_dir) == 0)
                return 0;
 
        mailbox_list_get_dir_permissions(list, name, &mode, &gid, &origin);
index 2cbbcd2ef1093cc1d317a6ef1c47b64f69b9ef03..6b4db3dc22fa422cc2a11fd9a071c46e6bfb8484 100644 (file)
@@ -17,6 +17,7 @@ libstorage_list_la_SOURCES = \
        mailbox-list-fs-iter.c \
        mailbox-list-maildir.c \
        mailbox-list-maildir-iter.c \
+       mailbox-list-none.c \
        mailbox-list-subscriptions.c \
        subscription-file.c
 
diff --git a/src/lib-storage/list/mailbox-list-none.c b/src/lib-storage/list/mailbox-list-none.c
new file mode 100644 (file)
index 0000000..ea1d1fc
--- /dev/null
@@ -0,0 +1,185 @@
+/* Copyright (c) 2006-2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "mailbox-list-private.h"
+
+#define MAILBOX_LIST_NAME_NONE "none"
+#define GLOBAL_TEMP_PREFIX ".temp."
+
+extern struct mailbox_list none_mailbox_list;
+
+static struct mailbox_list *none_list_alloc(void)
+{
+       struct mailbox_list *list;
+       pool_t pool;
+
+       pool = pool_alloconly_create("none list", 2048);
+
+       list = p_new(pool, struct mailbox_list, 1);
+       *list = none_mailbox_list;
+       list->pool = pool;
+       return list;
+}
+
+static void none_list_deinit(struct mailbox_list *list)
+{
+       pool_unref(&list->pool);
+}
+
+static bool
+none_is_valid_pattern(struct mailbox_list *list ATTR_UNUSED,
+                     const char *pattern ATTR_UNUSED)
+{
+       return TRUE;
+}
+
+static bool
+none_is_valid_existing_name(struct mailbox_list *list ATTR_UNUSED,
+                           const char *name ATTR_UNUSED)
+{
+       return TRUE;
+}
+
+static bool
+none_is_valid_create_name(struct mailbox_list *list ATTR_UNUSED,
+                         const char *name ATTR_UNUSED)
+{
+       return FALSE;
+}
+
+static const char *
+none_list_get_path(struct mailbox_list *list ATTR_UNUSED,
+                  const char *name ATTR_UNUSED,
+                  enum mailbox_list_path_type type ATTR_UNUSED)
+{
+       if (type == MAILBOX_LIST_PATH_TYPE_INDEX)
+               return "";
+       return NULL;
+}
+
+static int
+none_list_get_mailbox_name_status(struct mailbox_list *list ATTR_UNUSED,
+                                 const char *name ATTR_UNUSED,
+                                 enum mailbox_name_status *status)
+{
+       *status = MAILBOX_NAME_VALID;
+       return 0;
+}
+
+static const char *
+none_list_get_temp_prefix(struct mailbox_list *list ATTR_UNUSED,
+                         bool global ATTR_UNUSED)
+{
+       return GLOBAL_TEMP_PREFIX;
+}
+
+static int none_list_set_subscribed(struct mailbox_list *list,
+                                   const char *name ATTR_UNUSED,
+                                   bool set ATTR_UNUSED)
+{
+       mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported");
+       return -1;
+}
+
+static int
+none_list_create_mailbox_dir(struct mailbox_list *list,
+                            const char *name ATTR_UNUSED,
+                            bool directory ATTR_UNUSED)
+{
+       mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported");
+       return -1;
+}
+
+static int none_list_delete_mailbox(struct mailbox_list *list,
+                                   const char *name ATTR_UNUSED)
+{
+       mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported");
+       return -1;
+}
+
+static int none_list_delete_dir(struct mailbox_list *list,
+                               const char *name ATTR_UNUSED)
+{
+       mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE, "Not supported");
+       return -1;
+}
+
+static int
+none_list_rename_mailbox(struct mailbox_list *oldlist,
+                        const char *oldname ATTR_UNUSED,
+                        struct mailbox_list *newlist ATTR_UNUSED,
+                        const char *newname ATTR_UNUSED,
+                        bool rename_children ATTR_UNUSED)
+{
+       mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
+                              "Not supported");
+       return -1;
+}
+
+static struct mailbox_list_iterate_context *
+none_list_iter_init(struct mailbox_list *list,
+                   const char *const *patterns ATTR_UNUSED,
+                   enum mailbox_list_iter_flags flags)
+{
+       struct mailbox_list_iterate_context *ctx;
+
+       ctx = i_new(struct mailbox_list_iterate_context, 1);
+       ctx->list = list;
+       ctx->flags = flags;
+       return ctx;
+}
+
+static int
+none_list_iter_deinit(struct mailbox_list_iterate_context *ctx)
+{
+       i_free(ctx);
+       return 0;
+}
+
+static const struct mailbox_info *
+none_list_iter_next(struct mailbox_list_iterate_context *ctx ATTR_UNUSED)
+{
+       return NULL;
+}
+
+static int
+none_list_get_mailbox_flags(struct mailbox_list *list ATTR_UNUSED,
+                           const char *dir ATTR_UNUSED,
+                           const char *fname ATTR_UNUSED,
+                           enum mailbox_list_file_type type ATTR_UNUSED,
+                           struct stat *st_r ATTR_UNUSED,
+                           enum mailbox_info_flags *flags)
+{
+       *flags = MAILBOX_NONEXISTENT;
+       return 0;
+}
+
+struct mailbox_list none_mailbox_list = {
+       .name = MAILBOX_LIST_NAME_NONE,
+       .hierarchy_sep = '/',
+       .props = MAILBOX_LIST_PROP_NO_ROOT,
+       .mailbox_name_max_length = MAILBOX_LIST_NAME_MAX_LENGTH,
+
+       {
+               none_list_alloc,
+               none_list_deinit,
+               NULL,
+               none_is_valid_pattern,
+               none_is_valid_existing_name,
+               none_is_valid_create_name,
+               none_list_get_path,
+               none_list_get_mailbox_name_status,
+               none_list_get_temp_prefix,
+               NULL,
+               none_list_iter_init,
+               none_list_iter_next,
+               none_list_iter_deinit,
+               none_list_get_mailbox_flags,
+               NULL,
+               none_list_set_subscribed,
+               none_list_create_mailbox_dir,
+               none_list_delete_mailbox,
+               none_list_delete_dir,
+               none_list_rename_mailbox
+       }
+};
index a26a781c5736e61d8169f13c29774b7c700129c5..1837a6d0cadececd423509b174e32e74d6a1b332 100644 (file)
@@ -118,9 +118,9 @@ mail_storage_set_autodetection(const char **data, const char **driver)
 static struct mail_storage *
 mail_storage_get_class(struct mail_namespace *ns, const char *driver,
                       struct mailbox_list_settings *list_set,
-                      const char **error_r)
+                      enum mail_storage_flags flags, const char **error_r)
 {
-       struct mail_storage *storage_class;
+       struct mail_storage *storage_class = NULL;
        const char *home;
 
        if (driver != NULL) {
@@ -130,7 +130,27 @@ mail_storage_get_class(struct mail_namespace *ns, const char *driver,
                                "Unknown mail storage driver %s", driver);
                        return NULL;
                }
+       }
 
+       if (list_set->root_dir == NULL || *list_set->root_dir == '\0') {
+               /* no root directory given. is this allowed? */
+               const struct mailbox_list *list;
+
+               list = list_set->layout == NULL ? NULL :
+                       mailbox_list_find_class(list_set->layout);
+               if (storage_class == NULL &&
+                   (flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) == 0) {
+                       /* autodetection should take care of this */
+               } else if (list != NULL &&
+                          (list->props & MAILBOX_LIST_PROP_NO_ROOT) != 0) {
+                       /* root not required for this layout */
+               } else {
+                       *error_r = "Root mail directory not given";
+                       return NULL;
+               }
+       }
+
+       if (storage_class != NULL) {
                storage_class->v.get_list_settings(ns, list_set);
                return storage_class;
        }
@@ -255,14 +275,8 @@ int mail_storage_create(struct mail_namespace *ns, const char *driver,
                        return -1;
        }
 
-       if ((list_set.root_dir == NULL || *list_set.root_dir == '\0') &&
-           (driver != NULL ||
-            (flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) != 0)) {
-               *error_r = "Root mail directory not given";
-               return -1;
-       }
-
-       storage_class = mail_storage_get_class(ns, driver, &list_set, error_r);
+       storage_class = mail_storage_get_class(ns, driver, &list_set, flags,
+                                              error_r);
        if (storage_class == NULL)
                return -1;
        i_assert(list_set.layout != NULL);
index 2e304d69502b484f02b92bb8f554cb4717c2f329..0b3c58933545580e7c2048f2483918a1a7ec9ef2 100644 (file)
@@ -93,6 +93,19 @@ void mailbox_list_unregister(const struct mailbox_list *list)
        array_delete(&mailbox_list_drivers, idx, 1);
 }
 
+const struct mailbox_list *
+mailbox_list_find_class(const char *driver)
+{
+       const struct mailbox_list *const *class_p;
+       unsigned int idx;
+
+       if (!mailbox_list_driver_find(driver, &idx))
+               return NULL;
+
+       class_p = array_idx(&mailbox_list_drivers, idx);
+       return *class_p;
+}
+
 int mailbox_list_create(const char *driver, struct mail_namespace *ns,
                        const struct mailbox_list_settings *set,
                        enum mailbox_list_flags flags, const char **error_r)
@@ -103,7 +116,6 @@ int mailbox_list_create(const char *driver, struct mail_namespace *ns,
 
        i_assert(ns->list == NULL);
 
-       i_assert(set->root_dir == NULL || *set->root_dir != '\0');
        i_assert(set->subscription_fname == NULL ||
                 *set->subscription_fname != '\0');
 
@@ -124,6 +136,9 @@ int mailbox_list_create(const char *driver, struct mail_namespace *ns,
                return -1;
        }
 
+       i_assert(set->root_dir == NULL || *set->root_dir != '\0' ||
+                ((*class_p)->props & MAILBOX_LIST_PROP_NO_ROOT) != 0);
+
        list = (*class_p)->v.alloc();
        array_create(&list->module_contexts, list->pool, sizeof(void *), 5);
 
@@ -359,8 +374,16 @@ mailbox_list_get_permissions_full(struct mailbox_list *list, const char *name,
        const char *path;
        struct stat st;
 
+       /* use safe defaults */
+       *file_mode_r = 0600;
+       *dir_mode_r = 0700;
+       *gid_r = (gid_t)-1;
+       *gid_origin_r = "defaults";
+
        path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR);
-       if (stat(path, &st) < 0) {
+       if (path == NULL) {
+               /* no filesystem support in storage */
+       } else if (stat(path, &st) < 0) {
                if (!ENOTFOUND(errno)) {
                        mailbox_list_set_critical(list, "stat(%s) failed: %m",
                                                  path);
@@ -376,11 +399,6 @@ mailbox_list_get_permissions_full(struct mailbox_list *list, const char *name,
                                                          gid_origin_r);
                        return;
                }
-               /* return safe defaults */
-               *file_mode_r = 0600;
-               *dir_mode_r = 0700;
-               *gid_r = (gid_t)-1;
-               *gid_origin_r = "defaults";
        } else {
                *file_mode_r = st.st_mode & 0666;
                *dir_mode_r = st.st_mode & 0777;
@@ -418,7 +436,8 @@ mailbox_list_get_permissions_full(struct mailbox_list *list, const char *name,
 
        if (list->mail_set->mail_debug && name == NULL) {
                i_debug("Namespace %s: Using permissions from %s: "
-                       "mode=0%o gid=%ld", list->ns->prefix, path,
+                       "mode=0%o gid=%ld", list->ns->prefix,
+                       path != NULL ? path : "",
                        (int)list->dir_create_mode,
                        list->file_create_gid == (gid_t)-1 ? -1L :
                        (long)list->file_create_gid);
index 41f3197fb816d8decd65ba321b055f507ef58758..6a9d4b49d914a6a0c7065b6200c4a06a06db58a8 100644 (file)
@@ -21,7 +21,9 @@ enum mailbox_list_properties {
        /* alt directories not supported */
        MAILBOX_LIST_PROP_NO_ALT_DIR            = 0x02,
        /* no support for \noselect directories, only mailboxes */
-       MAILBOX_LIST_PROP_NO_NOSELECT           = 0x04
+       MAILBOX_LIST_PROP_NO_NOSELECT           = 0x04,
+       /* mail root directory isn't required */
+       MAILBOX_LIST_PROP_NO_ROOT               = 0x08
 };
 
 enum mailbox_list_flags {
@@ -141,6 +143,9 @@ void mailbox_list_register_all(void);
 void mailbox_list_register(const struct mailbox_list *list);
 void mailbox_list_unregister(const struct mailbox_list *list);
 
+const struct mailbox_list *
+mailbox_list_find_class(const char *driver);
+
 /* Returns 0 if ok, -1 if driver was unknown. */
 int mailbox_list_create(const char *driver, struct mail_namespace *ns,
                        const struct mailbox_list_settings *set,
index 70f22df0ef225ef44939b05c2312750564a95c9d..5ff9a522ef19d30c93c20dbff35aa863d48514ce 100644 (file)
@@ -2,7 +2,7 @@ noinst_LTLIBRARIES = libstorage_register.la
 
 mail_storages = @mail_storages@
 
-mailbox_list_drivers = maildir imapdir fs shared
+mailbox_list_drivers = maildir imapdir none fs shared
 
 mail-storage-register.c: Makefile
        rm -f $@