mailbox-list-maildir.c revision c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abe
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2006-2010 Dovecot authors, see the included COPYING file */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "lib.h"
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include "array.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "hostpid.h"
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen#include "eacces-error.h"
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen#include "mkdir-parents.h"
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen#include "str.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "subscription-file.h"
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen#include "mailbox-list-delete.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "mailbox-list-maildir.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen#include <stdio.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include <sys/stat.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen#define MAILDIR_SUBFOLDER_FILENAME "maildirfolder"
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
14e581093719c4353205bf5ba4743d8575c49d1bTimo Sirainen pool = pool_alloconly_create("maildir++ list", 2048);
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{
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen const char *root_dir;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen if (name == NULL) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* return root directories */
e0ca8f2484847b57e20798a9f9c7040708696a90Timo Sirainen return mailbox_list_get_root_path(&_list->set, type);
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
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen root_dir = _list->set.root_dir;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen switch (type) {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_DIR:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen case MAILBOX_LIST_PATH_TYPE_MAILBOX:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen break;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen case MAILBOX_LIST_PATH_TYPE_ALT_DIR:
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen case MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX:
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (_list->set.alt_dir == NULL)
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return NULL;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen root_dir = _list->set.alt_dir;
3c493c276f599d9b9cd10764876d648003046954Timo 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
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (type == MAILBOX_LIST_PATH_TYPE_ALT_DIR ||
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen type == MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen /* don't use inbox_path */
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else if (strcmp(name, "INBOX") == 0 && _list->set.inbox_path != NULL)
1d266a7419fafa25f3505a12217452a8c647074fTimo Sirainen return _list->set.inbox_path;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return maildir_list_get_dirname_path(_list, 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) {
a574952c01611899b8ecf81434dbbb3345f27518Timo Sirainen *status = MAILBOX_NAME_EXISTS_MAILBOX;
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
3c493c276f599d9b9cd10764876d648003046954Timo Sirainenstatic int
3c493c276f599d9b9cd10764876d648003046954Timo Sirainenmaildir_list_create_maildirfolder_file(struct mailbox_list *list,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen const char *dir)
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen{
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen const char *path, *gid_origin;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mode_t mode, old_mask;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen gid_t gid;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen int fd;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen /* Maildir++ spec wants that maildirfolder named file is created for
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen all subfolders. */
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_get_permissions(list, NULL, &mode, &gid, &gid_origin);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen path = t_strconcat(dir, "/" MAILDIR_SUBFOLDER_FILENAME, NULL);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen old_mask = umask(0);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen fd = open(path, O_CREAT | O_WRONLY, mode);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen umask(old_mask);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (fd != -1) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen /* ok */
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else if (errno == ENOENT) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen "Mailbox was deleted while it was being created");
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return -1;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_set_critical(list,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen "open(%s, O_CREAT) failed: %m", path);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return -1;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen }
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (gid != (gid_t)-1) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (fchown(fd, (uid_t)-1, gid) == 0) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen /* ok */
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else if (errno == EPERM) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_set_critical(list, "%s",
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen eperm_error_get_chgrp("fchown", path,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen gid, gid_origin));
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_set_critical(list,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen "fchown(%s) failed: %m", path);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen }
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen }
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen (void)close(fd);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return 0;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen}
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainenstatic int
3c493c276f599d9b9cd10764876d648003046954Timo Sirainenmaildir_list_create_mailbox_dir(struct mailbox_list *list, const char *name,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen bool directory ATTR_UNUSED)
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen{
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen const char *path, *root_dir, *gid_origin, *p;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mode_t mode;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen gid_t gid;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen bool create_parent_dir;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen path = mailbox_list_get_path(list, name,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen create_parent_dir = !directory &&
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen (list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (create_parent_dir) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen /* we only need to make sure that the parent directory exists */
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen p = strrchr(path, '/');
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (p == NULL)
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return 0;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen path = t_strdup_until(path, p);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen }
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen root_dir = mailbox_list_get_path(list, NULL,
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_get_dir_permissions(list, NULL, &mode,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen &gid, &gid_origin);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen if (mkdir_parents_chgrp(path, mode, gid, gid_origin) == 0) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen /* ok */
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else if (errno == EEXIST) {
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen if (create_parent_dir)
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen return 0;
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen if (!directory) {
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen if (strcmp(path, root_dir) == 0) {
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen /* even though the root directory exists,
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen the mailbox might not */
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen return 0;
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen }
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen }
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen mailbox_list_set_error(list, MAIL_ERROR_EXISTS,
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen "Mailbox already exists");
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen return -1;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else if (mailbox_list_set_error_from_errno(list)) {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return -1;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen } else {
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen mailbox_list_set_critical(list, "mkdir(%s) failed: %m", path);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen return -1;
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen }
029c8542982001bf1386aee0ea9cb9843e5ab62dTimo Sirainen return create_parent_dir || strcmp(path, root_dir) == 0 ? 0 :
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen maildir_list_create_maildirfolder_file(list, path);
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen}
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainenstatic const char *mailbox_list_maildir_get_trash_dir(struct mailbox_list *list)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen{
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen const char *root_dir;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen root_dir = mailbox_list_get_path(list, NULL,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen MAILBOX_LIST_PATH_TYPE_DIR);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return t_strdup_printf("%s/%c%c"MAILBOX_LIST_MAILDIR_TRASH_DIR_NAME,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen root_dir, list->hierarchy_sep,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen list->hierarchy_sep);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen}
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainenstatic int
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainenmaildir_list_delete_maildir(struct mailbox_list *list, const char *name)
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen{
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen const char *path, *trash_dir;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen int ret = 0;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen trash_dir = mailbox_list_maildir_get_trash_dir(list);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen ret = mailbox_list_delete_maildir_via_trash(list, name, trash_dir);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret < 0)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return -1;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (ret == 0) {
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen /* we could actually use just unlink_directory()
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen but error handling is easier this way :) */
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen path = mailbox_list_get_path(list, name,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen if (mailbox_list_delete_mailbox_nonrecursive(list, name,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen path, TRUE) < 0)
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return -1;
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen }
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen return 0;
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen}
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainenstatic int
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainenmaildir_list_delete_mailbox(struct mailbox_list *list, const char *name)
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen{
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen if ((list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) {
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen if (mailbox_list_delete_mailbox_file(list, name) < 0)
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen return -1;
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen } else {
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen if (maildir_list_delete_maildir(list, name) < 0)
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen return -1;
c18c8b130311374a5145226be03cda903047b1f8Timo Sirainen }
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen mailbox_list_delete_finish(list, name);
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen return 0;
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen}
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainenstatic int maildir_list_delete_dir(struct mailbox_list *list, const char *name)
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen{
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen const char *path;
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen struct stat st;
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen /* with maildir++ there aren't any non-selectable mailboxes.
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen we'll always fail. */
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen path = mailbox_list_get_path(list, name, MAILBOX_LIST_PATH_TYPE_DIR);
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen if (stat(path, &st) == 0) {
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen mailbox_list_set_error(list, MAIL_ERROR_EXISTS,
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen "Mailbox exists");
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen } else if (errno == ENOENT) {
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen mailbox_list_set_error(list, MAIL_ERROR_NOTFOUND,
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen } else {
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen mailbox_list_set_critical(list, "stat(%s) failed: %m", path);
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen }
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen return -1;
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen}
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenstatic int rename_dir(struct mailbox_list *oldlist, const char *oldname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen struct mailbox_list *newlist, const char *newname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen enum mailbox_list_path_type type)
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen{
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen const char *oldpath, *newpath;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen oldpath = mailbox_list_get_path(oldlist, oldname, type);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen newpath = mailbox_list_get_path(newlist, newname, type);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (strcmp(oldpath, newpath) == 0)
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return 0;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (rename(oldpath, newpath) < 0 && errno != ENOENT) {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen mailbox_list_set_critical(oldlist, "rename(%s, %s) failed: %m",
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen oldpath, newpath);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return -1;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return 0;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen}
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenstatic int
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenmaildir_rename_children(struct mailbox_list *oldlist, const char *oldname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen struct mailbox_list *newlist, const char *newname)
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen{
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen struct mailbox_list_iterate_context *iter;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen const struct mailbox_info *info;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ARRAY_DEFINE(names_arr, const char *);
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen const char *pattern, *oldpath, *newpath, *old_childname, *new_childname;
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen const char *const *names, *old_vname, *new_vname;
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen unsigned int i, count, old_vnamelen;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen pool_t pool;
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen string_t *str;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen int ret;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ret = 0;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* first get the list of the children and save them to memory, because
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen we can't rely on readdir() not skipping files while the directory
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen is being modified. this doesn't protect against modifications by
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen other processes though. */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen pool = pool_alloconly_create("Maildir++ children list", 1024);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen i_array_init(&names_arr, 64);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen str = t_str_new(256);
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen old_vname = t_strdup(mail_namespace_get_vname(oldlist->ns, str, oldname));
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen old_vnamelen = strlen(oldname);
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen str_truncate(str, 0);
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen new_vname = t_strdup(mail_namespace_get_vname(newlist->ns, str, newname));
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen pattern = t_strdup_printf("%s%c*", old_vname, oldlist->ns->sep);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen iter = mailbox_list_iter_init(oldlist, pattern,
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen MAILBOX_LIST_ITER_VIRTUAL_NAMES |
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_ITER_RETURN_NO_FLAGS |
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_ITER_RAW_LIST);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen while ((info = mailbox_list_iter_next(iter)) != NULL) {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen const char *name;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* verify that the prefix matches, otherwise we could have
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen problems with mailbox names containing '%' and '*' chars */
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen if (strncmp(info->name, old_vname, old_vnamelen) == 0 &&
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen info->name[old_vnamelen] == oldlist->ns->sep) {
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen name = p_strdup(pool, info->name + old_vnamelen);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen array_append(&names_arr, &name, 1);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (mailbox_list_iter_deinit(&iter) < 0) {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ret = -1;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen names = NULL; count = 0;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen } else {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen names = array_get(&names_arr, &count);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen for (i = 0; i < count; i++) {
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen old_childname = mail_namespace_get_storage_name(oldlist->ns,
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen t_strconcat(old_vname, names[i], NULL));
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen if (strcmp(old_childname, new_vname) == 0) {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* When doing RENAME "a" "a.b" we see "a.b" here.
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen We don't want to rename it anymore to "a.b.b". */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen continue;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen new_childname = mail_namespace_get_storage_name(newlist->ns,
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen t_strconcat(new_vname, names[i], NULL));
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen oldpath = mailbox_list_get_path(oldlist, old_childname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen newpath = mailbox_list_get_path(newlist, new_childname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* FIXME: it's possible to merge two mailboxes if either one of
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen them doesn't have existing root mailbox. We could check this
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen but I'm not sure if it's worth it. It could be even
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen considered as a feature.
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen Anyway, the bug with merging is that if both mailboxes have
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen identically named child mailbox they conflict. Just ignore
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen those and leave them under the old mailbox. */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (rename(oldpath, newpath) == 0 || EDESTDIREXISTS(errno))
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ret = 1;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen else {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen mailbox_list_set_critical(oldlist,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen "rename(%s, %s) failed: %m", oldpath, newpath);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ret = -1;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen break;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen (void)rename_dir(oldlist, old_childname, newlist, new_childname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PATH_TYPE_CONTROL);
c19f0dd4d274c15ef7b592dcc9d8c2c8c1e22abeTimo Sirainen (void)rename_dir(oldlist, old_childname, newlist, new_childname,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PATH_TYPE_INDEX);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen array_free(&names_arr);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen pool_unref(&pool);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return ret;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen}
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo 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{
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen const char *oldpath, *newpath, *root_path;
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
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen root_path = mailbox_list_get_path(oldlist, NULL,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen if (strcmp(oldpath, root_path) == 0) {
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* most likely INBOX */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen mailbox_list_set_error(oldlist, MAIL_ERROR_NOTPOSSIBLE,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen t_strdup_printf("Renaming %s isn't supported.",
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen oldname));
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen return -1;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen }
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo 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 = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = MAILBOX_LIST_NAME_MAILDIRPLUSPLUS,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .hierarchy_sep = '.',
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen .props = MAILBOX_LIST_PROP_NO_MAILDIR_NAME |
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PROP_NO_ALT_DIR |
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen MAILBOX_LIST_PROP_NO_NOSELECT,
48ca4c43ebca6fa3eee217bd4439cba5b5376dd4Timo Sirainen .mailbox_name_max_length = MAILBOX_LIST_NAME_MAX_LENGTH,
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,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen maildir_list_get_mailbox_flags,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen NULL,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen maildir_list_set_subscribed,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen maildir_list_create_mailbox_dir,
b039dabf4c53f72454e795930e7643b6e0e625f9Timo Sirainen maildir_list_delete_mailbox,
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen maildir_list_delete_dir,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen maildir_list_rename_mailbox
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen }
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen};
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainenstruct mailbox_list imapdir_mailbox_list = {
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .name = MAILBOX_LIST_NAME_IMAPDIR,
7bafda1813454621e03615e83d55bccfa7cc56bdTimo Sirainen .hierarchy_sep = '.',
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen .props = MAILBOX_LIST_PROP_NO_MAILDIR_NAME |
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen MAILBOX_LIST_PROP_NO_ALT_DIR |
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen MAILBOX_LIST_PROP_NO_NOSELECT,
48ca4c43ebca6fa3eee217bd4439cba5b5376dd4Timo Sirainen .mailbox_name_max_length = MAILBOX_LIST_NAME_MAX_LENGTH,
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,
dca6d617a23e3f93af3b8df59acb46478179fe55Timo Sirainen maildir_list_get_mailbox_flags,
61b0637759146621cbb7edcbd0b03a71cfd66dfeTimo Sirainen NULL,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_set_subscribed,
3c493c276f599d9b9cd10764876d648003046954Timo Sirainen maildir_list_create_mailbox_dir,
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen maildir_list_delete_mailbox,
2f30b72d49fbff0c4096125c139e4bdfef45669cTimo Sirainen maildir_list_delete_dir,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen maildir_list_rename_mailbox
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen }
63ca9cacc5d2d1b1cebfc430bb89637f8c138e4cTimo Sirainen};