bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2003-2018 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen#include "ioloop.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
1dd875d96ab5640f78250079961c10e99ed4aa79Timo Sirainen#include "eacces-error.h"
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen#include "hash.h"
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen#include "str-sanitize.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mmap-util.h"
89b548af722113acb5d63dfffb44423cb60f91e4Timo Sirainen#include "nfs-workarounds.h"
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#include "read-full.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "write-full.h"
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen#include "mail-index-alloc-cache.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index-private.h"
66ae183b6e895216037bd921367670f4b0665911Timo Sirainen#include "mail-index-view-private.h"
e86d0d34fe365da4c7ca4312d575bfcbf3a01c0eTimo Sirainen#include "mail-index-sync-private.h"
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen#include "mail-index-modseq.h"
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen#include "mail-transaction-log-private.h"
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi#include "mail-transaction-log-view-private.h"
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen#include "mail-cache.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stdio.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <stddef.h>
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include <time.h>
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen#include <sys/stat.h>
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainenstruct mail_index_module_register mail_index_module_register = { 0 };
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainenstruct event_category event_category_index = {
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen .name = "index",
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen};
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainenstatic void mail_index_close_nonopened(struct mail_index *index);
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainenstatic const struct mail_index_optimization_settings default_optimization_set = {
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen .index = {
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen .rewrite_min_log_bytes = 8 * 1024,
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen .rewrite_max_log_bytes = 128 * 1024,
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen },
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen .log = {
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen .min_size = 32 * 1024,
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen .max_size = 1024 * 1024,
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen .min_age_secs = 5 * 60,
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen .log2_max_age_secs = 3600 * 24 * 2,
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen },
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .cache = {
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .unaccessed_field_drop_secs = 3600 * 24 * 30,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .record_max_size = 64 * 1024,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .compress_min_size = 32 * 1024,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .compress_delete_percentage = 20,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .compress_continued_percentage = 200,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen .compress_header_continue_count = 4,
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen },
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen};
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainenstruct mail_index *mail_index_alloc(struct event *parent_event,
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen const char *dir, const char *prefix)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index *index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index = i_new(struct mail_index, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->dir = i_strdup(dir);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->prefix = i_strdup(prefix);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->fd = -1;
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen index->event = event_create(parent_event);
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen event_add_category(index->event, &event_category_index);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
8fa41238067c854435884c459963fde6f8c6436bTimo Sirainen index->extension_pool =
8fa41238067c854435884c459963fde6f8c6436bTimo Sirainen pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen p_array_init(&index->extensions, index->extension_pool, 5);
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_array_init(&index->sync_lost_handlers, 4);
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen i_array_init(&index->module_contexts,
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen I_MIN(5, mail_index_module_register.id));
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->mode = 0600;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->gid = (gid_t)-1;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen index->lock_method = FILE_LOCK_METHOD_FCNTL;
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen index->max_lock_timeout_secs = UINT_MAX;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen index->optimization_set = default_optimization_set;
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen index->keywords_ext_id =
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS,
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen 128, 2, 1);
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen i_array_init(&index->keywords, 16);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create(&index->keywords_hash, index->keywords_pool, 0,
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen strcase_hash, strcasecmp);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen index->log = mail_transaction_log_alloc(index);
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen mail_index_modseq_init(index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_free(struct mail_index **_index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen struct mail_index *index = *_index;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen *_index = NULL;
9f32b9444d2a6db8f556d2c49ffceab1a59791ffTimo Sirainen
9f32b9444d2a6db8f556d2c49ffceab1a59791ffTimo Sirainen i_assert(index->open_count == 0);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_transaction_log_free(&index->log);
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen hash_table_destroy(&index->keywords_hash);
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen pool_unref(&index->extension_pool);
648d24583c1574441c4fa0331a90bd4d6e7996c5Timo Sirainen pool_unref(&index->keywords_pool);
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen array_free(&index->sync_lost_handlers);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_free(&index->keywords);
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen array_free(&index->module_contexts);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen event_unref(&index->event);
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen i_free(index->cache_dir);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen i_free(index->ext_hdr_init_data);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen i_free(index->gid_origin);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(index->error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(index->dir);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(index->prefix);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainenvoid mail_index_set_cache_dir(struct mail_index *index, const char *dir)
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen{
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen i_free(index->cache_dir);
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen index->cache_dir = i_strdup(dir);
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen}
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainenvoid mail_index_set_fsync_mode(struct mail_index *index,
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen enum fsync_mode mode,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen enum mail_index_fsync_mask mask)
80fc743146da5130de34174cdaad2576f103723fTimo Sirainen{
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen index->fsync_mode = mode;
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen index->fsync_mask = mask;
80fc743146da5130de34174cdaad2576f103723fTimo Sirainen}
80fc743146da5130de34174cdaad2576f103723fTimo Sirainen
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainenbool mail_index_use_existing_permissions(struct mail_index *index)
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen{
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen struct stat st;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen
e704b4ab2c204e538f87b2a90aca68c0deac6296Timo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index))
e704b4ab2c204e538f87b2a90aca68c0deac6296Timo Sirainen return FALSE;
e704b4ab2c204e538f87b2a90aca68c0deac6296Timo Sirainen
96595bf98ed9264b2b35700a640daf53debc3082Timo Sirainen if (stat(index->dir, &st) < 0) {
96595bf98ed9264b2b35700a640daf53debc3082Timo Sirainen if (errno != ENOENT)
96595bf98ed9264b2b35700a640daf53debc3082Timo Sirainen i_error("stat(%s) failed: %m", index->dir);
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen return FALSE;
96595bf98ed9264b2b35700a640daf53debc3082Timo Sirainen }
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen index->mode = st.st_mode & 0666;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen if (S_ISDIR(st.st_mode) && (st.st_mode & S_ISGID) != 0) {
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen /* directory's GID is used automatically for new files */
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen index->gid = (gid_t)-1;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen } else if ((st.st_mode & 0070) >> 3 == (st.st_mode & 0007)) {
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen /* group has same permissions as world, so don't bother
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen changing it */
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen index->gid = (gid_t)-1;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen } else if (getegid() == st.st_gid) {
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen /* using our own gid, no need to change it */
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen index->gid = (gid_t)-1;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen } else {
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen index->gid = st.st_gid;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen }
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen i_free(index->gid_origin);
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen if (index->gid != (gid_t)-1)
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen index->gid_origin = i_strdup("preserved existing GID");
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen return TRUE;
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen}
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mode_t mode, gid_t gid, const char *gid_origin)
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen{
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen index->mode = mode & 0666;
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen index->gid = gid;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen i_free(index->gid_origin);
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen index->gid_origin = i_strdup(gid_origin);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen}
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainenvoid mail_index_set_lock_method(struct mail_index *index,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen enum file_lock_method lock_method,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen unsigned int max_timeout_secs)
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen{
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen index->lock_method = lock_method;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen index->max_lock_timeout_secs = max_timeout_secs;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen}
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainenvoid mail_index_set_optimization_settings(struct mail_index *index,
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen const struct mail_index_optimization_settings *set)
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen{
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen struct mail_index_optimization_settings *dest =
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen &index->optimization_set;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen /* index */
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen if (set->index.rewrite_min_log_bytes != 0)
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen dest->index.rewrite_min_log_bytes = set->index.rewrite_min_log_bytes;
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen if (set->index.rewrite_max_log_bytes != 0)
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen dest->index.rewrite_max_log_bytes = set->index.rewrite_max_log_bytes;
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen /* log */
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen if (set->log.min_size != 0)
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen dest->log.min_size = set->log.min_size;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen if (set->log.max_size != 0)
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen dest->log.max_size = set->log.max_size;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen if (set->log.min_age_secs != 0)
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen dest->log.min_age_secs = set->log.min_age_secs;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen if (set->log.log2_max_age_secs != 0)
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen dest->log.log2_max_age_secs = set->log.log2_max_age_secs;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* cache */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen if (set->cache.unaccessed_field_drop_secs != 0)
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dest->cache.unaccessed_field_drop_secs =
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen set->cache.unaccessed_field_drop_secs;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen if (set->cache.compress_min_size != 0)
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dest->cache.compress_min_size = set->cache.compress_min_size;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen if (set->cache.compress_delete_percentage != 0)
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dest->cache.compress_delete_percentage =
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen set->cache.compress_delete_percentage;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen if (set->cache.compress_continued_percentage != 0)
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dest->cache.compress_continued_percentage =
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen set->cache.compress_continued_percentage;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen if (set->cache.compress_header_continue_count != 0)
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dest->cache.compress_header_continue_count =
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen set->cache.compress_header_continue_count;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen if (set->cache.record_max_size != 0)
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen dest->cache.record_max_size = set->cache.record_max_size;
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen}
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainenvoid mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen const void *data, size_t size)
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen{
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen const struct mail_index_registered_ext *rext;
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen i_assert(index->ext_hdr_init_data == NULL ||
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen index->ext_hdr_init_id == ext_id);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen rext = array_idx(&index->extensions, ext_id);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen i_assert(rext->hdr_size == size);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen index->ext_hdr_init_id = ext_id;
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen i_free(index->ext_hdr_init_data);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen index->ext_hdr_init_data = i_malloc(size);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen memcpy(index->ext_hdr_init_data, data, size);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen}
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint32_t default_hdr_size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t default_record_size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t default_record_align)
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen{
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen struct mail_index_registered_ext rext;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen uint32_t ext_id;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen if (*name == '\0' || strcmp(name, str_sanitize(name, -1)) != 0)
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen i_panic("mail_index_ext_register(%s): Invalid name", name);
ffd9a1898a18fadfc5dce399162c25d50548f905Timo Sirainen
1e923fcf497665fe071a154c31fb452766b0b2deTimo Sirainen if (default_record_size != 0 && default_record_align == 0) {
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen i_panic("mail_index_ext_register(%s): "
1e923fcf497665fe071a154c31fb452766b0b2deTimo Sirainen "Invalid record alignment", name);
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen }
d161e3c2cde2bd8d5917840f68823a2259ed426eTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen if (mail_index_ext_lookup(index, name, &ext_id))
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen return ext_id;
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&rext);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext.name = p_strdup(index->extension_pool, name);
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen rext.index_idx = array_count(&index->extensions);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext.hdr_size = default_hdr_size;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext.record_size = default_record_size;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext.record_align = default_record_align;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen array_append(&index->extensions, &rext, 1);
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen return rext.index_idx;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen}
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainenvoid mail_index_ext_register_resize_defaults(struct mail_index *index,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint32_t ext_id,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint32_t default_hdr_size,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint16_t default_record_size,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint16_t default_record_align)
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen{
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen struct mail_index_registered_ext *rext;
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen rext->hdr_size = default_hdr_size;
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen rext->record_size = default_record_size;
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen rext->record_align = default_record_align;
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen}
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainenbool mail_index_ext_lookup(struct mail_index *index, const char *name,
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen uint32_t *ext_id_r)
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen{
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen const struct mail_index_registered_ext *extensions;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen unsigned int i, count;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen extensions = array_get(&index->extensions, &count);
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen for (i = 0; i < count; i++) {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen if (strcmp(extensions[i].name, name) == 0) {
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen *ext_id_r = i;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen return TRUE;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen }
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen }
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen *ext_id_r = (uint32_t)-1;
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen return FALSE;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen}
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen uint32_t ext_id, bool call_always,
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen mail_index_expunge_handler_t *cb,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen void *context)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen struct mail_index_registered_ext *rext;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
7d7b5c98f086ffa8ac9c90f21db17748ca607202Timo Sirainen i_assert(rext->expunge_handler == NULL || rext->expunge_handler == cb);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen rext->expunge_handler = cb;
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen rext->expunge_context = context;
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen rext->expunge_handler_call_always = call_always;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen uint32_t ext_id)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen{
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen struct mail_index_registered_ext *rext;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen i_assert(rext->expunge_handler != NULL);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen rext->expunge_handler = NULL;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen mail_index_sync_handler_t *cb,
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen enum mail_index_sync_handler_type type)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen{
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen struct mail_index_registered_ext *rext;
5626ae5e3316eced244adb6485c0927f1c7fdc41Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen i_assert(rext->sync_handler.callback == NULL);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext->sync_handler.callback = cb;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext->sync_handler.type = type;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen}
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen uint32_t ext_id)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen{
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen struct mail_index_registered_ext *rext;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen i_assert(rext->sync_handler.callback != NULL);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext->sync_handler.callback = NULL;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen rext->sync_handler.type = 0;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen mail_index_sync_lost_handler_t *cb)
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen{
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen}
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen mail_index_sync_lost_handler_t *cb)
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen{
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen mail_index_sync_lost_handler_t *const *handlers;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen unsigned int i, count;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen for (i = 0; i < count; i++) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen if (handlers[i] == cb) {
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen break;
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen }
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen}
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
6825360d446542046757b06064282301c4c6b27cTimo Sirainen const char *keyword, unsigned int *idx_r)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen char *key;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen void *value;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen Keywords are never removed from it, so the index values are valid
6a04c5112961c5f4fb2d2f25192b3dc424d62ad0Timo Sirainen for the lifetime of the mail_index. */
3ccab0bac68040f179a7de45c516cec258e28fdbTimo Sirainen if (hash_table_lookup_full(index->keywords_hash, keyword,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen &key, &value)) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return TRUE;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen *idx_r = UINT_MAX;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen return FALSE;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen}
6825360d446542046757b06064282301c4c6b27cTimo Sirainen
6825360d446542046757b06064282301c4c6b27cTimo Sirainenvoid mail_index_keyword_lookup_or_create(struct mail_index *index,
6825360d446542046757b06064282301c4c6b27cTimo Sirainen const char *keyword,
6825360d446542046757b06064282301c4c6b27cTimo Sirainen unsigned int *idx_r)
6825360d446542046757b06064282301c4c6b27cTimo Sirainen{
6825360d446542046757b06064282301c4c6b27cTimo Sirainen char *keyword_dup;
6825360d446542046757b06064282301c4c6b27cTimo Sirainen
c8d093d149253fe8faec267c5057f45fe626f84cTimo Sirainen i_assert(*keyword != '\0');
c8d093d149253fe8faec267c5057f45fe626f84cTimo Sirainen
6825360d446542046757b06064282301c4c6b27cTimo Sirainen if (mail_index_keyword_lookup(index, keyword, idx_r))
6825360d446542046757b06064282301c4c6b27cTimo Sirainen return;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *idx_r = array_count(&index->keywords);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen hash_table_insert(index->keywords_hash, keyword_dup,
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen POINTER_CAST(*idx_r));
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_append(&index->keywords, &keyword, 1);
f5c53272acbe1517440aa9c277133babc887ee84Timo Sirainen
f5c53272acbe1517440aa9c277133babc887ee84Timo Sirainen /* keep the array NULL-terminated, but the NULL itself invisible */
31a574fda352ef4f71dbff9c30e15e4744e132c0Timo Sirainen array_append_zero(&index->keywords);
f5c53272acbe1517440aa9c277133babc887ee84Timo Sirainen array_delete(&index->keywords, array_count(&index->keywords)-1, 1);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return &index->keywords;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen}
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainenstruct mail_keywords *
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainenmail_index_keywords_create(struct mail_index *index,
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen const char *const keywords[])
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen{
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen struct mail_keywords *k;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen unsigned int src, dest, i, count;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen count = str_array_length(keywords);
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen if (count == 0) {
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen k = i_new(struct mail_keywords, 1);
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen k->index = index;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen k->refcount = 1;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen return k;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen }
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen /* @UNSAFE */
e7d0bea63a08b08c47c4b5c187d2cb7127859657Timo Sirainen k = i_malloc(MALLOC_ADD(sizeof(struct mail_keywords),
9c93b5764f84126b3362cd96da4bd9b4de078bc7Timo Sirainen MALLOC_MULTIPLY(sizeof(k->idx[0]), count)));
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen k->index = index;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen k->refcount = 1;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen /* look up the keywords from index. they're never removed from there
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen so we can permanently store indexes to them. */
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen for (src = dest = 0; src < count; src++) {
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen mail_index_keyword_lookup_or_create(index, keywords[src],
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen &k->idx[dest]);
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen /* ignore if this is a duplicate */
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen for (i = 0; i < src; i++) {
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen if (k->idx[i] == k->idx[dest])
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen break;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen }
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen if (i == src)
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen dest++;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen }
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen k->count = dest;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen return k;
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen}
4a09c57f1c66b4a8880bcc12b567bb42c3549f52Timo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenstruct mail_keywords *
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenmail_index_keywords_create_from_indexes(struct mail_index *index,
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen const ARRAY_TYPE(keyword_indexes)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen *keyword_indexes)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen{
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen struct mail_keywords *k;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen const unsigned int *indexes;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen unsigned int src, dest, i, count;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen indexes = array_get(keyword_indexes, &count);
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen if (count == 0) {
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k = i_new(struct mail_keywords, 1);
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k->index = index;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k->refcount = 1;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen return k;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen }
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen /* @UNSAFE */
e7d0bea63a08b08c47c4b5c187d2cb7127859657Timo Sirainen k = i_malloc(MALLOC_ADD(sizeof(struct mail_keywords),
9c93b5764f84126b3362cd96da4bd9b4de078bc7Timo Sirainen MALLOC_MULTIPLY(sizeof(k->idx[0]), count)));
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k->index = index;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k->refcount = 1;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen /* copy but skip duplicates */
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen for (src = dest = 0; src < count; src++) {
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen for (i = 0; i < src; i++) {
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen if (k->idx[i] == indexes[src])
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen break;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen }
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen if (i == src)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k->idx[dest++] = indexes[src];
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen }
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen k->count = dest;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen return k;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen}
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenvoid mail_index_keywords_ref(struct mail_keywords *keywords)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen{
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen keywords->refcount++;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen}
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainenvoid mail_index_keywords_unref(struct mail_keywords **_keywords)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen{
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen struct mail_keywords *keywords = *_keywords;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen i_assert(keywords->refcount > 0);
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen *_keywords = NULL;
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen if (--keywords->refcount == 0)
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen i_free(keywords);
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen}
3f2ad7b8c3a243dabcba469c8a331423d036f3fcTimo Sirainen
2a34e2be33f8a17d21384a5527ed9f75f4d270e0Timo Sirainenint mail_index_try_open_only(struct mail_index *index)
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen{
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_assert(index->fd == -1);
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* Note that our caller must close index->fd by itself. */
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen if (index->readonly)
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen errno = EACCES;
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen else {
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen index->fd = nfs_safe_open(index->filepath, O_RDWR);
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen index->readonly = FALSE;
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen if (index->fd == -1 && errno == EACCES) {
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen index->fd = open(index->filepath, O_RDONLY);
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen index->readonly = TRUE;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen if (index->fd == -1) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (errno != ENOENT) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_index_set_syscall_error(index, "open()");
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen /* have to create it */
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return 0;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return 1;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainenstatic int
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenmail_index_try_open(struct mail_index *index)
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen{
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen int ret;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
1e47cfede3a0b62654105daab00e97b5d660bc6bTimo Sirainen i_assert(index->fd == -1);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index))
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen return 0;
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen if (ret == 0) {
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen /* it's corrupted - recreate it */
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen if (index->fd != -1) {
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen if (close(index->fd) < 0)
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen mail_index_set_syscall_error(index, "close()");
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen index->fd = -1;
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return ret;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainenint mail_index_create_tmp_file(struct mail_index *index,
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainen const char *path_prefix, const char **path_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen mode_t old_mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *path;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainen path = *path_r = t_strconcat(path_prefix, ".tmp", NULL);
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen old_mask = umask(0);
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
d22390f33eedbd2413debabc0662dde5241b1aa6Timo Sirainen umask(old_mask);
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen if (fd == -1 && errno == EEXIST) {
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen /* stale temp file. unlink and recreate rather than overwriting,
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen just to make sure locking problems won't cause corruption */
46b823ac3bce2c0f9f0fc73911e48d3a77b04fbeTimo Sirainen if (i_unlink(path) < 0)
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen return -1;
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen old_mask = umask(0);
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen umask(old_mask);
14b8bbb81e0b546436d4d5d5f38e45027c146b9bTimo Sirainen }
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen if (fd == -1) {
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen mail_index_file_set_syscall_error(index, path, "creat()");
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen return -1;
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen mail_index_fchown(index, fd, path);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainenstatic const char *mail_index_get_cache_path(struct mail_index *index)
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen{
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen const char *dir;
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen if (index->cache_dir != NULL)
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen dir = index->cache_dir;
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen else if (index->dir != NULL)
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen dir = index->dir;
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen else
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen return NULL;
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen return t_strconcat(dir, "/", index->prefix,
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen MAIL_CACHE_FILE_SUFFIX, NULL);
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen}
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainenstatic int mail_index_open_files(struct mail_index *index,
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen enum mail_index_open_flags flags)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen ret = mail_transaction_log_open(index->log);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return 0;
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen /* if dovecot.index exists, read it first so that we can get
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen the correct indexid and log sequence */
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen (void)mail_index_try_open(index);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen if (index->indexid == 0) {
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen /* Create a new indexid for us. If we're opening index
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen into memory, index->map doesn't exist yet. */
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen index->indexid = ioloop_time;
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen index->initial_create = TRUE;
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen if (index->map != NULL)
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen index->map->hdr.indexid = index->indexid;
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen }
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen ret = mail_transaction_log_create(index->log, FALSE);
2bda0d095e029ec72ec683b4186e04f322b4978eTimo Sirainen if (index->map != NULL) {
2bda0d095e029ec72ec683b4186e04f322b4978eTimo Sirainen /* log creation could have changed it if someone else
2bda0d095e029ec72ec683b4186e04f322b4978eTimo Sirainen just created it. */
2bda0d095e029ec72ec683b4186e04f322b4978eTimo Sirainen index->map->hdr.indexid = index->indexid;
2bda0d095e029ec72ec683b4186e04f322b4978eTimo Sirainen }
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen index->initial_create = FALSE;
95a284736b8b11319a3f575ba249ba2eb7dbac1bTimo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (ret >= 0) {
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen ret = index->map != NULL ? 1 : mail_index_try_open(index);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (ret == 0) {
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen /* corrupted */
0b49cfeae91a4020a404714b11c99e8e955fb631Timo Sirainen mail_transaction_log_close(index->log);
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainen ret = mail_transaction_log_create(index->log, TRUE);
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen if (ret == 0) {
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen if (index->map != NULL)
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen mail_index_unmap(&index->map);
0b49cfeae91a4020a404714b11c99e8e955fb631Timo Sirainen index->map = mail_index_map_alloc(index);
af1e2b2ab5d1c5ca5afe482ef8c8161c17acc190Timo Sirainen }
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen }
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (ret < 0) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* open/create failed, fallback to in-memory indexes */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return -1;
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (mail_index_move_to_memory(index) < 0)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return -1;
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen }
da5d50534cfca45d0aaaf0bdac17b287b4588809Timo Sirainen
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen if (index->cache == NULL) {
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen const char *path = mail_index_get_cache_path(index);
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen index->cache = mail_cache_open_or_create_path(index, path);
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen }
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen return 1;
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen}
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainenstatic int
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainenmail_index_open_opened(struct mail_index *index,
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen enum mail_index_open_flags flags)
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen{
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen int ret;
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen i_assert(index->map != NULL);
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen if ((index->map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen /* index was marked corrupted. we'll probably need to
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen recreate the files. */
7be1a5530fcb414588fbe90eaed65eff83e84737Timo Sirainen mail_index_unmap(&index->map);
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen mail_index_close_file(index);
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen mail_transaction_log_close(index->log);
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen if ((ret = mail_index_open_files(index, flags)) <= 0)
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen return ret;
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen }
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen index->open_count++;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen int ret;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
9f32b9444d2a6db8f556d2c49ffceab1a59791ffTimo Sirainen if (index->open_count > 0) {
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen if ((ret = mail_index_open_opened(index, flags)) <= 0) {
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen /* doesn't exist and create flag not used */
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen }
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen return ret;
0c27b881989bc2b391281650ee89a8cc4d89f5e7Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen index->filepath = MAIL_INDEX_IS_IN_MEMORY(index) ?
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen i_strdup("(in-memory index)") :
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen i_strconcat(index->dir, "/", index->prefix, NULL);
ee246b46953e4b94b2f22e093373674fa9155500Timo Sirainen
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen index->readonly = FALSE;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen index->nodiskspace = FALSE;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen index->index_lock_timeout = FALSE;
07e80e04c8876b6bf3f95266f48b41e1a681e445Timo Sirainen index->log_sync_locked = FALSE;
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen index->flags = flags;
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen index->readonly = (flags & MAIL_INDEX_OPEN_FLAG_READONLY) != 0;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen index->fsync_mode != FSYNC_MODE_ALWAYS)
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen i_fatal("nfs flush requires mail_fsync=always");
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen (flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) == 0)
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen i_fatal("nfs flush requires mmap_disable=yes");
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen /* NOTE: increase open_count only after mail_index_open_files().
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen it's used elsewhere to check if we're doing an initial opening
f01d1332d49dbd34baef4601ac7b3cc557021084Timo Sirainen of the index files */
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen if ((ret = mail_index_open_files(index, flags)) <= 0) {
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen /* doesn't exist and create flag not used */
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen mail_index_close_nonopened(index);
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return ret;
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen }
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi
3c72b9bc9fd67b4492d6e949f54a3964dcb26344Timo Sirainen index->open_count++;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi if (index->log->head == NULL) {
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi mail_index_close(index);
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi mail_index_set_error(index, "Index is corrupted "
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi "(log->view->head == NULL)");
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi return -1;
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi }
9e0b187933b52db68c1aefb913970eeba47b986eAki Tuomi
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen i_assert(index->map != NULL);
ac26a4607cb12b156f6a42f1ead2881bedd43d94Timo Sirainen mail_index_alloc_cache_index_opened(index);
1fd0d511885c30028aba388588151acf4ee85e75Timo Sirainen return 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainenint mail_index_open_or_create(struct mail_index *index,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen enum mail_index_open_flags flags)
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen{
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen int ret;
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen flags |= MAIL_INDEX_OPEN_FLAG_CREATE;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen ret = mail_index_open(index, flags);
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen i_assert(ret != 0);
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen return ret < 0 ? -1 : 0;
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen}
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen
c2feb7d13482d0f60691cd71d06d42a80df99397Timo Sirainenvoid mail_index_close_file(struct mail_index *index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (index->fd != -1) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (close(index->fd) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_set_syscall_error(index, "close()");
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->fd = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainenstatic void mail_index_close_nonopened(struct mail_index *index)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen{
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen i_assert(!index->syncing);
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen if (index->views != NULL) {
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen i_panic("Leaked view for index %s: Opened in %s:%u",
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen index->filepath, index->views->source_filename,
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen index->views->source_linenum);
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen }
ef4d0eafab4d26bba047551db1e23ceff8aa9404Timo Sirainen i_assert(index->views == NULL);
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen
90c5979b3c530707744beab6413f9d1e446335d1Timo Sirainen if (index->map != NULL)
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen mail_index_unmap(&index->map);
90c5979b3c530707744beab6413f9d1e446335d1Timo Sirainen
90c5979b3c530707744beab6413f9d1e446335d1Timo Sirainen mail_index_close_file(index);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_transaction_log_close(index->log);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (index->cache != NULL)
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_cache_free(&index->cache);
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen i_free_and_null(index->filepath);
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen index->indexid = 0;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainenvoid mail_index_close(struct mail_index *index)
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen{
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen i_assert(index->open_count > 0);
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen mail_index_alloc_cache_index_closing(index);
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen if (--index->open_count == 0)
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen mail_index_close_nonopened(index);
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen}
0bd15afe9cadd09b01e68b493b30c9d7e92b4095Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainenint mail_index_unlink(struct mail_index *index)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen{
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen const char *path;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen int last_errno = 0;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index) || index->readonly)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen return 0;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen /* main index */
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen if (unlink(index->filepath) < 0 && errno != ENOENT)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen last_errno = errno;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen /* logs */
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen path = t_strconcat(index->filepath, MAIL_TRANSACTION_LOG_SUFFIX, NULL);
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen if (unlink(path) < 0 && errno != ENOENT)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen last_errno = errno;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen path = t_strconcat(index->filepath,
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen MAIL_TRANSACTION_LOG_SUFFIX".2", NULL);
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen if (unlink(path) < 0 && errno != ENOENT)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen last_errno = errno;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen /* cache */
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen path = t_strconcat(index->filepath, MAIL_CACHE_FILE_SUFFIX, NULL);
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen if (unlink(path) < 0 && errno != ENOENT)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen last_errno = errno;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen if (last_errno == 0)
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen return 0;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen else {
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen errno = last_errno;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen return -1;
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen }
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen}
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainenint mail_index_reopen_if_changed(struct mail_index *index,
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen const char **reason_r)
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen{
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen struct stat st1, st2;
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen int ret;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index)) {
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "in-memory index";
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen return 0;
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen }
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen if (index->fd == -1)
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen goto final;
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0)
04b8a90af181cc4c7959266855e8ed50a22ed413Timo Sirainen nfs_flush_file_handle_cache(index->filepath);
6143fece58262865ce89b5012b73ef08f2ad6abcTimo Sirainen if (nfs_safe_stat(index->filepath, &st2) < 0) {
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen if (errno == ENOENT) {
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "index not found via stat()";
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen return 0;
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen }
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_index_set_syscall_error(index, "stat()");
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
dec85d9856c33f427a06dda01e0e50de0bc8fa7dTimo Sirainen if (fstat(index->fd, &st1) < 0) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen if (!ESTALE_FSTAT(errno)) {
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_index_set_syscall_error(index, "fstat()");
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return -1;
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen }
dec85d9856c33f427a06dda01e0e50de0bc8fa7dTimo Sirainen /* deleted/recreated, reopen */
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "index is stale";
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen } else if (st1.st_ino == st2.st_ino &&
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen CMP_DEV_T(st1.st_dev, st2.st_dev)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* the same file */
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "index unchanged";
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen return 1;
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen } else {
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "index inode changed";
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen }
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen /* new file, new locks. the old fd can keep its locks, they don't
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen matter anymore as no-one's going to modify the file. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_close_file(index);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainenfinal:
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen if ((ret = mail_index_try_open_only(index)) == 0)
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "index not found via open()";
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen else if (ret > 0)
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen *reason_r = "index opened";
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen return ret;
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen}
e4b09b008ab544eb8994beecbfffefa21d855e43Timo Sirainen
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainenint mail_index_refresh(struct mail_index *index)
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen{
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen int ret;
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen return ret <= 0 ? -1 : 0;
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen}
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_cache *mail_index_get_cache(struct mail_index *index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return index->cache;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen va_list va;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(index->error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (fmt == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->error = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen va_start(va, fmt);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->error = i_strdup_vprintf(fmt, va);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen va_end(va);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ceac664d4dbada5edccb5def4e49c6ff6da8ceb4Timo Sirainen e_error(index->event, "%s", index->error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainenvoid mail_index_set_error_nolog(struct mail_index *index, const char *str)
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen{
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen i_assert(str != NULL);
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen char *old_error = index->error;
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen index->error = i_strdup(str);
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen i_free(old_error);
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen}
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainenbool mail_index_is_in_memory(struct mail_index *index)
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainen{
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainen return MAIL_INDEX_IS_IN_MEMORY(index);
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainen}
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainen
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainenstatic void mail_index_set_as_in_memory(struct mail_index *index)
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen{
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen i_free_and_null(index->dir);
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen i_free(index->filepath);
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen index->filepath = i_strdup("(in-memory index)");
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen}
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainenint mail_index_move_to_memory(struct mail_index *index)
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen{
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen struct mail_index_map *map;
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen
c61d52810496376a2ea60b8f4e27bbcaa8754f3fTimo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index))
2469ed8e17534f6cb5f41493df8c7e6f3b2c9b61Timo Sirainen return index->map == NULL ? -1 : 0;
c61d52810496376a2ea60b8f4e27bbcaa8754f3fTimo Sirainen
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0)
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen return -1;
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen
5cc772dc8b507be0bc1996b5717943ba13432e08Timo Sirainen if (index->map == NULL) {
27db4ce5fe399c981e09dcf9e885a1546afd34f4Timo Sirainen /* index was never even opened. just mark it as being in
5cc772dc8b507be0bc1996b5717943ba13432e08Timo Sirainen memory and let the caller re-open the index. */
5cc772dc8b507be0bc1996b5717943ba13432e08Timo Sirainen i_assert(index->fd == -1);
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen mail_index_set_as_in_memory(index);
5cc772dc8b507be0bc1996b5717943ba13432e08Timo Sirainen return -1;
5cc772dc8b507be0bc1996b5717943ba13432e08Timo Sirainen }
5cc772dc8b507be0bc1996b5717943ba13432e08Timo Sirainen
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen /* move index map to memory */
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen map = mail_index_map_clone(index->map);
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen mail_index_unmap(&index->map);
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen index->map = map;
ccffbed92cb02c24fd717808a84138240bf1885bTimo Sirainen }
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen
ae14dfd895881f9d1c6899b0c09f1a8b51447d61Timo Sirainen if (index->log != NULL) {
ae14dfd895881f9d1c6899b0c09f1a8b51447d61Timo Sirainen /* move transaction log to memory */
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen if (mail_transaction_log_move_to_memory(index->log) < 0)
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen return -1;
ae14dfd895881f9d1c6899b0c09f1a8b51447d61Timo Sirainen }
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen
31189eeac1ccaaf1201c60427f8c1087b0f5dfceTimo Sirainen if (index->fd != -1) {
31189eeac1ccaaf1201c60427f8c1087b0f5dfceTimo Sirainen if (close(index->fd) < 0)
31189eeac1ccaaf1201c60427f8c1087b0f5dfceTimo Sirainen mail_index_set_syscall_error(index, "close()");
31189eeac1ccaaf1201c60427f8c1087b0f5dfceTimo Sirainen index->fd = -1;
31189eeac1ccaaf1201c60427f8c1087b0f5dfceTimo Sirainen }
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainen mail_index_set_as_in_memory(index);
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen return 0;
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen}
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen
87712707722ef7d73acb065546e61afa4455cd9eTimo Sirainenvoid mail_index_mark_corrupted(struct mail_index *index)
5ec0ca7ff13595daf0d096c17100afb352e6294aTimo Sirainen{
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen index->indexid = 0;
87712707722ef7d73acb065546e61afa4455cd9eTimo Sirainen
8d131435ba4648c8821160ec38d508c97177c715Timo Sirainen index->map->hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen if (!index->readonly) {
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen if (unlink(index->filepath) < 0 &&
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen errno != ENOENT && errno != ESTALE)
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen mail_index_set_syscall_error(index, "unlink()");
1be964ec6d835f95b4fdebf02add9265d58ad290Timo Sirainen (void)mail_transaction_log_unlink(index->log);
6bc0f424bcdb9119d8159874cf98adfa53eefd9aTimo Sirainen }
5ec0ca7ff13595daf0d096c17100afb352e6294aTimo Sirainen}
5ec0ca7ff13595daf0d096c17100afb352e6294aTimo Sirainen
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainenbool mail_index_is_deleted(struct mail_index *index)
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen{
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen return index->index_delete_requested || index->index_deleted;
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen}
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainenint mail_index_get_modification_time(struct mail_index *index, time_t *mtime_r)
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen{
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen struct stat st;
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen const char *path;
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen *mtime_r = 0;
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index)) {
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen /* this function doesn't make sense for in-memory indexes */
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen return 0;
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen }
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen /* index may not be open, so index->filepath may be NULL */
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen path = t_strconcat(index->dir, "/", index->prefix,
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen MAIL_TRANSACTION_LOG_SUFFIX, NULL);
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen if (stat(path, &st) < 0) {
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen if (errno == ENOENT) {
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen /* .log is always supposed to exist - don't bother
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen trying to stat(dovecot.index) */
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen return 0;
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen }
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen mail_index_file_set_syscall_error(index, path, "stat()");
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen return -1;
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen }
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen *mtime_r = st.st_mtime;
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen return 0;
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen}
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainen
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainenvoid mail_index_fchown(struct mail_index *index, int fd, const char *path)
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen{
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen mode_t mode;
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen if (index->gid == (gid_t)-1) {
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen /* no gid changing */
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen return;
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen } else if (fchown(fd, (uid_t)-1, index->gid) == 0) {
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen /* success */
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen return;
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen } if ((index->mode & 0060) >> 3 == (index->mode & 0006)) {
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen /* group and world permissions are the same, so group doesn't
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen really matter. ignore silently. */
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen return;
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen }
fe5c1094aec29b5d29356ad5f06c970eb4ce7a78Timo Sirainen if (errno != EPERM)
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mail_index_file_set_syscall_error(index, path, "fchown()");
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen else {
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mail_index_set_error(index, "%s",
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen eperm_error_get_chgrp("fchown", path, index->gid,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen index->gid_origin));
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen }
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen /* continue, but change permissions so that only the common
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen subset of group and world is used. this makes sure no one
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen gets any extra permissions. */
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen mode = ((index->mode & 0060) >> 3) & (index->mode & 0006);
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen mode |= (mode << 3) | (index->mode & 0600);
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen if (fchmod(fd, mode) < 0)
93688bfedcfb2b9c02750b8d4d409123a386de5cTimo Sirainen mail_index_file_set_syscall_error(index, path, "fchmod()");
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen}
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *function)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_index_file_set_syscall_error(index, index->filepath, function);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_file_set_syscall_error(struct mail_index *index,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *filepath,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *function)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen const char *errstr;
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(filepath != NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert(function != NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi if (errno == ENOENT) {
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi struct stat st;
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi int old_errno = errno;
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi i_assert(index->log->filepath != NULL);
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi if (nfs_safe_stat(index->log->filepath, &st) < 0 &&
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi errno == ENOENT) {
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi /* the index log has gone away */
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi index->index_deleted = TRUE;
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi errno = old_errno;
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi return;
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi }
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi errno = old_errno;
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi }
eba201921d0e5ddc2319e94359576fbcba78eb41Aki Tuomi
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ENOSPACE(errno)) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->nodiskspace = TRUE;
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) == 0)
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1dd875d96ab5640f78250079961c10e99ed4aa79Timo Sirainen if (errno == EACCES) {
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen function = t_strcut(function, '(');
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen if (strcmp(function, "creat") == 0 ||
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen strncmp(function, "file_dotlock_", 13) == 0)
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen errstr = eacces_error_get_creating(function, filepath);
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen else
e8fd7988ec183fb6c104aed19a61f1a096c51d34Timo Sirainen errstr = eacces_error_get(function, filepath);
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_index_set_error(index, "%s", errstr);
1dd875d96ab5640f78250079961c10e99ed4aa79Timo Sirainen } else {
6bb8c6900ad4f1223f388a6814bed0fb80ae27d2Timo Sirainen const char *suffix = errno != EFBIG ? "" :
6bb8c6900ad4f1223f388a6814bed0fb80ae27d2Timo Sirainen " (process was started with ulimit -f limit)";
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen mail_index_set_error(index, "%s failed with file %s: "
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen "%m%s", function, filepath, suffix);
1dd875d96ab5640f78250079961c10e99ed4aa79Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *mail_index_get_error_message(struct mail_index *index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return index->error;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_reset_error(struct mail_index *index)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (index->error != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_free(index->error);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->error = NULL;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->nodiskspace = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->index_lock_timeout = FALSE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen}