changeset 6434:7b745fb85975 HEAD

Moved mail_location data parsing to a common function. It supports now also specifying SUBSCRIPTIONS and DIRNAME.
author Timo Sirainen <tss@iki.fi>
date Mon, 17 Sep 2007 10:35:24 +0300
parents 375ba923a622
children 1672a4cb665e
files src/lib-storage/index/cydir/cydir-storage.c src/lib-storage/index/dbox/dbox-storage.c src/lib-storage/index/maildir/maildir-storage.c src/lib-storage/index/mbox/mbox-storage.c src/lib-storage/mailbox-list-private.h src/lib-storage/mailbox-list.c
diffstat 6 files changed, 88 insertions(+), 138 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/cydir/cydir-storage.c	Mon Sep 17 09:51:53 2007 +0300
+++ b/src/lib-storage/index/cydir/cydir-storage.c	Mon Sep 17 10:35:24 2007 +0300
@@ -38,11 +38,11 @@
 static int
 cydir_get_list_settings(struct mailbox_list_settings *list_set,
 			const char *data, enum mail_storage_flags flags,
-			const char **error_r)
+			const char **layout_r, const char **error_r)
 {
 	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
-	const char *p;
-	size_t len;
+
+	*layout_r = "fs";
 
 	memset(list_set, 0, sizeof(*list_set));
 	list_set->subscription_fname = CYDIR_SUBSCRIPTION_FILE_NAME;
@@ -56,32 +56,9 @@
 		return -1;
 	}
 
-	/* <root dir> [:INDEX=<dir>] */
 	if (debug)
 		i_info("cydir: data=%s", data);
-	p = strchr(data, ':');
-	if (p == NULL)
-		list_set->root_dir = data;
-	else {
-		list_set->root_dir = t_strdup_until(data, p);
-
-		do {
-			p++;
-			if (strncmp(p, "INDEX=", 6) == 0)
-				list_set->index_dir = t_strcut(p+6, ':');
-			p = strchr(p, ':');
-		} while (p != NULL);
-	}
-
-	/* strip trailing '/' */
-	len = strlen(list_set->root_dir);
-	if (len > 1 && list_set->root_dir[len-1] == '/')
-		list_set->root_dir = t_strndup(list_set->root_dir, len-1);
-
-	if (list_set->index_dir != NULL &&
-	    strcmp(list_set->index_dir, "MEMORY") == 0)
-		list_set->index_dir = "";
-	return 0;
+	return mailbox_list_settings_parse(data, list_set, layout_r, error_r);
 }
 
 static struct mail_storage *cydir_alloc(void)
@@ -103,9 +80,10 @@
 	struct cydir_storage *storage = (struct cydir_storage *)_storage;
 	struct mailbox_list_settings list_set;
 	struct stat st;
+	const char *layout;
 
 	if (cydir_get_list_settings(&list_set, data, _storage->flags,
-				    error_r) < 0)
+				    &layout, error_r) < 0)
 		return -1;
 	list_set.mail_storage_flags = &_storage->flags;
 	list_set.lock_method = &_storage->lock_method;
@@ -132,7 +110,7 @@
 		}
 	}
 
-	if (mailbox_list_alloc("fs", &_storage->list, error_r) < 0)
+	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 = cydir_list_iter_is_mailbox;
--- a/src/lib-storage/index/dbox/dbox-storage.c	Mon Sep 17 09:51:53 2007 +0300
+++ b/src/lib-storage/index/dbox/dbox-storage.c	Mon Sep 17 10:35:24 2007 +0300
@@ -40,11 +40,11 @@
 static int
 dbox_get_list_settings(struct mailbox_list_settings *list_set,
 		       const char *data, enum mail_storage_flags flags,
-		       const char **error_r)
+		       const char **layout_r, const char **error_r)
 {
 	bool debug = (flags & MAIL_STORAGE_FLAG_DEBUG) != 0;
-	const char *p;
-	size_t len;
+
+	*layout_r = "fs";
 
 	memset(list_set, 0, sizeof(*list_set));
 	list_set->subscription_fname = DBOX_SUBSCRIPTION_FILE_NAME;
@@ -58,32 +58,9 @@
 		return -1;
 	}
 
-	/* <root dir> [:INDEX=<dir>] */
 	if (debug)
 		i_info("dbox: data=%s", data);
-	p = strchr(data, ':');
-	if (p == NULL)
-		list_set->root_dir = data;
-	else {
-		list_set->root_dir = t_strdup_until(data, p);
-
-		do {
-			p++;
-			if (strncmp(p, "INDEX=", 6) == 0)
-				list_set->index_dir = t_strcut(p+6, ':');
-			p = strchr(p, ':');
-		} while (p != NULL);
-	}
-
-	/* strip trailing '/' */
-	len = strlen(list_set->root_dir);
-	if (len > 1 && list_set->root_dir[len-1] == '/')
-		list_set->root_dir = t_strndup(list_set->root_dir, len-1);
-
-	if (list_set->index_dir != NULL &&
-	    strcmp(list_set->index_dir, "MEMORY") == 0)
-		list_set->index_dir = "";
-	return 0;
+	return mailbox_list_settings_parse(data, list_set, layout_r, error_r);
 }
 
 static struct mail_storage *dbox_alloc(void)
