mailbox-list-index-backend.c revision ca31fc1a8e48281c6882796fa7d4372acc2f97e5
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2013 Dovecot authors, see the included COPYING file */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic struct mailbox_list *index_list_alloc(void)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen pool = pool_alloconly_create("index list", 2048);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen list = p_new(pool, struct index_mailbox_list, 1);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen list->temp_prefix = p_strconcat(pool, GLOBAL_TEMP_PREFIX,
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainenstatic int index_list_init(struct mailbox_list *_list, const char **error_r)
29543188462c9348f365ec29115d777ffe4769d3Timo Sirainen const char *dir;
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen *error_r = "LAYOUT=index requires mailbox_list_index=yes";
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",
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic void index_list_deinit(struct mailbox_list *_list)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic char index_list_get_hierarchy_sep(struct mailbox_list *list ATTR_UNUSED)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_get_node(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_refresh(&list->list) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen node = mailbox_list_index_lookup(&list->list, name);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainenstatic const char *
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainenindex_get_guid_path(struct mailbox_list *_list, const char *root_dir,
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 struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT(_list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* return root directories */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return mailbox_list_set_get_root_path(&_list->set, type,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* consistently use mailbox_dir_name as part of all mailbox
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen directories (index/control/etc) */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (!mailbox_list_set_get_root_path(&_list->set, type, &root_dir))
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, name, &node)) <= 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND,
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen /* we could get here during sync from
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen index_list_mailbox_create_selectable() */
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen view = ilist->sync_ctx == NULL ? 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 mailbox_list_set_error(_list, MAIL_ERROR_NOTFOUND,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen *path_r = index_get_guid_path(_list, root_dir, mailbox_guid);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic const char *
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_get_temp_prefix(struct mailbox_list *_list, bool global)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return global ? GLOBAL_TEMP_PREFIX : list->temp_prefix;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int index_list_set_subscribed(struct mailbox_list *_list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
3568ea090b5a072e498438e74db23b98103ff2deTimo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_NOTPOSSIBLE,
3568ea090b5a072e498438e74db23b98103ff2deTimo Sirainen "Subscriptions not supported");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen path = t_strconcat(_list->set.control_dir != NULL ?
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return subsfile_set_subscribed(_list, path, list->temp_prefix,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_node_exists(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, name, &node)) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((node->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* non-selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_mailbox_create_dir(struct index_mailbox_list *list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
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 /* already existed */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainenindex_list_mailbox_create_selectable(struct mailbox *box,
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen seq = mailbox_list_index_sync_name(sync_ctx, box->name, &node, &created);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (node->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* already selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_lookup_ext(sync_ctx->view, seq, sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* make it selectable */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE, 0);
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen memcpy(rec.guid, update->mailbox_guid, sizeof(rec.guid));
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_ext(sync_ctx->trans, seq, sync_ctx->ilist->ext_id,
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen success = ibox->module_ctx.super.create_box(box, update, FALSE) == 0;
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, success) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen const struct mailbox_update *update, bool directory)
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 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 } 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 (guid_128_is_empty(new_update.mailbox_guid))
ca31fc1a8e48281c6882796fa7d4372acc2f97e5Timo Sirainen ret = index_list_mailbox_create_selectable(box, &new_update);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_storage_copy_list_error(box->storage, box->list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_EXISTS,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Mailbox already exists");
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (mailbox_list_get_path(box->list, box->name,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen if (ibox->module_ctx.super.update_box(box, update) < 0)
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen /* rename the directory */
dfc96c43be0720d3a03faa1eb44032276cbf94cfTimo Sirainen if (!guid_128_is_empty(update->mailbox_guid) && old_path != NULL &&
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mailbox_list_set_get_root_path(&box->list->set,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen new_path = index_get_guid_path(box->list, root_dir,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mail_storage_set_error(box->storage, MAIL_ERROR_NOTFOUND,
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen "rename(%s, %s) failed: %m",
3a2f2adf5679aa383a2cab09f739d59233cada95Timo Sirainen mailbox_list_index_update_mailbox_index(box, update);
d71d05cf4417eaedb4d72491480a7d2bb46d8df3Timo Sirainenindex_list_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED,
d71d05cf4417eaedb4d72491480a7d2bb46d8df3Timo Sirainen if (index_list_node_exists(list, box->name, existence_r) < 0) {
d71d05cf4417eaedb4d72491480a7d2bb46d8df3Timo Sirainen mail_storage_copy_list_error(box->storage, box->list);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_try_delete(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_get_path(_list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_get_path(_list, name, type, &path) <= 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 /* avoid leaving empty directories lying around */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_delete_until_root(_list, path, type);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_finish(struct index_mailbox_list *list, const char *name)
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 Sirainenindex_list_delete_entry(struct index_mailbox_list *list, const char *name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list_index_sync_context *sync_ctx;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
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 (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND,
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 /* 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 /* 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 /* we can remove the entire node */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_index_node_unlink(sync_ctx->ilist, node);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_mailbox(struct mailbox_list *_list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* first delete the mailbox files */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen ret = mailbox_list_get_path(_list, name, MAILBOX_LIST_PATH_TYPE_MAILBOX,
201437e07fd40d296377cc20ed1dab1f2777544aTimo Sirainen if ((_list->flags & MAILBOX_LIST_FLAG_NO_MAIL_FILES) != 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 ret = mailbox_list_delete_mailbox_nonrecursive(_list, name,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (ret == 0 || (_list->props & MAILBOX_LIST_PROP_AUTOCREATE_DIRS) != 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (index_list_delete_entry(list, name, TRUE) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_dir(struct mailbox_list *_list, const char *name)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct index_mailbox_list *list = (struct index_mailbox_list *)_list;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_delete_entry(list, name, FALSE)) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_EXISTS,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Mailbox has children, delete them first");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_delete_symlink(struct mailbox_list *_list,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_set_error(_list, MAIL_ERROR_NOTPOSSIBLE,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Symlinks not supported");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_rename_mailbox(struct mailbox_list *_oldlist, const char *oldname,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen struct mailbox_list *_newlist, const char *newname)
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 mailbox_list_set_error(_oldlist, MAIL_ERROR_NOTPOSSIBLE,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen "Renaming not supported across namespaces.");
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if ((ret = index_list_get_node(list, oldname, &oldnode)) < 0) {
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen (void)mailbox_list_index_sync_end(&sync_ctx, FALSE);
31159b598c4188211ff8f292daad1d23ee5db3cbTimo Sirainen mailbox_list_set_error(&list->list, MAIL_ERROR_NOTFOUND,
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 newseq = mailbox_list_index_sync_name(sync_ctx, newname,
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 /* copy all the data from old node to new node */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen newnode->children = oldnode->children; oldnode->children = NULL;
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen for (child = newnode->children; child != NULL; child = child->next)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen /* remove the old node from existence */
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mailbox_list_index_node_unlink(sync_ctx->ilist, oldnode);
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 mail_index_lookup_ext(sync_ctx->view, newseq, sync_ctx->ilist->ext_id,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen mail_index_update_ext(sync_ctx->trans, oldseq,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen return mailbox_list_index_sync_end(&sync_ctx, TRUE);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenindex_list_iter_init(struct mailbox_list *list,
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen const char *const *patterns,
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen if ((flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0) {
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen return mailbox_list_subscriptions_iter_init(list, patterns,
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 array_create(&ctx->module_contexts, pool, sizeof(void *), 5);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic const struct mailbox_info *
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainenindex_list_iter_next(struct mailbox_list_iterate_context *ctx)
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0)
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen return mailbox_list_subscriptions_iter_next(ctx);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenstatic int index_list_iter_deinit(struct mailbox_list_iterate_context *ctx)
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen if ((ctx->flags & MAILBOX_LIST_ITER_SELECT_SUBSCRIBED) != 0)
90a2c5f48c5f88f07bbf0477e3023d2099252b92Timo Sirainen return mailbox_list_subscriptions_iter_deinit(ctx);
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen .mailbox_name_max_length = MAILBOX_LIST_NAME_MAX_LENGTH,
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainenvoid mailbox_list_index_backend_init_mailbox(struct mailbox *box)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen if (strcmp(box->list->name, MAILBOX_LIST_NAME_INDEX) != 0)
e0aff4c7e3336ec4b5edbcfc3a72e1e118603ee2Timo Sirainen box->v.create_box = index_list_mailbox_create;