mail-index.h revision d9de52132072d80b8c268094b879c0ef5a108db3
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#ifndef __MAIL_INDEX_H
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define __MAIL_INDEX_H
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#include "mail-types.h"
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define MAIL_INDEX_MAJOR_VERSION 4
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define MAIL_INDEX_MINOR_VERSION 0
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define MAIL_INDEX_HEADER_MIN_SIZE 120
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Number of keywords in mail_index_record. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define INDEX_KEYWORDS_COUNT (3*8)
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define INDEX_KEYWORDS_BYTE_COUNT ((INDEX_KEYWORDS_COUNT+CHAR_BIT-1) / CHAR_BIT)
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinenum mail_index_open_flags {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Create index if it doesn't exist */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_OPEN_FLAG_CREATE = 0x01,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Open the index as fast as possible - do only minimal checks and
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin delay opening cache/log files unless they're needed. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber MAIL_INDEX_OPEN_FLAG_FAST = 0x02,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Don't try to mmap() index files */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE = 0x04,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Don't try to write() to mmap()ed index files. Required for the few
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin OSes that don't have unified buffer cache
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin (currently OpenBSD <= 3.5) */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE = 0x08,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Don't use fcntl() locking */
ed4616b1cfbc84dd01caa8546d813e8c5d482921Christian Bühler MAIL_INDEX_OPEN_FLAG_FCNTL_LOCKS_DISABLE= 0x10
e29bf450cafa2ce2564aeb0b64d2014c17228407Dwight Engen};
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinenum mail_index_header_compat_flags {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinenum mail_index_header_flag {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Index file is corrupted, reopen or recreate it. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_HDR_FLAG_CORRUPTED = 0x0001,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_HDR_FLAG_HAVE_DIRTY = 0x0002
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinenum mail_index_mail_flags {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_MAIL_FLAG_DIRTY = 0x80
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinenum mail_index_error {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* No errors */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin MAIL_INDEX_ERROR_NONE,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* Internal error, see get_error_text() for more information. */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin MAIL_INDEX_ERROR_INTERNAL,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* We ran out of available disk space. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_ERROR_DISKSPACE
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define MAIL_INDEX_FLAGS_MASK \
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin (MAIL_ANSWERED | MAIL_FLAGGED | MAIL_DELETED | MAIL_SEEN | MAIL_DRAFT)
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalintypedef unsigned char keywords_mask_t[INDEX_KEYWORDS_BYTE_COUNT];
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinstruct mail_index_header {
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* major version is increased only when you can't have backwards
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin compatibility. minor version is increased when header size is
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin increased to contain new non-critical fields. */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t major_version;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t minor_version;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint16_t base_header_size;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t header_size; /* base + extended header size */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint16_t record_size;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint16_t keywords_mask_size;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* 0 = flags
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin 1 = sizeof(uoff_t)
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin 2 = sizeof(time_t)
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin 3 = unused */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t compat_data[4];
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t indexid;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t flags;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t uid_validity;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t next_uid;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t messages_count;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t recent_messages_count;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t seen_messages_count;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t deleted_messages_count;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* these UIDs may not exist and may not even be unseen */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t first_recent_uid_lowwater;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t first_unseen_uid_lowwater;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t first_deleted_uid_lowwater;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t log_file_seq;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t log_file_offset;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t sync_stamp;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint64_t sync_size;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t cache_file_seq;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t extra_records_hdr_offset;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* daily first UIDs that have been added to index. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t day_stamp;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t day_first_uid[8];
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin};
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index_record {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t uid;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t flags; /* mail_flags | mail_index_mail_flags */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin keywords_mask_t keywords;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t cache_offset;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinenum mail_index_sync_type {
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin MAIL_INDEX_SYNC_TYPE_APPEND = 0x01,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define MAIL_INDEX_SYNC_MASK_ALL 0xff
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index_sync_rec {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t uid1, uid2;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin enum mail_index_sync_type type;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* MAIL_INDEX_SYNC_TYPE_FLAGS: */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t add_flags;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin keywords_mask_t add_keywords;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t remove_flags;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin keywords_mask_t remove_keywords;
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin};
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinstruct mail_index_view;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinstruct mail_index_transaction;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinstruct mail_index_sync_ctx;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinstruct mail_index_view_sync_ctx;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinstruct mail_index *mail_index_alloc(const char *dir, const char *prefix);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinvoid mail_index_free(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* register extra data to be used in mail_index_record. name is a unique
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin identifier for the data. if same name is tried to be registered multiple
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin times, the rest are ignored. returns identifier for the name. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinuint32_t mail_index_register_record_extra(struct mail_index *index,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin const char *name, uint16_t size);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_close(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Force checking if index can be refreshed. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_refresh(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_cache *mail_index_get_cache(struct mail_index *index);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber/* View can be used to look into index. Sequence numbers inside view change
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin only when you synchronize it. The view acquires required locks
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin automatically, but you'll have to drop them manually. Opening view
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin acquires a lock immediately. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index_view *mail_index_view_open(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_view_close(struct mail_index_view *view);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns the index for given view. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index *mail_index_view_get_index(struct mail_index_view *view);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Call whenever you've done with requesting messages from view for a while. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_view_unlock(struct mail_index_view *view);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns number of mails in view. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinuint32_t mail_index_view_get_message_count(struct mail_index_view *view);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns TRUE if we lost track of changes for some reason. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graberint mail_index_view_is_inconsistent(struct mail_index_view *view);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Transaction has to be opened to be able to modify index. You can have
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin multiple transactions open simultaneously. Note that committed transactions
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin won't show up until you've synchronized mailbox (mail_index_sync_begin). */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index_transaction *
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinmail_index_transaction_begin(struct mail_index_view *view, int hide);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_transaction_commit(struct mail_index_transaction *t,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t *log_file_seq_r,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uoff_t *log_file_offset_r);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_transaction_rollback(struct mail_index_transaction *t);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns a view to transaction. Currently this differs from normal view only
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin in that it contains newly appended messages in transaction. The view can
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin still be used after transaction has been committed. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstruct mail_index_view *
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinmail_index_transaction_open_updated_view(struct mail_index_transaction *t);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
44d397891e691ab994a69766cc72e57265b62da1Serge Hallyn/* Begin synchronizing mailbox with index file. This call locks the index
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin exclusively against other modifications. Returns 1 if ok, -1 if error.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin If log_file_seq is not (uint32_t)-1 and index is already synchronized up
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin to given log_file_offset, the synchronization isn't started and this
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin function returns 0. This should be done when you wish to sync your previous
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin transaction instead of doing a full mailbox synchronization.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin mail_index_sync_next() returns all changes from previously committed
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin transactions which haven't yet been committed to the actual mailbox.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin They're returned in ascending order and they never overlap (if we add more
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin sync types, then they might). You must go through all of them and update
e29bf450cafa2ce2564aeb0b64d2014c17228407Dwight Engen the mailbox accordingly.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber None of the changes actually show up in index until after successful
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber mail_index_sync_commit().
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber Returned sequence numbers describe the mailbox state at the beginning of
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber synchronization, ie. expunges don't affect them.
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber You may create a new transaction for the returned view. That transaction
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber acts as "external mailbox changes" transaction. Any changes done there are
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber expected to describe mailbox's current state. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graberint mail_index_sync_begin(struct mail_index *index,
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber struct mail_index_sync_ctx **ctx_r,
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber struct mail_index_view **view_r,
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber uint32_t log_file_seq, uoff_t log_file_offset,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin int sync_recent);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_sync_next(struct mail_index_sync_ctx *ctx,
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber struct mail_index_sync_rec *sync_rec);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber/* Returns 1 if there's more to sync, 0 if not. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_sync_have_more(struct mail_index_sync_ctx *ctx);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Commit synchronization by writing all changes to mail index file. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graberint mail_index_sync_commit(struct mail_index_sync_ctx *ctx);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber/* Rollback synchronization - none of the changes listed by sync_next() are
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber actually written to index file. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Grabervoid mail_index_sync_rollback(struct mail_index_sync_ctx *ctx);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber/* Mark index file corrupted. Invalidates all views. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Grabervoid mail_index_mark_corrupted(struct mail_index *index);
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber/* Check and fix any found problems. If index is broken beyond repair, it's
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber marked corrupted and 0 is returned. Otherwise returns -1 if there was some
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber I/O error or 1 if everything went ok. */
fe253caa8b98854445aaf6ee253545ee1f13beb1Stéphane Graberint mail_index_fsck(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Synchronize changes in view. You have to go through all records, or view
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin will be marked inconsistent. Only sync_mask type records are
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin synchronized. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_view_sync_begin(struct mail_index_view *view,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin enum mail_index_sync_type sync_mask,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin struct mail_index_view_sync_ctx **ctx_r);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
1881820ae4ff9004beef1bf7f04553580840441dSerge Hallynint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin struct mail_index_sync_rec *sync_rec);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinconst uint32_t *
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin size_t *count_r);
eba7df9ee0a1963984ef212e7ddfc0e0835af288Stéphane Grabervoid mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx);
eee3ba81c88e64b8a732694fc4843a39d5bde491Serge Hallyn
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber/* Returns the index header. */
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graberint mail_index_get_header(struct mail_index_view *view,
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber const struct mail_index_header **hdr_r);
f02ce27d4b1a9d01b88d0ffaf626e5bafa671bf0Stéphane Graber/* Returns the given message. Returns -1 if error, 1 if ok, 0 if mail was
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin expunged but data was returned from some older index. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin const struct mail_index_record **rec_r);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns the UID for given message. May be slightly faster than
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin mail_index_lookup()->uid. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t *uid_r);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin/* Returns the wanted extra data for given message. If it doesn't exist,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin *data_r is set to NULL. Return values are same as for mail_index_lookup(). */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinint mail_index_lookup_extra(struct mail_index_view *view, uint32_t seq,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t data_id, const void **data_r);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin/* Convert UID range to sequence range. If no UIDs are found, sequences are
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin set to 0. Note that any of the returned sequences may have been expunged
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin already. */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinint mail_index_lookup_uid_range(struct mail_index_view *view,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t first_uid, uint32_t last_uid,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t *first_seq_r, uint32_t *last_seq_r);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin/* Find first mail with (mail->flags & flags_mask) == flags. Useful mostly for
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin taking advantage of lowwater-fields in headers. */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint8_t flags_mask, uint32_t *seq_r);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin/* Append a new record to index. */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinvoid mail_index_append(struct mail_index_transaction *t, uint32_t uid,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin uint32_t *seq_r);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin/* Assigns UIDs for appended mails all at once. UID must have been given as 0
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin for mail_index_append(). Returns the next unused UID. */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinvoid mail_index_append_assign_uids(struct mail_index_transaction *t,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t first_uid, uint32_t *next_uid_r);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Expunge record from index. Note that this doesn't affect sequence numbers
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin until transaction is committed and mailbox is synced. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_expunge(struct mail_index_transaction *t, uint32_t seq);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Update flags in index. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin enum modify_type modify_type,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin enum mail_flags flags, keywords_mask_t keywords);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Update field in header. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_update_header(struct mail_index_transaction *t,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin size_t offset, const void *data, size_t size);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Update extra record field. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_update_extra_rec(struct mail_index_transaction *t,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint32_t seq, uint32_t data_id,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin const void *data);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin/* Returns the last error code. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinenum mail_index_error mail_index_get_last_error(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Returns the full error message for last error. This message may
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin contain paths etc. so it shouldn't be shown to users. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinconst char *mail_index_get_error_message(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Reset the error message. */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinvoid mail_index_reset_error(struct mail_index *index);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin/* Apply changes in MAIL_INDEX_SYNC_TYPE_FLAGS typed sync records to given
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Graber flags variables. */
14d9c0f09d1a55d124ef210a4b4e205c9fe7596cStéphane Grabervoid mail_index_sync_flags_apply(const struct mail_index_sync_rec *sync_rec,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin uint8_t *flags, keywords_mask_t keywords);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#endif
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin