[dovecot-cvs] dovecot/src/lib-storage/list index-mailbox-list-sync.c, 1.5, 1.6 mailbox-list-fs-iter.c, 1.2, 1.3 mailbox-list-fs.c, 1.4, 1.5 mailbox-list-maildir-iter.c, 1.2, 1.3 mailbox-list-maildir.c, 1.5, 1.6
tss at dovecot.org
tss at dovecot.org
Thu Mar 29 10:59:34 EEST 2007
Update of /var/lib/cvs/dovecot/src/lib-storage/list
In directory talvi:/tmp/cvs-serv11000/lib-storage/list
Modified Files:
index-mailbox-list-sync.c mailbox-list-fs-iter.c
mailbox-list-fs.c mailbox-list-maildir-iter.c
mailbox-list-maildir.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: index-mailbox-list-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/list/index-mailbox-list-sync.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- index-mailbox-list-sync.c 15 Mar 2007 13:34:50 -0000 1.5
+++ index-mailbox-list-sync.c 29 Mar 2007 07:59:24 -0000 1.6
@@ -470,7 +470,7 @@
index_list_next_hook_mailbox_created(box);
/* FIXME: maildir-only for now */
- if (strcmp(box->storage->name, "maildir") != 0)
+ if (strcmp(box->storage->list->name, "maildir++") != 0)
return;
ibox = p_new(box->pool, struct index_list_mailbox, 1);
Index: mailbox-list-fs-iter.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/list/mailbox-list-fs-iter.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mailbox-list-fs-iter.c 25 Nov 2006 22:17:50 -0000 1.2
+++ mailbox-list-fs-iter.c 29 Mar 2007 07:59:24 -0000 1.3
@@ -22,7 +22,8 @@
struct imap_match_glob *glob;
struct subsfile_list_context *subsfile_ctx;
- bool inbox_found;
+ bool inbox_found, inbox_listed;
+ enum mailbox_info_flags inbox_flags;
struct mailbox_info *(*next)(struct fs_list_iterate_context *ctx);
@@ -121,7 +122,7 @@
virtual_path = mask_get_dir(mask);
path = mailbox_list_get_path(_list, virtual_path,
- MAILBOX_LIST_PATH_TYPE_MAILBOX);
+ MAILBOX_LIST_PATH_TYPE_DIR);
if (list_opendir(_list, path, TRUE, &dirp) < 0)
return &ctx->ctx;
/* if user gave invalid directory, we just don't show any results. */
@@ -189,6 +190,41 @@
return ctx->next(ctx);
}
+static void
+path_split(const char *path, const char **dir_r, const char **fname_r)
+{
+ const char *p;
+
+ p = strrchr(path, '/');
+ if (p == NULL) {
+ *dir_r = "";
+ *fname_r = path;
+ } else {
+ *dir_r = t_strdup_until(path, p);
+ *fname_r = p + 1;
+ }
+}
+
+static struct mailbox_info *fs_list_inbox(struct fs_list_iterate_context *ctx)
+{
+ const char *inbox_path, *dir, *fname;
+
+ ctx->info.flags = 0;
+ ctx->info.name = "INBOX";
+
+ t_push();
+ inbox_path = mailbox_list_get_path(ctx->ctx.list, "INBOX",
+ MAILBOX_LIST_PATH_TYPE_DIR);
+ path_split(inbox_path, &dir, &fname);
+ if (ctx->ctx.list->v.iter_is_mailbox(&ctx->ctx, dir, fname,
+ MAILBOX_LIST_FILE_TYPE_UNKNOWN,
+ &ctx->info.flags) < 0)
+ ctx->ctx.failed = TRUE;
+ t_pop();
+
+ return &ctx->info;
+}
+
static int
list_file(struct fs_list_iterate_context *ctx, const struct dirent *d)
{
@@ -218,23 +254,50 @@
/* get the info.flags using callback */
ctx->info.flags = 0;
- ret = ctx->ctx.list->callback(ctx->dir->real_path, fname,
- mailbox_list_get_file_type(d),
- ctx->ctx.flags, &ctx->info.flags,
- ctx->ctx.list->context);
+ ret = ctx->ctx.list->v.
+ iter_is_mailbox(&ctx->ctx, ctx->dir->real_path, fname,
+ mailbox_list_get_file_type(d),
+ &ctx->info.flags);
if (ret <= 0)
return ret;
/* make sure we give only one correct INBOX */
real_path = t_strconcat(ctx->dir->real_path, "/", fname, NULL);
- if (strcasecmp(list_path, "INBOX") == 0 &&
- (ctx->ctx.list->flags & MAILBOX_LIST_FLAG_INBOX) != 0) {
+ if ((ctx->ctx.list->flags & MAILBOX_LIST_FLAG_INBOX) != 0 &&
+ strcasecmp(list_path, "INBOX") == 0) {
+ if (ctx->inbox_listed) {
+ /* already listed the INBOX */
+ return 0;
+ }
+
inbox_path = mailbox_list_get_path(ctx->ctx.list, "INBOX",
- MAILBOX_LIST_PATH_TYPE_MAILBOX);
- if (ctx->inbox_found || strcmp(real_path, inbox_path) != 0)
+ MAILBOX_LIST_PATH_TYPE_DIR);
+ if (strcmp(real_path, inbox_path) == 0) {
+ /* delay listing in case there's a INBOX/ directory */
+ ctx->inbox_found = TRUE;
+ ctx->inbox_flags = ctx->info.flags;
+ return 0;
+ }
+ if (strcmp(fname, "INBOX") != 0 ||
+ (ctx->info.flags & MAILBOX_NOINFERIORS) != 0) {
+ /* duplicate INBOX, can't show this */
return 0;
+ }
- ctx->inbox_found = TRUE;
+ /* INBOX/ directory. show the INBOX list now */
+ if (!ctx->inbox_found) {
+ enum mailbox_info_flags dir_flags = ctx->info.flags;
+
+ (void)fs_list_inbox(ctx);
+ ctx->info.flags &= ~(MAILBOX_NOINFERIORS |
+ MAILBOX_NOCHILDREN);
+ ctx->info.flags |= dir_flags;
+ ctx->inbox_found = TRUE;
+ } else {
+ ctx->info.flags &= ~MAILBOX_NOSELECT;
+ ctx->info.flags |= ctx->inbox_flags;
+ }
+ ctx->inbox_listed = TRUE;
}
if ((ctx->info.flags & MAILBOX_NOINFERIORS) == 0) {
@@ -270,21 +333,6 @@
return 0;
}
-static void
-path_split(const char *path, const char **dir_r, const char **fname_r)
-{
- const char *p;
-
- p = strrchr(path, '/');
- if (p == NULL) {
- *dir_r = "";
- *fname_r = path;
- } else {
- *dir_r = t_strdup_until(path, p);
- *fname_r = p + 1;
- }
-}
-
static struct mailbox_info *fs_list_subs(struct fs_list_iterate_context *ctx)
{
const char *name, *path, *p, *dir, *fname;
@@ -321,12 +369,11 @@
t_push();
path = mailbox_list_get_path(ctx->ctx.list, ctx->info.name,
- MAILBOX_LIST_PATH_TYPE_MAILBOX);
+ MAILBOX_LIST_PATH_TYPE_DIR);
path_split(path, &dir, &fname);
- if (ctx->ctx.list->callback(dir, fname,
- MAILBOX_LIST_FILE_TYPE_UNKNOWN,
- ctx->ctx.flags, &ctx->info.flags,
- ctx->ctx.list->context) < 0)
+ if (ctx->ctx.list->v.iter_is_mailbox(&ctx->ctx, dir, fname,
+ MAILBOX_LIST_FILE_TYPE_UNKNOWN,
+ &ctx->info.flags) < 0)
ctx->ctx.failed = TRUE;
t_pop();
return &ctx->info;
@@ -346,27 +393,6 @@
return ctx->next(ctx);
}
-static struct mailbox_info *fs_list_inbox(struct fs_list_iterate_context *ctx)
-{
- const char *inbox_path, *dir, *fname;
-
- ctx->info.flags = 0;
- ctx->info.name = "INBOX";
-
- t_push();
- inbox_path = mailbox_list_get_path(ctx->ctx.list, "INBOX",
- MAILBOX_LIST_PATH_TYPE_MAILBOX);
- path_split(inbox_path, &dir, &fname);
- if (ctx->ctx.list->callback(dir, fname,
- MAILBOX_LIST_FILE_TYPE_UNKNOWN,
- ctx->ctx.flags, &ctx->info.flags,
- ctx->ctx.list->context) < 0)
- ctx->ctx.failed = TRUE;
- t_pop();
-
- return &ctx->info;
-}
-
static struct mailbox_info *fs_list_next(struct fs_list_iterate_context *ctx)
{
struct list_dir_context *dir;
@@ -399,9 +425,16 @@
(ctx->ctx.list->flags & MAILBOX_LIST_FLAG_INBOX) != 0 &&
ctx->glob != NULL && imap_match(ctx->glob, "INBOX") > 0) {
/* show inbox */
+ ctx->inbox_listed = TRUE;
ctx->inbox_found = TRUE;
return fs_list_inbox(ctx);
}
+ if (!ctx->inbox_listed && ctx->inbox_found) {
+ ctx->inbox_listed = TRUE;
+ ctx->info.flags = ctx->inbox_flags;
+ ctx->info.name = "INBOX";
+ return &ctx->info;
+ }
/* finished */
return NULL;
Index: mailbox-list-fs.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/list/mailbox-list-fs.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- mailbox-list-fs.c 1 Mar 2007 12:30:13 -0000 1.4
+++ mailbox-list-fs.c 29 Mar 2007 07:59:24 -0000 1.5
@@ -1,13 +1,18 @@
-/* Copyright (C) 2006 Timo Sirainen */
+/* Copyright (C) 2006-2007 Timo Sirainen */
#include "lib.h"
#include "hostpid.h"
#include "home-expand.h"
+#include "mkdir-parents.h"
#include "subscription-file.h"
#include "mailbox-list-fs.h"
+#include <stdio.h>
+#include <unistd.h>
#include <sys/stat.h>
+#define CREATE_MODE 0770 /* umask() should limit it more */
+
extern struct mailbox_list fs_mailbox_list;
static struct mailbox_list *fs_list_alloc(void)
@@ -28,8 +33,7 @@
static void fs_list_deinit(struct mailbox_list *_list)
{
- struct fs_mailbox_list *list =
- (struct fs_mailbox_list *)_list;
+ struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
pool_unref(list->list.pool);
}
@@ -136,8 +140,7 @@
fs_list_get_path(struct mailbox_list *_list, const char *name,
enum mailbox_list_path_type type)
{
- struct fs_mailbox_list *list =
- (struct fs_mailbox_list *)_list;
+ struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
const struct mailbox_list_settings *set = &_list->set;
mailbox_list_clear_error(&list->list);
@@ -158,7 +161,7 @@
i_unreached();
}
- i_assert(mailbox_list_is_valid_existing_name(_list, name));
+ i_assert(mailbox_list_is_valid_mask(_list, name));
if ((list->list.flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0 &&
(*name == '/' || *name == '~')) {
@@ -188,10 +191,8 @@
break;
}
- if (strcmp(name, "INBOX") == 0) {
- return set->inbox_path != NULL ?
- set->inbox_path : set->root_dir;
- }
+ if (strcmp(name, "INBOX") == 0 && set->inbox_path != NULL)
+ return set->inbox_path;
if (*set->maildir_name == '\0')
return t_strdup_printf("%s/%s", set->root_dir, name);
@@ -205,8 +206,7 @@
fs_list_get_mailbox_name_status(struct mailbox_list *_list, const char *name,
enum mailbox_name_status *status)
{
- struct fs_mailbox_list *list =
- (struct fs_mailbox_list *)_list;
+ struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
struct stat st;
const char *path;
@@ -245,8 +245,7 @@
static const char *
fs_list_get_temp_prefix(struct mailbox_list *_list)
{
- struct fs_mailbox_list *list =
- (struct fs_mailbox_list *)_list;
+ struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
return list->temp_prefix;
}
@@ -267,8 +266,7 @@
static int fs_list_set_subscribed(struct mailbox_list *_list,
const char *name, bool set)
{
- struct fs_mailbox_list *list =
- (struct fs_mailbox_list *)_list;
+ struct fs_mailbox_list *list = (struct fs_mailbox_list *)_list;
const char *path;
mailbox_list_clear_error(&list->list);
@@ -280,6 +278,103 @@
name, set);
}
+static int fs_list_delete_mailbox(struct mailbox_list *list, const char *name)
+{
+ /* let the backend handle the rest */
+ return mailbox_list_delete_index_control(list, name);
+}
+
+static bool fs_handle_errors(struct mailbox_list *list)
+{
+ if (ENOACCESS(errno))
+ mailbox_list_set_error(list, MAILBOX_LIST_ERR_NO_PERMISSION);
+ else if (ENOSPACE(errno))
+ mailbox_list_set_error(list, "Not enough disk space");
+ else if (ENOTFOUND(errno))
+ mailbox_list_set_error(list, "Directory structure is broken");
+ else
+ return FALSE;
+ return TRUE;
+}
+
+static int fs_list_rename_mailbox(struct mailbox_list *list,
+ const char *oldname, const char *newname)
+{
+ const char *oldpath, *newpath, *old_indexdir, *new_indexdir, *p;
+ struct stat st;
+
+ if (!mailbox_list_is_valid_existing_name(list, oldname) ||
+ !mailbox_list_is_valid_create_name(list, newname)) {
+ mailbox_list_set_error(list, "Invalid mailbox name");
+ return -1;
+ }
+
+ oldpath = mailbox_list_get_path(list, oldname,
+ MAILBOX_LIST_PATH_TYPE_MAILBOX);
+ newpath = mailbox_list_get_path(list, newname,
+ MAILBOX_LIST_PATH_TYPE_MAILBOX);
+
+ /* create the hierarchy */
+ p = strrchr(newpath, '/');
+ if (p != NULL) {
+ p = t_strdup_until(newpath, p);
+ if (mkdir_parents(p, CREATE_MODE) < 0) {
+ if (fs_handle_errors(list))
+ return -1;
+
+ mailbox_list_set_critical(list,
+ "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) {
+ mailbox_list_set_error(list, "Target mailbox already exists");
+ return -1;
+ } else if (errno == ENOTDIR) {
+ mailbox_list_set_error(list,
+ "Target mailbox doesn't allow inferior mailboxes");
+ return -1;
+ } else if (errno != ENOENT && errno != EACCES) {
+ mailbox_list_set_critical(list, "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)) {
+ mailbox_list_set_error(list, t_strdup_printf(
+ MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname));
+ } else if (!fs_handle_errors(list)) {
+ mailbox_list_set_critical(list,
+ "rename(%s, %s) failed: %m", oldpath, newpath);
+ }
+ return -1;
+ }
+
+ /* we need to rename the index directory as well */
+ old_indexdir = mailbox_list_get_path(list, oldname,
+ MAILBOX_LIST_PATH_TYPE_INDEX);
+ new_indexdir = mailbox_list_get_path(list, newname,
+ MAILBOX_LIST_PATH_TYPE_INDEX);
+ if (*old_indexdir != '\0') {
+ if (rename(old_indexdir, new_indexdir) < 0 &&
+ errno != ENOENT) {
+ mailbox_list_set_critical(list,
+ "rename(%s, %s) failed: %m",
+ old_indexdir, new_indexdir);
+ }
+ }
+
+ return 0;
+}
+
struct mailbox_list fs_mailbox_list = {
MEMBER(name) "fs",
MEMBER(hierarchy_sep) '/',
@@ -298,6 +393,9 @@
fs_list_iter_init,
fs_list_iter_next,
fs_list_iter_deinit,
- fs_list_set_subscribed
+ NULL,
+ fs_list_set_subscribed,
+ fs_list_delete_mailbox,
+ fs_list_rename_mailbox
}
};
Index: mailbox-list-maildir-iter.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/list/mailbox-list-maildir-iter.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- mailbox-list-maildir-iter.c 25 Nov 2006 22:17:50 -0000 1.2
+++ mailbox-list-maildir-iter.c 29 Mar 2007 07:59:24 -0000 1.3
@@ -98,10 +98,9 @@
/* check if this is an actual mailbox */
flags = 0;
- ret = ctx->ctx.list->callback(ctx->dir, fname,
- mailbox_list_get_file_type(d),
- ctx->ctx.flags, &flags,
- ctx->ctx.list->context);
+ ret = ctx->ctx.list->v.
+ iter_is_mailbox(&ctx->ctx, ctx->dir, fname,
+ mailbox_list_get_file_type(d), &flags);
if (ret < 0) {
t_pop();
return -1;
@@ -149,6 +148,11 @@
node->flags |= MAILBOX_FLAG_MATCHED;
}
}
+ if (node != NULL) {
+ node->flags |= flags & ~(MAILBOX_NOINFERIORS |
+ MAILBOX_CHILDREN |
+ MAILBOX_NOCHILDREN);
+ }
}
t_pop();
Index: mailbox-list-maildir.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/list/mailbox-list-maildir.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- mailbox-list-maildir.c 18 Jan 2007 14:34:45 -0000 1.5
+++ mailbox-list-maildir.c 29 Mar 2007 07:59:25 -0000 1.6
@@ -1,11 +1,13 @@
-/* Copyright (C) 2006 Timo Sirainen */
+/* Copyright (C) 2006-2007 Timo Sirainen */
#include "lib.h"
+#include "array.h"
#include "hostpid.h"
#include "home-expand.h"
#include "subscription-file.h"
#include "mailbox-list-maildir.h"
+#include <stdio.h>
#include <sys/stat.h>
extern struct mailbox_list maildir_mailbox_list;
@@ -270,6 +272,164 @@
name, set);
}
+static int rename_dir(struct mailbox_list *list,
+ enum mailbox_list_path_type type,
+ const char *oldname, const char *newname)
+{
+ const char *oldpath, *newpath;
+
+ oldpath = mailbox_list_get_path(list, oldname, type);
+ newpath = mailbox_list_get_path(list, newname, type);
+
+ if (strcmp(oldpath, newpath) == 0)
+ return 0;
+
+ if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
+ mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
+ oldpath, newpath);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int rename_children(struct mailbox_list *list,
+ const char *oldname, const char *newname)
+{
+ struct mailbox_list_iterate_context *iter;
+ struct mailbox_info *info;
+ ARRAY_DEFINE(names_arr, const char *);
+ const char *mask, *oldpath, *newpath, *old_listname, *new_listname;
+ const char *const *names;
+ unsigned int i, count;
+ size_t oldnamelen;
+ pool_t pool;
+ int ret;
+
+ ret = 0;
+ oldnamelen = strlen(oldname);
+
+ /* first get the list of the children and save them to memory, because
+ we can't rely on readdir() not skipping files while the directory
+ is being modified. this doesn't protect against modifications by
+ other processes though. */
+ pool = pool_alloconly_create("Maildir++ children list", 1024);
+ i_array_init(&names_arr, 64);
+
+ mask = t_strdup_printf("%s%c*", oldname,
+ mailbox_list_get_hierarchy_sep(list));
+ iter = mailbox_list_iter_init(list, mask, MAILBOX_LIST_ITER_FAST_FLAGS);
+ while ((info = mailbox_list_iter_next(iter)) != NULL) {
+ const char *name;
+
+ i_assert(oldnamelen <= strlen(info->name));
+
+ name = p_strdup(pool, info->name + oldnamelen);
+ array_append(&names_arr, &name, 1);
+ }
+ if (mailbox_list_iter_deinit(&iter) < 0) {
+ ret = -1;
+ names = NULL; count = 0;
+ } else {
+ names = array_get(&names_arr, &count);
+ }
+
+ for (i = 0; i < count; i++) {
+ t_push();
+
+ old_listname = t_strconcat(oldname, names[i], NULL);
+ new_listname = t_strconcat(newname, names[i], NULL);
+ oldpath = mailbox_list_get_path(list, old_listname,
+ MAILBOX_LIST_PATH_TYPE_MAILBOX);
+ newpath = mailbox_list_get_path(list, new_listname,
+ MAILBOX_LIST_PATH_TYPE_MAILBOX);
+
+ /* FIXME: it's possible to merge two mailboxes if either one of
+ them doesn't have existing root mailbox. We could check this
+ but I'm not sure if it's worth it. It could be even
+ considered as a feature.
+
+ Anyway, the bug with merging is that if both mailboxes have
+ identically named child mailbox they conflict. Just ignore
+ those and leave them under the old mailbox. */
+ if (rename(oldpath, newpath) == 0 || EDESTDIREXISTS(errno))
+ ret = 1;
+ else {
+ mailbox_list_set_critical(list,
+ "rename(%s, %s) failed: %m", oldpath, newpath);
+ ret = -1;
+ t_pop();
+ break;
+ }
+
+ (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_CONTROL,
+ old_listname, new_listname);
+ (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_INDEX,
+ old_listname, new_listname);
+ t_pop();
+ }
+ array_free(&names_arr);
+ pool_unref(pool);
+
+ return ret;
+}
+
+static int
+maildir_list_delete_mailbox(struct mailbox_list *list, const char *name)
+{
+ /* let the backend handle the rest */
+ return mailbox_list_delete_index_control(list, name);
+}
+
+static int maildir_list_rename_mailbox(struct mailbox_list *list,
+ const char *oldname, const char *newname)
+{
+ const char *oldpath, *newpath;
+ int ret;
+ bool found;
+
+ if (!mailbox_list_is_valid_existing_name(list, oldname) ||
+ !mailbox_list_is_valid_create_name(list, newname)) {
+ mailbox_list_set_error(list, "Invalid mailbox name");
+ return -1;
+ }
+
+ /* NOTE: it's possible to rename a nonexisting mailbox which has
+ children. In that case we should ignore the rename() error. */
+ oldpath = mailbox_list_get_path(list, oldname,
+ MAILBOX_LIST_PATH_TYPE_MAILBOX);
+ newpath = mailbox_list_get_path(list, newname,
+ MAILBOX_LIST_PATH_TYPE_MAILBOX);
+
+ ret = rename(oldpath, newpath);
+ if (ret == 0 || errno == ENOENT) {
+ (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_CONTROL,
+ oldname, newname);
+ (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_INDEX,
+ oldname, newname);
+
+ found = ret == 0;
+ ret = rename_children(list, oldname, newname);
+ if (ret < 0)
+ return -1;
+ if (!found && ret == 0) {
+ mailbox_list_set_error(list, t_strdup_printf(
+ MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname));
+ return -1;
+ }
+
+ return 0;
+ }
+
+ if (EDESTDIREXISTS(errno)) {
+ mailbox_list_set_error(list, "Target mailbox already exists");
+ } else {
+ mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
+ oldpath, newpath);
+ }
+ return -1;
+}
+
struct mailbox_list maildir_mailbox_list = {
MEMBER(name) "maildir++",
MEMBER(hierarchy_sep) '.',
@@ -288,6 +448,9 @@
maildir_list_iter_init,
maildir_list_iter_next,
maildir_list_iter_deinit,
- maildir_list_set_subscribed
+ NULL,
+ maildir_list_set_subscribed,
+ maildir_list_delete_mailbox,
+ maildir_list_rename_mailbox
}
};
More information about the dovecot-cvs
mailing list