[dovecot-cvs] dovecot/src/lib-storage/index/dbox dbox-file.c, 1.13, 1.14 dbox-storage.c, 1.38, 1.39 dbox-storage.h, 1.17, 1.18 dbox-sync-expunge.c, 1.22, 1.23 dbox-sync-full.c, 1.10, 1.11 dbox-uidlist.c, 1.46, 1.47

tss at dovecot.org tss at dovecot.org
Thu Mar 29 10:59:20 EEST 2007


Update of /var/lib/cvs/dovecot/src/lib-storage/index/dbox
In directory talvi:/tmp/cvs-serv11000/lib-storage/index/dbox

Modified Files:
	dbox-file.c dbox-storage.c dbox-storage.h dbox-sync-expunge.c 
	dbox-sync-full.c dbox-uidlist.c 
Log Message:
Moved delete/rename operations to mailbox_list API. Fixed mbox/maildir to
work with either fs/maildir++ directory layout. They can be changed by
appending :LAYOUT=fs|maildir++ to mail_location.



Index: dbox-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-file.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- dbox-file.c	12 Jun 2006 08:24:44 -0000	1.13
+++ dbox-file.c	29 Mar 2007 07:59:17 -0000	1.14
@@ -117,8 +117,7 @@
 		mbox->file->fd = -1;
 
 		mbox->file->path =
-			i_strdup_printf("%s/"DBOX_MAILDIR_NAME"/"
-					DBOX_MAIL_FILE_FORMAT,
+			i_strdup_printf("%s/"DBOX_MAIL_FILE_FORMAT,
 					mbox->path, file_seq);
 	}
 

Index: dbox-storage.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-storage.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- dbox-storage.c	22 Feb 2007 17:32:08 -0000	1.38
+++ dbox-storage.c	29 Mar 2007 07:59:18 -0000	1.39
@@ -1,6 +1,7 @@
 /* Copyright (C) 2005-2007 Timo Sirainen */
 
 #include "lib.h"
+#include "array.h"
 #include "ioloop.h"
 #include "mkdir-parents.h"
 #include "unlink-directory.h"
@@ -21,6 +22,10 @@
 /* How often to touch the uidlist lock file when using KEEP_LOCKED flag */
 #define DBOX_LOCK_TOUCH_MSECS (10*1000)
 
+#define DBOX_LIST_CONTEXT(obj) \
+	*((void **)array_idx_modifiable(&(obj)->module_contexts, \
+					dbox_mailbox_list_module_id))
+
 const struct dotlock_settings default_uidlist_dotlock_set = {
 	MEMBER(temp_prefix) NULL,
 	MEMBER(lock_suffix) NULL,
@@ -63,17 +68,51 @@
 extern struct mail_storage dbox_storage;
 extern struct mailbox dbox_mailbox;
 
-static bool dbox_handle_errors(struct mail_storage *storage)
+static unsigned int dbox_mailbox_list_module_id = 0;
+
+static int
+dbox_list_delete_mailbox(struct mailbox_list *list, const char *name);
+static int dbox_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx,
+				     const char *dir, const char *fname,
+				     enum mailbox_list_file_type type,
+				     enum mailbox_info_flags *flags);
+
+static bool
+dbox_storage_is_valid_existing_name(struct mailbox_list *list, const char *name)
 {
-	if (ENOACCESS(errno))
-		mail_storage_set_error(storage, MAIL_STORAGE_ERR_NO_PERMISSION);
-	else if (ENOSPACE(errno))
-		mail_storage_set_error(storage, "Not enough disk space");
-	else if (ENOTFOUND(errno))
-		mail_storage_set_error(storage, "Directory structure is broken");
-	else
+	struct dbox_storage *storage = DBOX_LIST_CONTEXT(list);
+	const char *p;
+
+	if (!storage->list_super.is_valid_existing_name(list, name))
 		return FALSE;
-	return TRUE;
+
+	/* Don't allow the mailbox name to end in dbox-Mails */
+	p = strrchr(name, '/');
+	if (p != NULL)
+		name = p + 1;
+	return strcmp(name, DBOX_MAILDIR_NAME) != 0;
+}
+
+static bool
+dbox_storage_is_valid_create_name(struct mailbox_list *list, const char *name)
+{
+	struct dbox_storage *storage = DBOX_LIST_CONTEXT(list);
+	const char *const *tmp;
+	bool ret = TRUE;
+
+	if (!storage->list_super.is_valid_create_name(list, name))
+		return FALSE;
+
+	/* Don't allow creating mailboxes under dbox-Mails */
+	t_push();
+	for (tmp = t_strsplit(name, "/"); *tmp != NULL; tmp++) {
+		if (strcmp(*tmp, DBOX_MAILDIR_NAME) == 0) {
+			ret = FALSE;
+			break;
+		}
+	}
+	t_pop();
+	return ret;
 }
 
 static int
@@ -86,7 +125,7 @@
 
 	memset(list_set, 0, sizeof(*list_set));
 	list_set->subscription_fname = DBOX_SUBSCRIPTION_FILE_NAME;
-	list_set->maildir_name = "";
+	list_set->maildir_name = DBOX_MAILDIR_NAME;
 
 	if (data == NULL || *data == '\0') {
 		/* we won't do any guessing for this format. */
@@ -162,12 +201,19 @@
 
 	if (mailbox_list_init("fs", &list_set,
 			      mail_storage_get_list_flags(flags),
-			      mailbox_storage_list_is_mailbox, storage,
 			      &list, &error) < 0) {
 		i_error("dbox fs: %s", error);
 		pool_unref(pool);
 		return NULL;
 	}
+	storage->list_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;
+	list->v.iter_is_mailbox = dbox_list_iter_is_mailbox;
+	list->v.delete_mailbox = dbox_list_delete_mailbox;
+
+	array_idx_set(&list->module_contexts,
+		      dbox_mailbox_list_module_id, &storage);
 
 	storage->uidlist_dotlock_set = default_uidlist_dotlock_set;
 	storage->file_dotlock_set = default_file_dotlock_set;
@@ -204,7 +250,7 @@
 
 	data = t_strcut(data, ':');
 
-	path = t_strconcat(data, "/inbox/"DBOX_MAILDIR_NAME, NULL);
+	path = t_strconcat(data, "/INBOX/"DBOX_MAILDIR_NAME, NULL);
 	if (stat(path, &st) < 0) {
 		if (debug)
 			i_info("dbox autodetect: stat(%s) failed: %m", path);
@@ -221,9 +267,13 @@
 
 static int create_dbox(struct mail_storage *storage, const char *path)
 {
+	const char *error;
+
 	if (mkdir_parents(path, CREATE_MODE) < 0 && errno != EEXIST) {
-		if (dbox_handle_errors(storage))
+		if (mail_storage_errno2str(&error)) {
+			mail_storage_set_error(storage, "%s", error);
 			return -1;
+		}
 
 		mail_storage_set_critical(storage, "mkdir(%s) failed: %m",
 					  path);
@@ -367,7 +417,7 @@
 		return dbox_open(storage, name, flags);
 	} else if (errno == ENOENT) {
 		mail_storage_set_error(_storage,
-			MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name);
+			MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name);
 		return NULL;
 	} else {
 		mail_storage_set_critical(_storage, "stat(%s) failed: %m",
@@ -400,34 +450,30 @@
 	return create_dbox(_storage, path);
 }
 
-static int dbox_mailbox_delete(struct mail_storage *_storage,
-			       const char *name)
+static int
+dbox_list_delete_mailbox(struct mailbox_list *list, const char *name)
 {
-	const char *path, *mail_path;
+	struct dbox_storage *storage = DBOX_LIST_CONTEXT(list);
 	struct stat st;
+	const char *path, *mail_path, *error;
 
-	mail_storage_clear_error(_storage);
-
-	if (strcmp(name, "INBOX") == 0) {
-		mail_storage_set_error(_storage, "INBOX can't be deleted.");
-		return -1;
-	}
+	/* make sure the indexes are closed before trying to delete the
+	   directory that contains them */
+	index_storage_destroy_unrefed();
 
-	if (!mailbox_list_is_valid_existing_name(_storage->list, name)) {
-		mail_storage_set_error(_storage, "Invalid mailbox name");
+	/* delete the index and control directories */
+	if (storage->list_super.delete_mailbox(list, name) < 0)
 		return -1;
-	}
 
-	path = mailbox_list_get_path(_storage->list, name,
-				     MAILBOX_LIST_PATH_TYPE_DIR);
-	mail_path = mailbox_list_get_path(_storage->list, name,
+	path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR);
+	mail_path = mailbox_list_get_path(list, name,
 					  MAILBOX_LIST_PATH_TYPE_MAILBOX);
 
 	if (stat(mail_path, &st) < 0 && ENOTFOUND(errno)) {
 		if (stat(path, &st) < 0) {
 			/* doesn't exist at all */
-			mail_storage_set_error(_storage,
-				MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, name);
+			mailbox_list_set_error(list, t_strdup_printf(
+				MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name));
 			return -1;
 		}
 
@@ -436,23 +482,23 @@
 			return 0;
 
 		if (errno == ENOTEMPTY) {
-			mail_storage_set_error(_storage,
-				"Mailbox has only submailboxes: %s", name);
+			mailbox_list_set_error(list, t_strdup_printf(
+				"Directory %s isn't empty, can't delete it.",
+				name));
 		} else {
-			mail_storage_set_critical(_storage,
+			mailbox_list_set_critical(list,
 				"rmdir() failed for %s: %m", path);
 		}
 
 		return -1;
 	}
 
-	/* make sure the indexes are closed before trying to delete the
-	   directory that contains them */
-	index_storage_destroy_unrefed();
 
 	if (unlink_directory(mail_path, TRUE) < 0) {
-		if (!dbox_handle_errors(_storage)) {
-			mail_storage_set_critical(_storage,
+		if (mail_storage_errno2str(&error))
+			mailbox_list_set_error(list, error);
+		else {
+			mailbox_list_set_critical(list,
 				"unlink_directory() failed for %s: %m",
 				mail_path);
 		}
@@ -467,79 +513,12 @@
 			break;
 
 		name = t_strdup_until(name, p);
-		path = mailbox_list_get_path(_storage->list, name,
+		path = mailbox_list_get_path(list, name,
 					     MAILBOX_LIST_PATH_TYPE_DIR);
 	}
 	return 0;
 }
 
-static int dbox_mailbox_rename(struct mail_storage *_storage,
-			       const char *oldname, const char *newname)
-{
-	const char *oldpath, *newpath, *p;
-	struct stat st;
-
-	mail_storage_clear_error(_storage);
-
-	if (!mailbox_list_is_valid_existing_name(_storage->list, oldname) ||
-	    !mailbox_list_is_valid_create_name(_storage->list, newname)) {
-		mail_storage_set_error(_storage, "Invalid mailbox name");
-		return -1;
-	}
-
-	oldpath = mailbox_list_get_path(_storage->list, oldname,
-					MAILBOX_LIST_PATH_TYPE_DIR);
-	newpath = mailbox_list_get_path(_storage->list, newname,
-					MAILBOX_LIST_PATH_TYPE_DIR);
-
-	/* create the hierarchy */
-	p = strrchr(newpath, '/');
-	if (p != NULL) {
-		p = t_strdup_until(newpath, p);
-		if (mkdir_parents(p, CREATE_MODE) < 0) {
-			if (dbox_handle_errors(_storage))
-				return -1;
-
-			mail_storage_set_critical(_storage,
-				"mkdir_parents(%s) failed: %m", p);
-			return -1;
-		}
-	}
-
-	/* first check that the destination mailbox doesn't exist.
-	   this is racy, but we need to be atomic and there's hardly any
-	   possibility that someone actually tries to rename two mailboxes
-	   to same new one */
-	if (lstat(newpath, &st) == 0) {
-		mail_storage_set_error(_storage,
-				       "Target mailbox already exists");
-		return -1;
-	} else if (errno == ENOTDIR) {
-		mail_storage_set_error(_storage,
-			"Target mailbox doesn't allow inferior mailboxes");
-		return -1;
-	} else if (errno != ENOENT && errno != EACCES) {
-		mail_storage_set_critical(_storage, "lstat(%s) failed: %m",
-					  newpath);
-		return -1;
-	}
-
-	/* NOTE: renaming INBOX works just fine with us, it's simply recreated
-	   the next time it's needed. */
-	if (rename(oldpath, newpath) < 0) {
-		if (ENOTFOUND(errno)) {
-			mail_storage_set_error(_storage,
-				MAIL_STORAGE_ERR_MAILBOX_NOT_FOUND, oldname);
-		} else if (!dbox_handle_errors(_storage)) {
-			mail_storage_set_critical(_storage,
-				"rename(%s, %s) failed: %m", oldpath, newpath);
-		}
-		return -1;
-	}
-
-	return 0;
-}
-
 static int dbox_storage_close(struct mailbox *box)
 {
 	struct dbox_mailbox *mbox = (struct dbox_mailbox *)box;
@@ -571,18 +550,15 @@
 		return;
 	}
 
-	index_mailbox_check_add(&mbox->ibox,
-		t_strconcat(mbox->path, "/"DBOX_MAILDIR_NAME, NULL));
+	index_mailbox_check_add(&mbox->ibox, mbox->path);
 }
 
-static int dbox_is_mailbox(struct mail_storage *storage,
-			   const char *dir, const char *fname,
-			   enum mailbox_list_iter_flags iter_flags,
-			   enum mailbox_info_flags *flags,
-			   enum mailbox_list_file_type type)
+static int dbox_list_iter_is_mailbox(struct mailbox_list_iterate_context *ctx,
+				     const char *dir, const char *fname,
+				     enum mailbox_list_file_type type,
+				     enum mailbox_info_flags *flags)
 {
-	const char *path, *mail_path;
-	size_t len;
+	const char *mail_path;
 	struct stat st;
 	int ret = 1;
 
@@ -591,18 +567,11 @@
 		return 0;
 	}
 
-	/* skip all .lock files */
-	len = strlen(fname);
-	if (len > 5 && strcmp(fname+len-5, ".lock") == 0) {
-		*flags = MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
-		return 0;
-	}
-
 	/* try to avoid stat() with these checks */
 	if (type != MAILBOX_LIST_FILE_TYPE_DIR &&
 	    type != MAILBOX_LIST_FILE_TYPE_SYMLINK &&
 	    type != MAILBOX_LIST_FILE_TYPE_UNKNOWN &&
-	    (iter_flags & MAILBOX_LIST_ITER_FAST_FLAGS) != 0) {
+	    (ctx->flags & MAILBOX_LIST_ITER_FAST_FLAGS) != 0) {
 		/* it's a file */
 		*flags |= MAILBOX_NOSELECT | MAILBOX_NOINFERIORS;
 		return 0;
@@ -610,8 +579,7 @@
 
 	/* need to stat() then */
 	t_push();
-	path = t_strconcat(dir, "/", fname, NULL);
-	mail_path = t_strconcat(path, "/"DBOX_MAILDIR_NAME, NULL);
+	mail_path = t_strconcat(dir, "/", fname, "/"DBOX_MAILDIR_NAME, NULL);
 
 	if (stat(mail_path, &st) == 0) {
 		if (!S_ISDIR(st.st_mode)) {
@@ -621,17 +589,9 @@
 		}
 	} else {
 		/* non-selectable, but may contain subdirs */
+		if (errno != ENOTDIR)
+			*flags |= MAILBOX_CHILDREN;
 		*flags |= MAILBOX_NOSELECT;
-		if (stat(path, &st) < 0) {
-			if (ENOTFOUND(errno)) {
-				/* just lost it */
-				ret = 0;
-			} else if (errno != EACCES && errno != ELOOP) {
-				mail_storage_set_critical(storage,
-					"stat(%s) failed: %m", path);
-				ret = -1;
-			}
-		}
 	}
 	t_pop();
 
@@ -640,6 +600,7 @@
 
 static void dbox_class_init(void)
 {
+	dbox_mailbox_list_module_id = mailbox_list_module_id++;
 	dbox_transaction_class_init();
 }
 
@@ -661,9 +622,6 @@
 		index_storage_set_callbacks,
 		dbox_mailbox_open,
 		dbox_mailbox_create,
-		dbox_mailbox_delete,
-		dbox_mailbox_rename,
-		dbox_is_mailbox,
 		index_storage_get_last_error
 	}
 };

Index: dbox-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-storage.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dbox-storage.h	22 Feb 2007 12:50:14 -0000	1.17
+++ dbox-storage.h	29 Mar 2007 07:59:18 -0000	1.18
@@ -2,6 +2,7 @@
 #define __DBOX_STORAGE_H
 
 #include "index-storage.h"
+#include "mailbox-list-private.h"
 #include "dbox-format.h"
 
 #define DBOX_STORAGE_NAME "dbox"
@@ -14,6 +15,7 @@
 
 struct dbox_storage {
 	struct index_storage storage;
+	struct mailbox_list_vfuncs list_super;
 
 	struct dotlock_settings uidlist_dotlock_set;
 	struct dotlock_settings file_dotlock_set;

Index: dbox-sync-expunge.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-sync-expunge.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- dbox-sync-expunge.c	28 Dec 2006 16:51:12 -0000	1.22
+++ dbox-sync-expunge.c	29 Mar 2007 07:59:18 -0000	1.23
@@ -116,8 +116,7 @@
 	file_seq = dbox_uidlist_get_new_file_seq(mbox->uidlist);
 
 	for (;; file_seq++) {
-		path = t_strdup_printf("%s/"DBOX_MAILDIR_NAME"/"
-				       DBOX_MAIL_FILE_FORMAT,
+		path = t_strdup_printf("%s/"DBOX_MAIL_FILE_FORMAT,
 				       mbox->path, file_seq);
 		fd = file_dotlock_open(&mbox->storage->new_file_dotlock_set,
 				       path, DOTLOCK_CREATE_FLAG_NONBLOCK,
@@ -352,8 +351,7 @@
 
 	if (!skipped_expunges) {
 		/* all mails expunged from file, unlink it. */
-		path = t_strdup_printf("%s/"DBOX_MAILDIR_NAME"/"
-				       DBOX_MAIL_FILE_FORMAT,
+		path = t_strdup_printf("%s/"DBOX_MAIL_FILE_FORMAT,
 				       mbox->path, entry->file_seq);
 		if (unlink(path) < 0) {
 			mail_storage_set_critical(STORAGE(mbox->storage),
@@ -469,8 +467,7 @@
 	if (ctx->dotlock_failed_file_seq != sync_entry->file_seq) {
 		/* we need to have the file locked in case another process is
 		   appending there already. */
-		path = t_strdup_printf("%s/"DBOX_MAILDIR_NAME"/"
-				       DBOX_MAIL_FILE_FORMAT,
+		path = t_strdup_printf("%s/"DBOX_MAIL_FILE_FORMAT,
 				       mbox->path, sync_entry->file_seq);
 		ret = file_dotlock_create(&mbox->storage->new_file_dotlock_set,
 					  path, DOTLOCK_CREATE_FLAG_NONBLOCK,

Index: dbox-sync-full.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-sync-full.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- dbox-sync-full.c	10 Sep 2006 12:48:26 -0000	1.10
+++ dbox-sync-full.c	29 Mar 2007 07:59:18 -0000	1.11
@@ -193,7 +193,6 @@
 	struct dbox_mailbox *mbox = ctx->mbox;
 	const struct mail_index_header *hdr;
 	unsigned int file_prefix_len = strlen(DBOX_MAIL_FILE_PREFIX);
-	const char *path;
 	uint32_t file_seq;
 	DIR *dirp;
 	struct dirent *dp;
@@ -201,11 +200,10 @@
 
 	/* go through msg.* files, sync them to index and based on it
 	   write dbox's index file */
-	path = t_strconcat(mbox->path, "/"DBOX_MAILDIR_NAME, NULL);
-	dirp = opendir(path);
+	dirp = opendir(mbox->path);
 	if (dirp == NULL) {
 		mail_storage_set_critical(STORAGE(mbox->storage),
-					  "opendir(%s) failed: %m", path);
+					  "opendir(%s) failed: %m", mbox->path);
 		return -1;
 	}
 
@@ -231,7 +229,7 @@
 	}
 	if (closedir(dirp) < 0) {
 		mail_storage_set_critical(STORAGE(mbox->storage),
-					  "closedir(%s) failed: %m", path);
+			"closedir(%s) failed: %m", mbox->path);
 		ret = -1;
 	}
 

Index: dbox-uidlist.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/dbox/dbox-uidlist.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- dbox-uidlist.c	15 Mar 2007 17:02:16 -0000	1.46
+++ dbox-uidlist.c	29 Mar 2007 07:59:18 -0000	1.47
@@ -93,9 +93,7 @@
 	uidlist->lock_fd = -1;
 	uidlist->entry_pool =
 		pool_alloconly_create("uidlist entry pool", 1024*32);
-	uidlist->path =
-		i_strconcat(mbox->path, "/"DBOX_MAILDIR_NAME"/"
-			    DBOX_UIDLIST_FILENAME, NULL);
+	uidlist->path = i_strconcat(mbox->path, "/"DBOX_UIDLIST_FILENAME, NULL);
 	i_array_init(&uidlist->entries, 64);
 	return uidlist;
 }
@@ -1054,8 +1052,8 @@
 
 		/* try locking the file. */
 		str_truncate(path, 0);
-		str_printfa(path, "%s/"DBOX_MAILDIR_NAME"/"
-			    DBOX_MAIL_FILE_FORMAT, mbox->path, file_seq);
+		str_printfa(path, "%s/"DBOX_MAIL_FILE_FORMAT,
+			    mbox->path, file_seq);
 		ret = file_dotlock_create(&mbox->storage->file_dotlock_set,
 					  str_c(path),
 					  DOTLOCK_CREATE_FLAG_NONBLOCK,



More information about the dovecot-cvs mailing list