c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef MAIL_INDEX_PRIVATE_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define MAIL_INDEX_PRIVATE_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "file-lock.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index.h"
bc397dfcbe6e22aa1ca2e15a9f3cd42f39e2ec4eTimo Sirainen#include "mail-index-util.h"
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen#include "mail-index-view-private.h"
d6badc27cd6e8d3398877b6766cb0aaeef3a7800Timo Sirainen#include "mail-index-transaction-private.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e57335924f5ff57cbd1929ec99764dc267c3312Timo Sirainen#include <sys/stat.h>
8e57335924f5ff57cbd1929ec99764dc267c3312Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_header;
fea541eec46707f9b01bd3cbc981d73c1e808a54Timo Sirainenstruct mail_transaction_log_view;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstruct mail_index_sync_map_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* How large index files to mmap() instead of reading to memory. */
bf91bed88d4e294b4577ba2a3b14d87cf35ae135Timo Sirainen#define MAIL_INDEX_MMAP_MIN_SIZE (1024*64)
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen/* How many times to retry opening index files if read/fstat returns ESTALE.
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen This happens with NFS when the file has been deleted (ie. index file was
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen rewritten by another computer than us). */
89b548af722113acb5d63dfffb44423cb60f91e4Timo Sirainen#define MAIL_INDEX_ESTALE_RETRY_COUNT NFS_ESTALE_RETRY_COUNT
ed50658501d9ae8c85f6264831056b1debed11c3Timo Sirainen/* Large extension header sizes are probably caused by file corruption, so
ed50658501d9ae8c85f6264831056b1debed11c3Timo Sirainen try to catch them by limiting the header size. */
ed50658501d9ae8c85f6264831056b1debed11c3Timo Sirainen#define MAIL_INDEX_EXT_HEADER_MAX_SIZE (1024*1024*16-1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen#define MAIL_INDEX_IS_IN_MEMORY(index) \
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen ((index)->dir == NULL)
4b231ca0bbe3b536acbd350101e183441ce0247aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define MAIL_INDEX_MAP_IS_IN_MEMORY(map) \
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen ((map)->rec_map->mmap_base == NULL)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen#define MAIL_INDEX_MAP_IDX(map, idx) \
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen ((struct mail_index_record *) \
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen PTR_OFFSET((map)->rec_map->records, (idx) * (map)->hdr.record_size))
f5e06b955adead65ab7281b6410059230c0bf512Phil Carmody#define MAIL_INDEX_REC_AT_SEQ(map, seq) \
f5e06b955adead65ab7281b6410059230c0bf512Phil Carmody ((struct mail_index_record *) \
f5e06b955adead65ab7281b6410059230c0bf512Phil Carmody PTR_OFFSET((map)->rec_map->records, ((seq)-1) * (map)->hdr.record_size))
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen#define MAIL_TRANSACTION_FLAG_UPDATE_IS_INTERNAL(u) \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen ((((u)->add_flags | (u)->remove_flags) & MAIL_INDEX_FLAGS_MASK) == 0 && \
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen (u)->modseq_inc_flag == 0)
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen#define MAIL_INDEX_EXT_KEYWORDS "keywords"
5aeb15e5817fbd4b1d8de540aa7673e3819a8030Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainentypedef int mail_index_expunge_handler_t(struct mail_index_sync_map_ctx *ctx,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t seq, const void *data,
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen void **sync_context, void *context);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainentypedef int mail_index_sync_handler_t(struct mail_index_sync_map_ctx *ctx,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t seq, void *old_data,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen const void *new_data, void **context);
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainentypedef void mail_index_sync_lost_handler_t(struct mail_index *index);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen#define MAIL_INDEX_HEADER_SIZE_ALIGN(size) \
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen (((size) + 7) & ~7)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstruct mail_index_ext {
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen const char *name;
ab286a8b58306eb8d22fc18342b6c199fd428e1eTimo Sirainen uint32_t index_idx; /* index ext_id */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t reset_id;
cfa9359fbd6a967ccdcd553c5e483a093885ab6fTimo Sirainen uint32_t ext_offset; /* points to beginning of mail_index_ext_header */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t hdr_offset; /* points to mail_index_ext_header.data[] */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_offset;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_size;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_align;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen};
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstruct mail_index_ext_header {
d74899545d913eac91c82b692927b32c3bf36abaTimo Sirainen uint32_t hdr_size; /* size of data[] */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t reset_id;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_offset;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_size;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_align;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t name_size;
d74899545d913eac91c82b692927b32c3bf36abaTimo Sirainen /* unsigned char name[name_size] */
d74899545d913eac91c82b692927b32c3bf36abaTimo Sirainen /* unsigned char data[hdr_size] (starting 64bit aligned) */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen};
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstruct mail_index_keyword_header {
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t keywords_count;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* struct mail_index_keyword_header_rec[] */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen /* char name[][] */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen};
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstruct mail_index_keyword_header_rec {
625101600b8c05f72f79b13604de0c751a73e959Timo Sirainen uint32_t unused; /* for backwards compatibility */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t name_offset; /* relative to beginning of name[] */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen};
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainenenum mail_index_sync_handler_type {
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen MAIL_INDEX_SYNC_HANDLER_FILE = 0x01,
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen MAIL_INDEX_SYNC_HANDLER_HEAD = 0x02,
9315dd69233d554452df0c12bc57002d2042a8f4Timo Sirainen MAIL_INDEX_SYNC_HANDLER_VIEW = 0x04
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen};
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainenstruct mail_index_sync_handler {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen mail_index_sync_handler_t *callback;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen enum mail_index_sync_handler_type type;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen};
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainenstruct mail_index_registered_ext {
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen const char *name;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t index_idx; /* index ext_id */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint32_t hdr_size; /* size of mail_index_ext_header.data[] */
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint16_t record_size;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen uint16_t record_align;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
de12ff295bb3d0873b4dced5840612cbacd635efTimo Sirainen struct mail_index_sync_handler sync_handler;
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen mail_index_expunge_handler_t *expunge_handler;
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen
da985034a708db2f61394b30d117050ae6829ee5Timo Sirainen void *expunge_context;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool expunge_handler_call_always:1;
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen};
c27f03fa8fd2ef4acd1db814fae7d90e0eb9d3aeTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainenstruct mail_index_record_map {
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct mail_index_map *) maps;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen void *mmap_base;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen size_t mmap_size, mmap_used_size;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen buffer_t *buffer;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen void *records; /* struct mail_index_record[] */
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen unsigned int records_count;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen struct mail_index_map_modseq *modseq;
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainen uint32_t last_appended_uid;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen};
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_map {
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainen struct mail_index *index;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int refcount;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail_index_header hdr;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const void *hdr_base;
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen buffer_t *hdr_copy_buf;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen pool_t extension_pool;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct mail_index_ext) extensions;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(uint32_t) ext_id_map; /* index -> file */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(unsigned int) keyword_idx_map; /* file -> index */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
3697080532ccd9f51fac108be6079b616c7a2ddfTimo Sirainen struct mail_index_record_map *rec_map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainenstruct mail_index_module_register {
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen unsigned int id;
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen};
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainenunion mail_index_module_context {
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen struct mail_index_module_register *reg;
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen};
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char *dir, *prefix;
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen char *cache_dir;
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen struct event *event;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_cache *cache;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log *log;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
9f32b9444d2a6db8f556d2c49ffceab1a59791ffTimo Sirainen unsigned int open_count;
66ecc94150cbce23aad3240135e0782e0a74d479Timo Sirainen enum mail_index_open_flags flags;
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen enum fsync_mode fsync_mode;
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen enum mail_index_fsync_mask fsync_mask;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mode_t mode;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen gid_t gid;
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen char *gid_origin;
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen struct mail_index_optimization_settings optimization_set;
4394b73cacaf2c31a9b601f66b6e26a1c8f114b4Timo Sirainen uint32_t pending_log2_rotate_time;
b66a207ddcfc72a634186ec7e9a82df28ffc1d4eTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen pool_t extension_pool;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct mail_index_registered_ext) extensions;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen uint32_t ext_hdr_init_id;
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen void *ext_hdr_init_data;
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(mail_index_sync_lost_handler_t *) sync_lost_handlers;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char *filepath;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen struct mail_index_map *map;
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi time_t last_mmap_error_time;
12f0c4396d2d9c02b7d5e070aaf64fed5853e9bfAki Tuomi
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t indexid;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen unsigned int inconsistency_id;
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
8e57335924f5ff57cbd1929ec99764dc267c3312Timo Sirainen /* last_read_log_file_* contains the seq/offsets we last read from
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen the main index file's headers. these are used to figure out when
2988b4cbf3540a0c02a9ddf185cafec5938c0cacTimo Sirainen the main index file should be updated. */
8e57335924f5ff57cbd1929ec99764dc267c3312Timo Sirainen uint32_t last_read_log_file_seq;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen uint32_t last_read_log_file_tail_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen /* transaction log head seq/offset when we last fscked */
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen uint32_t fsck_log_head_file_seq;
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen uoff_t fsck_log_head_file_offset;
e3689d0f073341e844638f34e1e4d0b7bb053cc8Timo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* syncing will update this if non-NULL */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen struct mail_index_transaction_commit_result *sync_commit_result;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen enum file_lock_method lock_method;
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen unsigned int max_lock_timeout_secs;
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen pool_t keywords_pool;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen ARRAY_TYPE(keywords) keywords;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen HASH_TABLE(char *, void *) keywords_hash; /* name -> unsigned int idx */
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t keywords_ext_id;
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen uint32_t modseq_ext_id;
690af4a90eaf8611c2573d34126bb7a852c50a44Timo Sirainen
ef4d0eafab4d26bba047551db1e23ceff8aa9404Timo Sirainen struct mail_index_view *views;
1727610dbc69920b7f0d0622b4e5d7127c59093dTimo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen /* Module-specific contexts. */
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(union mail_index_module_context *) module_contexts;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char *error;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool nodiskspace:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_lock_timeout:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_delete_requested:1; /* next sync sets it deleted */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_deleted:1; /* no changes allowed anymore */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool log_sync_locked:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool readonly:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool mapping:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool syncing:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool need_recreate:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_min_write:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool modseqs_enabled:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool initial_create:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool initial_mapped:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool fscked:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainenextern struct mail_index_module_register mail_index_module_register;
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainenextern struct event_category event_category_index;
46c31f64b9f0949f00b7819f45b22f2d64b2ea27Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* Add/replace sync handler for specified extra record. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen uint32_t ext_id, bool call_always,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen mail_index_expunge_handler_t *callback,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen void *context);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen uint32_t ext_id);
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);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen uint32_t ext_id);
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
f23298fea47eecbeded985ee2537a34c4c4ef56bTimo Sirainen mail_index_sync_lost_handler_t *cb);
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
519e0a461271843833a2b42626ad93f6e7ddc497Timo Sirainen mail_index_sync_lost_handler_t *cb);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainenint mail_index_create_tmp_file(struct mail_index *index,
06fc580f6baf83fe5bb94c64be8149d527b01a42Timo Sirainen const char *path_prefix, const char **path_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_try_open_only(struct mail_index *index);
c2feb7d13482d0f60691cd71d06d42a80df99397Timo Sirainenvoid mail_index_close_file(struct mail_index *index);
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainenint mail_index_reopen_if_changed(struct mail_index *index,
6a4bfb2b0bb9f53fb1d4e705bf3948ef4d1ecccbTimo Sirainen const char **reason_r);
10a97b15c34119ffe2d2eab9b975252fed631df2Timo Sirainen/* Update/rewrite the main index file from index->map */
10a97b15c34119ffe2d2eab9b975252fed631df2Timo Sirainenvoid mail_index_write(struct mail_index *index, bool want_rotate);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainenvoid mail_index_flush_read_cache(struct mail_index *index, const char *path,
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen int fd, bool locked);
bc564f1d3d953cf724828322b11ae89e0f59ffc9Timo Sirainen
2af769daebd83719ac696a440e06f6020471cec0Timo Sirainenint mail_index_lock_fd(struct mail_index *index, const char *path, int fd,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen int lock_type, unsigned int timeout_secs,
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen struct file_lock **lock_r);
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Allocate a new empty map. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_index_map *mail_index_map_alloc(struct mail_index *index);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Replace index->map with the latest index changes. This may reopen the index
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen file and/or it may read the latest changes from transaction log. The log is
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen read up to EOF, but non-synced expunges are skipped.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen If we mmap()ed the index file, the map is returned locked.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen Returns 1 = ok, 0 = corrupted, -1 = error. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_index_map(struct mail_index *index,
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen enum mail_index_sync_handler_type type);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Unreference given mapping and unmap it if it's dropped to zero. */
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainenvoid mail_index_unmap(struct mail_index_map **map);
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen/* Clone a map. The returned map is always in memory. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenstruct mail_index_map *mail_index_map_clone(const struct mail_index_map *map);
a28a6267f48971117dec958b160deefd14ebb7a6Timo Sirainenvoid mail_index_record_map_move_to_private(struct mail_index_map *map);
14c474d9f4591c397ed0b5206af6537c7b52c924Timo Sirainen/* Move a mmaped map to memory. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_index_map_move_to_memory(struct mail_index_map *map);
1f80b32fc28f7a723ff07c1694230a090808b506Timo Sirainenvoid mail_index_fchown(struct mail_index *index, int fd, const char *path);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainenbool mail_index_map_lookup_ext(struct mail_index_map *map, const char *name,
7ded22760598b78ee29f9418eacc0abe3fb51055Timo Sirainen uint32_t *idx_r);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenuint32_t
3675a7e9bd3775ba13fe8bc93915902513a0f1a4Timo Sirainenmail_index_map_register_ext(struct mail_index_map *map,
3675a7e9bd3775ba13fe8bc93915902513a0f1a4Timo Sirainen const char *name, uint32_t ext_offset,
3675a7e9bd3775ba13fe8bc93915902513a0f1a4Timo Sirainen const struct mail_index_ext_header *ext_hdr);
12053b7b4b57dbd2790057426d1633988eedad56Timo Sirainenbool mail_index_map_get_ext_idx(struct mail_index_map *map,
12053b7b4b57dbd2790057426d1633988eedad56Timo Sirainen uint32_t ext_id, uint32_t *idx_r);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenconst struct mail_index_ext *
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenmail_index_view_get_ext(struct mail_index_view *view, uint32_t ext_id);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainenvoid mail_index_map_lookup_seq_range(struct mail_index_map *map,
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen uint32_t first_uid, uint32_t last_uid,
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen uint32_t *first_seq_r,
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen uint32_t *last_seq_r);
c24c0f0a208e5ffc35dc8be19a9b504a5326467aTimo Sirainen
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen/* Returns 1 on success, 0 on non-critical errors we want to silently fix,
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen -1 if map isn't usable. The caller is responsible for logging the errors
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen if -1 is returned. */
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainenint mail_index_map_check_header(struct mail_index_map *map,
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen const char **error_r);
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen/* Returns 1 if header is usable, 0 or -1 if not. The caller should log an
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen error if -1 is returned, but not if 0 is returned. */
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenbool mail_index_check_header_compat(struct mail_index *index,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen const struct mail_index_header *hdr,
45b0d8d0b97be14d10e3a3c12c169e4b352b2aacTimo Sirainen uoff_t file_size, const char **error_r);
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenint mail_index_map_parse_extensions(struct mail_index_map *map);
b0be0bead3d6963149f7f2a9504b8ab5aced9af5Timo Sirainenint mail_index_map_parse_keywords(struct mail_index_map *map);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainenvoid mail_index_map_init_extbufs(struct mail_index_map *map,
5806683c1c3f5b1997e92a023c0fe39912d4df5dTimo Sirainen unsigned int initial_count);
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenint mail_index_map_ext_get_next(struct mail_index_map *map,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen unsigned int *offset,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const struct mail_index_ext_header **ext_hdr_r,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const char **name_r);
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainenint mail_index_map_ext_hdr_check(const struct mail_index_header *hdr,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const struct mail_index_ext_header *ext_hdr,
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen const char *name, const char **error_r);
8ababf3e7b15f793370d1dedf85825d38b42633fTimo Sirainenunsigned int mail_index_map_ext_hdr_offset(unsigned int name_len);
746d35bf3dba3ae5ddbcecb9732f60d5e9de77efTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_transaction_ref(struct mail_index_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_transaction_unref(struct mail_index_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainenvoid mail_index_fsck_locked(struct mail_index *index);
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen/* Log an error and set it as the index's current error that is available
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen with mail_index_get_error_message(). */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen ATTR_FORMAT(2, 3);
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainen/* Same as mail_index_set_error(), but don't log the error. */
d808185fd6263862e93637d296f0c4fb0529118eTimo Sirainenvoid mail_index_set_error_nolog(struct mail_index *index, const char *str);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* "%s failed with index file %s: %m" */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *function);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* "%s failed with file %s: %m" */
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainenvoid mail_index_file_set_syscall_error(struct mail_index *index,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *filepath,
e34d170f8f0e084bd94bfbc1a7085ece67e508dfTimo Sirainen const char *function);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#endif