mailbox-list-maildir.c revision 738cb8e908b144d6dd6f6d7484a40ad67054aac5
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen/* Copyright (c) 2006-2007 Dovecot authors, see the included COPYING file */
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#include "lib.h"
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#include "array.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "hostpid.h"
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#include "home-expand.h"
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#include "subscription-file.h"
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#include "mailbox-list-maildir.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen#include <stdio.h>
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#include <sys/stat.h>
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainenextern struct mailbox_list maildir_mailbox_list;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainenextern struct mailbox_list imapdir_mailbox_list;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainenstatic struct mailbox_list *maildir_list_alloc(void)
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen{
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct maildir_mailbox_list *list;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen pool_t pool;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen pool = pool_alloconly_create("maildir++ list", 1024);
9d3ccd79130199ffdb19a688027d49bf20a4aaaaTimo Sirainen list = p_new(pool, struct maildir_mailbox_list, 1);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen list->list = maildir_mailbox_list;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen list->list.pool = pool;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen list->temp_prefix =
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen p_strconcat(pool, "temp.", my_hostname, ".", my_pid, ".", NULL);
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return &list->list;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainenstatic struct mailbox_list *imapdir_list_alloc(void)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct maildir_mailbox_list *list;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen pool_t pool;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen pool = pool_alloconly_create("imapdir list", 1024);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen list = p_new(pool, struct maildir_mailbox_list, 1);
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen list->list = imapdir_mailbox_list;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen list->list.pool = pool;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen list->temp_prefix = p_strconcat(pool, ".temp.", my_hostname, ".",
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen my_pid, ".", NULL);
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen return &list->list;
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen}
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
8fb1e3e2349c9940732b5bb77a2a4053b8f72a4fTimo Sirainenstatic void maildir_list_deinit(struct mailbox_list *_list)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen struct maildir_mailbox_list *list =
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen (struct maildir_mailbox_list *)_list;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen pool_unref(&list->list.pool);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic const char *
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainenmaildir_list_get_dirname_path(struct mailbox_list *list, const char *dir,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *name)
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen{
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (strcmp(list->name, MAILBOX_LIST_NAME_IMAPDIR) == 0)
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen return t_strdup_printf("%s/%s", dir, name);
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen return t_strdup_printf("%s/%c%s", dir, list->hierarchy_sep, name);
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainenstatic const char *
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainenmaildir_list_get_absolute_path(struct mailbox_list *list, const char *name)
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen{
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen const char *p;
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen if (home_try_expand(&name) < 0) {
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen /* fallback to using as ~name */
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen return name;
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen }
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen p = strrchr(name, '/');
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen if (p == NULL)
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen return name;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return maildir_list_get_dirname_path(list, t_strdup_until(name, p),
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen p+1);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainenstatic bool
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainenmaildir_list_is_valid_common(struct mailbox_list *list, const char *name,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen size_t *len_r)
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen{
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen size_t len;
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen /* check that there are no adjacent hierarchy separators */
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen for (len = 0; name[len] != '\0'; len++) {
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen if (name[len] == list->hierarchy_sep &&
5b1da062c037e9352ddf18ccfdf99248116f44d0Timo Sirainen name[len+1] == list->hierarchy_sep)
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen return FALSE;
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen }
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen if (len == 0 || name[len-1] == '/')
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen return FALSE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (name[0] == list->hierarchy_sep ||
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen name[len-1] == list->hierarchy_sep)
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return FALSE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen *len_r = len;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return TRUE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic bool maildir_list_is_valid_common_nonfs(const char *name)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (*name == '~' || strchr(name, '/') != NULL)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return FALSE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen if (name[0] == '.' && (name[1] == '\0' ||
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen (name[1] == '.' && name[2] == '\0'))) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* "." and ".." aren't allowed. */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return FALSE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return TRUE;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
4bbee99b3aef449a9a2a11a5b5cf1ca486915c49Timo Sirainenstatic bool ATTR_NORETURN
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenmaildir_is_valid_pattern(struct mailbox_list *list ATTR_UNUSED,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *pattern ATTR_UNUSED)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen i_unreached();
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen#ifndef ATTRS_DEFINED
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return FALSE;
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen#endif
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen}
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainenstatic bool
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainenmaildir_is_valid_existing_name(struct mailbox_list *list, const char *name)
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen{
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen size_t len;
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen if (!maildir_list_is_valid_common(list, name, &len))
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen return FALSE;
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0)
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen return TRUE;
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen return maildir_list_is_valid_common_nonfs(name);
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen}
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainenstatic bool
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainenmaildir_is_valid_create_name(struct mailbox_list *list, const char *name)
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen{
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen size_t len;
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen if (!maildir_list_is_valid_common(list, name, &len))
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen return FALSE;
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen if (len > MAILDIR_MAX_CREATE_MAILBOX_NAME_LENGTH)
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen return FALSE;
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0)
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen return TRUE;
5cda0bfea032000c4a51134c748d9efe6614870bTimo Sirainen
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen if (!maildir_list_is_valid_common_nonfs(name))
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return FALSE;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen if (mailbox_list_name_is_too_large(name, list->hierarchy_sep))
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return FALSE;
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen return TRUE;
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen}
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainenstatic const char *
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainenmaildir_list_get_path(struct mailbox_list *_list, const char *name,
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen enum mailbox_list_path_type type)
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen{
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen struct maildir_mailbox_list *list =
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen (struct maildir_mailbox_list *)_list;
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen if (name == NULL) {
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen /* return root directories */
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen switch (type) {
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen case MAILBOX_LIST_PATH_TYPE_DIR:
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen case MAILBOX_LIST_PATH_TYPE_MAILBOX:
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return _list->set.root_dir;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen case MAILBOX_LIST_PATH_TYPE_CONTROL:
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return _list->set.control_dir != NULL ?
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen _list->set.control_dir : _list->set.root_dir;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen case MAILBOX_LIST_PATH_TYPE_INDEX:
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return _list->set.index_dir != NULL ?
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen _list->set.index_dir : _list->set.root_dir;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen i_unreached();
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen }
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_assert(mailbox_list_is_valid_existing_name(_list, name));
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if ((list->list.flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0 &&
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen (*name == '/' || *name == '~'))
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen return maildir_list_get_absolute_path(_list, name);
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen switch (type) {
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen case MAILBOX_LIST_PATH_TYPE_DIR:
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen case MAILBOX_LIST_PATH_TYPE_MAILBOX:
872b8fd8a8db97dc54067b7ab25bda96ec0aac0dTimo Sirainen break;
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen case MAILBOX_LIST_PATH_TYPE_CONTROL:
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen if (_list->set.control_dir != NULL) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return maildir_list_get_dirname_path(_list,
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen _list->set.control_dir, name);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen break;
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen case MAILBOX_LIST_PATH_TYPE_INDEX:
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen if (_list->set.index_dir != NULL) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (*_list->set.index_dir == '\0')
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return "";
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return maildir_list_get_dirname_path(_list,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen _list->set.index_dir, name);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen break;
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen }
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen if (strcmp(name, "INBOX") == 0) {
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return _list->set.inbox_path != NULL ?
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen _list->set.inbox_path : _list->set.root_dir;
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen }
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen return maildir_list_get_dirname_path(_list, _list->set.root_dir, name);
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen}
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainenstatic int
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainenmaildir_list_get_mailbox_name_status(struct mailbox_list *_list,
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen const char *name,
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen enum mailbox_name_status *status)
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen{
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen struct stat st;
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen const char *path;
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen path = mailbox_list_get_path(_list, name,
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
3af0a1a2c2ef22a14c6b3c5cc4f780a2ea4df438Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen if (strcmp(name, "INBOX") == 0 || stat(path, &st) == 0) {
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen *status = MAILBOX_NAME_EXISTS;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return 0;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen if (!mailbox_list_is_valid_create_name(_list, name)) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen *status = MAILBOX_NAME_INVALID;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return 0;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
644268f7848a7c4221146d0b11feb8ed5bbed233Timo Sirainen
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen if (ENOTFOUND(errno) || errno == EACCES) {
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen *status = MAILBOX_NAME_VALID;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return 0;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen } else {
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen mailbox_list_set_critical(_list, "stat(%s) failed: %m", path);
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen return -1;
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen }
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen}
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic const char *
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainenmaildir_list_get_temp_prefix(struct mailbox_list *_list)
38d7db318188c4ac9cdc8c6cdb936b36a5258e19Timo Sirainen{
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen struct maildir_mailbox_list *list =
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen (struct maildir_mailbox_list *)_list;
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return list->temp_prefix;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic int maildir_list_set_subscribed(struct mailbox_list *_list,
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen const char *name, bool set)
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct maildir_mailbox_list *list =
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen (struct maildir_mailbox_list *)_list;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen const char *path;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen path = t_strconcat(_list->set.control_dir != NULL ?
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen _list->set.control_dir : _list->set.root_dir,
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen "/", _list->set.subscription_fname, NULL);
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen return subsfile_set_subscribed(_list, path, list->temp_prefix,
e192a3b1ca8ae857e7d87298ea507d32977ba570Timo Sirainen name, set);
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen}
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainen
97511ac4d7607e1ba64ce151eda3d9b5f9775519Timo Sirainenstatic int rename_dir(struct mailbox_list *list,
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen enum mailbox_list_path_type type,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *oldname, const char *newname)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen const char *oldpath, *newpath;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen oldpath = mailbox_list_get_path(list, oldname, type);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen newpath = mailbox_list_get_path(list, newname, type);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (strcmp(oldpath, newpath) == 0)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return 0;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen oldpath, newpath);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return -1;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen }
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return 0;
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainenstatic int rename_children(struct mailbox_list *list,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *oldname, const char *newname)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen struct mailbox_list_iterate_context *iter;
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen const struct mailbox_info *info;
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen ARRAY_DEFINE(names_arr, const char *);
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen const char *pattern, *oldpath, *newpath, *old_listname, *new_listname;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen const char *const *names;
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen unsigned int i, count;
38d7db318188c4ac9cdc8c6cdb936b36a5258e19Timo Sirainen size_t oldnamelen;
38d7db318188c4ac9cdc8c6cdb936b36a5258e19Timo Sirainen pool_t pool;
38d7db318188c4ac9cdc8c6cdb936b36a5258e19Timo Sirainen int ret;
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen
38d7db318188c4ac9cdc8c6cdb936b36a5258e19Timo Sirainen ret = 0;
38d7db318188c4ac9cdc8c6cdb936b36a5258e19Timo Sirainen oldnamelen = strlen(oldname);
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen /* first get the list of the children and save them to memory, because
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen we can't rely on readdir() not skipping files while the directory
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen is being modified. this doesn't protect against modifications by
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen other processes though. */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen pool = pool_alloconly_create("Maildir++ children list", 1024);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen i_array_init(&names_arr, 64);
60576cd64e6a537413cd90104f7e862f71d48c81Timo Sirainen
203560029e3ad8687c2c759e6a81ecdb8b37ebe6Timo Sirainen pattern = t_strdup_printf("%s%c*", oldname,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mailbox_list_get_hierarchy_sep(list));
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen iter = mailbox_list_iter_init(list, pattern,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *name;
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen
644268f7848a7c4221146d0b11feb8ed5bbed233Timo Sirainen /* verify that the prefix matches, otherwise we could have
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen problems with mailbox names containing '%' and '*' chars */
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen if (strncmp(info->name, oldname, oldnamelen) == 0 &&
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen info->name[oldnamelen] ==
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen mailbox_list_get_hierarchy_sep(list)) {
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen name = p_strdup(pool, info->name + oldnamelen);
80cdfe47daf6129410bafcecbe5c9faf09f2721bTimo Sirainen array_append(&names_arr, &name, 1);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
80cdfe47daf6129410bafcecbe5c9faf09f2721bTimo Sirainen }
d2b94d25f842cd1b7acaf4dd7de858f7c6a821c9Timo Sirainen if (mailbox_list_iter_deinit(&iter) < 0) {
80cdfe47daf6129410bafcecbe5c9faf09f2721bTimo Sirainen ret = -1;
80cdfe47daf6129410bafcecbe5c9faf09f2721bTimo Sirainen names = NULL; count = 0;
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen } else {
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen names = array_get(&names_arr, &count);
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen }
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen for (i = 0; i < count; i++) {
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen t_push();
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen old_listname = t_strconcat(oldname, names[i], NULL);
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen if (strcmp(old_listname, newname) == 0) {
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen /* When doing RENAME "a" "a.b" we see "a.b" here.
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen We don't want to rename it anymore to "a.b.b". */
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen t_pop();
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen continue;
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen }
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen new_listname = t_strconcat(newname, names[i], NULL);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen oldpath = mailbox_list_get_path(list, old_listname,
a24b0595f0f7d3925d4c9ac26fa503ff87c43e43Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
1bdda5c0c30463160c47151537e6bb2c6c994841Timo Sirainen newpath = mailbox_list_get_path(list, new_listname,
2aecf7be5834e7f6520f8deaad683a6fa1de4d61Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen
aa04335e9bb7fc899275c7468c83bcdfad2778d1Timo Sirainen /* FIXME: it's possible to merge two mailboxes if either one of
aa04335e9bb7fc899275c7468c83bcdfad2778d1Timo Sirainen them doesn't have existing root mailbox. We could check this
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen but I'm not sure if it's worth it. It could be even
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen considered as a feature.
aa04335e9bb7fc899275c7468c83bcdfad2778d1Timo Sirainen
aa04335e9bb7fc899275c7468c83bcdfad2778d1Timo Sirainen Anyway, the bug with merging is that if both mailboxes have
96541d31299bb40b5a6efdbf9b4cb3d4f4b4a069Timo Sirainen identically named child mailbox they conflict. Just ignore
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen those and leave them under the old mailbox. */
96541d31299bb40b5a6efdbf9b4cb3d4f4b4a069Timo Sirainen if (rename(oldpath, newpath) == 0 || EDESTDIREXISTS(errno))
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen ret = 1;
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen else {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen mailbox_list_set_critical(list,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen "rename(%s, %s) failed: %m", oldpath, newpath);
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen ret = -1;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen t_pop();
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen break;
96541d31299bb40b5a6efdbf9b4cb3d4f4b4a069Timo Sirainen }
55773f17bccf6361d6599ffcbe072d7c9fe205bfTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_CONTROL,
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen old_listname, new_listname);
a24b0595f0f7d3925d4c9ac26fa503ff87c43e43Timo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_INDEX,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen old_listname, new_listname);
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen t_pop();
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen array_free(&names_arr);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen pool_unref(&pool);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return ret;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic int
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenmaildir_list_delete_mailbox(struct mailbox_list *list, const char *name)
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen{
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen /* let the backend handle the rest */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen return mailbox_list_delete_index_control(list, name);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen}
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenstatic int maildir_list_rename_mailbox(struct mailbox_list *list,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen const char *oldname, const char *newname)
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen{
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen const char *oldpath, *newpath;
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen int ret;
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen bool found;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
36977c4a74e164f7d81eb4785f0a5d3ff436fd19Timo Sirainen /* NOTE: it's possible to rename a nonexisting mailbox which has
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen children. In that case we should ignore the rename() error. */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen oldpath = mailbox_list_get_path(list, oldname,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
9db263f2b9ab771fbf9a2bff44a245c45eaef218Timo Sirainen newpath = mailbox_list_get_path(list, newname,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
d96f86fb881c5b106649e8994ead1052acf24030Timo Sirainen ret = rename(oldpath, newpath);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen if (ret == 0 || errno == ENOENT) {
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_CONTROL,
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen oldname, newname);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen (void)rename_dir(list, MAILBOX_LIST_PATH_TYPE_INDEX,
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen oldname, newname);
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen
20195ef995a4eb63a282283db63f1dc0605323e0Timo Sirainen found = ret == 0;
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen ret = rename_children(list, oldname, newname);
645f258ea29afaf09b673fc65d1bd788dfec8db8Timo Sirainen if (ret < 0)
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen return -1;
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen if (!found && ret == 0) {
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname));
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen return -1;
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen }
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen return 0;
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen }
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen if (EDESTDIREXISTS(errno)) {
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTPOSSIBLE,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen "Target mailbox already exists");
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen } else {
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen mailbox_list_set_critical(list, "rename(%s, %s) failed: %m",
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen oldpath, newpath);
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen }
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen return -1;
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen}
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainenstruct mailbox_list maildir_mailbox_list = {
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen MEMBER(name) MAILBOX_LIST_NAME_MAILDIRPLUSPLUS,
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen MEMBER(hierarchy_sep) '.',
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen MEMBER(mailbox_name_max_length) PATH_MAX,
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen
cf52b37d807553e91a2d6fb7cb2c8b4c34589e1dTimo Sirainen {
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_alloc,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_deinit,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_is_valid_pattern,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_is_valid_existing_name,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_is_valid_create_name,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_get_path,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_get_mailbox_name_status,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_get_temp_prefix,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen NULL,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen maildir_list_iter_init,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_iter_next,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_iter_deinit,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen NULL,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_set_subscribed,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_delete_mailbox,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_rename_mailbox
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen }
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen};
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainenstruct mailbox_list imapdir_mailbox_list = {
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen MEMBER(name) MAILBOX_LIST_NAME_IMAPDIR,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen MEMBER(hierarchy_sep) '.',
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen MEMBER(mailbox_name_max_length) PATH_MAX,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen {
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen imapdir_list_alloc,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_deinit,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_is_valid_pattern,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_is_valid_existing_name,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_is_valid_create_name,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen maildir_list_get_path,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_get_mailbox_name_status,
98dd8e6e81f11f1e6040ca72f4916242d246c863Timo Sirainen maildir_list_get_temp_prefix,
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen NULL,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen maildir_list_iter_init,
1e242794e7a4f653f18fbb8edfe9ccec489a3a08Timo Sirainen maildir_list_iter_next,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen maildir_list_iter_deinit,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen NULL,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen maildir_list_set_subscribed,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen maildir_list_delete_mailbox,
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen maildir_list_rename_mailbox
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen }
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen};
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen