mail-index.c revision ef5fb27361cc5e15766e85e28355750ff04b13c9
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */
4082d5b171d1c3a00ba705093d62b8afc9cf17aeTimo Sirainenstruct mail_index_module_register mail_index_module_register = { 0 };
4082d5b171d1c3a00ba705093d62b8afc9cf17aeTimo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
4082d5b171d1c3a00ba705093d62b8afc9cf17aeTimo Sirainen pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
4082d5b171d1c3a00ba705093d62b8afc9cf17aeTimo Sirainen p_array_init(&index->extensions, index->extension_pool, 5);
d06d6667bac64aabe1efb216af56ca45108d63b0Timo Sirainen mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS,
86bde2c1838d1ce967fa2b394bb952004a4adcb7Timo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
d06d6667bac64aabe1efb216af56ca45108d63b0Timo Sirainen hash_table_create(default_pool, index->keywords_pool, 0,
c8bac7666cdc780a3390110e420350fffb62b909Timo Sirainen strcase_hash, (hash_cmp_callback_t *)strcasecmp);
c8bac7666cdc780a3390110e420350fffb62b909Timo Sirainen index->log = mail_transaction_log_alloc(index);
d06d6667bac64aabe1efb216af56ca45108d63b0Timo Sirainenvoid mail_index_free(struct mail_index **_index)
199566f5a171b2c43b9a5254634f6bf47b8baca8Timo Sirainenvoid mail_index_set_fsync_types(struct mail_index *index,
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (*name == '\0' || strcmp(name, str_sanitize(name, -1)) != 0)
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen i_panic("mail_index_ext_register(%s): Invalid name", name);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (default_record_size != 0 && default_record_align == 0) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen if (mail_index_ext_lookup(index, name, &ext_id))
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody rext.name = p_strdup(index->extension_pool, name);
ba66ac5557ca97d8a6fe5d524056264a9f92243cPhil Carmody rext.index_idx = array_count(&index->extensions);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenbool mail_index_ext_lookup(struct mail_index *index, const char *name,
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen const struct mail_index_registered_ext *extensions;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen unsigned int i, count;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen extensions = array_get(&index->extensions, &count);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen for (i = 0; i < count; i++) {
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen i_assert(rext->expunge_handler == NULL || rext->expunge_handler == cb);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen rext->expunge_handler_call_always = call_always;
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen i_assert(rext->sync_handler.callback == NULL);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen i_assert(rext->sync_handler.callback != NULL);
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen mail_index_sync_lost_handler_t *const *handlers;
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen unsigned int i, count;
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen for (i = 0; i < count; i++) {
f7bd22354fb9311dfbf3e340a69c15d8b00facc1Timo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen Keywords are never removed from it, so the index values are valid
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen for the lifetime of the mail_index. */
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen if (hash_table_lookup_full(index->keywords_hash, keyword,
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainenvoid mail_index_keyword_lookup_or_create(struct mail_index *index,
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen unsigned int *idx_r)
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen if (mail_index_keyword_lookup(index, keyword, idx_r))
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainenint mail_index_try_open_only(struct mail_index *index)
369764cc0856a4c5e9b4081de8c4e29e90f11ccdTimo Sirainen /* Note that our caller must close index->fd by itself. */
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen index->fd = nfs_safe_open(index->filepath, O_RDWR);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen return mail_index_set_syscall_error(index, "open()");
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen /* have to create it */
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen i_assert(index->map == NULL || index->map->rec_map->lock_id == 0);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
48acc31adebfdd4e4945ee76e1f5259e4b1b6fffTimo Sirainen /* it's corrupted - recreate it */
d06d6667bac64aabe1efb216af56ca45108d63b0Timo 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;
int ret;
const char *function)
const char *filepath,
const char *function)
#if WORDS_BIGENDIAN
**p = num;
const uint8_t *c = *p;
unsigned int bits = 0;
*num_r = 0;
*p = end;
*num_r = 0;