@@ -105,9 +82,10 @@
 	struct dbox_storage *storage = (struct dbox_storage *)_storage;
 	struct mailbox_list_settings list_set;
 	struct stat st;
+	const char *layout;
 
 	if (dbox_get_list_settings(&list_set, data, _storage->flags,
-				   error_r) < 0)
+				   &layout, error_r) < 0)
 		return -1;
 	list_set.mail_storage_flags = &_storage->flags;
 	list_set.lock_method = &_storage->lock_method;
@@ -134,7 +112,7 @@
 		}
 	}
 
-	if (mailbox_list_alloc("fs", &_storage->list, error_r) < 0)
+	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 = dbox_list_iter_is_mailbox;
--- a/src/lib-storage/index/maildir/maildir-storage.c	Mon Sep 17 09:51:53 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-storage.c	Mon Sep 17 10:35:24 2007 +0300
@@ -59,28 +59,13 @@
 				enum mailbox_list_file_type type,
 				enum mailbox_info_flags *flags_r);
 
-static const char *strip_tail_slash(const char *path)
-{
-	size_t len = strlen(path);
-
-	if (len > 1 && path[len-1] == '/')
-		return t_strndup(path, len-1);
-	else
-		return path;
-}
-
-static const char *strip_tail_slash_and_cut(const char *path)
-{
-	return strip_tail_slash(t_strcut(path, ':'));
-}
-
 static int
 maildir_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;
-	const char *home, *path, *p;
+	const char *home, *path;
 
 	*layout_r = MAILDIR_PLUSPLUS_DRIVER_NAME;
 
@@ -121,33 +106,11 @@
 			list_set->root_dir = "/";
 		}
 	} else {
-		/* <Maildir> [:INBOX=<dir>] [:INDEX=<dir>] [:CONTROL=<dir>] */
 		if (debug)
 			i_info("maildir: data=%s", data);
-		p = strchr(data, ':');
-		if (p == NULL)
-			list_set->root_dir = data;
-		else {
-			list_set->root_dir = t_strdup_until(data, p);
-
-			do {
-				p++;
-				if (strncmp(p, "INBOX=", 6) == 0) {
-					list_set->inbox_path =
-						strip_tail_slash_and_cut(p+6);
-				} else if (strncmp(p, "INDEX=", 6) == 0) {
-					list_set->index_dir =
-						strip_tail_slash_and_cut(p+6);
-				} else if (strncmp(p, "CONTROL=", 8) == 0) {
-					list_set->control_dir =
-						strip_tail_slash_and_cut(p+8);
-				} else if (strncmp(p, "LAYOUT=", 7) == 0) {
-					*layout_r =
-						strip_tail_slash_and_cut(p+7);
-				}
-				p = strchr(p, ':');
-			} while (p != NULL);
-		}
+		if (mailbox_list_settings_parse(data, list_set, layout_r,
+						error_r) < 0)
+			return -1;
 	}
 
 	if (list_set->root_dir == NULL || *list_set->root_dir == '\0') {
@@ -156,13 +119,8 @@
 		*error_r = "Root mail directory not given";
 		return -1;
 	}
-	list_set->root_dir = strip_tail_slash(list_set->root_dir);
 	if (list_set->inbox_path == NULL)
 		list_set->inbox_path = list_set->root_dir;
-
-	if (list_set->index_dir != NULL &&
-	    strcmp(list_set->index_dir, "MEMORY") == 0)
-		list_set->index_dir = "";
 	return 0;
 }
 
--- a/src/lib-storage/index/mbox/mbox-storage.c	Mon Sep 17 09:51:53 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Mon Sep 17 10:35:24 2007 +0300
@@ -303,35 +303,23 @@
 		   either $HOME/mail or $HOME/Mail */
 		list_set->root_dir = get_root_dir(flags);
 	} else {
-		/* <root mail directory> | <INBOX path>
-		   [:INBOX=<path>] [:INDEX=<dir>] */
 		if (debug)
 			i_info("mbox: data=%s", data);
 		p = strchr(data, ':');
-		if (p == NULL) {
+		if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) == 0 &&
+		    p == NULL && data[strlen(data)-1] != '/') {
 			/* if the data points to a file, treat it as an INBOX */
-			if ((flags & MAIL_STORAGE_FLAG_NO_AUTODETECTION) != 0 ||
-			    stat(data, &st) < 0 || S_ISDIR(st.st_mode))
+			data = home_expand(data);
+			if (stat(data, &st) < 0 || S_ISDIR(st.st_mode))
 				list_set->root_dir = data;
 			else {
 				list_set->root_dir = get_root_dir(flags);
 				list_set->inbox_path = data;
 			}
 		} else {
-			list_set->root_dir = t_strdup_until(data, p);
-			do {
-				p++;
-				if (strncmp(p, "INBOX=", 6) == 0) {
-					list_set->inbox_path =
-						t_strcut(p+6, ':');
-				} else if (strncmp(p, "INDEX=", 6) == 0) {
-					list_set->index_dir =
-						t_strcut(p+6, ':');
-				} else if (strncmp(p, "LAYOUT=", 7) == 0) {
-					*layout_r = t_strcut(p+7, ':');
-				}
-				p = strchr(p, ':');
-			} while (p != NULL);
+			if (mailbox_list_settings_parse(data, list_set,
+							layout_r, error_r) < 0)
+				return -1;
 		}
 	}
 
