index-mailbox-list.c revision 7761758f43d6150be4b07f4c54457ce662f78c4c
a8c5a86d183db25a57bf193c06b41e092ec2e151Timo Sirainen/* Copyright (C) 2006-2007 Timo Sirainen */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "lib.h"
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen#include "ioloop.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "array.h"
ea5f188fc29dfaa0c4071e6413e16e1d04263722Timo Sirainen#include "file-lock.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "imap-match.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-index.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "mail-storage.h"
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen#include "mailbox-tree.h"
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen#include "mailbox-list-index.h"
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include "index-mailbox-list.h"
18565c69efcd7db003dbf27cf625ed822e889fb1Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <stdlib.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <time.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#include <sys/stat.h>
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen/* min 2 seconds */
d22301419109ed4a38351715e6760011421dadecTimo Sirainen#define MAILBOX_LIST_SYNC_SECS 2
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstruct index_mailbox_list_module index_mailbox_list_module =
d22301419109ed4a38351715e6760011421dadecTimo Sirainen MODULE_CONTEXT_INIT(&mailbox_list_module_register);
d22301419109ed4a38351715e6760011421dadecTimo Sirainenstatic void (*index_next_hook_mailbox_list_created)(struct mailbox_list *list);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic int
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainenindex_mailbox_view_sync(struct index_mailbox_list_iterate_context *ctx)
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen{
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainen struct mail_index_view_sync_ctx *sync_ctx;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen struct mail_index_view_sync_rec sync_rec;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen int ret;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen if (mail_index_view_sync_begin(ctx->mail_view, 0,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen &sync_ctx) < 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen mailbox_list_set_internal_error(ctx->ctx.list);
af1f4b17a92ca7b2661737e65c7849df289d3070Timo Sirainen return -1;
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen while ((ret = mail_index_view_sync_next(sync_ctx, &sync_rec)) > 0) ;
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mail_index_view_sync_end(&sync_ctx);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen return ret;
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen}
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
4b41116563110d00330896a568eff1078c382827Timo Sirainenstatic int
992a13add4eea0810e4db0f042a595dddf85536aTimo Sirainenindex_mailbox_list_is_synced(struct index_mailbox_list_iterate_context *ctx)
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen{
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const struct mail_index_header *hdr;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen struct stat st;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *path = ctx->ctx.list->set.root_dir;
ebe6df72f1309135f02b6a4d2aef1e81a073f91cTimo Sirainen
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen if (index_mailbox_view_sync(ctx) < 0)
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen return -1;
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen /* FIXME: single sync_stamp works only with maildir++ */
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen if (stat(path, &st) < 0) {
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen mailbox_list_set_critical(ctx->ctx.list,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen "stat(%s) failed: %m", path);
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen return -1;
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen /*
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen if mtime is older than 2 secs, we set the first bit on
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if mtime is 0-2 secs old, we set the first bit off.
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen this way we'll always do a resync later when syncing a recently
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen changed directory. if the directory changes while we're syncing it
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen we'll resync it again later.
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen this would work with 1 second difference if we didn't store the
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen dirtyness flag in the stamp's first bit.
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen */
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (st.st_mtime < ioloop_time - MAILBOX_LIST_SYNC_SECS)
d22301419109ed4a38351715e6760011421dadecTimo Sirainen st.st_mtime |= 1;
1f1ee8db68d9ae1604350801cd8dc33ebe29fe8aTimo Sirainen else
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen st.st_mtime &= ~1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen ctx->sync_stamp = st.st_mtime;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen hdr = mail_index_get_header(ctx->mail_view);
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen return hdr->sync_stamp == ctx->sync_stamp;
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen}
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainenstatic void mask_parse(struct mailbox_list *list, const char *mask,
86c6b2546b0bbfce326583f14d05f59674a6d861Timo Sirainen const char **prefix_r, int *recurse_level_r)
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen{
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen char sep = list->hierarchy_sep;
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen const char *prefix_start, *prefix_end;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen bool seen_wildcards = FALSE;
597dce34068d603fb759b4dff404b34049213e51Timo Sirainen int recurse_level = 0;
63a61b7a739ae0f3f520215137d9c50f94d0f34fTimo Sirainen
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen prefix_start = prefix_end = mask;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen for (; *mask != '\0'; mask++) {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (*mask == '%')
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen seen_wildcards = TRUE;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen else if (*mask == '*') {
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen recurse_level = -1;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen break;
4b41116563110d00330896a568eff1078c382827Timo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen if (*mask == sep) {
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen if (!seen_wildcards)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen prefix_end = mask;
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen recurse_level++;
6060b7c8edf8fce73470d0df6a2479b69b01c537Timo Sirainen }
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen }
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen *prefix_r = prefix_start == prefix_end ? "" :
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen t_strdup_until(prefix_start, prefix_end);
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen *recurse_level_r = recurse_level;
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen}
4b41116563110d00330896a568eff1078c382827Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenstatic struct mailbox_list_iterate_context *
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenindex_mailbox_list_iter_init(struct mailbox_list *list, const char *mask,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen enum mailbox_list_iter_flags flags)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen{
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(list);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen struct index_mailbox_list_iterate_context *ctx;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen enum mailbox_list_sync_flags sync_flags;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const char *prefix;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen int recurse_level;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ctx = i_new(struct index_mailbox_list_iterate_context, 1);
4b41116563110d00330896a568eff1078c382827Timo Sirainen ctx->ctx.list = list;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx->ctx.flags = flags;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ctx->glob = imap_match_init(default_pool, mask, TRUE,
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen list->hierarchy_sep);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen ctx->mail_view = mail_index_view_open(ilist->mail_index);
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen ctx->view = mailbox_list_index_view_init(ilist->list_index,
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen ctx->mail_view);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if ((flags & MAILBOX_LIST_ITER_RAW_LIST) != 0) {
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen /* Ignore indexes completely */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx->backend_ctx = ilist->module_ctx.super.
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen iter_init(list, mask, flags);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen } else if (index_mailbox_list_is_synced(ctx) > 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* synced, list from index */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mask_parse(list, mask, &prefix, &recurse_level);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen ctx->info_pool =
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen pool_alloconly_create("mailbox name pool", 128);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen ctx->iter_ctx = mailbox_list_index_iterate_init(ctx->view,
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen prefix,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen recurse_level);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen ctx->recurse_level = recurse_level;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen ctx->prefix = *prefix == '\0' ? i_strdup("") :
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen i_strdup_printf("%s%c", prefix, list->hierarchy_sep);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen } else {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen /* FIXME: this works nicely with maildir++, but not others */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen sync_flags = MAILBOX_LIST_SYNC_FLAG_RECURSIVE;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (strchr(mask, '*') != NULL)
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen ctx->recurse_level = -1;
915bb1572a406d30013ed3ee83fba7082a6d1baePhil Carmody else {
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen ctx->mailbox_tree =
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen mailbox_tree_init(list->hierarchy_sep);
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen }
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen ctx->info_pool =
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen pool_alloconly_create("mailbox name pool", 128);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen if (mailbox_list_index_sync_init(ilist->list_index, "",
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen sync_flags,
e6aa82aeb50948cb47a45a1b61a9c16d6a162388Timo Sirainen &ctx->sync_ctx) == 0) {
e6aa82aeb50948cb47a45a1b61a9c16d6a162388Timo Sirainen mask = "*";
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen prefix = "";
e6aa82aeb50948cb47a45a1b61a9c16d6a162388Timo Sirainen ctx->trans = mailbox_list_index_sync_get_transaction(
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainen ctx->sync_ctx);
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen }
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen ctx->backend_ctx = ilist->module_ctx.super.
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen iter_init(list, mask, flags);
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainen }
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainen return &ctx->ctx;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen}
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainenstatic enum mailbox_info_flags
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainenindex_mailbox_list_index_flags_translate(enum mailbox_list_index_flags flags)
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen{
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen enum mailbox_info_flags info_flags = 0;
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen if ((flags & MAILBOX_LIST_INDEX_FLAG_CHILDREN) != 0)
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen info_flags |= MAILBOX_CHILDREN;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if ((flags & MAILBOX_LIST_INDEX_FLAG_NOCHILDREN) != 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen info_flags |= MAILBOX_NOCHILDREN;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if ((flags & MAILBOX_LIST_INDEX_FLAG_NONEXISTENT) != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen info_flags |= MAILBOX_NONEXISTENT;
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if ((flags & MAILBOX_LIST_INDEX_FLAG_NOSELECT) != 0)
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen info_flags |= MAILBOX_NOSELECT;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen return info_flags;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen}
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstatic enum mailbox_list_index_flags
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenindex_mailbox_list_info_flags_translate(enum mailbox_info_flags info_flags)
4b41116563110d00330896a568eff1078c382827Timo Sirainen{
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen enum mailbox_list_index_flags flags = 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if ((info_flags & MAILBOX_CHILDREN) != 0)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen flags |= MAILBOX_LIST_INDEX_FLAG_CHILDREN;
ee3e01f75b1db691bf20dd4e2558965421b8f937Timo Sirainen if ((info_flags & MAILBOX_NOCHILDREN) != 0)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen flags |= MAILBOX_LIST_INDEX_FLAG_NOCHILDREN;
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen if ((info_flags & MAILBOX_NONEXISTENT) != 0)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen flags |= MAILBOX_LIST_INDEX_FLAG_NONEXISTENT;
ea5f188fc29dfaa0c4071e6413e16e1d04263722Timo Sirainen if ((info_flags & MAILBOX_NOSELECT) != 0)
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen flags |= MAILBOX_LIST_INDEX_FLAG_NOSELECT;
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen return flags;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen}
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen/* skip nonexistent mailboxes when finding with "*" */
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen#define info_flags_match(ctx, info) \
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen (((info)->flags & MAILBOX_NONEXISTENT) == 0 || \
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen (ctx)->recurse_level >= 0)
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainenstatic int iter_next_nonsync(struct index_mailbox_list_iterate_context *ctx,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen struct mailbox_info **info_r)
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen{
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(ctx->ctx.list);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen struct mailbox_list_index_info iinfo;
36f4f01d56ec9156ab75bc2047a8388192df3178Timo Sirainen const struct mail_index_record *rec;
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen uint32_t seq;
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen int ret;
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen /* find the next matching mailbox */
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen do {
cbcde6379f1b0b27bdefc4b11eec93ad69e459d4Timo Sirainen p_clear(ctx->info_pool);
f140f88a5ab3e2194f214c11f9f418559e949c83Timo Sirainen ret = mailbox_list_index_iterate_next(ctx->iter_ctx, &iinfo);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen if (ret <= 0) {
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen *info_r = NULL;
e48c10b9db945fd72e2315e3ec343174fa55c7c7Timo Sirainen return ret;
e48c10b9db945fd72e2315e3ec343174fa55c7c7Timo Sirainen }
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen ctx->info.name = *ctx->prefix == '\0' ? iinfo.name :
fc22ecbb03396eda9270472446a6065a986a43e0Timo Sirainen p_strconcat(ctx->info_pool, ctx->prefix,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen iinfo.name, NULL);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen } while (imap_match(ctx->glob, ctx->info.name) != IMAP_MATCH_YES);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* get the mailbox's flags */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (mail_index_lookup_uid_range(ctx->mail_view, iinfo.uid, iinfo.uid,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen &seq, &seq) < 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen return -1;
915bb1572a406d30013ed3ee83fba7082a6d1baePhil Carmody if (seq == 0) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mailbox_list_index_set_corrupted(ilist->list_index,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen "Desynced: Record expunged from mail index");
d22301419109ed4a38351715e6760011421dadecTimo Sirainen return -1;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen if (mail_index_lookup(ctx->mail_view, seq, &rec) < 0)
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen return -1;
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen ctx->info.flags = index_mailbox_list_index_flags_translate(rec->flags);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
7bd301fdbfefe7cef3576d19ece29c75ebe53bafTimo Sirainen /* do some sanity checks to the flags */
7bd301fdbfefe7cef3576d19ece29c75ebe53bafTimo Sirainen if ((ctx->info.flags & MAILBOX_CHILDREN) != 0 &&
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen (ctx->info.flags & MAILBOX_NOCHILDREN) != 0) {
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen mailbox_list_index_set_corrupted(ilist->list_index,
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen "Mail index has both children and nochildren flags");
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen return -1;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if ((ctx->info.flags & MAILBOX_NOCHILDREN) != 0 &&
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen iinfo.has_children) {
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen mailbox_list_index_set_corrupted(ilist->list_index,
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen "Desynced: Children flags wrong in mail index");
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen return -1;
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen }
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen if (!info_flags_match(ctx, &ctx->info))
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return iter_next_nonsync(ctx, info_r);
d22301419109ed4a38351715e6760011421dadecTimo Sirainen
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen *info_r = &ctx->info;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen return 0;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen}
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainenstatic struct mailbox_info *
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainenmailbox_info_move_to_parent(struct index_mailbox_list_iterate_context *ctx,
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen const struct mailbox_info *info)
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen{
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen const char *p, *name = info->name;
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen char sep = ctx->ctx.list->hierarchy_sep;
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen p_clear(ctx->info_pool);
767cd7e92a46ca7c0dc4823936750b2bf2eb99e3Timo Sirainen
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen t_push();
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen while ((p = strrchr(name, sep)) != NULL) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen name = t_strdup_until(name, p);
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen if (imap_match(ctx->glob, name) == IMAP_MATCH_YES) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen ctx->info.name = p_strdup(ctx->info_pool, name);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen break;
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen }
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen t_pop();
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (p == NULL)
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen i_unreached();
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
d22301419109ed4a38351715e6760011421dadecTimo Sirainen ctx->info.flags = MAILBOX_CHILDREN | MAILBOX_NONEXISTENT;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen return &ctx->info;
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen}
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainenstatic struct mailbox_info *
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainenindex_mailbox_list_iter_next(struct mailbox_list_iterate_context *_ctx)
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen{
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen struct index_mailbox_list_iterate_context *ctx =
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen (struct index_mailbox_list_iterate_context *)_ctx;
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(_ctx->list);
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen struct mailbox_info *info;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen uint32_t seq, flags;
a1808be0774cbcb28fec45341aabf803ec44bae5Timo Sirainen enum imap_match_result match;
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen if (ctx->iter_ctx != NULL) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (iter_next_nonsync(ctx, &info) < 0) {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen ctx->failed = TRUE;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return NULL;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen return info;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen }
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen do {
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen info = ilist->module_ctx.super.iter_next(ctx->backend_ctx);
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen if (info == NULL || ctx->sync_ctx == NULL)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen return info;
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen /* if the sync fails, just ignore it. we don't require synced
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen indexes to be able to return valid output. */
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen if (mailbox_list_index_sync_more(ctx->sync_ctx, info->name,
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen &seq) == 0) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen flags = index_mailbox_list_info_flags_translate(
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen info->flags);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mail_index_update_flags(ctx->trans, seq, MODIFY_REPLACE,
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen flags);
a5c8dc283ef673fcdae158513b8032e74b45f59aTimo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen match = imap_match(ctx->glob, info->name);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (match == IMAP_MATCH_PARENT) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen info = mailbox_info_move_to_parent(ctx, info);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen match = IMAP_MATCH_YES;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen }
d22301419109ed4a38351715e6760011421dadecTimo Sirainen if (ctx->recurse_level >= 0) {
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen /* no "*" wildcards, keep track of what mailboxes we
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen have returned so we don't return same parents
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen multiple times. */
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen bool created;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen (void)mailbox_tree_get(ctx->mailbox_tree,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen info->name, &created);
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen if (!created)
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen match = IMAP_MATCH_NO;
4b41116563110d00330896a568eff1078c382827Timo Sirainen }
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen } while (match != IMAP_MATCH_YES || !info_flags_match(ctx, info));
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen return info;
f480b30abdddf6f1beb8a2c5b1ce4bf8999400dbTimo Sirainen}
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainenstatic int
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenindex_mailbox_list_iter_deinit(struct mailbox_list_iterate_context *_ctx)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen{
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct index_mailbox_list_iterate_context *ctx =
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen (struct index_mailbox_list_iterate_context *)_ctx;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(_ctx->list);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen int ret = ctx->failed ? -1 : 0;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (ctx->iter_ctx != NULL)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mailbox_list_index_iterate_deinit(&ctx->iter_ctx);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (ctx->info_pool != NULL)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen pool_unref(ctx->info_pool);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (ctx->mailbox_tree != NULL)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mailbox_tree_deinit(&ctx->mailbox_tree);
8f017a40470ef2f4b530000d947a8bce44350a5eTimo Sirainen
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen if (ctx->mail_view != NULL)
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen mail_index_view_close(&ctx->mail_view);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (ctx->view != NULL)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mailbox_list_index_view_deinit(&ctx->view);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (ctx->sync_ctx != NULL) {
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen /* FIXME: single sync_stamp works only with maildir++ */
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mail_index_update_header(ctx->trans,
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen offsetof(struct mail_index_header, sync_stamp),
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen &ctx->sync_stamp, sizeof(ctx->sync_stamp), TRUE);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen ret = ilist->module_ctx.super.iter_deinit(ctx->backend_ctx);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen if (ret < 0)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen mailbox_list_index_sync_rollback(&ctx->sync_ctx);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen else {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* index updates aren't that important. if the commit
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen fails, we've still returned full output. */
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen (void)mailbox_list_index_sync_commit(&ctx->sync_ctx);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen }
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen } else if (ctx->backend_ctx != NULL) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ret = ilist->module_ctx.super.iter_deinit(ctx->backend_ctx);
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen }
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen imap_match_deinit(&ctx->glob);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen i_free(ctx->prefix);
7631f16156aca373004953fe6b01a7f343fb47e0Timo Sirainen i_free(ctx);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen return ret;
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen}
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainenstatic void index_mailbox_list_deinit(struct mailbox_list *list)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen{
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(list);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mailbox_list_index_free(&ilist->list_index);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mailbox_list_index_view_deinit(&ilist->list_sync_view);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen mail_index_free(&ilist->mail_index);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen ilist->module_ctx.super.deinit(list);
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen}
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainenstatic int index_mailbox_list_open_indexes(struct mailbox_list *list,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen const char *dir)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen{
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen struct index_mailbox_list *ilist = INDEX_LIST_CONTEXT(list);
aa247243412a49f9bdebf7255e131dc6ece4ed46Timo Sirainen const char *path;
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen enum mail_index_open_flags index_flags;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen enum mail_storage_flags storage_flags;
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen int ret;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* FIXME: a bit ugly way to get the flags, but this will do for now.. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index_flags = MAIL_INDEX_OPEN_FLAG_CREATE;
a757f31393b9d6fc7760a9dec8363404ab3ae576Timo Sirainen storage_flags = *list->set.mail_storage_flags;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#ifndef MMAP_CONFLICTS_WRITE
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen if ((storage_flags & MAIL_STORAGE_FLAG_MMAP_DISABLE) != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen#endif
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen index_flags |= MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen if (mail_index_open(ilist->mail_index, index_flags,
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen *list->set.lock_method) < 0) {
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen if (mail_index_move_to_memory(ilist->mail_index) < 0) {
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen /* try opening once more. it should be created
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen directly into memory now. */
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen ret = mail_index_open(ilist->mail_index, index_flags,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen *list->set.lock_method);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (ret <= 0) {
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* everything failed. there's a bug in the
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen code, but just work around it by disabling
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen the index completely */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen return -1;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen }
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen }
225e82df5dd1e765f4e52b80c954558f00e5a7dfTimo Sirainen }
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainen
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen path = t_strconcat(dir, "/"MAILBOX_LIST_INDEX_NAME, NULL);
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen ilist->list_index = mailbox_list_index_alloc(path, list->hierarchy_sep,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ilist->mail_index);
if (mailbox_list_index_open_or_create(ilist->list_index) < 0) {
/* skip indexing */
mailbox_list_index_free(&ilist->list_index);
return -1;
}
ilist->list_sync_view = mailbox_list_index_view_init(ilist->list_index,
NULL);
return 0;
}
static void index_mailbox_list_created(struct mailbox_list *list)
{
struct index_mailbox_list *ilist = NULL;
const char *dir;
/* FIXME: for now we only work with maildir++ */
dir = mailbox_list_get_path(list, NULL, MAILBOX_LIST_PATH_TYPE_INDEX);
if (*dir == '\0' || getenv("MAILBOX_LIST_INDEX_DISABLE") != NULL ||
strcmp(list->name, "maildir++") != 0) {
/* reserve the module context anyway, so syncing code knows
that the index is disabled */
MODULE_CONTEXT_SET(list, index_mailbox_list_module, ilist);
return;
}
ilist = p_new(list->pool, struct index_mailbox_list, 1);
ilist->module_ctx.super = list->v;
list->v.deinit = index_mailbox_list_deinit;
list->v.iter_init = index_mailbox_list_iter_init;
list->v.iter_deinit = index_mailbox_list_iter_deinit;
list->v.iter_next = index_mailbox_list_iter_next;
MODULE_CONTEXT_SET(list, index_mailbox_list_module, ilist);
ilist->mail_index = mail_index_alloc(dir, MAIL_INDEX_PREFIX);
/* sync_init allocates the extensions. do it here before opening the
index files, so that our initial memory pool size guesses are a
bit more optimal */
index_mailbox_list_sync_init_list(list);
if (index_mailbox_list_open_indexes(list, dir) < 0) {
list->v = ilist->module_ctx.super;
mail_index_free(&ilist->mail_index);
MODULE_CONTEXT_UNSET(list, index_mailbox_list_module);
}
}
void index_mailbox_list_init(void); /* called in mailbox-list-register.c */
void index_mailbox_list_init(void)
{
index_next_hook_mailbox_list_created = hook_mailbox_list_created;
hook_mailbox_list_created = index_mailbox_list_created;
index_mailbox_list_sync_init();
}