Fixed the most obvious crashes when using the driver.
--HG--
branch : HEAD
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);
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
--- /dev/null
+/* 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
+ }
+};
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) {
"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;
}
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);
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)
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');
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);
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);
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;
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);
/* 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 {
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,
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 $@