mail-index.c revision da985034a708db2f61394b30d117050ae6829ee5
183bea41fa640dc8117f3eb45ff935cd81377a84Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
b2ed2b25c4c457ec1c99ebe5e9bd66a2e2f89cfdTimo Sirainenstatic int mail_index_try_open_only(struct mail_index *index);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenstatic void mail_index_create_in_memory(struct mail_index *index,
870bcf0d0c07f7d915f1f571f38968426ba575a1Timo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen index->extension_pool = pool_alloconly_create("extension", 512);
f6edc54aa72596af8da681c07223108c322712d5Timo Sirainen ARRAY_CREATE(&index->extensions, index->extension_pool,
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen ARRAY_CREATE(&index->sync_lost_handlers, default_pool,
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen ARRAY_CREATE(&index->mail_index_module_contexts, default_pool,
f6edc54aa72596af8da681c07223108c322712d5Timo Sirainen mail_index_ext_register(index, "keywords", 128, 2, 1);
f6edc54aa72596af8da681c07223108c322712d5Timo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen ARRAY_CREATE(&index->keywords, default_pool, const char *, 16);
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen hash_create(default_pool, index->keywords_pool, 0,
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen strcase_hash, (hash_cmp_callback_t *)strcasecmp);
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainenvoid mail_index_free(struct mail_index **_index)
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen const struct mail_index_registered_ext *extensions;
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen unsigned int i, ext_count;
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen extensions = array_get(&index->extensions, &ext_count);
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen /* see if it's already there */
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainen for (i = 0; i < ext_count; i++) {
c0e5c6a86e1de5d4f5591d39b4aa921a23c807d7Timo Sirainen rext.name = p_strdup(index->extension_pool, name);
d8552f9f65e5ff64be5de9faf9a8171799a0bbecTimo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen rext->expunge_handler_call_always = call_always;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
f6edc54aa72596af8da681c07223108c322712d5Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(rext->sync_handler.callback == NULL);
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen i_assert(rext->sync_handler.callback != NULL);
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen mail_index_sync_lost_handler_t *const *handlers;
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen unsigned int i, count;
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen for (i = 0; i < count; i++) {
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
9cd232cda7563ad81c01776e5ebc5ed2b3cef898Timo Sirainenstatic void mail_index_map_init_extbufs(struct mail_index_map *map,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen size = (sizeof(map->extensions) + BUFFER_APPROX_SIZE) * 2 +
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen sizeof(struct mail_index_ext) +
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen ARRAY_CREATE(&map->extensions, map->extension_pool,
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen ARRAY_CREATE(&map->ext_id_map, map->extension_pool,
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainenuint32_t mail_index_map_lookup_ext(struct mail_index_map *map, const char *name)
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen unsigned int i, size;
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen extensions = array_get(&map->extensions, &size);
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen for (i = 0; i < size; i++) {
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainenmail_index_map_register_ext(struct mail_index *index,
3a79fdaf3253dae045dfa14d2a88b94086327da4Timo Sirainen i_assert(mail_index_map_lookup_ext(map, name) == (uint32_t)-1);
699b27536eeb446e05ed9c9c1ab35cc6174ac0aaTimo Sirainen ext->name = p_strdup(map->extension_pool, name);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen ext->index_idx = mail_index_ext_register(index, name, hdr_size,
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen /* Update index ext_id -> map ext_id mapping. Fill non-used
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen ext_ids with (uint32_t)-1 */
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen while (array_count(&map->ext_id_map) < ext->index_idx)
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen array_append(&map->ext_id_map, &empty_idx, 1);
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen array_idx_set(&map->ext_id_map, ext->index_idx, &idx);
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainenstatic bool size_check(size_t *size_left, size_t size)
f7f13e206c9839f6e868088034b0b59d1d9be13aTimo Sirainen size_t size = sizeof(struct mail_index_ext_header) + name_len;
f7f13e206c9839f6e868088034b0b59d1d9be13aTimo Sirainen return MAIL_INDEX_HEADER_SIZE_ALIGN(size) - size;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenstatic int mail_index_parse_extensions(struct mail_index *index,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int i, old_count;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* extension headers always start from 64bit offsets, so if base header
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen doesn't happen to be 64bit aligned we'll skip some bytes */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen offset = MAIL_INDEX_HEADER_SIZE_ALIGN(map->hdr.base_header_size);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (offset >= map->hdr.header_size && map->extension_pool == NULL) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* nothing to do, skip allocatations and all */
2806f15ceb68023baf65a9daad9dfdf54c622708Timo Sirainen mail_index_map_init_extbufs(map, old_count + 5);
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen for (i = 0; i < old_count; i++)
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen ext_hdr = CONST_PTR_OFFSET(map->hdr_base, offset);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* Extension header contains:
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen - struct mail_index_ext_header
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen - name (not 0-terminated)
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen - 64bit alignment padding
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen - extension header contents
2f6a8ef44beaee4ef74adfcda455ce426c6e7c45Timo Sirainen - 64bit alignment padding
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen if (!size_check(&size_left, sizeof(*ext_hdr)) ||
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen !size_check(&size_left, ext_hdr->name_size) ||
cdc8485491045d82bb98405d4b995f277d12838eTimo Sirainen !size_check(&size_left, get_align(ext_hdr->name_size)) ||
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "Header extension goes outside header",
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen offset += ext_hdr->name_size + get_align(ext_hdr->name_size);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen name = t_strndup(CONST_PTR_OFFSET(map->hdr_base, name_offset),
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (mail_index_map_lookup_ext(map, name) != (uint32_t)-1) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen "Duplicate header extension %s",
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen if ((ext_hdr->record_offset % ext_hdr->record_align) != 0 ||
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen (map->hdr.record_size % ext_hdr->record_align) != 0) {
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen "Record field %s alignmentation %u not used",
b2ed2b25c4c457ec1c99ebe5e9bd66a2e2f89cfdTimo Sirainen index->filepath, name, ext_hdr->record_align);
acef354e742a39416b0697e1554f5d49b0369850Timo Sirainen offset += MAIL_INDEX_HEADER_SIZE_ALIGN(ext_hdr->hdr_size);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int *idx_r)
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen Keywords are never removed from it, so the index values are valid
3005627bf2ed223194c2d08a8c1630769d048f69Timo Sirainen for the lifetime of the mail_index. */
3005627bf2ed223194c2d08a8c1630769d048f69Timo Sirainen if (hash_lookup_full(index->keywords_hash, keyword, NULL, &value)) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen hash_insert(index->keywords_hash, keyword_dup, POINTER_CAST(*idx_r));
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainenint mail_index_map_parse_keywords(struct mail_index *index,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct mail_index_keyword_header *kw_hdr;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const struct mail_index_keyword_header_rec *kw_rec;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen unsigned int i, name_area_end_offset, old_count;
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainen ext_id = mail_index_map_lookup_ext(map, "keywords");
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen /* Extension header contains:
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen - struct mail_index_keyword_header
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen - struct mail_index_keyword_header_rec * keywords_count
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen - const char names[] * keywords_count
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen i_assert(ext->hdr_offset < map->hdr.header_size);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen kw_hdr = CONST_PTR_OFFSET(map->hdr_base, ext->hdr_offset);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen name = (const char *)(kw_rec + kw_hdr->keywords_count);
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen old_count = !array_is_created(&map->keyword_idx_map) ? 0 :
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen /* Keywords can only be added into same mapping. Removing requires a
4f4943f6ef1bc45c23de73eebe83779712b3c8cbTimo Sirainen new mapping (recreating the index file) */
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen /* nothing changed */
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen /* make sure the header is valid */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "Keywords removed unexpectedly",
dc07b75b7ea83ff5f447970a20419032725271a7Timo Sirainen if ((size_t)(name - (const char *)kw_hdr) > ext->hdr_size) {
dc07b75b7ea83ff5f447970a20419032725271a7Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
dc07b75b7ea83ff5f447970a20419032725271a7Timo Sirainen "keywords_count larger than header size",
dc07b75b7ea83ff5f447970a20419032725271a7Timo Sirainen name_area_end_offset = (const char *)kw_hdr + ext->hdr_size - name;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen for (i = 0; i < kw_hdr->keywords_count; i++) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (kw_rec[i].name_offset > name_area_end_offset) {
b2ed2b25c4c457ec1c99ebe5e9bd66a2e2f89cfdTimo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "name_offset points outside allocated header",
4f4943f6ef1bc45c23de73eebe83779712b3c8cbTimo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
4f4943f6ef1bc45c23de73eebe83779712b3c8cbTimo Sirainen "Keyword header doesn't end with NUL",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* create file -> index mapping */
55bc6a7a0940ec48a68558ef70838991c5d301d2Timo Sirainen if (!array_is_created(&map->keyword_idx_map)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ARRAY_CREATE(&map->keyword_idx_map, default_pool,
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen /* Check that existing headers are still the same. It's behind DEBUG
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen since it's pretty useless waste of CPU normally. */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen for (i = 0; i < array_count(&map->keyword_idx_map); i++) {
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const char *keyword = name + kw_rec[i].name_offset;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen const unsigned int *old_idx;
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int idx;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen old_idx = array_idx(&map->keyword_idx_map, i);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (!mail_index_keyword_lookup(index, keyword, FALSE, &idx) ||
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen "Keywords changed unexpectedly",
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen /* Register the newly seen keywords */
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen const char *keyword = name + kw_rec[i].name_offset;
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen unsigned int idx;
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen (void)mail_index_keyword_lookup(index, keyword, TRUE, &idx);
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen /* Make sure all the keywords are in index->keywords. It's quick to do
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen if nothing has changed. */
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen (void)mail_index_map_parse_keywords(index, index->map);
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainenstatic int mail_index_check_header(struct mail_index *index,
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainen const struct mail_index_header *hdr = &map->hdr;
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainen enum mail_index_header_compat_flags compat_flags = 0;
29f32cdcf44cda9688576bfdc7450a8a15e90e86Timo Sirainen compat_flags |= MAIL_INDEX_COMPAT_LITTLE_ENDIAN;
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen if (hdr->major_version != MAIL_INDEX_MAJOR_VERSION) {
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainen /* major version change - handle silently(?) */
7bd72e4deca3cbf757dd1ea298486d9f3bc24226Timo Sirainen /* architecture change - handle silently(?) */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if ((map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* we've already complained about it */
870bcf0d0c07f7d915f1f571f38968426ba575a1Timo Sirainen /* following some extra checks that only take a bit of CPU */
2b2e5f7a24c24d971351877ad4c5150662856bfbTimo Sirainen if (hdr->uid_validity == 0 && hdr->next_uid != 1) {
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
6c2ce1d5bf17b21e804a079eb0f973b7ab83e0d8Timo Sirainen "uid_validity = 0, next_uid = %u",
870bcf0d0c07f7d915f1f571f38968426ba575a1Timo Sirainen if (hdr->record_size < sizeof(struct mail_index_record)) {
870bcf0d0c07f7d915f1f571f38968426ba575a1Timo Sirainen mail_index_set_error(index, "Corrupted index file %s: "
2b2e5f7a24c24d971351877ad4c5150662856bfbTimo Sirainen sizeof(struct mail_index_record));
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if ((hdr->flags & MAIL_INDEX_HDR_FLAG_FSCK) != 0)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (hdr->recent_messages_count > hdr->messages_count ||
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen hdr->seen_messages_count > hdr->messages_count ||
bad5fa318c6c1384ab83bd72d53ce06593274c18Timo Sirainen hdr->deleted_messages_count > hdr->messages_count)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (hdr->first_recent_uid_lowwater > hdr->next_uid ||
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen hdr->first_unseen_uid_lowwater > hdr->next_uid ||
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen hdr->first_deleted_uid_lowwater > hdr->next_uid)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen return mail_index_parse_extensions(index, map);
1c7b0cbdb08cccbd25c19ae0fb69abe8ed9ee9b4Timo Sirainenstatic void mail_index_map_clear(struct mail_index *index,
4f4943f6ef1bc45c23de73eebe83779712b3c8cbTimo Sirainen if (munmap(map->mmap_base, map->mmap_size) < 0)
4f4943f6ef1bc45c23de73eebe83779712b3c8cbTimo Sirainen mail_index_set_syscall_error(index, "munmap()");
3b959c98e05e780de2a063a4a9d8d393dc61ed58Timo Sirainenvoid mail_index_unmap(struct mail_index *index, struct mail_index_map **_map)
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;