mail-index.h revision b37634f5bf23ff8c72b88ef6966fd5c730017419
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifndef __MAIL_INDEX_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define __MAIL_INDEX_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "byteorder.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "file-dotlock.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "message-parser.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "imap-util.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define MAIL_INDEX_MAJOR_VERSION 3
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define MAIL_INDEX_MINOR_VERSION 0
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define INDEX_FILE_PREFIX ".imap.index"
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenenum mail_index_open_flags {
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* Create index if it doesn't exist */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen MAIL_INDEX_OPEN_FLAG_CREATE = 0x01,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* Update \Recent flag counters */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen MAIL_INDEX_OPEN_FLAG_UPDATE_RECENT = 0x02,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* Compressing and cache updates are not performed */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen MAIL_INDEX_OPEN_FLAG_FAST = 0x04,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen /* Invalidate memory maps before accessing them */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen MAIL_INDEX_OPEN_FLAG_MMAP_INVALIDATE = 0x08,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* internal: we're creating the index */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen _MAIL_INDEX_OPEN_FLAG_CREATING = 0x100
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainenenum mail_index_header_compat {
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen};
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenenum mail_index_header_flag {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Rebuild flag is set while index is being rebuilt or when
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen some error is noticed in the index file. If this flag is set,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen the index shouldn't be used before rebuilding it. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_HDR_FLAG_FSCK = NBO32_BIT0,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_HDR_FLAG_REBUILD = NBO32_BIT1,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_HDR_FLAG_COMPRESS = NBO32_BIT2,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_HDR_FLAG_COMPRESS_CACHE = NBO32_BIT3,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_HDR_FLAG_DIRTY_MESSAGES = NBO32_BIT4,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_HDR_FLAG_DIRTY_CUSTOMFLAGS = NBO32_BIT5,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen MAIL_INDEX_HDR_FLAG_MAILDIR_NEW = NBO32_BIT6
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen};
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_index_record_flag {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* If binary flags are set, it's not checked whether mail is
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen missing CRs. So this flag may be set as an optimization for
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen regular non-binary mails as well if it's known that it contains
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen valid CR+LF line breaks. */
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen MAIL_INDEX_FLAG_BINARY_HEADER = NBO32_BIT0,
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen MAIL_INDEX_FLAG_BINARY_BODY = NBO32_BIT1,
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen /* Mail flags have been changed in index, but not written into
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen actual mailbox yet. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_FLAG_DIRTY = NBO32_BIT2,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Maildir: Mail file is in new/ dir instead of cur/ */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_FLAG_MAILDIR_NEW = NBO32_BIT3,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Mail header or body is known to contain NUL characters. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_FLAG_HAS_NULS = NBO32_BIT4,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Mail header or body is known to not contain NUL characters. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_FLAG_HAS_NO_NULS = NBO32_BIT5
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen};
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainenenum mail_lock_type {
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen MAIL_LOCK_UNLOCK = 0,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen MAIL_LOCK_SHARED,
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen MAIL_LOCK_EXCLUSIVE
5c1a8aee989af87bddefd71e2aa83aa2bd695155Timo Sirainen};
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainenenum mail_lock_notify_type {
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen /* Mailbox is locked, will abort in secs_left */
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen /* Mailbox lock looks stale, will override in secs_left */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Index is locked, will abort in secs_left */
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen MAIL_LOCK_NOTIFY_INDEX_ABORT
ec1e30ecc38f0deddaf655413cf02d5972ddbc70Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_index_error {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* No errors */
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen MAIL_INDEX_ERROR_NONE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Internal error, see get_error_text() for more information. */
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen MAIL_INDEX_ERROR_INTERNAL,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Index is now in inconsistent state with the previous known state,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen meaning that the message IDs etc. may have changed - only way to
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen recover this would be to fully close the mailbox and reopen it.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen With IMAP this would mean a forced disconnection since we can't do
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen forced CLOSE. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_ERROR_INCONSISTENT,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* We ran out of available disk space. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_ERROR_DISKSPACE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Mail index locking timeouted */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_ERROR_INDEX_LOCK_TIMEOUT,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Mailbox locking timeouted */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_ERROR_MAILBOX_LOCK_TIMEOUT
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainentypedef void mail_lock_notify_callback_t(enum mail_lock_notify_type notify_type,
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen unsigned int secs_left, void *context);
93b29720c5141f787bd1861796867e4595c9d084Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_header {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* major version is increased only when you can't have backwards
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen compatibility. minor version is increased when header size is
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen increased to contain new non-critical fields. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t major_version;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t minor_version;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t header_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t reserved;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t indexid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t used_file_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t sync_id; /* re-mmap() when changed, required only
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if file size is shrinked */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t uid_validity;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t next_uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t messages_count;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t seen_messages_count;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t deleted_messages_count;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t last_nonrecent_uid;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* these UIDs may not exist and may not even be unseen */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t first_unseen_uid_lowwater;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t first_deleted_uid_lowwater;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen};
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstruct mail_index_record {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t uid;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t msg_flags;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen uint32_t data_offset;
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen};
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainenstruct mail_index {
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* Note that opening same index twice in the same process is a bad
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen idea since they share the same file locks. As soon one of the
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen indexes is closed, the locks in second index are dropped which
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen especially hurts modify log since it keeps locks all the time. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen int (*open)(struct mail_index *index, enum mail_index_open_flags flags);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* Free index from memory. */
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen void (*free)(struct mail_index *index);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen /* Lock/unlock index. May block. Note that unlocking must not
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen reset error from get_last_error() as unlocking can be done as
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen a cleanup after some other function failed. Index is always
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen mmap()ed after set_lock() succeeds.
bef8712387812fc5d9496b9958935c6d0c418777Timo Sirainen
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen Trying to change a shared lock into exclusive lock is a fatal
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen error, since it may create a deadlock. Even though operating
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen system should detect it and fail, it's not a good idea to even
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen let it happen. Better ways to do this would be to a) mark the
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen data to be updated later, b) use try_lock() if the update is
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen preferred but not required, c) unlock + lock again, but make
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen sure that won't create race conditions. */
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen int (*set_lock)(struct mail_index *index,
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen enum mail_lock_type lock_type);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen /* Try locking the index. Returns TRUE if the lock was got and
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen FALSE if lock isn't possible to get currently or some other error
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen occured. Never blocks. */
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen int (*try_lock)(struct mail_index *index,
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen enum mail_lock_type lock_type);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen /* If we have to wait for the lock, the given lock notify function
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen is called once in a while. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void (*set_lock_notify_callback)(struct mail_index *index,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen mail_lock_notify_callback_t *callback,
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen void *context);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Rebuild the whole index. Note that this changes the indexid
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen so all the other files must also be rebuilt after this call.
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen Index MUST NOT have shared lock, but exclusive lock or no lock at
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen all is fine. Note that this function may leave the index
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen exclusively locked, and always sets index->inconsistent = TRUE. */
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen int (*rebuild)(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen /* Verify that the index is valid. If anything invalid is found,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index is set inconsistent and to be rebuilt at next open.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Same locking issues as with rebuild(). */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen int (*fsck)(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* Synchronize the index with the mailbox. Index must not have shared
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen lock when calling this function. The data_lock_type specifies what
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen lock should be set to data file (mbox file). This function may
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen leave the index in ANY locking state. If changes is non-NULL, it's
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen set to TRUE if any changes were noticed. If minimal_sync is TRUE,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen we do as little as possible to get data file locked (ie. noop with
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen maildir). */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int (*sync_and_lock)(struct mail_index *index, int minimal_sync,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_lock_type data_lock_type, int *changes);
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* Returns the index header (never fails). The index needs to be
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen locked before calling this function, and must be kept locked as
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen long as you keep using the returned structure. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_header *(*get_header)(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* sequence -> data lookup. The index needs to be locked before calling
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen this function, and must be kept locked as long as you keep using
5529671faac3c5672a948be93091056736c7afffTimo Sirainen the returned structure. */
5529671faac3c5672a948be93091056736c7afffTimo Sirainen struct mail_index_record *(*lookup)(struct mail_index *index,
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen unsigned int seq);
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* Return the next record after specified record, or NULL if it was
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen last record. The index must be locked all the time between
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen lookup() and last next() call. rec must not have been expunged. */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen struct mail_index_record *(*next)(struct mail_index *index,
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen struct mail_index_record *rec);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen /* Find first existing UID in range. Sequence number is also retrieved
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if seq_r is non-NULL. */
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen struct mail_index_record *(*lookup_uid_range)(struct mail_index *index,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen unsigned int first_uid,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen unsigned int last_uid,
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen unsigned int *seq_r);
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen /* Open mail file and return it as mmap()ed IStream. If we fail,
7c5b51bdf43a98e12c654ad437e0b258c5fffbc1Timo Sirainen we return NULL and set deleted = TRUE if failure was because the
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen mail was just deleted (ie. not an error). received_date is set
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen if it's non-NULL. */
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen struct istream *(*open_mail)(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_record *rec,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t *received_date, int *deleted);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen /* Returns received date of message, or (time_t)-1 if error occured. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t (*get_received_date)(struct mail_index *index,
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen struct mail_index_record *rec);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen /* Expunge mails from index. Modifylog is also updated. The
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index must be exclusively locked before calling this function.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen first_rec+1 .. last_rec-1 range may contain already expunged
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen records.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Note that all record pointers are invalidated after this call as
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen expunging may radically modify the file. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int (*expunge)(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_record *first_rec,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_record *last_rec,
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen unsigned int first_seq, unsigned int last_seq,
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen int external_change);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen /* Update mail flags. The index must be exclusively locked before
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen calling this function. */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen int (*update_flags)(struct mail_index *index,
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen struct mail_index_record *rec, unsigned int seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum modify_type modify_type, enum mail_flags flags,
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen int external_change);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Append a new record to index. The index must be exclusively
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen locked before calling this function. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_record *(*append)(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* Returns the last error code. */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen enum mail_index_error (*get_last_error)(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* Returns the full error message for last error. This message may
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen contain paths etc. so it shouldn't be shown to users. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *(*get_last_error_text)(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* private: */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_cache *cache;
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen struct mail_modify_log *modifylog;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen struct mail_custom_flags *custom_flags;
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen char *dir; /* directory where to place the index files */
62950eeff28f00989a17b20eeade3af7e200c6bcTimo Sirainen char *filepath; /* index file path */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen char *mailbox_path; /* file/directory for mailbox location */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen char *control_dir; /* destination for control files */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen unsigned int indexid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int sync_id;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen /* updated whenever exclusive lock is set/unset */
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen unsigned int excl_lock_counter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* updated whenever expunge() is called */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int expunge_counter;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen int mbox_fd;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct istream *mbox_stream;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_lock_type mbox_lock_type;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct dotlock mbox_dotlock;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* these counters can be used to check that we've synced the mailbox
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen after locking it */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int mbox_lock_counter;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int mbox_sync_counter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* last mbox sync: */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t mbox_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen dev_t mbox_dev;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ino_t mbox_ino;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen /* last maildir sync: */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t last_new_mtime, last_uidlist_mtime;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t maildir_cur_dirty, next_dirty_flush;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen int maildir_lock_fd;
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen pool_t new_filename_pool;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen struct hash_table *new_filenames;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen int fd; /* opened index file */
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen char *error; /* last error message */
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen void *mmap_base;
b0a446671b8f09a1d2ed1d8c86a47298309e989dTimo Sirainen size_t mmap_used_length;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t mmap_full_length;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_header *header;
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen size_t header_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_lock_type lock_type;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen time_t file_sync_stamp;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int first_recent_uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_lock_notify_callback_t *lock_notify_cb;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void *lock_notify_context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* these fields are OR'ed to the fields in index header once we
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen get around grabbing exclusive lock */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int set_flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int cache_later_locks;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int anon_mmap:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int mmap_invalidate:1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int opened:1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int rebuilding:1;
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen unsigned int mail_read_mmaped:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int inconsistent:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int nodiskspace:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int index_lock_timeout:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int allow_new_custom_flags:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int mailbox_readonly:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int mailbox_lock_timeout:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int maildir_keep_new:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int maildir_have_new:1;
f99575e1d6cd251bd7b6d0654bd75b475e6a894cTimo Sirainen unsigned int maildir_synced_once:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifdef DEV_T_STRUCT
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen/* we can't initialize dev_t as 0, and we don't know what it actually
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen contains, so don't initialize them. gcc's -W option should be disabled
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen with this or we get warnings.. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# define MAIL_INDEX_PRIVATE_FILL 0
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#else
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* needed to remove annoying warnings about not initializing all struct
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen members.. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define MAIL_INDEX_PRIVATE_FILL \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0, 0, 0, 0, { 0, 0, 0 }, 0, 0, 0, \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen 0, 0, 0, 0, 0, 0, 0
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#endif
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* defaults - same as above but prefixed with mail_index_. */
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags);
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenint mail_index_set_lock(struct mail_index *index,
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen enum mail_lock_type lock_type);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainenint mail_index_try_lock(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_lock_type lock_type);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_set_lock_notify_callback(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_lock_notify_callback_t *callback,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void *context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_fsck(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_header *mail_index_get_header(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_record *mail_index_lookup(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int seq);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstruct mail_index_record *mail_index_next(struct mail_index *index,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_record *rec);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstruct mail_index_record *
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenmail_index_lookup_uid_range(struct mail_index *index, unsigned int first_uid,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen unsigned int last_uid, unsigned int *seq_r);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenint mail_index_expunge(struct mail_index *index,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_record *first_rec,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_record *last_rec,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen unsigned int first_seq, unsigned int last_seq,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen int external_change);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_update_flags(struct mail_index *index,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_record *rec, unsigned int seq,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen enum modify_type modify_type, enum mail_flags flags,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen int external_change);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstruct mail_index_record *mail_index_append(struct mail_index *index);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenenum mail_index_error mail_index_get_last_error(struct mail_index *index);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenconst char *mail_index_get_last_error_text(struct mail_index *index);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen/* INTERNAL: */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenvoid mail_index_init(struct mail_index *index, const char *dir);
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainenint mail_index_mmap_update(struct mail_index *index);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenvoid mail_index_init_header(struct mail_index_header *hdr);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenvoid mail_index_close(struct mail_index *index);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenint mail_index_fmdatasync(struct mail_index *index, size_t size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenvoid mail_index_mark_flag_changes(struct mail_index *index,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_record *rec,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen enum mail_flags old_flags,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen enum mail_flags new_flags);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_rebuild(struct mail_index *index);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_compress(struct mail_index *index);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenint mail_index_truncate(struct mail_index *index);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenint mail_index_expunge_record_range(struct mail_index *index,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_record *first_rec,
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen struct mail_index_record *last_rec);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* Maximum allowed UID number. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#define MAX_ALLOWED_UID 4294967295U /* 2^32 - 1 */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* Max. mmap()ed size for a message */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#define MAIL_MMAP_BLOCK_SIZE (1024*256)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* Block size when read()ing message. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#define MAIL_READ_BLOCK_SIZE (1024*8)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* Delete unused non-local temp files after 24h. Just to be sure we don't
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen delete it too early. The temp files don't harm much anyway. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define TEMP_FILE_TIMEOUT (60*24)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* number of records to always keep allocated in index file,
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen either used or unused */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#define INDEX_MIN_RECORDS_COUNT 64
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* when empty space in index file gets full, grow the file n% larger */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#define INDEX_GROW_PERCENTAGE 10
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* ftruncate() the index file when only n% of it is in use */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#define INDEX_TRUNCATE_PERCENTAGE 30
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen/* don't truncate whole file anyway, keep n% of the empty space */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define INDEX_TRUNCATE_KEEP_PERCENTAGE 10
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen/* Compress the file when deleted space reaches n% of total size */
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen#define INDEX_COMPRESS_PERCENTAGE 50
1b3bb8d39686ed24730cbc31cc9a33dc62c8c6c3Timo Sirainen/* Compress the file when searching deleted records tree has to go this deep */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define INDEX_COMPRESS_DEPTH 10
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen/* uoff_t to index file for given record */
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen#define INDEX_FILE_POSITION(index, ptr) \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ((uoff_t) ((char *) (ptr) - (char *) ((index)->mmap_base)))
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen/* record for given index */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define INDEX_RECORD_AT(index, idx) \
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen ((struct mail_index_record *) \
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen ((char *) index->mmap_base + (index)->header_size) + (idx))
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainen/* returns the next record after last one */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define INDEX_END_RECORD(index) \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ((struct mail_index_record *) \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen ((char *) (index)->mmap_base + (index)->mmap_used_length))
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen/* index number for uoff_t position */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen#define INDEX_POSITION_INDEX(index, pos) \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen (((pos) - (index)->header_size) / \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen sizeof(struct mail_index_record))
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen/* index number for given record */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen#define INDEX_RECORD_INDEX(index, ptr) \
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen INDEX_POSITION_INDEX(index, INDEX_FILE_POSITION(index, ptr))
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen/* mark the index corrupted */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen#define INDEX_MARK_CORRUPTED(index) \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen STMT_START { \
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen (index)->set_flags |= MAIL_INDEX_HDR_FLAG_REBUILD; \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen } STMT_END
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* get number of records in mmaped index */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen#define MAIL_INDEX_RECORD_COUNT(index) \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ((index->mmap_used_length - (index)->header_size) / \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen sizeof(struct mail_index_record))
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen/* minimum size for index file */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen#define INDEX_FILE_MIN_SIZE(index) \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ((index)->header_size + \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen INDEX_MIN_RECORDS_COUNT * sizeof(struct mail_index_record))
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen/* enum mail_lock_type to fcntl() lock type */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define MAIL_LOCK_TO_FLOCK(lock_type) \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ((lock_type) == MAIL_LOCK_EXCLUSIVE ? F_WRLCK : \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen (lock_type) == MAIL_LOCK_SHARED ? F_RDLCK : F_UNLCK)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define INDEX_IS_IN_MEMORY(index) \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen ((index)->anon_mmap)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* Returns alignmentation for given size */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define INDEX_ALIGN(size) \
287ba82a8da3eaa473b5735d4eeac2fb4c5d8117Timo Sirainen (((size) + INDEX_ALIGN_SIZE-1) & ~((unsigned int) INDEX_ALIGN_SIZE-1))
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen#endif
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen