mail-index.c revision cf48e5c9975b854a23aeca883b7e689eb24430c4
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic int mail_index_try_open_only(struct mail_index *index);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void mail_index_create_in_memory(struct mail_index *index,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen index->extension_pool = pool_alloconly_create("extension", 512);
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen ARRAY_CREATE(&index->extensions, index->extension_pool,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ARRAY_CREATE(&index->sync_lost_handlers, default_pool,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen mail_index_ext_register(index, "keywords", 128, 2, 1);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen ARRAY_CREATE(&index->keywords, default_pool, const char *, 16);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen hash_create(default_pool, index->keywords_pool, 0,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen strcase_hash, (hash_cmp_callback_t *)strcasecmp);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid mail_index_free(struct mail_index **_index)
2726de0d31ed0f1a1425e4c8d167f7681e07fc25Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen const struct mail_index_registered_ext *extensions;
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen unsigned int i, ext_count;
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen extensions = array_get(&index->extensions, &ext_count);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen /* see if it's already there */
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen for (i = 0; i < ext_count; i++) {
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen rext.name = p_strdup(index->extension_pool, name);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen rext = array_idx_modifyable(&index->extensions, ext_id);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen rext = array_idx_modifyable(&index->extensions, ext_id);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen rext = array_idx_modifyable(&index->extensions, ext_id);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen i_assert(rext->sync_handler.callback == NULL);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
b75feeb580a78d76188f66d589939b298da4b61bTimo Sirainen rext = array_idx_modifyable(&index->extensions, ext_id);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen i_assert(rext->sync_handler.callback != NULL);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
447bf65ddb82ec279e7386828748ef47e199a6afTimo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
b75feeb580a78d76188f66d589939b298da4b61bTimo Sirainen mail_index_sync_lost_handler_t *const *handlers;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, count;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void mail_index_map_init_extbufs(struct mail_index_map *map,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen size = (sizeof(array_t) + BUFFER_APPROX_SIZE) * 2 +
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen sizeof(struct mail_index_ext) +
5733207dc3ec10e6e5a6e0a8b30fbd1b061062b9Timo Sirainen ARRAY_CREATE(&map->extensions, map->extension_pool,
5733207dc3ec10e6e5a6e0a8b30fbd1b061062b9Timo Sirainen ARRAY_CREATE(&map->ext_id_map, map->extension_pool,
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainenuint32_t mail_index_map_lookup_ext(struct mail_index_map *map, const char *name)
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen unsigned int i, size;
b6b9c99fefbbc662bd9a0006566133c4480bf0e8Timo Sirainen extensions = array_get(&map->extensions, &size);
dc1bc1685e4a0d58ae7bacaecc282d0ebde2d7daTimo Sirainen for (i = 0; i < size; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenmail_index_map_register_ext(struct mail_index *index,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_assert(mail_index_map_lookup_ext(map, name) == (uint32_t)-1);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ext->name = p_strdup(map->extension_pool, name);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ext->index_idx = mail_index_ext_register(index, name, hdr_size,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* Update index ext_id -> map ext_id mapping. Fill non-used
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ext_ids with (uint32_t)-1 */
5733207dc3ec10e6e5a6e0a8b30fbd1b061062b9Timo Sirainen while (array_count(&map->ext_id_map) < ext->index_idx)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_append(&map->ext_id_map, &empty_idx, 1);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen array_idx_set(&map->ext_id_map, ext->index_idx, &idx);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic bool size_check(size_t *size_left, size_t size)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen size_t size = sizeof(struct mail_index_ext_header) + name_len;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return MAIL_INDEX_HEADER_SIZE_ALIGN(size) - size;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic int mail_index_parse_extensions(struct mail_index *index,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i, old_count;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* extension headers always start from 64bit offsets, so if base header
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen doesn't happen to be 64bit aligned we'll skip some bytes */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen offset = MAIL_INDEX_HEADER_SIZE_ALIGN(map->hdr.base_header_size);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if (offset >= map->hdr.header_size && map->extension_pool == NULL) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen /* nothing to do, skip allocatations and all */
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen mail_index_map_init_extbufs(map, old_count + 5);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < old_count; i++)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ext_hdr = CONST_PTR_OFFSET(map->hdr_base, offset);
t_push();
t_pop();
t_pop();
t_pop();
unsigned int *idx_r)
char *keyword_dup;
void *value;
return TRUE;
if (!autocreate) {
return FALSE;
return TRUE;
const char *name;
#ifdef DEBUG
const unsigned int *old_idx;
unsigned int idx;
unsigned int idx;
#ifndef WORDS_BIGENDIAN
sizeof(struct mail_index_record));
unsigned int records_count;
int ret;
pos = 0;
if (ret > 0)
return ret;
pos);
if (ret > 0) {
if (ret < 0) {
if (ret == 0) {
&prev_offset);
bool sync_to_index)
const void *tdata;
int ret;
if (sync_to_index) {
MAIL_TRANSACTION_TYPE_MASK) <= 0) {
&skipped)) > 0) {
ret = 0;
&prev_offset);
return ret;
bool sync_to_index)
unsigned int i, count;
int ret;
bool retry;
if (ret != 0)
return ret;
for (i = 0; i < count; i++)
return ret;
if (ret <= 0) {
if (ret == 0) {
int ret;
if (ret != 0) {
return ret;
if (ret > 0) {
if (ret < 0)
ret = 0;
else if (ret == 0) {
if (ret <= 0) {
return ret;
int ret;
if (ret > 0)
return ret;
&pos);
if (ret <= 0) {
if (ret == 0) {
if (ret < 0)
return ret;
struct mail_index_map *
unsigned int i, count;
for (i = 0; i < count; i++) {
return mem_map;
unsigned int lock_id;
int ret;
*lock_id_r = 0;
if (ret <= 0)
return ret;
if (ret == 0) {
*lock_id_r = 0;
return ret;
const char *path;
int fd;
return fd;
const char *path;
int ret;
if (ret != 0) {
/* create it fully in index.tmp first */
if (ret == 0) {
if (ret < 0) {
return ret;
#ifndef WORDS_BIGENDIAN
unsigned int lock_id = 0;
int ret;
if (ret > 0)
else if (ret == 0) {
} else if (ret < 0)
if (lock_id != 0) {
lock_id = 0;
if (lock_id == 0) {
int i = 0, ret;
if (ret <= 0)
if (ret == 0) {
if (ret <= 0)
return ret;
ret = 0;
if (ret > 0)
else if (ret == 0) {
if (ret == 0) {
if (lock_id != 0)
if (ret == 0) {
return ret;
unsigned int lock_id;
int ret;
int ret = 0;
return ret;
const char *function)
const char *filepath,
const char *function)
return MAIL_INDEX_ERROR_DISKSPACE;
return MAIL_INDEX_ERROR_INTERNAL;
return MAIL_INDEX_ERROR_NONE;