mail-index.c revision ea91861234475257f436dc07925f80cf4ac32b71
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2003-2015 Dovecot authors, see the included COPYING file */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "lib.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "ioloop.h"
dfa2201c6ac8ddb2d2798dee15662cfe774e644eMartti Rannanjärvi#include "array.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "buffer.h"
fd8b93ca5cbeba64fe6fa5dc98a3e580fb046791Timo Sirainen#include "eacces-error.h"
472369cba85d9f7c995dda60e7cd01d78b4a960aTimo Sirainen#include "hash.h"
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen#include "str-sanitize.h"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#include "mmap-util.h"
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen#include "nfs-workarounds.h"
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen#include "read-full.h"
b1f37113a5760bee842c5a7678bb5fa6f5bd8b60Timo Sirainen#include "write-full.h"
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen#include "mail-index-alloc-cache.h"
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen#include "mail-index-private.h"
9393445a6dabd17ce62ebfc12fd73545b0065824Timo Sirainen#include "mail-index-view-private.h"
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen#include "mail-index-sync-private.h"
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen#include "mail-index-modseq.h"
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen#include "mail-transaction-log.h"
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen#include "mail-cache.h"
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen
13d98ffa534f2e7d04a832c9d0153fc9c568b878Timo Sirainen#include <stdio.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include <stddef.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include <time.h>
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include <sys/stat.h>
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainenstruct mail_index_module_register mail_index_module_register = { 0 };
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainenstatic void mail_index_close_nonopened(struct mail_index *index);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix)
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen{
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen struct mail_index *index;
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen index = i_new(struct mail_index, 1);
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen index->dir = i_strdup(dir);
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen index->prefix = i_strdup(prefix);
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen index->fd = -1;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
220e21750948941dc6e33b8f11b552fa21d7f81eTimo Sirainen index->extension_pool =
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen p_array_init(&index->extensions, index->extension_pool, 5);
697ff56bf3cdc9e7989ea2a70accf866b14b64d1Timo Sirainen i_array_init(&index->sync_lost_handlers, 4);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_array_init(&index->module_contexts,
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen I_MIN(5, mail_index_module_register.id));
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen index->mode = 0600;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen index->gid = (gid_t)-1;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen index->lock_method = FILE_LOCK_METHOD_FCNTL;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen index->max_lock_timeout_secs = UINT_MAX;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen index->keywords_ext_id =
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS,
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen 128, 2, 1);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen index->keywords_pool = pool_alloconly_create("keywords", 512);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_array_init(&index->keywords, 16);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen hash_table_create(&index->keywords_hash, index->keywords_pool, 0,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen strcase_hash, strcasecmp);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen index->log = mail_transaction_log_alloc(index);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen mail_index_modseq_init(index);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return index;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenvoid mail_index_free(struct mail_index **_index)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct mail_index *index = *_index;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen *_index = NULL;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_assert(index->open_count == 0);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen mail_transaction_log_free(&index->log);
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen hash_table_destroy(&index->keywords_hash);
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen pool_unref(&index->extension_pool);
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen pool_unref(&index->keywords_pool);
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen array_free(&index->sync_lost_handlers);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen array_free(&index->keywords);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen array_free(&index->module_contexts);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_free(index->ext_hdr_init_data);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_free(index->gid_origin);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_free(index->error);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_free(index->dir);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_free(index->prefix);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_free(index);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenvoid mail_index_set_fsync_mode(struct mail_index *index,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen enum fsync_mode mode,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen enum mail_index_fsync_mask mask)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen index->fsync_mode = mode;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen index->fsync_mask = mask;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen}
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen mode_t mode, gid_t gid, const char *gid_origin)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen{
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen index->mode = mode & 0666;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen index->gid = gid;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen i_free(index->gid_origin);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen index->gid_origin = i_strdup(gid_origin);
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid mail_index_set_lock_method(struct mail_index *index,
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen enum file_lock_method lock_method,
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen unsigned int max_timeout_secs)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek index->lock_method = lock_method;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen index->max_lock_timeout_secs = max_timeout_secs;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainenvoid mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const void *data, size_t size)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const struct mail_index_registered_ext *rext;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek i_assert(index->ext_hdr_init_data == NULL ||
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen index->ext_hdr_init_id == ext_id);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen rext = array_idx(&index->extensions, ext_id);
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen i_assert(rext->hdr_size == size);
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek
63e207529879438e9f4412d97cdc34bdc82a3702Timo Sirainen index->ext_hdr_init_id = ext_id;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen i_free(index->ext_hdr_init_data);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen index->ext_hdr_init_data = i_malloc(size);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen memcpy(index->ext_hdr_init_data, data, size);
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek}
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen uint32_t default_hdr_size,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen uint16_t default_record_size,
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen uint16_t default_record_align)
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen{
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek struct mail_index_registered_ext rext;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen uint32_t ext_id;
ac2defed599a97c4a71a9e90ba185929dfe59226Josef 'Jeff' Sipek
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen if (*name == '\0' || strcmp(name, str_sanitize(name, -1)) != 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen i_panic("mail_index_ext_register(%s): Invalid name", name);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (default_record_size != 0 && default_record_align == 0) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen i_panic("mail_index_ext_register(%s): "
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen "Invalid record alignment", name);
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen }
76b91bac787101e6b0075122ab6478dd98c8a884Timo Sirainen
3fe67ec75ccae1230bb9eb9f16affc48377f6441Timo Sirainen if (mail_index_ext_lookup(index, name, &ext_id))
eaa2d473ed2ecdb9856cd98a33f4d3063cfaf2a1Timo Sirainen return ext_id;
eaa2d473ed2ecdb9856cd98a33f4d3063cfaf2a1Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen memset(&rext, 0, sizeof(rext));
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen rext.name = p_strdup(index->extension_pool, name);
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen rext.index_idx = array_count(&index->extensions);
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen rext.hdr_size = default_hdr_size;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen rext.record_size = default_record_size;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen rext.record_align = default_record_align;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen array_append(&index->extensions, &rext, 1);
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen return rext.index_idx;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen}
638600575ee95f2513c683ef09cb188f76eacd22Timo Sirainen
638600575ee95f2513c683ef09cb188f76eacd22Timo Sirainenvoid mail_index_ext_register_resize_defaults(struct mail_index *index,
638600575ee95f2513c683ef09cb188f76eacd22Timo Sirainen uint32_t ext_id,
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen uint32_t default_hdr_size,
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen uint16_t default_record_size,
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen uint16_t default_record_align)
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_index_registered_ext *rext;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen rext->hdr_size = default_hdr_size;
fa780a18c41881036af582f7a3473d6399e9d34dTimo Sirainen rext->record_size = default_record_size;
fa780a18c41881036af582f7a3473d6399e9d34dTimo Sirainen rext->record_align = default_record_align;
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen}
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen
5214b67a7dabab87da74e04bb8b227f94b95bce4Timo Sirainenbool mail_index_ext_lookup(struct mail_index *index, const char *name,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uint32_t *ext_id_r)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const struct mail_index_registered_ext *extensions;
27586e4785d56aeb76e1fd96af8db799688dc64aTimo Sirainen unsigned int i, count;
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen
fd8b93ca5cbeba64fe6fa5dc98a3e580fb046791Timo Sirainen extensions = array_get(&index->extensions, &count);
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen for (i = 0; i < count; i++) {
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen if (strcmp(extensions[i].name, name) == 0) {
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen *ext_id_r = i;
eaa2d473ed2ecdb9856cd98a33f4d3063cfaf2a1Timo Sirainen return TRUE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
5214b67a7dabab87da74e04bb8b227f94b95bce4Timo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen *ext_id_r = (uint32_t)-1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return FALSE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid mail_index_register_expunge_handler(struct mail_index *index,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uint32_t ext_id, bool call_always,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_expunge_handler_t *cb,
f0d09be40bd0c4423873128ae2f88a4020075dc4Timo Sirainen void *context)
f0d09be40bd0c4423873128ae2f88a4020075dc4Timo Sirainen{
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen struct mail_index_registered_ext *rext;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen i_assert(rext->expunge_handler == NULL || rext->expunge_handler == cb);
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen rext->expunge_handler = cb;
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen rext->expunge_context = context;
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen rext->expunge_handler_call_always = call_always;
917498e6f84969d2b93410c1e479735abe8e0ed7Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainenvoid mail_index_unregister_expunge_handler(struct mail_index *index,
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk uint32_t ext_id)
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk{
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk struct mail_index_registered_ext *rext;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk rext = array_idx_modifiable(&index->extensions, ext_id);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk i_assert(rext->expunge_handler != NULL);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen rext->expunge_handler = NULL;
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainenvoid mail_index_register_sync_handler(struct mail_index *index, uint32_t ext_id,
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen mail_index_sync_handler_t *cb,
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen enum mail_index_sync_handler_type type)
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen{
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_index_registered_ext *rext;
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen i_assert(rext->sync_handler.callback == NULL);
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen rext->sync_handler.callback = cb;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen rext->sync_handler.type = type;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen}
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenvoid mail_index_unregister_sync_handler(struct mail_index *index,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen uint32_t ext_id)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen{
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen struct mail_index_registered_ext *rext;
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen rext = array_idx_modifiable(&index->extensions, ext_id);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen i_assert(rext->sync_handler.callback != NULL);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen rext->sync_handler.callback = NULL;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen rext->sync_handler.type = 0;
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen}
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenvoid mail_index_register_sync_lost_handler(struct mail_index *index,
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen mail_index_sync_lost_handler_t *cb)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen{
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen array_append(&index->sync_lost_handlers, &cb, 1);
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen}
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainenvoid mail_index_unregister_sync_lost_handler(struct mail_index *index,
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen mail_index_sync_lost_handler_t *cb)
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen{
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen mail_index_sync_lost_handler_t *const *handlers;
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen unsigned int i, count;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen handlers = array_get(&index->sync_lost_handlers, &count);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen for (i = 0; i < count; i++) {
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen if (handlers[i] == cb) {
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen array_delete(&index->sync_lost_handlers, i, 1);
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen break;
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen }
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen }
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen}
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
5c597df6aa8d81de4053c6986fab7739f3b44b20Timo Sirainen const char *keyword, unsigned int *idx_r)
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen{
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen char *key;
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen void *value;
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen /* keywords_hash keeps a name => index mapping of keywords.
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen Keywords are never removed from it, so the index values are valid
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen for the lifetime of the mail_index. */
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen if (hash_table_lookup_full(index->keywords_hash, keyword,
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen &key, &value)) {
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen *idx_r = POINTER_CAST_TO(value, unsigned int);
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen return TRUE;
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch }
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen *idx_r = UINT_MAX;
fa780a18c41881036af582f7a3473d6399e9d34dTimo Sirainen return FALSE;
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen}
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainenvoid mail_index_keyword_lookup_or_create(struct mail_index *index,
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen const char *keyword,
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen unsigned int *idx_r)
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen{
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen char *keyword_dup;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen i_assert(*keyword != '\0');
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (mail_index_keyword_lookup(index, keyword, idx_r))
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen return;
33525312d3f45995686aa0b538dea1cd6eb936e2Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen keyword = keyword_dup = p_strdup(index->keywords_pool, keyword);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen *idx_r = array_count(&index->keywords);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen hash_table_insert(index->keywords_hash, keyword_dup,
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen POINTER_CAST(*idx_r));
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen array_append(&index->keywords, &keyword, 1);
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen /* keep the array NULL-terminated, but the NULL itself invisible */
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen array_append_zero(&index->keywords);
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen array_delete(&index->keywords, array_count(&index->keywords)-1, 1);
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen}
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index)
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen{
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen return &index->keywords;
c58c12049c883b281c088d47a2a7278c21c390e1Timo Sirainen}
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenstruct mail_keywords *
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainenmail_index_keywords_create(struct mail_index *index,
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen const char *const keywords[])
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen{
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen struct mail_keywords *k;
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen unsigned int src, dest, i, count;
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen count = str_array_length(keywords);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (count == 0) {
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen k = i_new(struct mail_keywords, 1);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen k->index = index;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen k->refcount = 1;
c1d19144dd7b1de6822df6ed1d10af0c9cb38840Timo Sirainen return k;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen }
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen /* @UNSAFE */
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen k = i_malloc(sizeof(struct mail_keywords) +
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen (sizeof(k->idx) * (count-1)));
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen k->index = index;
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen k->refcount = 1;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen /* look up the keywords from index. they're never removed from there
638600575ee95f2513c683ef09cb188f76eacd22Timo Sirainen so we can permanently store indexes to them. */
638600575ee95f2513c683ef09cb188f76eacd22Timo Sirainen for (src = dest = 0; src < count; src++) {
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen mail_index_keyword_lookup_or_create(index, keywords[src],
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen &k->idx[dest]);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* ignore if this is a duplicate */
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen for (i = 0; i < src; i++) {
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen if (k->idx[i] == k->idx[dest])
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen break;
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen }
360123b1b41b7aa8af6c4a91c39046be646cd349Timo Sirainen if (i == src)
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen dest++;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen }
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen k->count = dest;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen return k;
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen}
5494a6bc149da8f02fd25c0434a9d612ac33f659Timo Sirainen
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainenstruct mail_keywords *
fd8b93ca5cbeba64fe6fa5dc98a3e580fb046791Timo Sirainenmail_index_keywords_create_from_indexes(struct mail_index *index,
fd8b93ca5cbeba64fe6fa5dc98a3e580fb046791Timo Sirainen const ARRAY_TYPE(keyword_indexes)
fa780a18c41881036af582f7a3473d6399e9d34dTimo Sirainen *keyword_indexes)
fa780a18c41881036af582f7a3473d6399e9d34dTimo Sirainen{
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen struct mail_keywords *k;
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen const unsigned int *indexes;
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen unsigned int src, dest, i, count;
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen indexes = array_get(keyword_indexes, &count);
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen if (count == 0) {
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen k = i_new(struct mail_keywords, 1);
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen k->index = index;
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen k->refcount = 1;
7d2d0ae1131c8b632cc7e86000adaaf8c9ef42a9Timo Sirainen return k;
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen }
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen /* @UNSAFE */
eaa2d473ed2ecdb9856cd98a33f4d3063cfaf2a1Timo Sirainen k = i_malloc(sizeof(struct mail_keywords) +
eaa2d473ed2ecdb9856cd98a33f4d3063cfaf2a1Timo Sirainen (sizeof(k->idx) * (count-1)));
eaa2d473ed2ecdb9856cd98a33f4d3063cfaf2a1Timo Sirainen k->index = index;
12b4dbf933ee54f7b96968ba150095baa985fdafTimo Sirainen k->refcount = 1;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen /* copy but skip duplicates */
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen for (src = dest = 0; src < count; src++) {
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen for (i = 0; i < src; i++) {
94b0ff77495c3ed14bdd4b5d7ae1eb37e8c9efb5Timo Sirainen if (k->idx[i] == indexes[src])
02e61e13a8360a9d3ec92c5fa5ae60c0f0181b71Timo Sirainen break;
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen }
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen if (i == src)
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen k->idx[dest++] = indexes[src];
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen }
b365bd121cdc87f63e1dd47c5085a27091118e00Timo Sirainen k->count = dest;
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen return k;
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen}
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainenvoid mail_index_keywords_ref(struct mail_keywords *keywords)
1728ff34ee03de825ad3aeed67d19f8ae140ee2eTimo Sirainen{
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen keywords->refcount++;
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen}
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainenvoid mail_index_keywords_unref(struct mail_keywords **_keywords)
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen{
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen struct mail_keywords *keywords = *_keywords;
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen i_assert(keywords->refcount > 0);
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen *_keywords = NULL;
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen if (--keywords->refcount == 0)
49c48631cfd07017d5f93d83713fffe4f13730c4Timo Sirainen i_free(keywords);
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen}
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainenint mail_index_try_open_only(struct mail_index *index)
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen{
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen i_assert(index->fd == -1);
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen /* Note that our caller must close index->fd by itself. */
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen if (index->readonly)
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen errno = EACCES;
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen else {
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen index->fd = nfs_safe_open(index->filepath, O_RDWR);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen index->readonly = FALSE;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen }
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen if (index->fd == -1 && errno == EACCES) {
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen index->fd = open(index->filepath, O_RDONLY);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen index->readonly = TRUE;
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen }
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen if (index->fd == -1) {
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen if (errno != ENOENT) {
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen mail_index_set_syscall_error(index, "open()");
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen return -1;
1433bf361ddb0bba8878c8ada5726d0284edad57Timo Sirainen }
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen /* have to create it */
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return 0;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen }
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return 1;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen}
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainenstatic int
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainenmail_index_try_open(struct mail_index *index)
4a514fb20e04df397842cde11cc9ea92abfe9728Timo Sirainen{
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen int ret;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen i_assert(index->fd == -1);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index))
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return 0;
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen if (ret == 0) {
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen /* it's corrupted - recreate it */
0bf25546c91ccafff9e2cc93368d2d25acb5c39eTimo Sirainen if (index->fd != -1) {
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen if (close(index->fd) < 0)
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen mail_index_set_syscall_error(index, "close()");
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen index->fd = -1;
9fc97c8aa8190df87624d214bcc5d0b5362bec93Timo Sirainen }
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen }
0b4e1043e596bfb36d999dacbf1d4d63ee96d75fTimo Sirainen return ret;
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen}
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainenint mail_index_create_tmp_file(struct mail_index *index,
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen const char *path_prefix, const char **path_r)
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen{
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen mode_t old_mask;
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen const char *path;
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen int fd;
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen i_assert(!MAIL_INDEX_IS_IN_MEMORY(index));
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen path = *path_r = t_strconcat(path_prefix, ".tmp", NULL);
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen old_mask = umask(0);
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen umask(old_mask);
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen if (fd == -1 && errno == EEXIST) {
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen /* stale temp file. unlink and recreate rather than overwriting,
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen just to make sure locking problems won't cause corruption */
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen if (unlink(path) < 0) {
d3e5a14ea363264dcc7640ca7226249d0c27a793Timo Sirainen i_error("unlink(%s) failed: %m", path);
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen return -1;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen }
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen old_mask = umask(0);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen fd = open(path, O_RDWR|O_CREAT|O_EXCL, index->mode);
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen umask(old_mask);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen }
d9a7e950a9cd21f2b4a90ec7759fca9e8fcc7995Timo Sirainen if (fd == -1) {
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mail_index_file_set_syscall_error(index, path, "creat()");
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen return -1;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen }
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen mail_index_fchown(index, fd, path);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen return fd;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen}
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainenstatic int mail_index_open_files(struct mail_index *index,
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen enum mail_index_open_flags flags)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen{
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen int ret;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen ret = mail_transaction_log_open(index->log);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (ret == 0) {
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen return 0;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen /* if dovecot.index exists, read it first so that we can get
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen the correct indexid and log sequence */
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen (void)mail_index_try_open(index);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen if (index->indexid == 0) {
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* Create a new indexid for us. If we're opening index
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen into memory, index->map doesn't exist yet. */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen index->indexid = ioloop_time;
d508ab8db2b0f74b5e225d199b4aaa5293342746Timo Sirainen index->initial_create = TRUE;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (index->map != NULL)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen index->map->hdr.indexid = index->indexid;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen }
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen ret = mail_transaction_log_create(index->log, FALSE);
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen if (index->map != NULL) {
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen /* log creation could have changed it if someone else
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen just created it. */
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen index->map->hdr.indexid = index->indexid;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen }
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen index->initial_create = FALSE;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen }
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen if (ret >= 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen ret = index->map != NULL ? 1 : mail_index_try_open(index);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (ret == 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* corrupted */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_transaction_log_close(index->log);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen ret = mail_transaction_log_create(index->log, TRUE);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (ret == 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (index->map != NULL)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_unmap(&index->map);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen index->map = mail_index_map_alloc(index);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (ret < 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* open/create failed, fallback to in-memory indexes */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_CREATE) == 0)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return -1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (mail_index_move_to_memory(index) < 0)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return -1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (index->cache == NULL)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen index->cache = mail_cache_open_or_create(index);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return 1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen}
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenstatic int
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenmail_index_open_opened(struct mail_index *index,
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen enum mail_index_open_flags flags)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen{
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen int ret;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen i_assert(index->map != NULL);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if ((index->map->hdr.flags & MAIL_INDEX_HDR_FLAG_CORRUPTED) != 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* index was marked corrupted. we'll probably need to
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen recreate the files. */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_unmap(&index->map);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_close_file(index);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_transaction_log_close(index->log);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if ((ret = mail_index_open_files(index, flags)) <= 0)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return ret;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen index->open_count++;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return 1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen}
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen{
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen int ret;
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen if (index->open_count > 0) {
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen if ((ret = mail_index_open_opened(index, flags)) <= 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* doesn't exist and create flag not used */
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen }
e58f291e777b25c1286965b80e142ada6fdacb03Timo Sirainen return ret;
e58f291e777b25c1286965b80e142ada6fdacb03Timo Sirainen }
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen index->filepath = MAIL_INDEX_IS_IN_MEMORY(index) ?
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen i_strdup("(in-memory index)") :
494a5de15db3b2806ab31d5ecc3e1c306ae14d06Timo Sirainen i_strconcat(index->dir, "/", index->prefix, NULL);
e58f291e777b25c1286965b80e142ada6fdacb03Timo Sirainen
e58f291e777b25c1286965b80e142ada6fdacb03Timo Sirainen index->readonly = FALSE;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen index->nodiskspace = FALSE;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen index->index_lock_timeout = FALSE;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen index->log_sync_locked = FALSE;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen index->flags = flags;
9d4c027e7de01ab948d6221bc27c9b45d32d1ea5Timo Sirainen index->readonly = (flags & MAIL_INDEX_OPEN_FLAG_READONLY) != 0;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen index->fsync_mode != FSYNC_MODE_ALWAYS)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_fatal("nfs flush requires mail_fsync=always");
08ed4ab71fd2a4e800d9025a736f0f46b771ea90Timo Sirainen if ((flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0 &&
08ed4ab71fd2a4e800d9025a736f0f46b771ea90Timo Sirainen (flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) == 0)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_fatal("nfs flush requires mmap_disable=yes");
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen /* NOTE: increase open_count only after mail_index_open_files().
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen it's used elsewhere to check if we're doing an initial opening
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen of the index files */
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen if ((ret = mail_index_open_files(index, flags)) <= 0) {
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen /* doesn't exist and create flag not used */
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen mail_index_close_nonopened(index);
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen return ret;
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen }
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen index->open_count++;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_assert(index->map != NULL);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_index_alloc_cache_index_opened(index);
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen return 1;
0bd259973f98837cf0e41fdee3e2a578e51ad09eTimo Sirainen}
0bd259973f98837cf0e41fdee3e2a578e51ad09eTimo Sirainen
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainenint mail_index_open_or_create(struct mail_index *index,
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen enum mail_index_open_flags flags)
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen{
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen int ret;
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen flags |= MAIL_INDEX_OPEN_FLAG_CREATE;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen ret = mail_index_open(index, flags);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen i_assert(ret != 0);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return ret < 0 ? -1 : 0;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen}
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenvoid mail_index_close_file(struct mail_index *index)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen{
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (index->fd != -1) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (close(index->fd) < 0)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_set_syscall_error(index, "close()");
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen index->fd = -1;
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen}
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenstatic void mail_index_close_nonopened(struct mail_index *index)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen{
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen i_assert(!index->syncing);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen i_assert(index->views == NULL);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (index->map != NULL)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_unmap(&index->map);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_index_close_file(index);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_transaction_log_close(index->log);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (index->cache != NULL)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_cache_free(&index->cache);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_free_and_null(index->filepath);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen index->indexid = 0;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen}
d3e5a14ea363264dcc7640ca7226249d0c27a793Timo Sirainen
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainenvoid mail_index_close(struct mail_index *index)
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen{
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen i_assert(index->open_count > 0);
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mail_index_alloc_cache_index_closing(index);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (--index->open_count == 0)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen mail_index_close_nonopened(index);
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen}
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainenint mail_index_unlink(struct mail_index *index)
8f70c97f7ab7b7e1683ed5cfcd96721a899c2520Timo Sirainen{
8f70c97f7ab7b7e1683ed5cfcd96721a899c2520Timo Sirainen const char *path;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen int last_errno = 0;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index) || index->readonly)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen return 0;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* main index */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (unlink(index->filepath) < 0 && errno != ENOENT)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen last_errno = errno;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* logs */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen path = t_strconcat(index->filepath, MAIL_TRANSACTION_LOG_SUFFIX, NULL);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (unlink(path) < 0 && errno != ENOENT)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen last_errno = errno;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen path = t_strconcat(index->filepath,
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen MAIL_TRANSACTION_LOG_SUFFIX".2", NULL);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (unlink(path) < 0 && errno != ENOENT)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen last_errno = errno;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* cache */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen path = t_strconcat(index->filepath, MAIL_CACHE_FILE_SUFFIX, NULL);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (unlink(path) < 0 && errno != ENOENT)
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen last_errno = errno;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen if (last_errno == 0)
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen return 0;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen else {
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen errno = last_errno;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen return -1;
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen }
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen}
a4e2101473cfd7ce960fc49b3ce097c3f89ec2adTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenint mail_index_reopen_if_changed(struct mail_index *index)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen{
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct stat st1, st2;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index))
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return 0;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (index->fd == -1)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return mail_index_try_open_only(index);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NFS_FLUSH) != 0)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen nfs_flush_file_handle_cache(index->filepath);
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (nfs_safe_stat(index->filepath, &st2) < 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (errno == ENOENT)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return 0;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_set_syscall_error(index, "stat()");
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return -1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (fstat(index->fd, &st1) < 0) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen if (!ESTALE_FSTAT(errno)) {
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_set_syscall_error(index, "fstat()");
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return -1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* deleted/recreated, reopen */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen } else if (st1.st_ino == st2.st_ino &&
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen CMP_DEV_T(st1.st_dev, st2.st_dev)) {
1f4399a277b861419b82758ab0462e90c00a4c41Timo Sirainen /* the same file */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return 1;
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen }
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen /* new file, new locks. the old fd can keep its locks, they don't
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen matter anymore as no-one's going to modify the file. */
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen mail_index_close_file(index);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen return mail_index_try_open_only(index);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen}
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainenint mail_index_refresh(struct mail_index *index)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen{
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen int ret;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen return ret <= 0 ? -1 : 0;
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen}
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainenstruct mail_cache *mail_index_get_cache(struct mail_index *index)
9b00ecffbe74fd864d0d72e6112ec53b86f619baTimo Sirainen{
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen return index->cache;
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen}
3e0bae44b65f5c46989fcef3d1e07203f496327eTimo Sirainen
0bd259973f98837cf0e41fdee3e2a578e51ad09eTimo Sirainenvoid mail_index_set_error(struct mail_index *index, const char *fmt, ...)
0bd259973f98837cf0e41fdee3e2a578e51ad09eTimo Sirainen{
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen va_list va;
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen i_free(index->error);
e4cb3bfcd42f1f2c9e676ece6f7f53803f5c6a16Timo Sirainen
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen if (fmt == NULL)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen index->error = NULL;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen else {
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen va_start(va, fmt);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen index->error = i_strdup_vprintf(fmt, va);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen va_end(va);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_error("%s", index->error);
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen }
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen}
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenbool mail_index_is_in_memory(struct mail_index *index)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen{
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen return MAIL_INDEX_IS_IN_MEMORY(index);
636f017be100bce67d66fd3ae1544a47681efd33Timo Sirainen}
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainenint mail_index_move_to_memory(struct mail_index *index)
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen{
69af83d4e6c2c5c825a17edd7a41a4fb014caa8fTimo Sirainen struct mail_index_map *map;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (MAIL_INDEX_IS_IN_MEMORY(index))
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen return index->map == NULL ? -1 : 0;
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) != 0)
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen return -1;
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen /* set the index as being into memory */
6f970b9a0dadb80e120d017c75c637b5a3879dacTimo Sirainen i_free_and_null(index->dir);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_free(index->filepath);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen index->filepath = i_strdup("(in-memory index)");
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (index->map == NULL) {
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* index was never even opened. just mark it as being in
e7d0bea63a08b08c47c4b5c187d2cb7127859657Timo Sirainen memory and let the caller re-open the index. */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen i_assert(index->fd == -1);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen return -1;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen }
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen /* move index map to memory */
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen if (!MAIL_INDEX_MAP_IS_IN_MEMORY(index->map)) {
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen map = mail_index_map_clone(index->map);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_index_unmap(&index->map);
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen index->map = map;
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen }
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (index->log != NULL) {
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen /* move transaction log to memory */
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen mail_transaction_log_move_to_memory(index->log);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen }
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (index->fd != -1) {
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen if (close(index->fd) < 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_set_syscall_error(index, "close()");
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen index->fd = -1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen return 0;
8ca217bf3aa23c7922d0d4aa44fcd2320416d61cMartti Rannanjärvi}
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenvoid mail_index_mark_corrupted(struct mail_index *index)
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen{
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen index->indexid = 0;
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainen index->map->hdr.flags |= MAIL_INDEX_HDR_FLAG_CORRUPTED;
cb933f0a570a9cef5c975eadb818aa6b1002a269Timo Sirainen if (!index->readonly) {
cb933f0a570a9cef5c975eadb818aa6b1002a269Timo Sirainen if (unlink(index->filepath) < 0 &&
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen errno != ENOENT && errno != ESTALE)
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen mail_index_set_syscall_error(index, "unlink()");
4654cf737f538f5de032b8c9908913f121917366Timo Sirainen (void)mail_transaction_log_unlink(index->log);
4654cf737f538f5de032b8c9908913f121917366Timo Sirainen }
4654cf737f538f5de032b8c9908913f121917366Timo Sirainen}
4654cf737f538f5de032b8c9908913f121917366Timo Sirainen
4654cf737f538f5de032b8c9908913f121917366Timo Sirainenbool mail_index_is_deleted(struct mail_index *index)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen return index->index_delete_requested || index->index_deleted;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen}
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenint mail_index_get_modification_time(struct mail_index *index, time_t *mtime_r)
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen{
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct stat st;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
ae2b61a8c6318e56dabd44de17e227c95985aedaTimo Sirainen if (mail_transaction_log_get_mtime(index->log, mtime_r) < 0)
ae2b61a8c6318e56dabd44de17e227c95985aedaTimo Sirainen return -1;
ae2b61a8c6318e56dabd44de17e227c95985aedaTimo Sirainen
e36574dadcac802d6780fa94ee45951e75594c96Timo Sirainen if (*mtime_r == 0) {
ae2b61a8c6318e56dabd44de17e227c95985aedaTimo Sirainen if (stat(index->filepath, &st) < 0) {
ae2b61a8c6318e56dabd44de17e227c95985aedaTimo Sirainen mail_index_set_syscall_error(index, "stat()");
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen return -1;
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen }
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen *mtime_r = st.st_mtime;
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen }
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen return 0;
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen}
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainenvoid mail_index_fchown(struct mail_index *index, int fd, const char *path)
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen{
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen mode_t mode;
c58906589cafc32df4c04ffbef933baadd3f2276Timo Sirainen
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen if (index->gid == (gid_t)-1) {
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen /* no gid changing */
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen return;
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen } else if (fchown(fd, (uid_t)-1, index->gid) == 0) {
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen /* success */
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen return;
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen } if ((index->mode & 0060) >> 3 == (index->mode & 0006)) {
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen /* group and world permissions are the same, so group doesn't
6dd77763f5451269ace733579cf58f2f3b18bca4Timo Sirainen really matter. ignore silently. */
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen return;
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen }
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen if (errno != EPERM)
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mail_index_file_set_syscall_error(index, path, "fchown()");
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen else {
0df9428baed48afaff90b4d4f03792d2fd756a43Timo Sirainen mail_index_set_error(index, "%s",
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen eperm_error_get_chgrp("fchown", path, index->gid,
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen index->gid_origin));
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen }
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen /* continue, but change permissions so that only the common
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen subset of group and world is used. this makes sure no one
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen gets any extra permissions. */
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen mode = ((index->mode & 0060) >> 3) & (index->mode & 0006);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen mode |= (mode << 3) | (index->mode & 0600);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen if (fchmod(fd, mode) < 0)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen mail_index_file_set_syscall_error(index, path, "fchmod()");
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen}
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainenvoid mail_index_set_syscall_error(struct mail_index *index,
4b1781e4c64be52e25b5994e5242dbe696cc7d29Timo Sirainen const char *function)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen{
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen mail_index_file_set_syscall_error(index, index->filepath, function);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen}
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainenvoid mail_index_file_set_syscall_error(struct mail_index *index,
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen const char *filepath,
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen const char *function)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen{
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen const char *errstr;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen i_assert(filepath != NULL);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen i_assert(function != NULL);
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (ENOSPACE(errno)) {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen index->nodiskspace = TRUE;
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen if ((index->flags & MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY) == 0)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen return;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen }
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen if (errno == EACCES) {
15bfe73fb3988bb80e6afe6a60b9a715c7207600Timo Sirainen function = t_strcut(function, '(');
4809537f0c5a2e1cee9559ec842cc869884d2cb7Timo Sirainen if (strcmp(function, "creat") == 0 ||
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen strncmp(function, "file_dotlock_", 13) == 0)
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen errstr = eacces_error_get_creating(function, filepath);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen else
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen errstr = eacces_error_get(function, filepath);
d2e74f2af690b8e2d536400f02f397cbed1334b7Timo Sirainen mail_index_set_error(index, "%s", errstr);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen } else {
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const char *suffix = errno != EFBIG ? "" :
8709b2fe6ec2b5ca1d90a63490f8371472062efdTimo Sirainen " (process was started with ulimit -f limit)";
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mail_index_set_error(index, "%s failed with file %s: "
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen "%m%s", function, filepath, suffix);
949fa97a4ab5c62e4db73c3973e35ae3b73a2b23Timo Sirainen }
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen}
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainenconst char *mail_index_get_error_message(struct mail_index *index)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen{
e353d03d3643f380dc7e6dc29a512dec86b8a3deTimo Sirainen return index->error;
e353d03d3643f380dc7e6dc29a512dec86b8a3deTimo Sirainen}
e353d03d3643f380dc7e6dc29a512dec86b8a3deTimo Sirainen
e353d03d3643f380dc7e6dc29a512dec86b8a3deTimo Sirainenvoid mail_index_reset_error(struct mail_index *index)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen{
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (index->error != NULL) {
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen i_free(index->error);
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen index->error = NULL;
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen }
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen index->nodiskspace = FALSE;
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen index->index_lock_timeout = FALSE;
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen}
4225ae95dd2110fe678ee70c64be14784a53c364Timo Sirainen