dovecot-2.2: lib-storage: Cleanups to mailbox mkdir() related fu...

dovecot at dovecot.org dovecot at dovecot.org
Wed Sep 26 17:17:23 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/02d00843dd79
changeset: 15118:02d00843dd79
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Sep 26 17:11:22 2012 +0300
description:
lib-storage: Cleanups to mailbox mkdir() related functions.

diffstat:

 src/lib-storage/index/dbox-common/dbox-storage.c |    8 +-
 src/lib-storage/index/dbox-multi/mdbox-file.c    |    9 +-
 src/lib-storage/index/dbox-multi/mdbox-map.c     |   29 +--
 src/lib-storage/index/index-storage.c            |   11 +-
 src/lib-storage/index/index-sync-pvt.c           |    2 +-
 src/lib-storage/index/maildir/maildir-util.c     |   14 +-
 src/lib-storage/list/subscription-file.c         |   14 +-
 src/lib-storage/mail-storage-private.h           |   10 +
 src/lib-storage/mail-storage.c                   |   65 ++++++-
 src/lib-storage/mailbox-list-private.h           |    4 -
 src/lib-storage/mailbox-list.c                   |  205 +++++++---------------
 src/lib-storage/mailbox-list.h                   |   21 +-
 src/plugins/acl/acl-backend-vfile-acllist.c      |   16 +-
 src/plugins/fts-lucene/fts-backend-lucene.c      |    7 +-
 14 files changed, 199 insertions(+), 216 deletions(-)

diffs (truncated from 723 to 300 lines):

diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/index/dbox-common/dbox-storage.c
--- a/src/lib-storage/index/dbox-common/dbox-storage.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c	Wed Sep 26 17:11:22 2012 +0300
@@ -285,7 +285,7 @@
 
 int dbox_verify_alt_storage(struct mailbox_list *list)
 {
-	const char *alt_path, *error;
+	const char *alt_path;
 	struct stat st;
 
 	alt_path = mailbox_list_get_root_path(list, MAILBOX_LIST_PATH_TYPE_ALT_DIR);
@@ -303,11 +303,7 @@
 	/* try to create the alt directory. if it fails, it means alt
 	   storage isn't mounted. */
 	if (mailbox_list_mkdir_root(list, alt_path,
-				    MAILBOX_LIST_PATH_TYPE_ALT_DIR,
-				    &error) < 0) {
-		i_error("Couldn't create dbox alt root dir %s: %s",
-			alt_path, error);
+				    MAILBOX_LIST_PATH_TYPE_ALT_DIR) < 0)
 		return -1;
-	}
 	return 0;
 }
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/index/dbox-multi/mdbox-file.c
--- a/src/lib-storage/index/dbox-multi/mdbox-file.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-file.c	Wed Sep 26 17:11:22 2012 +0300
@@ -303,7 +303,7 @@
 	struct mdbox_file *mfile = (struct mdbox_file *)file;
 	struct mdbox_map *map = mfile->storage->map;
 	mode_t old_mask;
-	const char *p, *dir, *error;
+	const char *p, *dir;
 	int fd;
 
 	old_mask = umask(0666 & ~map->perm.file_create_mode);
@@ -315,10 +315,9 @@
 		if (mailbox_list_mkdir_root(map->root_list, dir,
 					    path != file->alt_path ?
 					    MAILBOX_LIST_PATH_TYPE_DIR :
-					    MAILBOX_LIST_PATH_TYPE_ALT_DIR,
-					    &error) < 0) {
-			mail_storage_set_critical(&file->storage->storage,
-				"Couldn't create %s: %s", dir, error);
+					    MAILBOX_LIST_PATH_TYPE_ALT_DIR) < 0) {
+			mail_storage_copy_list_error(&file->storage->storage,
+						     map->root_list);
 			return -1;
 		}
 		/* try again */
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/index/dbox-multi/mdbox-map.c
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-map.c	Wed Sep 26 17:11:22 2012 +0300
@@ -98,34 +98,23 @@
 	i_free(map);
 }
 
