mailbox-list-maildir.c revision 2fb976923a6d6e45a7c2da90484944b2fac50c06
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2006-2009 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 "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
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen#define MAILDIR_GLOBAL_TEMP_PREFIX "temp."
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen#define IMAPDIR_GLOBAL_TEMP_PREFIX ".temp."
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenextern struct mailbox_list maildir_mailbox_list;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo 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;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
b5a084602a3dc2c118345f6d2990f47c1ff66264Timo 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
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen list->global_temp_prefix = MAILDIR_GLOBAL_TEMP_PREFIX;
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen list->temp_prefix = p_strconcat(pool, list->global_temp_prefix,
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen my_hostname, ".", my_pid, ".", NULL);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return &list->list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainenstatic struct mailbox_list *imapdir_list_alloc(void)
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen{
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen struct maildir_mailbox_list *list;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen pool_t pool;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen pool = pool_alloconly_create("imapdir list", 1024);
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen list = p_new(pool, struct maildir_mailbox_list, 1);
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen list->list = imapdir_mailbox_list;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen list->list.pool = pool;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen list->global_temp_prefix = IMAPDIR_GLOBAL_TEMP_PREFIX;
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen list->temp_prefix = p_strconcat(pool, list->global_temp_prefix,
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen my_hostname, ".", my_pid, ".", NULL);
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen return &list->list;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen}
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic void maildir_list_deinit(struct mailbox_list *_list)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (struct maildir_mailbox_list *)_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen pool_unref(&list->list.pool);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainenstatic const char *
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainenmaildir_list_get_dirname_path(struct mailbox_list *list, const char *dir,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen const char *name)
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen{
1c885b304f060e3ac4fe04195a2f53457d0ac99eTimo Sirainen if (strcmp(list->name, MAILBOX_LIST_NAME_IMAPDIR) == 0 || *name == '\0')
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen return t_strdup_printf("%s/%s", dir, name);
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen return t_strdup_printf("%s/%c%s", dir, list->hierarchy_sep, name);
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen}
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo 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
96f2533c48ce5def0004931606a2fdf275578880Timo Sirainen if (!mailbox_list_try_get_absolute_path(list, &name)) {
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainen /* fallback to using as ~name */
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainen return name;
83c21c990eb2a370f0da56240e73dac846f4acc3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen p = strrchr(name, '/');
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (p == NULL)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return name;
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen return maildir_list_get_dirname_path(list, t_strdup_until(name, p),
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo 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 }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (len == 0 || name[len-1] == '/')
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (name[0] == list->hierarchy_sep ||
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen name[len-1] == list->hierarchy_sep)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo 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
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainenstatic bool ATTR_NORETURN
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainenmaildir_is_valid_pattern(struct mailbox_list *list ATTR_UNUSED,
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen const char *pattern ATTR_UNUSED)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_unreached();
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen#ifndef ATTRS_DEFINED
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return FALSE;
65b7beb7cefce89e175920ef6c16118b1b0dbfb3Timo 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
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (list->mail_set->mail_full_filesystem_access)
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
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (list->mail_set->mail_full_filesystem_access)
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 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
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (_list->mail_set->mail_full_filesystem_access &&
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) {
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen return maildir_list_get_dirname_path(_list,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo 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 "";
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen return maildir_list_get_dirname_path(_list,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen _list->set.index_dir, name);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
1d266a7419fafa25f3505a12217452a8c647074fTimo Sirainen if (strcmp(name, "INBOX") == 0 && _list->set.inbox_path != NULL)
1d266a7419fafa25f3505a12217452a8c647074fTimo Sirainen return _list->set.inbox_path;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo 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
1d266a7419fafa25f3505a12217452a8c647074fTimo Sirainen if ((strcmp(name, "INBOX") == 0 &&
1d266a7419fafa25f3505a12217452a8c647074fTimo Sirainen (_list->ns->flags & NAMESPACE_FLAG_INBOX) != 0) ||
1d266a7419fafa25f3505a12217452a8c647074fTimo Sirainen 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 *
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainenmaildir_list_get_temp_prefix(struct mailbox_list *_list, bool global)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (struct maildir_mailbox_list *)_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
c040ee67d0ac0fb7375bb543965bf67dcae6affaTimo Sirainen return global ? list->global_temp_prefix : list->temp_prefix;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstatic int maildir_list_set_subscribed(struct mailbox_list *_list,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *name, bool set)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct maildir_mailbox_list *list =
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen (struct maildir_mailbox_list *)_list;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen const char *path;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen path = t_strconcat(_list->set.control_dir != NULL ?
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen _list->set.control_dir : _list->set.root_dir,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen "/", _list->set.subscription_fname, NULL);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return subsfile_set_subscribed(_list, path, list->temp_prefix,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen name, set);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainenstatic int rename_dir(struct mailbox_list *oldlist, const char *oldname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen struct mailbox_list *newlist, const char *newname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen enum mailbox_list_path_type type)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *oldpath, *newpath;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen oldpath = mailbox_list_get_path(oldlist, oldname, type);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen newpath = mailbox_list_get_path(newlist, 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) {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m",
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainenstatic int
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainenmaildir_rename_children(struct mailbox_list *oldlist, const char *oldname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen struct mailbox_list *newlist, const char *newname)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen struct mailbox_list_iterate_context *iter;
61e84692827b6a64912343f515c984853021483aTimo Sirainen const struct mailbox_info *info;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ARRAY_DEFINE(names_arr, const char *);
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo 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;
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen char old_sep;
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
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen old_sep = mailbox_list_get_hierarchy_sep(oldlist);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen pattern = t_strdup_printf("%s%c*", oldname, old_sep);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen iter = mailbox_list_iter_init(oldlist, pattern,
2fb976923a6d6e45a7c2da90484944b2fac50c06Timo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS |
2fb976923a6d6e45a7c2da90484944b2fac50c06Timo Sirainen MAILBOX_LIST_ITER_RAW_LIST);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *name;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
33f002135617b5b34577433b30c32560bd4b5e3cTimo Sirainen /* verify that the prefix matches, otherwise we could have
33f002135617b5b34577433b30c32560bd4b5e3cTimo Sirainen problems with mailbox names containing '%' and '*' chars */
33f002135617b5b34577433b30c32560bd4b5e3cTimo Sirainen if (strncmp(info->name, oldname, oldnamelen) == 0 &&
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen info->name[oldnamelen] == old_sep) {
33f002135617b5b34577433b30c32560bd4b5e3cTimo Sirainen name = p_strdup(pool, info->name + oldnamelen);
33f002135617b5b34577433b30c32560bd4b5e3cTimo Sirainen array_append(&names_arr, &name, 1);
33f002135617b5b34577433b30c32560bd4b5e3cTimo Sirainen }
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 old_listname = t_strconcat(oldname, names[i], NULL);
738cb8e908b144d6dd6f6d7484a40ad67054aac5Timo Sirainen if (strcmp(old_listname, newname) == 0) {
738cb8e908b144d6dd6f6d7484a40ad67054aac5Timo Sirainen /* When doing RENAME "a" "a.b" we see "a.b" here.
738cb8e908b144d6dd6f6d7484a40ad67054aac5Timo Sirainen We don't want to rename it anymore to "a.b.b". */
738cb8e908b144d6dd6f6d7484a40ad67054aac5Timo Sirainen continue;
738cb8e908b144d6dd6f6d7484a40ad67054aac5Timo Sirainen }
738cb8e908b144d6dd6f6d7484a40ad67054aac5Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen new_listname = t_strconcat(newname, names[i], NULL);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen oldpath = mailbox_list_get_path(oldlist, old_listname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen newpath = mailbox_list_get_path(newlist, 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 {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen mailbox_list_set_critical(oldlist,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen "rename(%s, %s) failed: %m", oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen break;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen (void)rename_dir(oldlist, old_listname, newlist, new_listname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen MAILBOX_LIST_PATH_TYPE_CONTROL);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen (void)rename_dir(oldlist, old_listname, newlist, new_listname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen MAILBOX_LIST_PATH_TYPE_INDEX);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen array_free(&names_arr);
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo 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
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainenstatic int
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainenmaildir_list_rename_mailbox(struct mailbox_list *oldlist, const char *oldname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen struct mailbox_list *newlist, const char *newname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen bool rename_children)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen const char *oldpath, *newpath;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo 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. */
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen oldpath = mailbox_list_get_path(oldlist, oldname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen newpath = mailbox_list_get_path(newlist, newname,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen ret = rename(oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (ret == 0 || errno == ENOENT) {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen (void)rename_dir(oldlist, oldname, newlist, newname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen MAILBOX_LIST_PATH_TYPE_CONTROL);
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen (void)rename_dir(oldlist, oldname, newlist, newname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen MAILBOX_LIST_PATH_TYPE_INDEX);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen found = ret == 0;
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen if (!rename_children)
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen ret = 0;
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen else T_BEGIN {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen ret = maildir_rename_children(oldlist, oldname,
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen newlist, newname);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen } T_END;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (ret < 0)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (!found && ret == 0) {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTFOUND,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname));
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen if (EDESTDIREXISTS(errno)) {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_EXISTS,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen "Target mailbox already exists");
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen } else {
91b203fd2132510a47a4b34252c0ae0efd688a19Timo Sirainen mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m",
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen oldpath, newpath);
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen }
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen return -1;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstruct mailbox_list maildir_mailbox_list = {
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen MEMBER(name) MAILBOX_LIST_NAME_MAILDIRPLUSPLUS,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MEMBER(hierarchy_sep) '.',
bbd0a870f8639767e4e4011d2aedadac08d5c66fTimo Sirainen MEMBER(props) MAILBOX_LIST_PROP_NO_MAILDIR_NAME,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MEMBER(mailbox_name_max_length) PATH_MAX,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_alloc,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_deinit,
77c462c3a415536f9c87028ee34546ee96fd1445Timo Sirainen NULL,
533bfba437e4120aa29dd45bca2aa87e30ee28a2Timo Sirainen maildir_is_valid_pattern,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_is_valid_existing_name,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_is_valid_create_name,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_get_path,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_get_mailbox_name_status,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_get_temp_prefix,
5160580b0ec3f3288a320987abdf12a990f09df5Timo Sirainen NULL,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_iter_init,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_iter_next,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen maildir_list_iter_deinit,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen NULL,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen maildir_list_set_subscribed,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen maildir_list_delete_mailbox,
0e5f8c4589cfeccb752307c8ac35a2f1633e4ecaTimo Sirainen maildir_list_rename_mailbox,
0e5f8c4589cfeccb752307c8ac35a2f1633e4ecaTimo Sirainen NULL
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen};
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainenstruct mailbox_list imapdir_mailbox_list = {
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen MEMBER(name) MAILBOX_LIST_NAME_IMAPDIR,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen MEMBER(hierarchy_sep) '.',
bbd0a870f8639767e4e4011d2aedadac08d5c66fTimo Sirainen MEMBER(props) MAILBOX_LIST_PROP_NO_MAILDIR_NAME,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen MEMBER(mailbox_name_max_length) PATH_MAX,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen {
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen imapdir_list_alloc,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_deinit,
77c462c3a415536f9c87028ee34546ee96fd1445Timo Sirainen NULL,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_is_valid_pattern,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_is_valid_existing_name,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_is_valid_create_name,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_get_path,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_get_mailbox_name_status,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_get_temp_prefix,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen NULL,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_iter_init,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_iter_next,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_iter_deinit,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen NULL,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_set_subscribed,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_delete_mailbox,
0e5f8c4589cfeccb752307c8ac35a2f1633e4ecaTimo Sirainen maildir_list_rename_mailbox,
0e5f8c4589cfeccb752307c8ac35a2f1633e4ecaTimo Sirainen NULL
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen }
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen};