mailbox-list-maildir.c revision 89a126810703c666309310d0f3189e9834d70b5b
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "lib.h"
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include "array.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "hostpid.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "home-expand.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "subscription-file.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "mailbox-list-maildir.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include <stdio.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include <sys/stat.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenextern struct mailbox_list maildir_mailbox_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenextern struct mailbox_list imapdir_mailbox_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic struct mailbox_list *maildir_list_alloc(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pool_t pool;
b5a084602a3dc2c118345f6d2990f47c1ff66264Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pool = pool_alloconly_create("maildir++ list", 1024);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list = p_new(pool, struct maildir_mailbox_list, 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list->list = maildir_mailbox_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list->list.pool = pool;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list->temp_prefix =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen p_strconcat(pool, "temp.", my_hostname, ".", my_pid, ".", NULL);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return &list->list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic struct mailbox_list *imapdir_list_alloc(void)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pool_t pool;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pool = pool_alloconly_create("imapdir list", 1024);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list = p_new(pool, struct maildir_mailbox_list, 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list->list = imapdir_mailbox_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list->list.pool = pool;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen list->temp_prefix = p_strconcat(pool, ".temp.", my_hostname, ".",
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen my_pid, ".", NULL);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return &list->list;
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainen}
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainen
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainenstatic void maildir_list_deinit(struct mailbox_list *_list)
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (struct maildir_mailbox_list *)_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen pool_unref(&list->list.pool);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic const char *
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_list_get_dirname_path(struct mailbox_list *list, const char *dir,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *name)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (strcmp(list->name, MAILBOX_LIST_NAME_IMAPDIR) == 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return t_strdup_printf("%s/%s", dir, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return t_strdup_printf("%s/%c%s", dir, list->hierarchy_sep, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic const char *
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_list_get_absolute_path(struct mailbox_list *list, const char *name)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *p;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (home_try_expand(&name) < 0) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* fallback to using as ~name */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return name;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen p = strrchr(name, '/');
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (p == NULL)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return name;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return maildir_list_get_dirname_path(list, t_strdup_until(name, p),
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen p+1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic bool
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_list_is_valid_common(struct mailbox_list *list, const char *name,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size_t *len_r)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size_t len;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* check that there are no adjacent hierarchy separators */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen for (len = 0; name[len] != '\0'; len++) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (name[len] == list->hierarchy_sep &&
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen name[len+1] == list->hierarchy_sep)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
65b7beb7cefce89e175920ef6c16118b1b0dbfb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (len == 0 || name[len-1] == '/')
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (name[0] == list->hierarchy_sep ||
65b7beb7cefce89e175920ef6c16118b1b0dbfb3Timo Sirainen name[len-1] == list->hierarchy_sep)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
65b7beb7cefce89e175920ef6c16118b1b0dbfb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen *len_r = len;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return TRUE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic bool maildir_list_is_valid_common_nonfs(const char *name)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (*name == '~' || strchr(name, '/') != NULL)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (name[0] == '.' && (name[1] == '\0' ||
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (name[1] == '.' && name[2] == '\0'))) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* "." and ".." aren't allowed. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return TRUE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic bool ATTR_NORETURN
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_is_valid_pattern(struct mailbox_list *list ATTR_UNUSED,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *pattern ATTR_UNUSED)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_unreached();
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#ifndef ATTRS_DEFINED
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#endif
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic bool
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_is_valid_existing_name(struct mailbox_list *list, const char *name)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size_t len;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (!maildir_list_is_valid_common(list, name, &len))
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return TRUE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return maildir_list_is_valid_common_nonfs(name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic bool
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_is_valid_create_name(struct mailbox_list *list, const char *name)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size_t len;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (!maildir_list_is_valid_common(list, name, &len))
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (len > MAILDIR_MAX_CREATE_MAILBOX_NAME_LENGTH)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return TRUE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (!maildir_list_is_valid_common_nonfs(name))
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (mailbox_list_name_is_too_large(name, list->hierarchy_sep))
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return TRUE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic const char *
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_list_get_path(struct mailbox_list *_list, const char *name,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen enum mailbox_list_path_type type)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (struct maildir_mailbox_list *)_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (name == NULL) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* return root directories */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen switch (type) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_DIR:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_MAILBOX:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return _list->set.root_dir;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_CONTROL:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return _list->set.control_dir != NULL ?
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen _list->set.control_dir : _list->set.root_dir;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_INDEX:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return _list->set.index_dir != NULL ?
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen _list->set.index_dir : _list->set.root_dir;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_unreached();
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_assert(mailbox_list_is_valid_existing_name(_list, name));
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if ((list->list.flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0 &&
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (*name == '/' || *name == '~'))
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return maildir_list_get_absolute_path(_list, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen switch (type) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_DIR:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_MAILBOX:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_CONTROL:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (_list->set.control_dir != NULL) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return maildir_list_get_dirname_path(_list,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen _list->set.control_dir, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_INDEX:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (_list->set.index_dir != NULL) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (*_list->set.index_dir == '\0')
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return "";
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return maildir_list_get_dirname_path(_list,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen _list->set.index_dir, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (strcmp(name, "INBOX") == 0) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return _list->set.inbox_path != NULL ?
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen _list->set.inbox_path : _list->set.root_dir;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return maildir_list_get_dirname_path(_list, _list->set.root_dir, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenmaildir_list_get_mailbox_name_status(struct mailbox_list *_list,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *name,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen enum mailbox_name_status *status)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct stat st;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *path;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen path = mailbox_list_get_path(_list, name,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (strcmp(name, "INBOX") == 0 || stat(path, &st) == 0) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen *status = MAILBOX_NAME_EXISTS;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (!mailbox_list_is_valid_create_name(_list, name)) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen *status = MAILBOX_NAME_INVALID;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (ENOTFOUND(errno) || errno == EACCES) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen *status = MAILBOX_NAME_VALID;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen } else {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen mailbox_list_set_critical(_list, "stat(%s) failed: %m", path);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return -1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic const char *
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenmaildir_list_get_temp_prefix(struct mailbox_list *_list)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen struct maildir_mailbox_list *list =
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen (struct maildir_mailbox_list *)_list;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return list->temp_prefix;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic int maildir_list_set_subscribed(struct mailbox_list *_list,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *name, bool set)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen struct maildir_mailbox_list *list =
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen (struct maildir_mailbox_list *)_list;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *path;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen path = t_strconcat(_list->set.control_dir != NULL ?
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen _list->set.control_dir : _list->set.root_dir,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen "/", _list->set.subscription_fname, NULL);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return subsfile_set_subscribed(_list, path, list->temp_prefix,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen name, set);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic int rename_dir(struct mailbox_list *list,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen enum mailbox_list_path_type type,
61e84692827b6a64912343f515c984853021483aTimo Sirainen const char *oldname, const char *newname)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *oldpath, *newpath;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath = mailbox_list_get_path(list, oldname, type);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen newpath = mailbox_list_get_path(list, newname, type);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (strcmp(oldpath, newpath) == 0)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic int rename_children(struct mailbox_list *list,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *oldname, const char *newname)
18ffea71d9beeec3cc1d400f751926ee72807f62Timo Sirainen{
18ffea71d9beeec3cc1d400f751926ee72807f62Timo Sirainen struct mailbox_list_iterate_context *iter;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const struct mailbox_info *info;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ARRAY_DEFINE(names_arr, const char *);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *pattern, *oldpath, *newpath, *old_listname, *new_listname;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *const *names;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen unsigned int i, count;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen size_t oldnamelen;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen pool_t pool;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen int ret;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldnamelen = strlen(oldname);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen /* first get the list of the children and save them to memory, because
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen we can't rely on readdir() not skipping files while the directory
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen is being modified. this doesn't protect against modifications by
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen other processes though. */
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen pool = pool_alloconly_create("Maildir++ children list", 1024);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen i_array_init(&names_arr, 64);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen pattern = t_strdup_printf("%s%c*", oldname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen mailbox_list_get_hierarchy_sep(list));
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen iter = mailbox_list_iter_init(list, pattern,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *name;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen i_assert(oldnamelen <= strlen(info->name));
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen name = p_strdup(pool, info->name + oldnamelen);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen array_append(&names_arr, &name, 1);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (mailbox_list_iter_deinit(&iter) < 0) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen names = NULL; count = 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen } else {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen names = array_get(&names_arr, &count);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen for (i = 0; i < count; i++) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen t_push();
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen old_listname = t_strconcat(oldname, names[i], NULL);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen new_listname = t_strconcat(newname, names[i], NULL);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath = mailbox_list_get_path(list, old_listname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen newpath = mailbox_list_get_path(list, new_listname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen /* FIXME: it's possible to merge two mailboxes if either one of
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen them doesn't have existing root mailbox. We could check this
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen but I'm not sure if it's worth it. It could be even
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen considered as a feature.
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen Anyway, the bug with merging is that if both mailboxes have
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen identically named child mailbox they conflict. Just ignore
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen those and leave them under the old mailbox. */
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (rename(oldpath, newpath) == 0 || EDESTDIREXISTS(errno))
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = 1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen else {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen mailbox_list_set_critical(list,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen "rename(%s, %s) failed: %m", oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen t_pop();
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen break;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_CONTROL,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen old_listname, new_listname);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_INDEX,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen old_listname, new_listname);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen t_pop();
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen array_free(&names_arr);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen pool_unref(&pool);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return ret;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic int
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenmaildir_list_delete_mailbox(struct mailbox_list *list, const char *name)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen /* let the backend handle the rest */
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return mailbox_list_delete_index_control(list, name);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic int maildir_list_rename_mailbox(struct mailbox_list *list,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *oldname, const char *newname)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen const char *oldpath, *newpath;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen int ret;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen bool found;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen /* NOTE: it's possible to rename a nonexisting mailbox which has
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen children. In that case we should ignore the rename() error. */
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath = mailbox_list_get_path(list, oldname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen newpath = mailbox_list_get_path(list, newname,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = rename(oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (ret == 0 || errno == ENOENT) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_CONTROL,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldname, newname);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_INDEX,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldname, newname);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen found = ret == 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ret = rename_children(list, oldname, newname);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (ret < 0)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return -1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (!found && ret == 0) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname));
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return -1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return 0;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (EDESTDIREXISTS(errno)) {
5160580b0ec3f3288a320987abdf12a990f09df5Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen "Target mailbox already exists");
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen } else {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstruct mailbox_list maildir_mailbox_list = {
MEMBER(name) MAILBOX_LIST_NAME_MAILDIRPLUSPLUS,
MEMBER(hierarchy_sep) '.',
MEMBER(mailbox_name_max_length) PATH_MAX,
{
maildir_list_alloc,
maildir_list_deinit,
maildir_is_valid_pattern,
maildir_is_valid_existing_name,
maildir_is_valid_create_name,
maildir_list_get_path,
maildir_list_get_mailbox_name_status,
maildir_list_get_temp_prefix,
NULL,
maildir_list_iter_init,
maildir_list_iter_next,
maildir_list_iter_deinit,
NULL,
maildir_list_set_subscribed,
maildir_list_delete_mailbox,
maildir_list_rename_mailbox
}
};
struct mailbox_list imapdir_mailbox_list = {
MEMBER(name) MAILBOX_LIST_NAME_IMAPDIR,
MEMBER(hierarchy_sep) '.',
MEMBER(mailbox_name_max_length) PATH_MAX,
{
imapdir_list_alloc,
maildir_list_deinit,
maildir_is_valid_pattern,
maildir_is_valid_existing_name,
maildir_is_valid_create_name,
maildir_list_get_path,
maildir_list_get_mailbox_name_status,
maildir_list_get_temp_prefix,
NULL,
maildir_list_iter_init,
maildir_list_iter_next,
maildir_list_iter_deinit,
NULL,
maildir_list_set_subscribed,
maildir_list_delete_mailbox,
maildir_list_rename_mailbox
}
};