-static int mdbox_map_mkdir_storage_path(struct mdbox_map *map, const char *path)
+static int mdbox_map_mkdir_storage(struct mdbox_map *map)
 {
-	struct stat st;
+	if (mailbox_list_mkdir_root(map->root_list, map->path,
+				    MAILBOX_LIST_PATH_TYPE_DIR) < 0) {
+		mail_storage_copy_list_error(MAP_STORAGE(map), map->root_list);
+		return -1;
+	}
 
-	if (stat(path, &st) == 0)
-		return 1;
-
-	if (mailbox_list_mkdir(map->root_list, NULL, path) < 0) {
+	if (strcmp(map->path, map->index_path) != 0 &&
+	    mailbox_list_mkdir_root(map->root_list, map->index_path,
+				    MAILBOX_LIST_PATH_TYPE_INDEX) < 0) {
 		mail_storage_copy_list_error(MAP_STORAGE(map), map->root_list);
 		return -1;
 	}
 	return 0;
 }
 
-static int mdbox_map_mkdir_storage(struct mdbox_map *map)
-{
-	int ret;
-
-	if ((ret = mdbox_map_mkdir_storage_path(map, map->path)) < 0)
-		return -1;
-
-	if (strcmp(map->path, map->index_path) != 0) {
-		if (mdbox_map_mkdir_storage_path(map, map->index_path) < 0)
-			return -1;
-	}
-	return ret;
-}
-
 static void mdbox_map_cleanup(struct mdbox_map *map)
 {
 	unsigned int interval =
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/index/index-storage.c	Wed Sep 26 17:11:22 2012 +0300
@@ -192,7 +192,7 @@
 	if (box->index != NULL)
 		return 0;
 
-	if (mailbox_list_create_missing_index_dir(box->list, box->name) < 0) {
+	if (mailbox_create_missing_dir(box, MAILBOX_LIST_PATH_TYPE_INDEX) < 0) {
 		mail_storage_set_internal_error(box->storage);
 		return -1;
 	}
@@ -464,13 +464,14 @@
 int index_storage_mailbox_create(struct mailbox *box, bool directory)
 {
 	const char *path, *p;
+	enum mailbox_list_path_type type;
 	enum mailbox_existence existence;
 	bool create_parent_dir;
 	int ret;
 
-	path = mailbox_list_get_path(box->list, box->name,
-				     directory ? MAILBOX_LIST_PATH_TYPE_DIR :
-				     MAILBOX_LIST_PATH_TYPE_MAILBOX);
+	type = directory ? MAILBOX_LIST_PATH_TYPE_DIR :
+		MAILBOX_LIST_PATH_TYPE_MAILBOX;
+	path = mailbox_list_get_path(box->list, box->name, type);
 	if (path == NULL) {
 		/* layout=none */
 		mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
@@ -487,7 +488,7 @@
 		path = t_strdup_until(path, p);
 	}
 
-	if ((ret = mailbox_list_mkdir(box->list, box->name, path)) < 0) {
+	if ((ret = mailbox_mkdir(box, path, type)) < 0) {
 		mail_storage_copy_list_error(box->storage, box->list);
 		return -1;
 	}
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/index/index-sync-pvt.c
--- a/src/lib-storage/index/index-sync-pvt.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/index/index-sync-pvt.c	Wed Sep 26 17:11:22 2012 +0300
@@ -18,7 +18,7 @@
 		return 0;
 	}
 
-	if (mailbox_list_create_missing_index_pvt_dir(box->list, box->name) < 0) {
+	if (mailbox_create_missing_dir(box, MAILBOX_LIST_PATH_TYPE_INDEX_PRIVATE) < 0) {
 		mail_storage_set_internal_error(box->storage);
 		return -1;
 	}
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/index/maildir/maildir-util.c
--- a/src/lib-storage/index/maildir/maildir-util.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/index/maildir/maildir-util.c	Wed Sep 26 17:11:22 2012 +0300
@@ -167,7 +167,7 @@
 			       enum mailbox_list_path_type type, bool retry)
 {
 	const struct mailbox_permissions *perm = mailbox_get_permissions(box);
-	const char *p, *parent, *error;
+	const char *p, *parent;
 
 	if (mkdir_chgrp(path, perm->dir_create_mode, perm->file_create_gid,
 			perm->file_create_gid_origin) == 0)
@@ -186,14 +186,12 @@
 		}
 		/* create index/control root directory */
 		parent = t_strdup_until(path, p);
-		if (mailbox_list_mkdir_root(box->list, parent, type, &error) == 0) {
-			/* should work now, try again */
-			return maildir_create_path(box, path, type, FALSE);
+		if (mailbox_list_mkdir_root(box->list, parent, type) < 0) {
+			mail_storage_copy_list_error(box->storage, box->list);
+			return -1;
 		}
-		/* fall through */
-		mail_storage_set_critical(box->storage,
-			"Couldn't create %s: %s", parent, error);
-		path = parent;
+		/* should work now, try again */
+		return maildir_create_path(box, path, type, FALSE);
 	default:
 		mail_storage_set_critical(box->storage,
 					  "mkdir(%s) failed: %m", path);
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/list/subscription-file.c
--- a/src/lib-storage/list/subscription-file.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/list/subscription-file.c	Wed Sep 26 17:11:22 2012 +0300
@@ -89,10 +89,11 @@
 	struct dotlock_settings dotlock_set;
 	struct dotlock *dotlock;
 	struct mailbox_permissions perm;
-	const char *line;
+	const char *line, *dir, *fname;
 	struct istream *input;
 	struct ostream *output;
 	int fd_in, fd_out;
+	enum mailbox_list_path_type type;
 	bool found, changed = FALSE, failed = FALSE;
 
 	if (strcasecmp(name, "INBOX") == 0)
@@ -112,8 +113,15 @@
 					 perm.file_create_gid_origin, &dotlock);
 	if (fd_out == -1 && errno == ENOENT) {
 		/* directory hasn't been created yet. */
-		if (mailbox_list_mkdir_parent(list, NULL, path) < 0)
-			return -1;
+		type = list->set.control_dir != NULL ?
+			MAILBOX_LIST_PATH_TYPE_CONTROL :
+			MAILBOX_LIST_PATH_TYPE_DIR;
+		fname = strrchr(path, '/');
+		if (fname != NULL) {
+			dir = t_strdup_until(path, fname);
+			if (mailbox_list_mkdir_root(list, dir, type) < 0)
+				return -1;
+		}
 		fd_out = file_dotlock_open_group(&dotlock_set, path, 0,
 						 perm.file_create_mode,
 						 perm.file_create_gid,
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/mail-storage-private.h
--- a/src/lib-storage/mail-storage-private.h	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/mail-storage-private.h	Wed Sep 26 17:11:22 2012 +0300
@@ -566,6 +566,16 @@
 /* Force permissions to be refreshed on next lookup */
 void mailbox_refresh_permissions(struct mailbox *box);
 
+/* Create path's directory with proper permissions. The root directory is also
+   created if necessary. Returns 1 if created, 0 if it already existed,
+   -1 if error. */
+int mailbox_mkdir(struct mailbox *box, const char *path,
+		  enum mailbox_list_path_type type);
+/* Create a non-mailbox type directory for mailbox if it's missing (e.g. index).
+   Optimized for case where the directory usually exists. */
+int mailbox_create_missing_dir(struct mailbox *box,
+			       enum mailbox_list_path_type type);
+
 /* Returns -1 if error, 0 if failed with EEXIST, 1 if ok */
 int mailbox_create_fd(struct mailbox *box, const char *path, int flags,
 		      int *fd_r);
diff -r 3a694c8090a3 -r 02d00843dd79 src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Wed Sep 26 02:31:33 2012 +0300
+++ b/src/lib-storage/mail-storage.c	Wed Sep 26 17:11:22 2012 +0300
@@ -257,9 +257,9 @@
 	autocreate = (flags & MAIL_STORAGE_FLAG_NO_AUTOCREATE) == 0;
 	ret = mail_storage_verify_root(root_dir, autocreate, error_r);
 	if (ret == 0) {
-		ret = mailbox_list_mkdir_root(list, root_dir,
-					      MAILBOX_LIST_PATH_TYPE_MAILBOX,
-					      error_r);
+		ret = mailbox_list_try_mkdir_root(list, root_dir,
+						  MAILBOX_LIST_PATH_TYPE_MAILBOX,
+						  error_r);
 	}
 	return ret < 0 ? -1 : 0;
 }
@@ -1973,6 +1973,65 @@
 	return 1;
 }
 
+int mailbox_mkdir(struct mailbox *box, const char *path,
+		  enum mailbox_list_path_type type)
+{
+	struct mailbox_permissions perm;
+	const char *root_dir;
+
+	mailbox_list_get_permissions(box->list, box->name, &perm);
+	if (!perm.gid_origin_is_mailbox_path) {
+		/* mailbox root directory doesn't exist, create it */
+		root_dir = mailbox_list_get_root_path(box->list, type);
+		if (mailbox_list_mkdir_root(box->list, root_dir, type) < 0) {
+			mail_storage_copy_list_error(box->storage, box->list);
+			return -1;
+		}
+	}
+
+	if (mkdir_parents_chgrp(path, perm.dir_create_mode,
+				perm.file_create_gid,
+				perm.file_create_gid_origin) == 0)
+		return 1;
+	else if (errno == EEXIST)
+		return 0;
+	else if (errno == ENOTDIR) {
+		mail_storage_set_error(box->storage, MAIL_ERROR_NOTPOSSIBLE,
+			"Mailbox doesn't allow inferior mailboxes");
+		return -1;
+	} else if (mail_storage_set_error_from_errno(box->storage)) {
+		return -1;
+	} else {
+		mail_storage_set_critical(box->storage,
+					  "mkdir_parents(%s) failed: %m", path);
+		return -1;
+	}
+}
+
+int mailbox_create_missing_dir(struct mailbox *box,
+			       enum mailbox_list_path_type type)
+{
+	const char *mail_dir, *dir;
+	struct stat st;
+
+	dir = mailbox_get_path_to(box, type);
+	mail_dir = mailbox_get_path_to(box, MAILBOX_LIST_PATH_TYPE_MAILBOX);
+	if (dir == NULL || *dir == '\0')
+		return 0;


More information about the dovecot-cvs mailing list