@@ -345,18 +333,8 @@
 		if (list_set->root_dir == NULL)
 			return -1;
 	} else {
-		/* strip trailing '/' */
-		size_t len = strlen(list_set->root_dir);
-
-		if (len > 1 && list_set->root_dir[len-1] == '/') {
-			list_set->root_dir =
-				t_strndup(list_set->root_dir, len-1);
-		}
-		list_set->root_dir = home_expand(list_set->root_dir);
-
 		/* make sure the directory exists */
-		if (*list_set->root_dir == '\0' ||
-		    lstat(list_set->root_dir, &st) == 0) {
+		if (lstat(list_set->root_dir, &st) == 0) {
 			/* yep, go ahead */
 		} else if (errno != ENOENT && errno != ENOTDIR) {
 			*error_r = t_strdup_printf("lstat(%s) failed: %m",
@@ -379,10 +357,6 @@
 		list_set->inbox_path =
 			get_inbox_file(list_set->root_dir, !autodetect, debug);
 	}
-
-	if (list_set->index_dir != NULL &&
-	    strcmp(list_set->index_dir, "MEMORY") == 0)
-		list_set->index_dir = "";
 	return 0;
 }
 
--- a/src/lib-storage/mailbox-list-private.h	Mon Sep 17 09:51:53 2007 +0300
+++ b/src/lib-storage/mailbox-list-private.h	Mon Sep 17 10:35:24 2007 +0300
@@ -94,6 +94,10 @@
 
 extern void (*hook_mailbox_list_created)(struct mailbox_list *list);
 
+int mailbox_list_settings_parse(const char *data,
+				struct mailbox_list_settings *set,
+				const char **layout, const char **error_r);
+
 int mailbox_list_delete_index_control(struct mailbox_list *list,
 				      const char *name);
 
--- a/src/lib-storage/mailbox-list.c	Mon Sep 17 09:51:53 2007 +0300
+++ b/src/lib-storage/mailbox-list.c	Mon Sep 17 10:35:24 2007 +0300
@@ -3,6 +3,7 @@
 #include "lib.h"
 #include "array.h"
 #include "ioloop.h"
+#include "home-expand.h"
 #include "mkdir-parents.h"
 #include "unlink-directory.h"
 #include "mailbox-list-private.h"
@@ -95,6 +96,63 @@
 	return 0;
 }
 
+static const char *fix_path(const char *path)
+{
+	size_t len = strlen(path);
+
+	if (len > 1 && path[len-1] == '/')
+		path = t_strndup(path, len-1);
+	return home_expand(path);
+}
+
+int mailbox_list_settings_parse(const char *data,
+				struct mailbox_list_settings *set,
+				const char **layout, const char **error_r)
+{
+	const char *const *tmp, *key, *value;
+
+	i_assert(*data != '\0');
+
+	*error_r = NULL;
+
+	/* <root dir> */
+	tmp = t_strsplit(data, ":");
+	set->root_dir = fix_path(*tmp);
+	tmp++;
+
+	for (; *tmp != NULL; tmp++) {
+		value = strchr(*tmp, '=');
+		if (value == NULL) {
+			key = *tmp;
+			value = "";
+		} else {
+			key = t_strdup_until(*tmp, value);
+			value++;
+		}
+
+		if (strcmp(key, "INBOX") == 0)
+			set->inbox_path = fix_path(value);
+		else if (strcmp(key, "INDEX") == 0)
+			set->index_dir = fix_path(value);
+		else if (strcmp(key, "CONTROL") == 0)
+			set->control_dir = fix_path(value);
+		else if (strcmp(key, "LAYOUT") == 0)
+			*layout = value;
+		else if (strcmp(key, "SUBSCRIPTIONS") == 0)
+			set->subscription_fname = fix_path(value);
+		else if (strcmp(key, "DIRNAME") == 0)
+			set->maildir_name = value;
+		else {
+			*error_r = t_strdup_printf("Unknown setting: %s", key);
+			return -1;
+		}
+	}
+
+	if (set->index_dir != NULL && strcmp(set->index_dir, "MEMORY") == 0)
+		set->index_dir = "";
+	return 0;
+}
+
 void mailbox_list_init(struct mailbox_list *list, struct mail_namespace *ns,
 		       const struct mailbox_list_settings *set,
 		       enum mailbox_list_flags flags)