mailbox-list-index-backend.c revision 68b968ad67513632a02aa0f8f81679fe072ca3c0
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "lib.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "hostpid.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "mail-index.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "subscription-file.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "mailbox-list-delete.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "mailbox-list-subscriptions.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "mailbox-list-index-storage.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#include "mailbox-list-index-sync.h"
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen#include <stdio.h>
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen#define GLOBAL_TEMP_PREFIX ".temp."
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstruct index_mailbox_list {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *temp_prefix;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen};
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenextern struct mailbox_list index_mailbox_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic struct mailbox_list *index_list_alloc(void)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen pool_t pool;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen pool = pool_alloconly_create("index list", 2048);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen list = p_new(pool, struct index_mailbox_list, 1);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen list->list = index_mailbox_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen list->list.pool = pool;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen list->temp_prefix = p_strconcat(pool, GLOBAL_TEMP_PREFIX,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen my_hostname, ".", my_pid, ".", NULL);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return &list->list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainenstatic int index_list_init(struct mailbox_list *_list, const char **error_r)
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen{
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen const char *dir;
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen if (!_list->mail_set->mailbox_list_index) {
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen *error_r = "LAYOUT=index requires mailbox_list_index=yes";
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen return -1;
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen }
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen if (mailbox_list_get_root_path(_list, MAILBOX_LIST_PATH_TYPE_INDEX, &dir) &&
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen mailbox_list_mkdir_root(_list, dir, MAILBOX_LIST_PATH_TYPE_INDEX) < 0) {
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen *error_r = t_strdup_printf("Failed to create the index root directory: %s",
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen mailbox_list_get_last_error(_list, NULL));
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen return -1;
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen }
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen return 0;
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen}
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic void index_list_deinit(struct mailbox_list *_list)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen pool_unref(&list->list.pool);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic char index_list_get_hierarchy_sep(struct mailbox_list *list ATTR_UNUSED)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return MAILBOX_LIST_INDEX_HIERARHCY_SEP;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_get_node(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node **node_r)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_refresh(&list->list) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen node = mailbox_list_index_lookup(&list->list, name);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (node == NULL)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen *node_r = node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainenstatic const char *
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainenindex_get_guid_path(struct mailbox_list *_list, const char *root_dir,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen const guid_128_t mailbox_guid)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen{
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (_list->set.mailbox_dir_name == '\0') {
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen return t_strconcat(root_dir, "/",
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen guid_128_to_string(mailbox_guid), NULL);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen } else {
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen return t_strdup_printf("%s/%s%s", root_dir,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen _list->set.mailbox_dir_name,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen guid_128_to_string(mailbox_guid));
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen }
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen}
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_get_path(struct mailbox_list *_list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen enum mailbox_list_path_type type, const char **path_r)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mail_index_view *view;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_status status;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen guid_128_t mailbox_guid;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *root_dir;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen uint32_t seq;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (name == NULL) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* return root directories */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return mailbox_list_set_get_root_path(&_list->set, type,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen path_r) ? 1 : 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* consistently use mailbox_dir_name as part of all mailbox
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen directories (index/control/etc) */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen switch (type) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen case MAILBOX_LIST_PATH_TYPE_MAILBOX:
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen type = MAILBOX_LIST_PATH_TYPE_DIR;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen break;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen case MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX:
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen type = MAILBOX_LIST_PATH_TYPE_ALT_DIR;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen break;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen default:
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen break;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!mailbox_list_set_get_root_path(&_list->set, type, &root_dir))
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, name, &node)) <= 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen view = mail_index_view_open(ilist->index);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!mail_index_lookup_seq(view, node->uid, &seq))
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_panic("mailbox list index: lost uid=%u", node->uid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!mailbox_list_index_status(_list, view, seq, 0,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &status, mailbox_guid)) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else {
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen *path_r = index_get_guid_path(_list, root_dir, mailbox_guid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = 1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_view_close(&view);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic const char *
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_get_temp_prefix(struct mailbox_list *_list, bool global)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return global ? GLOBAL_TEMP_PREFIX : list->temp_prefix;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int index_list_set_subscribed(struct mailbox_list *_list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *name, bool set)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *path;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen path = t_strconcat(_list->set.control_dir != NULL ?
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen _list->set.control_dir : _list->set.root_dir,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "/", _list->set.subscription_fname, NULL);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return subsfile_set_subscribed(_list, path, list->temp_prefix,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen name, set);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_node_exists(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen enum mailbox_existence *existence_r)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen *existence_r = MAILBOX_EXISTENCE_NONE;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, name, &node)) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((node->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen MAILBOX_LIST_INDEX_FLAG_NOSELECT)) == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen *existence_r = MAILBOX_EXISTENCE_SELECT;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* non-selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen *existence_r = MAILBOX_EXISTENCE_NOSELECT;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_mailbox_create_dir(struct index_mailbox_list *list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen uint32_t seq;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen bool created;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen seq = mailbox_list_index_sync_name(sync_ctx, name, &node, &created);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (created || (node->flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* didn't already exist */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen node->flags = MAILBOX_LIST_INDEX_FLAG_NOSELECT;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (enum mail_flags)node->flags);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = 1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* already existed */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_mailbox_create_selectable(struct index_mailbox_list *list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *name, guid_128_t mailbox_guid)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_record rec;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const void *data;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen bool expunged, created;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen uint32_t seq;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen seq = mailbox_list_index_sync_name(sync_ctx, name, &node, &created);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!created &&
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (node->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen MAILBOX_LIST_INDEX_FLAG_NOSELECT)) == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* already selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_lookup_ext(sync_ctx->view, seq, sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &data, &expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_assert(data != NULL && !expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memcpy(&rec, data, sizeof(rec));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_assert(guid_128_is_empty(rec.guid));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* make it selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen node->flags = 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE, 0);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memcpy(rec.guid, mailbox_guid, sizeof(rec.guid));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_ext(sync_ctx->trans, seq, sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &rec, NULL);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_mailbox_create(struct mailbox *box,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const struct mailbox_update *update, bool directory)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list =
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (struct index_mailbox_list *)box->list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_update new_update;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen enum mailbox_existence existence;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* first do a quick check that it doesn't exist */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_node_exists(list, box->name, &existence)) < 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_storage_copy_list_error(box->storage, box->list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (existence == MAILBOX_EXISTENCE_NONE && directory) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* now add the directory to index locked */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_mailbox_create_dir(list, box->name)) < 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_storage_copy_list_error(box->storage, box->list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else if (existence != MAILBOX_EXISTENCE_SELECT && !directory) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* if no GUID is requested, generate it ourself. set
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen UIDVALIDITY to index sometimes later. */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (update == NULL)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memset(&new_update, 0, sizeof(new_update));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen else
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen new_update = *update;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (guid_128_is_empty(new_update.mailbox_guid))
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen guid_128_generate(new_update.mailbox_guid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = index_list_mailbox_create_selectable(list, box->name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen new_update.mailbox_guid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret < 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_storage_copy_list_error(box->storage, box->list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* the storage backend needs to use the same GUID */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen update = &new_update;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Mailbox already exists");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return directory ? 0 :
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ibox->module_ctx.super.create_box(box, update, directory);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainenstatic int
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainenindex_list_mailbox_update(struct mailbox *box,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen const struct mailbox_update *update)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen{
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen const char *root_dir, *old_path, *new_path;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (mailbox_list_get_path(box->list, box->name,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen &old_path) <= 0)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen old_path = NULL;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (ibox->module_ctx.super.update_box(box, update) < 0)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen return -1;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen /* rename the directory */
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (!guid_128_is_empty(update->mailbox_guid) &&
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mailbox_list_set_get_root_path(&box->list->set,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen MAILBOX_LIST_PATH_TYPE_MAILBOX,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen &root_dir)) {
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen new_path = index_get_guid_path(box->list, root_dir,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen update->mailbox_guid);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (strcmp(old_path, new_path) == 0)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen ;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen else if (rename(old_path, new_path) == 0)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen ;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen else if (errno == ENOENT) {
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(box->name));
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen return -1;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen } else {
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mail_storage_set_critical(box->storage,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen "rename(%s, %s) failed: %m",
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen old_path, new_path);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen return -1;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen }
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen }
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mailbox_list_index_update_mailbox_index(box, update);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen return 0;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen}
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic void
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_try_delete(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen enum mailbox_list_path_type type)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list *_list = &list->list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *mailbox_path, *path;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_get_path(_list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &mailbox_path) <= 0 ||
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_get_path(_list, name, type, &path) <= 0 ||
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen strcmp(path, mailbox_path) == 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (*_list->set.maildir_name == '\0' &&
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (_list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* this directory may contain also child mailboxes' data.
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen we don't want to delete that. */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen bool rmdir_path = *_list->set.maildir_name != '\0';
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_delete_mailbox_nonrecursive(_list, name, path,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen rmdir_path) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_delete_trash(path) < 0 &&
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen errno != ENOENT && errno != ENOTEMPTY) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_critical(_list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "unlink_directory(%s) failed: %m", path);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* avoid leaving empty directories lying around */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_delete_until_root(_list, path, type);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic void
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_finish(struct index_mailbox_list *list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_INDEX);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_CONTROL);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_try_delete(list, name, MAILBOX_LIST_PATH_TYPE_ALT_MAILBOX);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_entry(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen bool delete_selectable)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_record rec;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *node;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const void *data;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen bool expunged;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen uint32_t seq;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, name, &node)) < 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(name));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!mail_index_lookup_seq(sync_ctx->view, node->uid, &seq))
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_panic("mailbox list index: lost uid=%u", node->uid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (delete_selectable) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* make it at least non-selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen node->flags = MAILBOX_LIST_INDEX_FLAG_NOSELECT;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (enum mail_flags)node->flags);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_lookup_ext(sync_ctx->view, seq,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &data, &expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_assert(data != NULL && !expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memcpy(&rec, data, sizeof(rec));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen rec.uid_validity = 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memset(&rec.guid, 0, sizeof(rec.guid));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_ext(sync_ctx->trans, seq,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen sync_ctx->ilist->ext_id, &rec, NULL);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (node->children != NULL) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* can't delete this directory before its children,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen but we may have made it non-selectable already */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* we can remove the entire node */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_expunge(sync_ctx->trans, seq);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_index_node_unlink(sync_ctx->ilist, node);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_mailbox(struct mailbox_list *_list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *path;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* first delete the mailbox files */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = mailbox_list_get_path(_list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &path);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret <= 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
201437e07fd40d296377cc20ed1dab1f2777544aTimo Sirainen if ((_list->flags & MAILBOX_LIST_FLAG_NO_MAIL_FILES) != 0) {
201437e07fd40d296377cc20ed1dab1f2777544aTimo Sirainen ret = 0;
201437e07fd40d296377cc20ed1dab1f2777544aTimo Sirainen } else if ((_list->flags & MAILBOX_LIST_FLAG_MAILBOX_FILES) != 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = mailbox_list_delete_mailbox_file(_list, name, path);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen } else {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = mailbox_list_delete_mailbox_nonrecursive(_list, name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen path, TRUE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_delete_finish(list, name);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (index_list_delete_entry(list, name, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_dir(struct mailbox_list *_list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_delete_entry(list, name, FALSE)) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_EXISTS,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Mailbox has children, delete them first");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_symlink(struct mailbox_list *_list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *name ATTR_UNUSED)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_NOTPOSSIBLE,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Symlinks not supported");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_rename_mailbox(struct mailbox_list *_oldlist, const char *oldname,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list *_newlist, const char *newname)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_oldlist;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_record oldrec, newrec;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_node *oldnode, *newnode, *child;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const void *data;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen bool created, expunged;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen uint32_t oldseq, newseq;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen int ret;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (_oldlist != _newlist) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_oldlist, MAIL_ERROR_NOTPOSSIBLE,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Renaming not supported across namespaces.");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, oldname, &oldnode)) < 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen if (ret == 0) {
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND,
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen T_MAIL_ERR_MAILBOX_NOT_FOUND(oldname));
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen return -1;
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!mail_index_lookup_seq(sync_ctx->view, oldnode->uid, &oldseq))
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_panic("mailbox list index: lost uid=%u", oldnode->uid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen newseq = mailbox_list_index_sync_name(sync_ctx, newname,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &newnode, &created);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!created) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(&list->list, MAIL_ERROR_EXISTS,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Target mailbox already exists");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return -1;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_assert(oldnode != newnode);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* copy all the data from old node to new node */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen newnode->uid = oldnode->uid;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen newnode->flags = oldnode->flags;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen newnode->children = oldnode->children; oldnode->children = NULL;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen for (child = newnode->children; child != NULL; child = child->next)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen child->parent = newnode;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* remove the old node from existence */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_index_node_unlink(sync_ctx->ilist, oldnode);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* update the old index record to contain the new name_id/parent_uid,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen then expunge the added index record */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_lookup_ext(sync_ctx->view, oldseq, sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &data, &expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_assert(data != NULL && !expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memcpy(&oldrec, data, sizeof(oldrec));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_lookup_ext(sync_ctx->view, newseq, sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen &data, &expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen i_assert(data != NULL && !expunged);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen memcpy(&newrec, data, sizeof(newrec));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen oldrec.name_id = newrec.name_id;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen oldrec.parent_uid = newrec.parent_uid;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_ext(sync_ctx->trans, oldseq,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen sync_ctx->ilist->ext_id, &oldrec, NULL);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_expunge(sync_ctx->trans, newseq);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return mailbox_list_index_sync_end(&sync_ctx, TRUE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic struct mailbox_list_iterate_context *
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_iter_init(struct mailbox_list *list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const char *const *patterns ATTR_UNUSED,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen enum mailbox_list_iter_flags flags)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_iterate_context *ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen pool_t pool;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen pool = pool_alloconly_create("mailbox list index backend iter", 1024);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ctx = p_new(pool, struct mailbox_list_iterate_context, 1);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ctx->pool = pool;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ctx->list = list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ctx->flags = flags;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen array_create(&ctx->module_contexts, pool, sizeof(void *), 5);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic const struct mailbox_info *
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_iter_next(struct mailbox_list_iterate_context *ctx ATTR_UNUSED)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return NULL;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int index_list_iter_deinit(struct mailbox_list_iterate_context *ctx)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen pool_unref(&ctx->pool);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return 0;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstruct mailbox_list index_mailbox_list = {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen .name = MAILBOX_LIST_NAME_INDEX,
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen .props = MAILBOX_LIST_PROP_NO_ROOT,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen .mailbox_name_max_length = MAILBOX_LIST_NAME_MAX_LENGTH,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_alloc,
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen index_list_init,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_deinit,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen NULL,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_get_hierarchy_sep,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_default_get_vname,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_default_get_storage_name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_get_path,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_get_temp_prefix,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen NULL,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_iter_init,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_iter_next,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_iter_deinit,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen NULL,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen NULL,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_subscriptions_refresh,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_set_subscribed,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_delete_mailbox,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_delete_dir,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_delete_symlink,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen index_list_rename_mailbox,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen NULL, NULL, NULL, NULL
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen }
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen};
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenvoid mailbox_list_index_backend_init_mailbox(struct mailbox *box)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen{
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (strcmp(box->list->name, MAILBOX_LIST_NAME_INDEX) != 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen box->v.create_box = index_list_mailbox_create;
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen box->v.update_box = index_list_mailbox_update;
68b968ad67513632a02aa0f8f81679fe072ca3c0Timo Sirainen
68b968ad67513632a02aa0f8f81679fe072ca3c0Timo Sirainen box->v.list_index_has_changed = NULL;
68b968ad67513632a02aa0f8f81679fe072ca3c0Timo Sirainen box->v.list_index_update_sync = NULL;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen}