mail-index.c revision 902222fb0928d1701f20a384b73f327b1d9a15dd
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
4c1deab456fe8877bf025d11843167ac1f36327aTimo Sirainenstruct mail_index_module_register mail_index_module_register = { 0 };
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen p_array_init(&index->extensions, index->extension_pool, 5);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_ext_register(index, "keywords", 128, 2, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
a81b240cfe84231eac64084efd5b0e1e91a9e817Timo Sirainen hash_create(default_pool, index->keywords_pool, 0,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen strcase_hash, (hash_cmp_callback_t *)strcasecmp);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen index->log = mail_transaction_log_alloc(index);
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainenvoid mail_index_free(struct mail_index **_index)
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
d7b205394bd07152718152976dfa089e13253d7eTimo Sirainen const struct mail_index_registered_ext *extensions;
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen unsigned int i, ext_count;
d7b205394bd07152718152976dfa089e13253d7eTimo Sirainen extensions = array_get(&index->extensions, &ext_count);
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen /* see if it's already there */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < ext_count; i++) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rext.name = p_strdup(index->extension_pool, name);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_assert(rext->expunge_handler == NULL || rext->expunge_handler == cb);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rext->expunge_handler_call_always = call_always;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_assert(rext->sync_handler.callback == NULL);
ea1f67e14d727496179ee4ff391f592bce8f4f2dTimo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
b8d314c6355009ad0b9e332b6acecdfac5cc8891Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
b8d314c6355009ad0b9e332b6acecdfac5cc8891Timo Sirainen i_assert(rext->sync_handler.callback != NULL);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen mail_index_sync_lost_handler_t *const *handlers;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, count;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for (i = 0; i < count; i++) {
d22301419109ed4a38351715e6760011421dadecTimo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int *idx_r)
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen Keywords are never removed from it, so the index values are valid
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen for the lifetime of the mail_index. */
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen if (hash_lookup_full(index->keywords_hash, keyword, NULL, &value)) {
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen hash_insert(index->keywords_hash, keyword_dup, POINTER_CAST(*idx_r));
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainenint mail_index_map_parse_keywords(struct mail_index *index,
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mail_index_keyword_header *kw_hdr;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen const struct mail_index_keyword_header_rec *kw_rec;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen unsigned int i, name_area_end_offset, old_count;
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen ext_id = mail_index_map_lookup_ext(map, "keywords");
b58aafbd21b365117538f73f306d22f75acd91f1Timo Sirainen /* Extension header contains:
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen - struct mail_index_keyword_header
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen - struct mail_index_keyword_header_rec * keywords_count
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen - const char names[] * keywords_count
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen i_assert(ext->hdr_offset < map->hdr.header_size);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen kw_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen name = (const char *)(kw_rec + kw_hdr->keywords_count);
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen old_count = !array_is_created(&map->keyword_idx_map) ? 0 :
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen /* Keywords can only be added into same mapping. Removing requires a
1ac7c8e9040e0d0b7e9f849e45b94bfe919595a9Timo Sirainen new mapping (recreating the index file) */
#ifdef DEBUG
const unsigned int *old_idx;
unsigned int idx;
unsigned int idx;
unsigned int lock_id;
int ret;
if (ret == 0) {
return ret;
const char *path;
int fd;
return fd;
int ret;
if (ret == 0) {
return FALSE;
if (ret >= 0) {
if (ret == 0) {
if (ret < 0) {
return FALSE;
return FALSE;
return TRUE;
ret = 0;
if (ret == 0) {
if (ret <= 0)
return ret;
unsigned int lock_id;
int ret;
const char *function)
const char *filepath,
const char *function)
#ifdef WORDS_BIGENDIAN