mail-index.c revision 4a09c57f1c66b4a8880bcc12b567bb42c3549f52
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstruct mail_index_module_register mail_index_module_register = { 0 };
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
f1901fd21906911f7be075c965ac882f6a87b4c3Timo Sirainen pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen p_array_init(&index->extensions, index->extension_pool, 5);
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS,
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
b12a6d0e54318273acf0d0fb8b3f4c29f67b62b0Timo Sirainen hash_table_create(default_pool, index->keywords_pool, 0,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen strcase_hash, (hash_cmp_callback_t *)strcasecmp);
73247459cf41eb1e5ae5bc61354db46d3b05ee75Timo Sirainen index->log = mail_transaction_log_alloc(index);
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainenvoid mail_index_free(struct mail_index **_index)
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainenvoid mail_index_set_fsync_types(struct mail_index *index,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
fe6c1556d3529a6376d4cbb3766c34aebde0de99Timo Sirainen mode_t mode, gid_t gid, const char *gid_origin)
6060b7c8edf8fce73470d0df6a2479b69b01c537Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (*name == '\0' || strcmp(name, str_sanitize(name, -1)) != 0)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen i_panic("mail_index_ext_register(%s): Invalid name", name);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen if (default_record_size != 0 && default_record_align == 0) {
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen if (mail_index_ext_lookup(index, name, &ext_id))
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen rext.name = p_strdup(index->extension_pool, name);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen rext.index_idx = array_count(&index->extensions);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenbool mail_index_ext_lookup(struct mail_index *index, const char *name,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const struct mail_index_registered_ext *extensions;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen unsigned int i, count;
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen extensions = array_get(&index->extensions, &count);
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainen for (i = 0; i < count; i++) {
90adcaa0a00eba29b7fbd50ca66be11c8d086d6aTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen i_assert(rext->expunge_handler == NULL || rext->expunge_handler == cb);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen rext->expunge_handler_call_always = call_always;
bf9402875418faf11825cf11fbe06326b6086e3dTimo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
4b41116563110d00330896a568eff1078c382827Timo Sirainen i_assert(rext->sync_handler.callback == NULL);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainen i_assert(rext->sync_handler.callback != NULL);
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
5daa12cc1c862eec4f63df42227812d3514da2ccTimo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
a0b0d629931773c17a236f6214adbe0e13b9b3fdTimo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen mail_index_sync_lost_handler_t *const *handlers;
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen unsigned int i, count;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen for (i = 0; i < count; i++) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen Keywords are never removed from it, so the index values are valid
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen for the lifetime of the mail_index. */
8ed8c821ba8aab0b4ed0375f87d48737ef0e0d8eTimo Sirainen if (hash_table_lookup_full(index->keywords_hash, keyword,
690bafa70767e3f6e98bbfd62ad4a26be2387ea9Timo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainenvoid mail_index_keyword_lookup_or_create(struct mail_index *index,
54d42552005111841ab45ec9ca7559075fabd5dfTimo Sirainen unsigned int *idx_r)
5abb33fdc94c081ccd3213bf7d0fa9d0367b4bfdTimo Sirainen if (mail_index_keyword_lookup(index, keyword, idx_r))
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainenmail_index_keywords_create(struct mail_index *index,
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen const char *const keywords[])
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen /* @UNSAFE */
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* look up the keywords from index. they're never removed from there
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen so we can permanently store indexes to them. */
1b5366b2234892f8930a29351da06b193e385150Timo Sirainen mail_index_keyword_lookup_or_create(index, keywords[src],
aa215ab623706463cea1d047f975ffe51d3f0c05Timo Sirainen /* ignore if this is a duplicate */
d67fde1a8ebc1d85704c5986d8f93aae97eccef3Timo Sirainen for (i = 0; i < src; i++) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenmail_index_keywords_create_from_indexes(struct mail_index *index,
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen const unsigned int *indexes;
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* @UNSAFE */
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen /* copy but skip duplicates */
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainen for (i = 0; i < src; i++) {
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenvoid mail_index_keywords_ref(struct mail_keywords *keywords)
64a67c0296b120b6e15169ac9d84dec964e55969Timo Sirainenvoid mail_index_keywords_unref(struct mail_keywords **_keywords)
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenint mail_index_try_open_only(struct mail_index *index)
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen /* Note that our caller must close index->fd by itself. */
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen index->fd = nfs_safe_open(index->filepath, O_RDWR);
0d86aa0d47f7393c669c084b34c0537b193688adTimo Sirainen return mail_index_set_syscall_error(index, "open()");
ae1b268ffff743ad9927c304a1344c5cbd7f909dTimo Sirainen /* have to create it */
87460b08cb97b31cde640d4975a6aa2c1d0e7226Timo Sirainen i_assert(index->map == NULL || index->map->rec_map->lock_id == 0);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen /* it's corrupted - recreate it */
bddd52cb7f3e5a894c080f60750aa76b5aeaf103Timo Sirainen mail_index_set_syscall_error(index, "close()");
const char *path;
int fd;
return fd;
int ret;
if (ret == 0) {
if (ret >= 0) {
if (ret == 0) {
if (ret == 0) {
if (ret < 0) {
int ret;
MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
return ret;
int ret;
const char *path;
int last_errno = 0;
if (last_errno == 0)
int ret;
const char *function)
const char *filepath,
const char *function)