c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef MAIL_INDEX_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define MAIL_INDEX_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
80c1d98d3638b71e57a39cafa88b9122bf8169c6Timo Sirainen#include "file-lock.h"
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen#include "fsync-mode.h"
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen#include "guid.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-types.h"
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen#include "seq-range-array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen#define MAIL_INDEX_MAJOR_VERSION 7
795aeec896095aa8f08cc5d3282c88cc0921bff6Timo Sirainen#define MAIL_INDEX_MINOR_VERSION 3
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen#define MAIL_INDEX_HEADER_MIN_SIZE 120
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e307c8202280c6db60a0615381f18cac33e46a53Timo Sirainen/* Log a warning when transaction log has been locked for this many seconds.
e307c8202280c6db60a0615381f18cac33e46a53Timo Sirainen This lock is held also between mail_index_sync_begin()..commit(). */
e307c8202280c6db60a0615381f18cac33e46a53Timo Sirainen#define MAIL_TRANSACTION_LOG_LOCK_WARN_SECS 30
e307c8202280c6db60a0615381f18cac33e46a53Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_index_open_flags {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Create index if it doesn't exist */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_OPEN_FLAG_CREATE = 0x01,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* Don't try to mmap() index files */
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE = 0x04,
8887bf3757d51d73887dd20b1db3334d867d3817Timo Sirainen /* Rely on O_EXCL when creating dotlocks */
8887bf3757d51d73887dd20b1db3334d867d3817Timo Sirainen MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL = 0x10,
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen /* Flush NFS attr/data/write cache when necessary */
51b979b6414b940f04677a7e2d064be119345954Timo Sirainen MAIL_INDEX_OPEN_FLAG_NFS_FLUSH = 0x40,
c53e8ee216904ffe6de4f6518d9f9f5107b7610eTimo Sirainen /* Open the index read-only */
589a9c6e8ee22071c14171c04bfc6bfe17121871Timo Sirainen MAIL_INDEX_OPEN_FLAG_READONLY = 0x80,
589a9c6e8ee22071c14171c04bfc6bfe17121871Timo Sirainen /* Create backups of dovecot.index files once in a while */
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen MAIL_INDEX_OPEN_FLAG_KEEP_BACKUPS = 0x100,
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen /* If we run out of disk space, fail modifications instead of moving
ef5fb27361cc5e15766e85e28355750ff04b13c9Timo Sirainen indexes to memory. */
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen MAIL_INDEX_OPEN_FLAG_NEVER_IN_MEMORY = 0x200,
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen /* We're only going to save new messages to the index.
18d92dbbb752c79dc461514e52f7ef11847e636bTimo Sirainen Avoid unnecessary reads. */
f883b315ca72073b58020798e6d907340b327228Timo Sirainen MAIL_INDEX_OPEN_FLAG_SAVEONLY = 0x400,
f883b315ca72073b58020798e6d907340b327228Timo Sirainen /* Enable debug logging */
f883b315ca72073b58020798e6d907340b327228Timo Sirainen MAIL_INDEX_OPEN_FLAG_DEBUG = 0x800,
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen /* MAIL_INDEX_MAIL_FLAG_DIRTY can be used as a backend-specific flag.
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen All special handling of the flag is disabled by this. */
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen MAIL_INDEX_OPEN_FLAG_NO_DIRTY = 0x1000,
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen};
a53cb86b4d733d9c48ee4d285bed477c80825804Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_index_header_compat_flags {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_index_header_flag {
b7b81543899e306c71e6152516d8698416162bcbTimo Sirainen /* Index file is corrupted, reopen or recreate it. */
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainen MAIL_INDEX_HDR_FLAG_CORRUPTED = 0x0001,
02d6628c1fea2990c67c60b111c8e68867160885Timo Sirainen MAIL_INDEX_HDR_FLAG_HAVE_DIRTY = 0x0002,
02d6628c1fea2990c67c60b111c8e68867160885Timo Sirainen /* Index has been fsck'd. The caller may want to resync the index
02d6628c1fea2990c67c60b111c8e68867160885Timo Sirainen to make sure it's valid and drop this flag. */
02d6628c1fea2990c67c60b111c8e68867160885Timo Sirainen MAIL_INDEX_HDR_FLAG_FSCKD = 0x0004,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fd3d711f219fd6813492acbe051e04327f0ca0f0Timo Sirainenenum mail_index_mail_flags {
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen /* For private use by backend. Replacing flags doesn't change this. */
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen MAIL_INDEX_MAIL_FLAG_BACKEND = 0x40,
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen /* Message flags haven't been written to backend. If
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen MAIL_INDEX_OPEN_FLAG_NO_DIRTY is set, this is treated as a
945565e0c9cf979b5feeba6fbd4efce3bf4484adTimo Sirainen backend-specific flag with no special internal handling. */
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen MAIL_INDEX_MAIL_FLAG_DIRTY = 0x80,
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen /* Force updating this message's modseq via a flag update record */
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen MAIL_INDEX_MAIL_FLAG_UPDATE_MODSEQ = 0x100
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define MAIL_INDEX_FLAGS_MASK \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (MAIL_ANSWERED | MAIL_FLAGGED | MAIL_DELETED | MAIL_SEEN | MAIL_DRAFT)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo 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;
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen uint16_t base_header_size;
024815ea2ffdda9ea79919f18e865663977f73eaTimo Sirainen uint32_t header_size; /* base + extended header size */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint32_t record_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen uint8_t compat_flags; /* enum mail_index_header_compat_flags */
811f2e26d9782d9cb99fdf82e18ffa0a77564fe2Timo Sirainen uint8_t unused[3];
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t indexid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t uid_validity;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t next_uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t messages_count;
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen uint32_t unused_old_recent_messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t seen_messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t deleted_messages_count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen uint32_t first_recent_uid;
1d3f7c1278168d5b1cbfa9a2cc9929a0909056b4Timo Sirainen /* these UIDs may not exist and may not even be unseen/deleted */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t first_unseen_uid_lowwater;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t first_deleted_uid_lowwater;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t log_file_seq;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen /* non-external records between tail..head haven't been committed to
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen mailbox yet. */
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen uint32_t log_file_tail_offset;
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen uint32_t log_file_head_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
4394b73cacaf2c31a9b601f66b6e26a1c8f114b4Timo Sirainen uint32_t unused_old_sync_size_part1;
4394b73cacaf2c31a9b601f66b6e26a1c8f114b4Timo Sirainen /* Timestamp of when .log was rotated into .log.2. This can be used to
4394b73cacaf2c31a9b601f66b6e26a1c8f114b4Timo Sirainen optimize checking when it's time to unlink it without stat()ing it.
4394b73cacaf2c31a9b601f66b6e26a1c8f114b4Timo Sirainen 0 = unknown, -1 = .log.2 doesn't exists. */
4394b73cacaf2c31a9b601f66b6e26a1c8f114b4Timo Sirainen uint32_t log2_rotate_time;
2ecee6ed2bfd5c9bc5c6cc8a675b9db4cbbcd81fTimo Sirainen uint32_t last_temp_file_scan;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen /* daily first UIDs that have been added to index. */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen uint32_t day_stamp;
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen uint32_t day_first_uid[8];
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
df1b2c3ff9cea4b57a4b9f1688bef54998fda5a4Timo Sirainen#define MAIL_INDEX_RECORD_MIN_SIZE (sizeof(uint32_t) + sizeof(uint8_t))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_record {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t uid;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint8_t flags; /* enum mail_flags | enum mail_index_mail_flags */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstruct mail_keywords {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct mail_index *index;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen unsigned int count;
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainen int refcount;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* variable sized list of keyword indexes */
9c93b5764f84126b3362cd96da4bd9b4de078bc7Timo Sirainen unsigned int idx[FLEXIBLE_ARRAY_MEMBER];
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen};
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainenenum mail_index_transaction_flags {
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen /* If transaction is marked as hidden, the changes are marked with
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen hidden=TRUE when the view is synchronized. */
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen MAIL_INDEX_TRANSACTION_FLAG_HIDE = 0x01,
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen /* External transactions describe changes to mailbox that have already
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen happened. */
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL = 0x02,
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen /* Don't add flag updates unless they actually change something.
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen This is reliable only when syncing, otherwise someone else might
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen have already committed a transaction that had changed the flags. */
807b48fe1f6a57b01ed2cc20247d5b5e3facc562Timo Sirainen MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES = 0x04,
807b48fe1f6a57b01ed2cc20247d5b5e3facc562Timo Sirainen /* fsync() this transaction (unless fsyncs are disabled) */
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen MAIL_INDEX_TRANSACTION_FLAG_FSYNC = 0x08,
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen /* Sync transaction describes changes to mailbox that already happened
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen to another mailbox with whom we're syncing with (dsync) */
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen MAIL_INDEX_TRANSACTION_FLAG_SYNC = 0x10
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen};
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_index_sync_type {
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04,
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD = 0x08,
250105a1440167ef000323cdb2721cd2a3688e1eTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE = 0x10
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainenenum mail_index_fsync_mask {
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen MAIL_INDEX_FSYNC_MASK_APPENDS = 0x01,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen MAIL_INDEX_FSYNC_MASK_EXPUNGES = 0x02,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen MAIL_INDEX_FSYNC_MASK_FLAGS = 0x04,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen MAIL_INDEX_FSYNC_MASK_KEYWORDS = 0x08
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen};
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainenenum mail_index_sync_flags {
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen /* Resync all dirty messages' flags. */
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY = 0x01,
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen /* Drop recent flags from all messages */
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen MAIL_INDEX_SYNC_FLAG_DROP_RECENT = 0x02,
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen /* Create the transaction with AVOID_FLAG_UPDATES flag */
c8adec8db635f5efb13b9879a5f3fb523abdc969Timo Sirainen MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES = 0x04,
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen /* If there are no new transactions and nothing else to do,
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen return 0 in mail_index_sync_begin() */
807b48fe1f6a57b01ed2cc20247d5b5e3facc562Timo Sirainen MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES = 0x08,
807b48fe1f6a57b01ed2cc20247d5b5e3facc562Timo Sirainen /* Create the transaction with FSYNC flag */
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen MAIL_INDEX_SYNC_FLAG_FSYNC = 0x10,
cfbacf6ea5fb39ae5304e4d95a78d9d4751bdfe1Timo Sirainen /* If we see "delete index" request transaction, finish it.
dc912088f84c263db1609435c2f5d7cb29bf1a33Timo Sirainen This flag also allows committing more changes to a deleted index. */
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen MAIL_INDEX_SYNC_FLAG_DELETING_INDEX = 0x20,
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen /* Same as MAIL_INDEX_SYNC_FLAG_DELETING_INDEX, but finish index
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen deletion only once and fail the rest (= avoid race conditions when
f90cbe597c41d5cc91debd371f8648bd8e6ffbc2Timo Sirainen multiple processes try to mark the index deleted) */
b356019bca27927bed2995e55aa6bfea756cc776Timo Sirainen MAIL_INDEX_SYNC_FLAG_TRY_DELETING_INDEX = 0x40,
b356019bca27927bed2995e55aa6bfea756cc776Timo Sirainen /* Update header's tail_offset to head_offset, even if it's the only
b356019bca27927bed2995e55aa6bfea756cc776Timo Sirainen thing we do and there's no strict need for it. */
b356019bca27927bed2995e55aa6bfea756cc776Timo Sirainen MAIL_INDEX_SYNC_FLAG_UPDATE_TAIL_OFFSET = 0x80
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen};
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen
7761758f43d6150be4b07f4c54457ce662f78c4cTimo Sirainenenum mail_index_view_sync_flags {
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen /* Don't sync expunges */
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES = 0x01,
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen /* Make sure view isn't inconsistent after syncing. This also means
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen that you don't care about view_sync_next()'s output, so it won't
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen return anything. */
62f4a199b5c9a0862f486cbf18e195cc621bbe25Timo Sirainen MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT = 0x02
6bc98d3898c475ba7615ba2b016e5142c8b2c09fTimo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_sync_rec {
659fe5d24825b160cae512538088020d97a60239Timo Sirainen uint32_t uid1, uid2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum mail_index_sync_type type;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* MAIL_INDEX_SYNC_TYPE_FLAGS: */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t add_flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t remove_flags;
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD, .._REMOVE: */
26ff8f8a4867bf8e9551a27a2de8c12cd138b065Timo Sirainen unsigned int keyword_idx;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen /* MAIL_INDEX_SYNC_TYPE_EXPUNGE: */
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen guid_128_t guid_128;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1f43c8ac132c153c224c4fffe34b2c3075d87ef7Timo Sirainenenum mail_index_view_sync_type {
1f43c8ac132c153c224c4fffe34b2c3075d87ef7Timo Sirainen /* Flags or keywords changed */
e68fc7dc8c8a75842f1e39deb49d196d1cfdb3b3Timo Sirainen MAIL_INDEX_VIEW_SYNC_TYPE_FLAGS = 0x01,
e68fc7dc8c8a75842f1e39deb49d196d1cfdb3b3Timo Sirainen MAIL_INDEX_VIEW_SYNC_TYPE_MODSEQ = 0x02
1f43c8ac132c153c224c4fffe34b2c3075d87ef7Timo Sirainen};
1f43c8ac132c153c224c4fffe34b2c3075d87ef7Timo Sirainen
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainenstruct mail_index_view_sync_rec {
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen uint32_t uid1, uid2;
1f43c8ac132c153c224c4fffe34b2c3075d87ef7Timo Sirainen enum mail_index_view_sync_type type;
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen
b9c44feadade0481b957f2978640afb3317bd1dfTimo Sirainen /* TRUE if this was a hidden transaction. */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool hidden:1;
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen};
020a39a395d2adb768e0179631b37bc78ecd9471Timo Sirainen
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainenenum mail_index_transaction_change {
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_APPEND = BIT(0),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_EXPUNGE = BIT(1),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_FLAGS = BIT(2),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_KEYWORDS = BIT(3),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_MODSEQ = BIT(4),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_ATTRIBUTE = BIT(5),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen MAIL_INDEX_TRANSACTION_CHANGE_OTHERS = BIT(30),
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen};
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenstruct mail_index_transaction_commit_result {
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* seq/offset points to end of transaction */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen uint32_t log_file_seq;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen uoff_t log_file_offset;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen /* number of bytes in the written transaction.
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen all of it was written to the same file. */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen uoff_t commit_size;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen
6a0855a04d75bce3c0a2f68517d02f86ae72087fTimo Sirainen enum mail_index_transaction_change changes_mask;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen unsigned int ignored_modseq_changes;
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen};
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainenstruct mail_index_base_optimization_settings {
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen /* Rewrite the index when the number of bytes that needs to be read
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen from the .log on refresh is between these min/max values. */
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen uoff_t rewrite_min_log_bytes;
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen uoff_t rewrite_max_log_bytes;
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen};
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainenstruct mail_index_log_optimization_settings {
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen /* Rotate transaction log after it's a) min_size or larger and it was
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen created at least min_age_secs or b) larger than max_size. */
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen uoff_t min_size;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen uoff_t max_size;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen unsigned int min_age_secs;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen /* Delete .log.2 when it's older than log2_stale_secs. Don't be too
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen eager, because older files are useful for QRESYNC and dsync. */
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen unsigned int log2_max_age_secs;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen};
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainenstruct mail_index_cache_optimization_settings {
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* Drop fields that haven't been accessed for n seconds */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen unsigned int unaccessed_field_drop_secs;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* If cache record becomes larger than this, don't add it. */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen unsigned int record_max_size;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* Never compress the file if it's smaller than this */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen uoff_t compress_min_size;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* Compress the file when n% of records are deleted */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen unsigned int compress_delete_percentage;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* Compress the file when n% of rows contain continued rows.
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen For example 200% means that the record has 2 continued rows, i.e.
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen it exists in 3 separate segments in the cache file. */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen unsigned int compress_continued_percentage;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen /* Compress the file when we need to follow more than n next_offsets to
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen find the latest cache header. */
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen unsigned int compress_header_continue_count;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen};
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainenstruct mail_index_optimization_settings {
3a78329166819e06f2929ce44e360514c6a80a8eTimo Sirainen struct mail_index_base_optimization_settings index;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen struct mail_index_log_optimization_settings log;
67bbcd664bebce9a507a49c67273be4814d07c97Timo Sirainen struct mail_index_cache_optimization_settings cache;
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen};
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstruct mail_index_map;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_transaction;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_sync_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_view_sync_ctx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainenstruct mail_index *mail_index_alloc(struct event *parent_event,
82d158d37db5cfb4e26affe4bc2f2a235901d1b9Timo Sirainen const char *dir, const char *prefix);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_free(struct mail_index **index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainen/* Change .cache file's directory. */
72af6886cb51e0ee02c9b3d6a7572eef8a0e236fTimo Sirainenvoid mail_index_set_cache_dir(struct mail_index *index, const char *dir);
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen/* Specify how often to do fsyncs. If mode is FSYNC_MODE_OPTIMIZED, the mask
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainen can be used to specify which transaction types to fsync. */
b780aa272b742a43579cdb523cc79cc8d4521306Timo Sirainenvoid mail_index_set_fsync_mode(struct mail_index *index, enum fsync_mode mode,
724b7fcf28c2547eb9c837d0e99241c0501dccf3Timo Sirainen enum mail_index_fsync_mask mask);
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen/* Try to set the index's permissions based on its index directory. Returns
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen TRUE if successful (directory existed), FALSE if mail_index_set_permissions()
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainen should be called. */
cded712c19ea8fb43c22726331de26b8a8dd234bTimo Sirainenbool mail_index_use_existing_permissions(struct mail_index *index);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainenvoid mail_index_set_permissions(struct mail_index *index,
e156adefc1260d31a145df2f5e9b3c82050d4163Timo Sirainen mode_t mode, gid_t gid, const char *gid_origin);
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen/* Set locking method and maximum time to wait for a lock
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen (UINT_MAX = default). */
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainenvoid mail_index_set_lock_method(struct mail_index *index,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen enum file_lock_method lock_method,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen unsigned int max_timeout_secs);
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen/* Override the default optimization-related settings. Anything set to 0 will
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen use the default. */
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainenvoid mail_index_set_optimization_settings(struct mail_index *index,
7ce557e379d2df8c4c3c5639f251881f0a55f3b5Timo Sirainen const struct mail_index_optimization_settings *set);
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen/* When creating a new index file or reseting an existing one, add the given
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen extension header data immediately to it. */
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainenvoid mail_index_set_ext_init_data(struct mail_index *index, uint32_t ext_id,
47e0598840ecffa364ebed523e06939e22738f06Timo Sirainen const void *data, size_t size);
20a802016205bbcafc90f164f769ea801f88d014Timo Sirainen
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen/* Open index. Returns 1 if ok, 0 if index doesn't exist and CREATE flags
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen wasn't given, -1 if error. */
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags);
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainen/* Open or create index. Returns 0 if ok, -1 if error. */
41e6eb07b411ea58352ba9d2cc8cf340325d49f3Timo Sirainenint mail_index_open_or_create(struct mail_index *index,
036626b19f14bef582f96e556913ae91b1d67881Timo Sirainen enum mail_index_open_flags flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_close(struct mail_index *index);
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen/* unlink() all the index files. */
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainenint mail_index_unlink(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainen/* Returns TRUE if index is currently in memory. */
15cc66ca72982a43e3bfa58f307adc57e9caa52dTimo Sirainenbool mail_index_is_in_memory(struct mail_index *index);
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen/* Move the index into memory. Returns 0 if ok, -1 if error occurred. */
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainenint mail_index_move_to_memory(struct mail_index *index);
a045c3aba2610c6ed0bf1c346df1c6d8f7b9fbfdTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_cache *mail_index_get_cache(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen/* Refresh index so mail_index_lookup*() will return latest values. Note that
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen immediately after this call there may already be changes, so if you need to
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen rely on validity of the returned values, use some external locking for it. */
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainenint ATTR_NOWARN_UNUSED_RESULT
b66d803de86bfb411165b3465b0d9ef64ecfe2a1Timo Sirainenmail_index_refresh(struct mail_index *index);
d30da25fb6be1f1c667d93767c9194000194b618Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* View can be used to look into index. Sequence numbers inside view change
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen only when you synchronize it. The view acquires required locks
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen automatically, but you'll have to drop them manually. */
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainenstruct mail_index_view *
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainenmail_index_view_open(struct mail_index *index,
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen const char *source_filename, unsigned int source_linenum);
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen#define mail_index_view_open(index) \
5ea06115cb60413b62ffb58ffdd62786fec6a316Timo Sirainen mail_index_view_open(index, __FILE__, __LINE__)
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_view_close(struct mail_index_view **view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns the index for given view. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns number of mails in view. */
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainenuint32_t mail_index_view_get_messages_count(struct mail_index_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns TRUE if we lost track of changes for some reason. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_index_view_is_inconsistent(struct mail_index_view *view);
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainen/* Returns number of transactions open for the view. */
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainenunsigned int
ec77cd41241208345efd51c1fcce9030be30aa9bTimo Sirainenmail_index_view_get_transaction_count(struct mail_index_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Transaction has to be opened to be able to modify index. You can have
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen multiple transactions open simultaneously. Committed transactions won't
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen show up until you've synchronized the view. Expunges won't show up until
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen you've synchronized the mailbox (mail_index_sync_begin). */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_transaction *
7c95b03620a03a43dd72d39608cea5fc77393ad6Timo Sirainenmail_index_transaction_begin(struct mail_index_view *view,
db87d16551d1081ada01f787ea21aa3ed1402c31Timo Sirainen enum mail_index_transaction_flags flags);
9404a7b90dcb80d31bd37ee2493f03751acdb1bdTimo Sirainenint mail_index_transaction_commit(struct mail_index_transaction **t);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenint mail_index_transaction_commit_full(struct mail_index_transaction **t,
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen struct mail_index_transaction_commit_result *result_r);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_transaction_rollback(struct mail_index_transaction **t);
eac3948d67eff8623d51aeaea9eca582f3aec677Timo Sirainen/* Discard all changes in the transaction. */
2674b4f0cf8f3c203d8e56b29735f5e267038dafTimo Sirainenvoid mail_index_transaction_reset(struct mail_index_transaction *t);
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen/* When committing transaction, drop flag/keyword updates for messages whose
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen mdoseq is larger than max_modseq. Save those messages' sequences to the
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen given array. */
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainenvoid mail_index_transaction_set_max_modseq(struct mail_index_transaction *t,
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen uint64_t max_modseq,
48270badadd82279bfe50ae3d187aea8b0b2b30eTimo Sirainen ARRAY_TYPE(seq_range) *seqs);
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainen/* Returns the resulting highest-modseq after this commit. This can be called
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainen only if transaction log is locked, which normally means only during mail
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainen index syncing. If there are any appends, they all must have been assigned
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainen UIDs before calling this. */
9e6d83a3ef6abb393eeebca423cfd0d8cb08d430Timo Sirainenuint64_t mail_index_transaction_get_highest_modseq(struct mail_index_transaction *t);
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen
48136ae5a0eb49daa44e343553f3688a500307e2Timo Sirainen/* Returns the view transaction was created for. */
48136ae5a0eb49daa44e343553f3688a500307e2Timo Sirainenstruct mail_index_view *
2674b4f0cf8f3c203d8e56b29735f5e267038dafTimo Sirainenmail_index_transaction_get_view(struct mail_index_transaction *t);
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen/* Returns TRUE if the given sequence is being expunged in this transaction. */
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainenbool mail_index_transaction_is_expunged(struct mail_index_transaction *t,
e376693bfa3985232c41df99c7010fca22612c89Timo Sirainen uint32_t seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
97735b96d442568f65efa20f8c292a496498c17bTimo Sirainen/* Returns a view containing the mailbox state after changes in transaction
97735b96d442568f65efa20f8c292a496498c17bTimo Sirainen are applied. The view can still be used after transaction has been
97735b96d442568f65efa20f8c292a496498c17bTimo Sirainen committed. */
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainenstruct mail_index_view *
09c3a491f4f6ccebe290c7709bdc0d79a187610bTimo Sirainenmail_index_transaction_open_updated_view(struct mail_index_transaction *t);
24fc71a693331ffe77e2b6d81c70aca6fa055e47Timo Sirainen
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen/* Begin synchronizing mailbox with index file. Returns 1 if ok,
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen 0 if MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES is set and there's nothing to
d6a1fa1d65c6d1996937802c2482c0f14dd821a7Timo Sirainen sync, -1 if error.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_sync_next() returns all changes from previously committed
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen transactions which haven't yet been committed to the actual mailbox.
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen They're returned in ascending order and they never overlap (if we add more
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen sync types, then they might). You must go through all of them and update
b92813e2f96d4b28f989528ed5dd6115da7d9bdbTimo Sirainen the mailbox accordingly.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen Changes done to the returned transaction are expected to describe the
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen mailbox's current state.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen The returned view already contains all the changes (except expunge
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen requests). After applying sync records on top of backend flags they should
db5164c9a1129af0cfb11fc18d88da361a8011fbTimo Sirainen match flags in the view. If they don't, there have been external changes.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen Returned expunges are treated as expunge requests. They're not really
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen removed from the index until you mark them expunged to the returned
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen transaction. If it's not possible to expunge the message (e.g. permission
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen denied), simply don't mark them expunged.
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen Returned sequence numbers describe the mailbox state at the beginning of
d152ccd0d29fae1bc6092bf198ee7eb843202f96Timo Sirainen synchronization, ie. expunges don't affect them. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_sync_begin(struct mail_index *index,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_sync_ctx **ctx_r,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_index_view **view_r,
aa0647f2debf0d48d504a321186f66c85596aaf4Timo Sirainen struct mail_index_transaction **trans_r,
2d39dc1a453546892109b35c0d9770369011a13dTimo Sirainen enum mail_index_sync_flags flags);
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen/* Like mail_index_sync_begin(), but returns 1 if OK and if index is already
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen synchronized up to the given log_file_seq+offset, the synchronization isn't
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen started and this function returns 0. This should be done when you wish to
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen sync your committed transaction instead of doing a full mailbox
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen synchronization. */
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainenint mail_index_sync_begin_to(struct mail_index *index,
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen struct mail_index_sync_ctx **ctx_r,
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen struct mail_index_view **view_r,
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen struct mail_index_transaction **trans_r,
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset,
8f8315e4b4e27ead12dd1c3da65bf4dee3762f18Timo Sirainen enum mail_index_sync_flags flags);
768b7f5783c8de119d7386321e5d0c72d5c2d9f6Timo Sirainen/* Returns TRUE if it currently looks like syncing would return changes. */
768b7f5783c8de119d7386321e5d0c72d5c2d9f6Timo Sirainenbool mail_index_sync_have_any(struct mail_index *index,
768b7f5783c8de119d7386321e5d0c72d5c2d9f6Timo Sirainen enum mail_index_sync_flags flags);
5fb7f20862718b2546e9d154d8924510d3f02729Timo Sirainen/* Returns TRUE if it currently looks like syncing would return expunges. */
5fb7f20862718b2546e9d154d8924510d3f02729Timo Sirainenbool mail_index_sync_have_any_expunges(struct mail_index *index);
079f54c97145a0a5daa36c37eead3eae91b67a1eTimo Sirainen/* Returns the log file seq+offsets for the area which this sync is handling. */
079f54c97145a0a5daa36c37eead3eae91b67a1eTimo Sirainenvoid mail_index_sync_get_offsets(struct mail_index_sync_ctx *ctx,
079f54c97145a0a5daa36c37eead3eae91b67a1eTimo Sirainen uint32_t *seq1_r, uoff_t *offset1_r,
079f54c97145a0a5daa36c37eead3eae91b67a1eTimo Sirainen uint32_t *seq2_r, uoff_t *offset2_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
b08b33d1f5ce3721dc2d83586c9cb0ca141331fdTimo Sirainenbool mail_index_sync_next(struct mail_index_sync_ctx *ctx,
b08b33d1f5ce3721dc2d83586c9cb0ca141331fdTimo Sirainen struct mail_index_sync_rec *sync_rec);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen/* Returns TRUE if there's more to sync. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_index_sync_have_more(struct mail_index_sync_ctx *ctx);
3955d6726c939b3b30527c22b70c879fbe78692eTimo Sirainen/* Returns TRUE if sync has any expunges to handle. */
3955d6726c939b3b30527c22b70c879fbe78692eTimo Sirainenbool mail_index_sync_has_expunges(struct mail_index_sync_ctx *ctx);
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen/* Reset syncing to initial state after mail_index_sync_begin(), so you can
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainen go through all the sync records again with mail_index_sync_next(). */
89caf81340a4da959ef18c5f9b9c99824a53066bTimo Sirainenvoid mail_index_sync_reset(struct mail_index_sync_ctx *ctx);
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen/* Update result when refreshing index at the end of sync. */
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainenvoid mail_index_sync_set_commit_result(struct mail_index_sync_ctx *ctx,
9f19a50d5966643c4d1c5ca06868ac2ad31bc4d5Timo Sirainen struct mail_index_transaction_commit_result *result);
f6ae4001e33637ad80ebb8f5716ca2020e718625Timo Sirainen/* Don't log a warning even if syncing took over
f6ae4001e33637ad80ebb8f5716ca2020e718625Timo Sirainen MAIL_TRANSACTION_LOG_LOCK_WARN_SECS seconds. Usually this is called because
f6ae4001e33637ad80ebb8f5716ca2020e718625Timo Sirainen the caller itself already logged a warning about it. */
f6ae4001e33637ad80ebb8f5716ca2020e718625Timo Sirainenvoid mail_index_sync_no_warning(struct mail_index_sync_ctx *ctx);
5bced341c27719fe5ec48e1cd079843f33c6d4b5Timo Sirainen/* If a warning is logged because syncing took over
5bced341c27719fe5ec48e1cd079843f33c6d4b5Timo Sirainen MAIL_TRANSACTION_LOG_LOCK_WARN_SECS seconds, log this as the reason for the
5bced341c27719fe5ec48e1cd079843f33c6d4b5Timo Sirainen syncing. */
5bced341c27719fe5ec48e1cd079843f33c6d4b5Timo Sirainenvoid mail_index_sync_set_reason(struct mail_index_sync_ctx *ctx,
5bced341c27719fe5ec48e1cd079843f33c6d4b5Timo Sirainen const char *reason);
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen/* Commit synchronization by writing all changes to mail index file. */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenint mail_index_sync_commit(struct mail_index_sync_ctx **ctx);
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen/* Rollback synchronization - none of the changes listed by sync_next() are
d9de52132072d80b8c268094b879c0ef5a108db3Timo Sirainen actually written to index file. */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_index_sync_rollback(struct mail_index_sync_ctx **ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
685393de106e55b61f754d420e378d05bd462ebbTimo Sirainen/* Mark index file corrupted. Invalidates all views. */
87712707722ef7d73acb065546e61afa4455cd9eTimo Sirainenvoid mail_index_mark_corrupted(struct mail_index *index);
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen/* Check and fix any found problems. Returns -1 if we couldn't lock for sync,
3b80595fcf2001cf7b2fcc6290823e38f4a142fcTimo Sirainen 0 if everything went ok. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_fsck(struct mail_index *index);
8a3f549a3cb1d6dd980a4fa3db284653e256dae7Timo Sirainen/* Returns TRUE if mail_index_fsck() has been called since the last
8a3f549a3cb1d6dd980a4fa3db284653e256dae7Timo Sirainen mail_index_reset_fscked() call. */
8a3f549a3cb1d6dd980a4fa3db284653e256dae7Timo Sirainenbool mail_index_reset_fscked(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Synchronize changes in view. You have to go through all records, or view
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen will be marked inconsistent. Only sync_mask type records are
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen synchronized. */
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainenstruct mail_index_view_sync_ctx *
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainenmail_index_view_sync_begin(struct mail_index_view *view,
5a86309a6c58bdeb9921bf2989aaabaaa04a29abTimo Sirainen enum mail_index_view_sync_flags flags);
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainenbool mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen struct mail_index_view_sync_rec *sync_rec);
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainenvoid
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
94a8cb0ee1d85569ad1a2acacd92d3ce22f8a1cbTimo Sirainen const ARRAY_TYPE(seq_range) **expunges_r);
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainenint mail_index_view_sync_commit(struct mail_index_view_sync_ctx **ctx,
17da42c31202b1b3e7e308121ea17d922c24da1bTimo Sirainen bool *delayed_expunges_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns the index header. */
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainenconst struct mail_index_header *
b20fb5b1df9d604a7541f5118fc5b4b466d211efTimo Sirainenmail_index_get_header(struct mail_index_view *view);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen/* Returns the wanted message record. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenconst struct mail_index_record *
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenmail_index_lookup(struct mail_index_view *view, uint32_t seq);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenconst struct mail_index_record *
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenmail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen struct mail_index_map **map_r);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen/* Returns TRUE if the given message has already been expunged from index. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenbool mail_index_is_expunged(struct mail_index_view *view, uint32_t seq);
bb26f09873c18f342cd1ab2d0ee0b9018e6546d9Timo Sirainen/* Note that returned keyword indexes aren't sorted. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen ARRAY_TYPE(keyword_indexes) *keyword_idx);
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen/* Return keywords from given map. */
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainenvoid mail_index_map_lookup_keywords(struct mail_index_map *map, uint32_t seq,
c4db5f0fb7cea8160dc10b5f0ab57ab7c02bf8a5Timo Sirainen ARRAY_TYPE(keyword_indexes) *keyword_idx);
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen/* mail_index_lookup[_keywords]() returns the latest flag changes.
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen This function instead attempts to return the flags and keywords done by the
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen last view sync. */
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainenvoid mail_index_lookup_view_flags(struct mail_index_view *view, uint32_t seq,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen enum mail_flags *flags_r,
dd9712b013e5a14939deed84b2e391d89897d2cfTimo Sirainen ARRAY_TYPE(keyword_indexes) *keyword_idx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns the UID for given message. May be slightly faster than
b5ea11802f2bafbec06282a7b3b6704dc5fae584Timo Sirainen mail_index_lookup()->uid. */
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenvoid mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen uint32_t *uid_r);
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen/* Convert UID range to sequence range. If no UIDs are found, returns FALSE and
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen sequences are set to 0. Note that any of the returned sequences may have
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen been expunged already. */
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainenbool mail_index_lookup_seq_range(struct mail_index_view *view,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen uint32_t first_uid, uint32_t last_uid,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r);
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainenbool mail_index_lookup_seq(struct mail_index_view *view,
3da614c39dd29f536c485089e67839b4cf89fed3Timo Sirainen uint32_t uid, uint32_t *seq_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Find first mail with (mail->flags & flags_mask) == flags. Useful mostly for
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen taking advantage of lowwater-fields in headers. */
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenvoid mail_index_lookup_first(struct mail_index_view *view,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen enum mail_flags flags, uint8_t flags_mask,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen uint32_t *seq_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Append a new record to index. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_append(struct mail_index_transaction *t, uint32_t uid,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *seq_r);
d48860922190d08427ceaf30475994017ef09e2bTimo Sirainen/* Assign UIDs for mails with uid=0 or uid<first_uid. All the assigned UIDs
d48860922190d08427ceaf30475994017ef09e2bTimo Sirainen are higher than the highest unassigned UID (i.e. it doesn't try to fill UID
d48860922190d08427ceaf30475994017ef09e2bTimo Sirainen gaps). Assumes that mailbox is locked in a way that UIDs can be safely
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi assigned. Returns UIDs for all assigned messages, in their sequence order
d48860922190d08427ceaf30475994017ef09e2bTimo Sirainen (so UIDs are not necessary ascending). */
8cf32443413f811d514123c5c74c95c87594b0e3Timo Sirainenvoid mail_index_append_finish_uids(struct mail_index_transaction *t,
8cf32443413f811d514123c5c74c95c87594b0e3Timo Sirainen uint32_t first_uid,
8cf32443413f811d514123c5c74c95c87594b0e3Timo Sirainen ARRAY_TYPE(seq_range) *uids_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Expunge record from index. Note that this doesn't affect sequence numbers
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen until transaction is committed and mailbox is synced. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_expunge(struct mail_index_transaction *t, uint32_t seq);
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen/* Like mail_index_expunge(), but also write message GUID to transaction log. */
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenvoid mail_index_expunge_guid(struct mail_index_transaction *t, uint32_t seq,
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen const guid_128_t guid_128);
d0ed540d897d62713ac74523af11dac204874b5dTimo Sirainen/* Revert all changes done in this transaction to the given existing mail. */
d0ed540d897d62713ac74523af11dac204874b5dTimo Sirainenvoid mail_index_revert_changes(struct mail_index_transaction *t, uint32_t seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Update flags in index. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen enum modify_type modify_type,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen enum mail_flags flags);
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainenvoid mail_index_update_flags_range(struct mail_index_transaction *t,
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen uint32_t seq1, uint32_t seq2,
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen enum modify_type modify_type,
c251a38df327599a62d341bf5c2282f31352faa5Timo Sirainen enum mail_flags flags);
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen/* Specified attribute's value was changed. This is just a notification so the
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen change gets assigned its own modseq and any log readers can find out about
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen this change. */
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainenvoid mail_index_attribute_set(struct mail_index_transaction *t,
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen bool pvt, const char *key,
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen time_t timestamp, uint32_t value_len);
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen/* Attribute was deleted. */
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainenvoid mail_index_attribute_unset(struct mail_index_transaction *t,
238812433b4f7965fd662dce0f4efccb092630a8Timo Sirainen bool pvt, const char *key, time_t timestamp);
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen/* Update message's modseq to be at least min_modseq. */
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenvoid mail_index_update_modseq(struct mail_index_transaction *t, uint32_t seq,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen uint64_t min_modseq);
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen/* Update highest modseq to be at least min_modseq. */
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainenvoid mail_index_update_highest_modseq(struct mail_index_transaction *t,
4b89231f4ec9cc69f4aea715e1d34f405c7e317dTimo Sirainen uint64_t min_modseq);
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen/* Reset the index before committing this transaction. This is usually done
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen only when UIDVALIDITY changes. */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenvoid mail_index_reset(struct mail_index_transaction *t);
c5073d5b57145e9d2912ea69e44e25550bf274feTimo Sirainen/* Remove MAIL_INDEX_HDR_FLAG_FSCKD from header if it exists. This must be
c5073d5b57145e9d2912ea69e44e25550bf274feTimo Sirainen called only during syncing so that the mailbox is locked. */
c5073d5b57145e9d2912ea69e44e25550bf274feTimo Sirainenvoid mail_index_unset_fscked(struct mail_index_transaction *t);
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen/* Mark index deleted. No further changes will be possible after the
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen transaction has been committed. */
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainenvoid mail_index_set_deleted(struct mail_index_transaction *t);
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen/* Mark a deleted index as undeleted. Afterwards index can be changed again. */
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainenvoid mail_index_set_undeleted(struct mail_index_transaction *t);
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen/* Returns TRUE if index has been set deleted. This gets set only after
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen index has been opened/refreshed and the transaction has been seen. */
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainenbool mail_index_is_deleted(struct mail_index *index);
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen/* Returns the last time the index was modified. This can be called even if the
bb444f746dc6c15a8d0af67ef81bfa48c28471d0Timo Sirainen index isn't open. If the index doesn't exist, sets mtime to 0. */
6c2ddb9f586e6392552ddfb82ab55e57fcfc4110Timo Sirainenint mail_index_get_modification_time(struct mail_index *index, time_t *mtime_r);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
6825360d446542046757b06064282301c4c6b27cTimo Sirainen/* Lookup a keyword, returns TRUE if found, FALSE if not. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_index_keyword_lookup(struct mail_index *index,
6825360d446542046757b06064282301c4c6b27cTimo Sirainen const char *keyword, unsigned int *idx_r);
6825360d446542046757b06064282301c4c6b27cTimo Sirainenvoid mail_index_keyword_lookup_or_create(struct mail_index *index,
6825360d446542046757b06064282301c4c6b27cTimo Sirainen const char *keyword,
6825360d446542046757b06064282301c4c6b27cTimo Sirainen unsigned int *idx_r);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen/* Return a pointer to array of NULL-terminated list of keywords. Note that
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen the array contents (and thus pointers inside it) may change after calling
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_index_keywords_create() or mail_index_sync_begin(). */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainenconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainen/* Create a keyword list structure. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstruct mail_keywords *
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainenmail_index_keywords_create(struct mail_index *index,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen const char *const keywords[]) ATTR_NULL(2);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenstruct mail_keywords *
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainenmail_index_keywords_create_from_indexes(struct mail_index *index,
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen const ARRAY_TYPE(keyword_indexes)
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen *keyword_indexes);
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainenvoid mail_index_keywords_ref(struct mail_keywords *keywords);
84ed9f8f3d0e5ed47607ef417618e49e4f865557Timo Sirainenvoid mail_index_keywords_unref(struct mail_keywords **keywords);
61f5256ef248d35459b53534ae428bf6d016e1c5Timo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* Update keywords for given message. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenvoid mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen enum modify_type modify_type,
41e1c7380edda701719d8ce1fb4d465d2ec4c84dTimo Sirainen struct mail_keywords *keywords);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen/* Update field in header. If prepend is TRUE, the header change is visible
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen before message syncing begins. */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenvoid mail_index_update_header(struct mail_index_transaction *t,
aa38d1a0945f0bc13a225d043f53fad2eec666b1Timo Sirainen size_t offset, const void *data, size_t size,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen bool prepend);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo 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 Sirainenconst char *mail_index_get_error_message(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Reset the error message. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_reset_error(struct mail_index *index);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Apply changes in MAIL_INDEX_SYNC_TYPE_FLAGS typed sync records to given
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen flags variable. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_sync_flags_apply(const struct mail_index_sync_rec *sync_rec,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint8_t *flags);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen/* Apply changes in MAIL_INDEX_SYNC_TYPE_KEYWORD_* typed sync records to given
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen keywords array. Returns TRUE If something was changed. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_index_sync_keywords_apply(const struct mail_index_sync_rec *sync_rec,
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen ARRAY_TYPE(keyword_indexes) *keywords);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen/* register index extension. name is a unique identifier for the extension.
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen returns unique identifier for the name. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint32_t default_hdr_size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t default_record_size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t default_record_align);
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen/* Change an already registered extension's default sizes. */
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainenvoid mail_index_ext_register_resize_defaults(struct mail_index *index,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint32_t ext_id,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint32_t default_hdr_size,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint16_t default_record_size,
ea91861234475257f436dc07925f80cf4ac32b71Timo Sirainen uint16_t default_record_align);
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen/* Returns TRUE and sets ext_id_r if extension with given name is registered. */
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainenbool mail_index_ext_lookup(struct mail_index *index, const char *name,
c5454841b5067a22827556ca9bc7935d190f57baTimo Sirainen uint32_t *ext_id_r);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen/* Resize existing extension data. If size is grown, the new data will be
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen zero-filled. If size is shrinked, the data is simply dropped. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenvoid mail_index_ext_resize(struct mail_index_transaction *t, uint32_t ext_id,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint32_t hdr_size, uint16_t record_size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_align);
c7fc0431b23dc8d29e12e09c8120e223fbee116bTimo Sirainen/* Resize header, keeping the old record size. */
c7fc0431b23dc8d29e12e09c8120e223fbee116bTimo Sirainenvoid mail_index_ext_resize_hdr(struct mail_index_transaction *t,
c7fc0431b23dc8d29e12e09c8120e223fbee116bTimo Sirainen uint32_t ext_id, uint32_t hdr_size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen/* Reset extension. Any updates for this extension which were issued before the
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen writer had seen this reset are discarded. reset_id is used to figure this
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen out, so it must be different every time. If clear_data=TRUE, records and
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen header is zeroed. */
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenvoid mail_index_ext_reset(struct mail_index_transaction *t, uint32_t ext_id,
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen uint32_t reset_id, bool clear_data);
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen/* Like mail_index_ext_reset(), but increase extension's reset_id atomically
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen when the transaction is being committed. If prev_reset_id doesn't match the
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen latest reset_id, the reset_id isn't increased and all extension changes are
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen ignored. */
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainenvoid mail_index_ext_reset_inc(struct mail_index_transaction *t, uint32_t ext_id,
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen uint32_t prev_reset_id, bool clear_data);
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen/* Discard existing extension updates in this transaction and write new updates
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen using the given reset_id. The difference to mail_index_ext_reset() is that
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen this doesn't clear any existing record or header data. */
893e5bbd5184ec5c21f47c67c8ea6efbea41f7d0Timo Sirainenvoid mail_index_ext_set_reset_id(struct mail_index_transaction *t,
893e5bbd5184ec5c21f47c67c8ea6efbea41f7d0Timo Sirainen uint32_t ext_id, uint32_t reset_id);
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen/* Get the current reset_id for given extension. Returns TRUE if it exists. */
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainenbool mail_index_ext_get_reset_id(struct mail_index_view *view,
44c5e644cb413a6559bf2d4179cbe48f9a82f366Timo Sirainen struct mail_index_map *map,
5278c93bd7105c32ac7ec37f36015d5950f6cbcaTimo Sirainen uint32_t ext_id, uint32_t *reset_id_r);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen/* Returns extension header. */
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenvoid mail_index_get_header_ext(struct mail_index_view *view, uint32_t ext_id,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen const void **data_r, size_t *data_size_r);
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainenvoid mail_index_map_get_header_ext(struct mail_index_view *view,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen struct mail_index_map *map, uint32_t ext_id,
88187ee880b4829443e0d55ea7d145d9d5880217Timo Sirainen const void **data_r, size_t *data_size_r);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen/* Returns the wanted extension record for given message. If it doesn't exist,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen *data_r is set to NULL. expunged_r is TRUE if the message has already been
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen expunged from the index. */
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_index_lookup_ext(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen uint32_t ext_id, const void **data_r,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen bool *expunged_r);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainenvoid mail_index_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen const void **data_r, bool *expunged_r);
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen/* Get current extension sizes. Returns 1 if ok, 0 if extension doesn't exist
bb2b91b4c5363348b737237893d414639510a561Timo Sirainen in view. Any of the _r parameters may be NULL. */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenvoid mail_index_ext_get_size(struct mail_index_map *map, uint32_t ext_id,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen uint32_t *hdr_size_r, uint16_t *record_size_r,
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen uint16_t *record_align_r);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen/* Update extension header field. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenvoid mail_index_update_header_ext(struct mail_index_transaction *t,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint32_t ext_id, size_t offset,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen const void *data, size_t size);
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen/* Update extension record. If old_data_r is non-NULL and the record extension
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen was already updated in this transaction, it's set to contain the data it's
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen now overwriting. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenvoid mail_index_update_ext(struct mail_index_transaction *t, uint32_t seq,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen uint32_t ext_id, const void *data, void *old_data)
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen ATTR_NULL(5);
b7a5580abb62dd82e82e58ed81dcb307ed338144Timo Sirainen/* Increase/decrease number in extension atomically. Returns the sum of the
b7a5580abb62dd82e82e58ed81dcb307ed338144Timo Sirainen diffs for this seq. */
b7a5580abb62dd82e82e58ed81dcb307ed338144Timo Sirainenint mail_index_atomic_inc_ext(struct mail_index_transaction *t,
b7a5580abb62dd82e82e58ed81dcb307ed338144Timo Sirainen uint32_t seq, uint32_t ext_id, int diff);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#endif