changeset 5461:08b42ced91a6 HEAD

Removed mail_storage_create_with_data(). mail_storage_create() with driver=NULL behaves the same way. Removed parameters from mail_storage.create(), they're now put into the storage structure before calling create().
author Timo Sirainen <tss@iki.fi>
date Fri, 30 Mar 2007 16:40:12 +0300
parents 105e0cd21036
children 163b48489bc6
files src/deliver/deliver.c src/imap/namespace.c src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/plugins/convert/convert-storage.c src/plugins/expire/expire-tool.c src/pop3/main.c
diffstat 14 files changed, 118 insertions(+), 182 deletions(-) [+]
line wrap: on
line diff
--- a/src/deliver/deliver.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/deliver/deliver.c	Fri Mar 30 16:40:12 2007 +0300
@@ -660,8 +660,8 @@
 
 	/* FIXME: how should we handle namespaces? */
 	mail_storage_parse_env(&flags, &lock_method);
-	storage = mail_storage_create_with_data(mail_env, destination,
-						flags, lock_method);
+	storage = mail_storage_create(NULL, mail_env, destination,
+				      flags, lock_method);
 	if (storage == NULL) {
 		i_fatal_status(EX_TEMPFAIL,
 			"Failed to create storage for '%s' with mail '%s'",
--- a/src/imap/namespace.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/imap/namespace.c	Fri Mar 30 16:40:12 2007 +0300
@@ -72,8 +72,7 @@
 	ns->inbox = inbox;
 	ns->hidden = hidden;
 	ns->subscriptions = subscriptions;
-	ns->storage = mail_storage_create_with_data(data, user, flags,
-						    lock_method);
+	ns->storage = mail_storage_create(NULL, data, user, flags, lock_method);
 	if (ns->storage == NULL) {
 		i_fatal("Failed to create storage for '%s' with data: %s",
 			ns->prefix, data);
@@ -132,8 +131,7 @@
 	ns->prefix = "";
 
 	flags |= MAIL_STORAGE_FLAG_HAS_INBOX;
-	ns->storage = mail_storage_create_with_data(mail, user, flags,
-						    lock_method);
+	ns->storage = mail_storage_create(NULL, mail, user, flags, lock_method);
 	if (ns->storage == NULL) {
 		if (mail != NULL && *mail != '\0')
 			i_fatal("Failed to create storage with data: %s", mail);
--- a/src/lib-storage/index/cydir/cydir-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -95,22 +95,19 @@
 	return &storage->storage;
 }
 
-static int
-cydir_create(struct mail_storage *_storage, const char *data, const char *user,
-	     enum mail_storage_flags flags, enum file_lock_method lock_method)
+static int cydir_create(struct mail_storage *_storage, const char *data)
 {
 	struct cydir_storage *storage = (struct cydir_storage *)_storage;
 	struct mailbox_list_settings list_set;
-	struct mailbox_list *list;
 	const char *error;
 	struct stat st;
 
-	if (cydir_get_list_settings(&list_set, data, flags) < 0)
+	if (cydir_get_list_settings(&list_set, data, _storage->flags) < 0)
 		return -1;
-	list_set.mail_storage_flags = &flags;
-	list_set.lock_method = &lock_method;
+	list_set.mail_storage_flags = &_storage->flags;
+	list_set.lock_method = &_storage->lock_method;
 
-	if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
+	if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
 		if (stat(list_set.root_dir, &st) < 0) {
 			if (errno != ENOENT) {
 				i_error("stat(%s) failed: %m",
@@ -127,20 +124,17 @@
 	}
 
 	if (mailbox_list_init("fs", &list_set,
-			      mail_storage_get_list_flags(flags),
-			      &list, &error) < 0) {
+			      mail_storage_get_list_flags(_storage->flags),
+			      &_storage->list, &error) < 0) {
 		i_error("cydir fs: %s", error);
 		return -1;
 	}
-	storage->list_module_ctx.super = list->v;
-	list->v.iter_is_mailbox = cydir_list_iter_is_mailbox;
-	list->v.delete_mailbox = cydir_list_delete_mailbox;
+	storage->list_module_ctx.super = _storage->list->v;
+	_storage->list->v.iter_is_mailbox = cydir_list_iter_is_mailbox;
+	_storage->list->v.delete_mailbox = cydir_list_delete_mailbox;
 
-	MODULE_CONTEXT_SET_FULL(list, cydir_mailbox_list_module,
+	MODULE_CONTEXT_SET_FULL(_storage->list, cydir_mailbox_list_module,
 				storage, &storage->list_module_ctx);
-
-	_storage->user = p_strdup(_storage->pool, user);
-	index_storage_init(_storage, list, flags, lock_method);
 	return 0;
 }
 
--- a/src/lib-storage/index/dbox/dbox-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -175,9 +175,7 @@
 	return &storage->storage;
 }
 
-static int
-dbox_create(struct mail_storage *_storage, const char *data, const char *user,
-	    enum mail_storage_flags flags, enum file_lock_method lock_method)
+static int dbox_create(struct mail_storage *_storage, const char *data)
 {
 	struct dbox_storage *storage = (struct dbox_storage *)_storage;
 	struct mailbox_list_settings list_set;
@@ -185,12 +183,12 @@
 	const char *error;
 	struct stat st;
 
-	if (dbox_get_list_settings(&list_set, data, flags) < 0)
+	if (dbox_get_list_settings(&list_set, data, _storage->flags) < 0)
 		return -1;
-	list_set.mail_storage_flags = &flags;
-	list_set.lock_method = &lock_method;
+	list_set.mail_storage_flags = &_storage->flags;
+	list_set.lock_method = &_storage->lock_method;
 
-	if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
+	if ((_storage->flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
 		if (stat(list_set.root_dir, &st) < 0) {
 			if (errno != ENOENT) {
 				i_error("stat(%s) failed: %m",
@@ -207,11 +205,12 @@
 	}
 
 	if (mailbox_list_init("fs", &list_set,
-			      mail_storage_get_list_flags(flags),
+			      mail_storage_get_list_flags(_storage->flags),
 			      &list, &error) < 0) {
 		i_error("dbox fs: %s", error);
 		return -1;
 	}
+	_storage->list = list;
 	storage->list_module_ctx.super = list->v;
 	list->v.is_valid_existing_name = dbox_storage_is_valid_existing_name;
 	list->v.is_valid_create_name = dbox_storage_is_valid_create_name;
@@ -224,15 +223,11 @@
 	storage->uidlist_dotlock_set = default_uidlist_dotlock_set;
 	storage->file_dotlock_set = default_file_dotlock_set;
 	storage->new_file_dotlock_set = default_new_file_dotlock_set;
-	if ((flags & MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0) {
+	if ((_storage->flags & MAIL_STORAGE_FLAG_DOTLOCK_USE_EXCL) != 0) {
 		storage->uidlist_dotlock_set.use_excl_lock = TRUE;
 		storage->file_dotlock_set.use_excl_lock = TRUE;
 		storage->new_file_dotlock_set.use_excl_lock = TRUE;
 	}
-
-	storage->storage.user = p_strdup(_storage->pool, user);
-	index_storage_init(_storage, list, flags, lock_method);
-
 	return 0;
 }
 
--- a/src/lib-storage/index/index-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/index/index-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -38,33 +38,12 @@
 
 static struct index_list *indexes = NULL;
 static struct timeout *to_index = NULL;
-static int index_storage_refcount = 0;
-
-void index_storage_init(struct mail_storage *storage,
-			struct mailbox_list *list,
-			enum mail_storage_flags flags,
-			enum file_lock_method lock_method)
-{
-	storage->list = list;
-	storage->flags = flags;
-	storage->lock_method = lock_method;
-
-	storage->callbacks =
-		p_new(storage->pool, struct mail_storage_callbacks, 1);
-
-	array_create(&storage->module_contexts,
-		     storage->pool, sizeof(void *), 5);
-	index_storage_refcount++;
-}
 
 void index_storage_deinit(struct mail_storage *storage)
 {
 	mailbox_list_deinit(storage->list);
 	i_free(storage->error);
 
-	if (--index_storage_refcount > 0)
-		return;
-
         index_storage_destroy_unrefed();
 }
 
--- a/src/lib-storage/index/index-storage.h	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/index/index-storage.h	Fri Mar 30 16:40:12 2007 +0300
@@ -101,10 +101,6 @@
 void index_storage_unref(struct mail_index *index);
 void index_storage_destroy_unrefed(void);
 
-void index_storage_init(struct mail_storage *storage,
-			struct mailbox_list *list,
-			enum mail_storage_flags flags,
-			enum file_lock_method lock_method);
 void index_storage_deinit(struct mail_storage *storage);
 
 void index_storage_mailbox_init(struct index_mailbox *ibox, const char *name,
--- a/src/lib-storage/index/maildir/maildir-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -224,11 +224,10 @@
 }
 
 static int
-maildir_create(struct mail_storage *_storage,
-	       const char *data, const char *user,
-	       enum mail_storage_flags flags, enum file_lock_method lock_method)
+maildir_create(struct mail_storage *_storage, const char *data)
 {
 	struct maildir_storage *storage = (struct maildir_storage *)_storage;
+	enum mail_storage_flags flags = _storage->flags;
 	struct mailbox_list_settings list_set;
 	struct mailbox_list *list;
 	enum mailbox_open_flags open_flags;
@@ -237,8 +236,8 @@
 
 	if (maildir_get_list_settings(&list_set, data, flags, &layout) < 0)
 		return -1;
-	list_set.mail_storage_flags = &flags;
-	list_set.lock_method = &lock_method;
+	list_set.mail_storage_flags = &_storage->flags;
+	list_set.lock_method = &_storage->lock_method;
 
 	/* normally the maildir is created in verify_inbox() */
 	if ((flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) != 0) {
@@ -257,6 +256,7 @@
 		i_error("maildir %s: %s", layout, error);
 		return -1;
 	}
+	_storage->list = list;
 	storage->list_module_ctx.super = list->v;
 	if (strcmp(layout, MAILDIR_PLUSPLUS_DRIVER_NAME) == 0) {
 		list->v.iter_is_mailbox = maildirplusplus_iter_is_mailbox;
@@ -287,9 +287,6 @@
 				    "tmp/", storage->temp_prefix, NULL);
 	}
 
-	_storage->user = p_strdup(_storage->pool, user);
-	index_storage_init(_storage, list, flags, lock_method);
-
 	open_flags = 0;
 	(void)verify_inbox(_storage, &open_flags);
 	return 0;
--- a/src/lib-storage/index/mbox/mbox-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -413,39 +413,34 @@
 	return &storage->storage;
 }
 
-static int
-mbox_create(struct mail_storage *_storage, const char *data, const char *user,
-	    enum mail_storage_flags flags, enum file_lock_method lock_method)
+static int mbox_create(struct mail_storage *_storage, const char *data)
 {
 	struct mbox_storage *storage = (struct mbox_storage *)_storage;
 	struct mailbox_list_settings list_set;
-	struct mailbox_list *list;
 	const char *layout, *error;
 
-	if (mbox_get_list_settings(&list_set, data, flags, &layout) < 0)
+	if (mbox_get_list_settings(&list_set, data,
+				   _storage->flags, &layout) < 0)
 		return -1;
-	list_set.mail_storage_flags = &flags;
-	list_set.lock_method = &lock_method;
+	list_set.mail_storage_flags = &_storage->flags;
+	list_set.lock_method = &_storage->lock_method;
 
 	if (mailbox_list_init(layout, &list_set,
-			      mail_storage_get_list_flags(flags),
-			      &list, &error) < 0) {
+			      mail_storage_get_list_flags(_storage->flags),
+			      &_storage->list, &error) < 0) {
 		i_error("mbox %s: %s", layout, error);
 		return -1;
 	}
-	storage->list_module_ctx.super = list->v;
+	storage->list_module_ctx.super = _storage->list->v;
 	if (strcmp(layout, "fs") == 0 && *list_set.maildir_name == '\0') {
 		/* have to use .imap/ directories */
-		list->v.get_path = mbox_list_get_path;
+		_storage->list->v.get_path = mbox_list_get_path;
 	}
-	list->v.iter_is_mailbox = mbox_list_iter_is_mailbox;
-	list->v.delete_mailbox = mbox_list_delete_mailbox;
+	_storage->list->v.iter_is_mailbox = mbox_list_iter_is_mailbox;
+	_storage->list->v.delete_mailbox = mbox_list_delete_mailbox;
 
-	MODULE_CONTEXT_SET_FULL(list, mbox_mailbox_list_module,
+	MODULE_CONTEXT_SET_FULL(_storage->list, mbox_mailbox_list_module,
 				storage, &storage->list_module_ctx);
-
-	_storage->user = p_strdup(_storage->pool, user);
-	index_storage_init(_storage, list, flags, lock_method);
 	return 0;
 }
 
--- a/src/lib-storage/mail-storage-private.h	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/mail-storage-private.h	Fri Mar 30 16:40:12 2007 +0300
@@ -24,10 +24,7 @@
 	void (*class_deinit)(void);
 
 	struct mail_storage *(*alloc)(void);
-	int (*create)(struct mail_storage *storage,
-		      const char *data, const char *user,
-		      enum mail_storage_flags flags,
-		      enum file_lock_method lock_method);
+	int (*create)(struct mail_storage *storage, const char *data);
 	void (*destroy)(struct mail_storage *storage);
 
 	bool (*autodetect)(const char *data, enum mail_storage_flags flags);
--- a/src/lib-storage/mail-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/mail-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -114,52 +114,6 @@
 	return NULL;
 }
 
-struct mail_storage *
-mail_storage_create(const char *driver, const char *data, const char *user,
-		    enum mail_storage_flags flags,
-		    enum file_lock_method lock_method)
-{
-	struct mail_storage *storage_class, *storage;
-
-	storage_class = mail_storage_find(driver);
-	if (storage_class == NULL)
-		return NULL;
-
-	storage = storage_class->v.alloc();
-	if (storage_class->v.create(storage, data, user,
-				    flags, lock_method) < 0) {
-		pool_unref(storage->pool);
-		return NULL;
-	}
-
-	if (hook_mail_storage_created != NULL)
-		hook_mail_storage_created(storage);
-	return storage;
-}
-
-static struct mail_storage *
-mail_storage_create_default(const char *user, enum mail_storage_flags flags,
-			    enum file_lock_method lock_method)
-{
-	struct mail_storage *const *classes;
-	struct mail_storage *storage;
-	unsigned int i, count;
-
-	classes = array_get(&storages, &count);
-	for (i = 0; i < count; i++) {
-		storage = classes[i]->v.alloc();
-		if (classes[i]->v.create(storage, NULL, user,
-					 flags, lock_method) < 0)
-			pool_unref(storage->pool);
-		else {
-			if (hook_mail_storage_created != NULL)
-				hook_mail_storage_created(storage);
-			return storage;
-		}
-	}
-	return NULL;
-}
-
 static struct mail_storage *
 mail_storage_autodetect(const char *data, enum mail_storage_flags flags)
 {
@@ -174,47 +128,81 @@
 	return NULL;
 }
 
-struct mail_storage *
-mail_storage_create_with_data(const char *data, const char *user,
-			      enum mail_storage_flags flags,
-			      enum file_lock_method lock_method)
+static void
+mail_storage_set_autodetection(const char **data, const char **driver,
+			       enum mail_storage_flags *flags)
 {
-	struct mail_storage *storage_class, *storage;
-	const char *p, *name;
+	const char *p;
 
-	if (data == NULL || *data == '\0')
-		return mail_storage_create_default(user, flags, lock_method);
-
-	/* check if we're in the form of mailformat:data
-	   (eg. maildir:Maildir) */
-	p = data;
+	/* check if data is in driver:data format (eg. mbox:~/mail) */
+	p = *data;
 	while (i_isalnum(*p)) p++;
 
-	if (*p == ':') {
+	if (*p == ':' && p != *data) {
 		/* no autodetection if the storage format is given. */
-		flags |= MAIL_STORAGE_FLAG_NO_AUTODETECTION;
+		*flags |= MAIL_STORAGE_FLAG_NO_AUTODETECTION;
+
+		*driver = t_strdup_until(*data, p);
+		*data = p + 1;
+	}
+}
+
+struct mail_storage *
+mail_storage_create(const char *driver, const char *data, const char *user,
+		    enum mail_storage_flags flags,
+		    enum file_lock_method lock_method)
+{
+	struct mail_storage *storage_class, *storage;
+	struct mail_storage *const *classes;
+	unsigned int i, count;
+
+	if (data == NULL)
+		data = "";
+	else if (driver == NULL)
+		mail_storage_set_autodetection(&data, &driver, &flags);
 
-		name = t_strdup_until(data, p);
-		return mail_storage_create(name, p+1, user, flags, lock_method);
+	if (*data == '\0' && driver == NULL) {
+		/* use the first driver that works */
+		classes = array_get(&storages, &count);
+	} else if (driver == NULL) {
+		storage_class = mail_storage_autodetect(data, flags);
+		if (storage_class == NULL) {
+			i_error("Ambiguous mail location setting, "
+				"don't know what to do with it: %s "
+				"(try prefixing it with mbox: or maildir:)",
+				data);
+			return NULL;
+		}
+		classes = &storage_class;
+		count = 1;
+	} else {
+		storage_class = mail_storage_find(driver);
+		if (storage_class == NULL)
+			return NULL;
+		classes = &storage_class;
+		count = 1;
 	}
 
-	storage_class = mail_storage_autodetect(data, flags);
-	if (storage_class == NULL) {
-		i_error("Ambiguous mail location setting, "
-			"don't know what to do with it: %s "
-			"(try prefixing it with mbox: or maildir:)",
-			data);
-		storage = NULL;
-	} else {
-		storage = storage_class->v.alloc();
-		if (storage_class->v.create(storage, data, user,
-					    flags, lock_method) < 0) {
-			pool_unref(storage->pool);
-			storage = NULL;
-		}
+	for (i = 0; i < count; i++) {
+		storage = classes[i]->v.alloc();
+		storage->flags = flags;
+		storage->lock_method = lock_method;
+		storage->user = p_strdup(storage->pool, user);
+
+		storage->callbacks =
+			p_new(storage->pool, struct mail_storage_callbacks, 1);
+		p_array_init(&storage->module_contexts, storage->pool, 5);
+
+		if (classes[i]->v.create(storage, data) == 0)
+			break;
+
+		/* try the next one */
+		pool_unref(storage->pool);
 	}
+	if (i == count)
+		return NULL;
 
-	if (hook_mail_storage_created != NULL && storage != NULL)
+	if (hook_mail_storage_created != NULL)
 		hook_mail_storage_created(storage);
 	return storage;
 }
--- a/src/lib-storage/mail-storage.h	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/lib-storage/mail-storage.h	Fri Mar 30 16:40:12 2007 +0300
@@ -202,16 +202,13 @@
 			    enum file_lock_method *lock_method_r);
 
 /* Create a new instance of registered mail storage class with given
-   storage-specific data. If data is NULL, it tries to autodetect defaults.
+   storage-specific data. If driver is NULL, it's tried to be autodetected
+   from data. If data is NULL, it uses the first storage that exists.
    May return NULL if anything fails. */
 struct mail_storage *
 mail_storage_create(const char *driver, const char *data, const char *user,
 		    enum mail_storage_flags flags,
 		    enum file_lock_method lock_method);
-struct mail_storage *
-mail_storage_create_with_data(const char *data, const char *user,
-			      enum mail_storage_flags flags,
-			      enum file_lock_method lock_method);
 void mail_storage_destroy(struct mail_storage **storage);
 
 char mail_storage_get_hierarchy_sep(struct mail_storage *storage);
--- a/src/plugins/convert/convert-storage.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/plugins/convert/convert-storage.c	Fri Mar 30 16:40:12 2007 +0300
@@ -255,8 +255,8 @@
 
 	mail_storage_parse_env(&flags, &lock_method);
 	flags |= MAIL_STORAGE_FLAG_NO_AUTOCREATE | MAIL_STORAGE_FLAG_HAS_INBOX;
-	source_storage = mail_storage_create_with_data(source_data, user,
-						       flags, lock_method);
+	source_storage = mail_storage_create(NULL, source_data, user,
+					     flags, lock_method);
 	if (source_storage == NULL) {
 		/* No need for conversion. */
 		return 0;
@@ -276,16 +276,16 @@
 	/* just in case if another process just had converted the mailbox,
 	   reopen the source storage */
 	mail_storage_destroy(&source_storage);
-	source_storage = mail_storage_create_with_data(source_data, user,
-						       flags, lock_method);
+	source_storage = mail_storage_create(NULL, source_data, user,
+					     flags, lock_method);
 	if (source_storage == NULL) {
 		/* No need for conversion anymore. */
 		file_dotlock_delete(&dotlock);
 		return 0;
 	}
 
-	dest_storage = mail_storage_create_with_data(dest_data, user,
-						     flags, lock_method);
+	dest_storage = mail_storage_create(NULL, dest_data, user,
+					   flags, lock_method);
 	if (dest_storage == NULL) {
 		i_error("Mailbox conversion: Failed to create destination "
 			"storage with data: %s", dest_data);
--- a/src/plugins/expire/expire-tool.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/plugins/expire/expire-tool.c	Fri Mar 30 16:40:12 2007 +0300
@@ -43,8 +43,8 @@
 
 	mail_env = getenv("MAIL");
 	mail_storage_parse_env(&flags, &lock_method);
-	ctx->storage = mail_storage_create_with_data(mail_env, user,
-						     flags, lock_method);
+	ctx->storage = mail_storage_create(NULL, mail_env, user,
+					   flags, lock_method);
 	if (ctx->storage == NULL) {
 		i_error("Failed to create storage for '%s' with mail '%s'",
 			user, mail_env == NULL ? "(null)" : mail_env);
--- a/src/pop3/main.c	Fri Mar 30 15:58:50 2007 +0300
+++ b/src/pop3/main.c	Fri Mar 30 16:40:12 2007 +0300
@@ -239,8 +239,8 @@
 			"%% variables.");
 
 	mail_storage_parse_env(&flags, &lock_method);
-	storage = mail_storage_create_with_data(mail, getenv("USER"),
-						flags, lock_method);
+	storage = mail_storage_create(NULL, mail, getenv("USER"),
+				      flags, lock_method);
 	if (storage == NULL) {
 		/* failed */
 		if (mail != NULL && *mail != '\0')