mail-index.h revision d2475500ee2a5f3c07eb22886797cef0e11ce7c4
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen#ifndef __MAIL_INDEX_H
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#define __MAIL_INDEX_H
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#include "mail-types.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "seq-range-array.h"
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#define MAIL_INDEX_MAJOR_VERSION 7
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#define MAIL_INDEX_MINOR_VERSION 1
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#define MAIL_INDEX_HEADER_MIN_SIZE 120
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkenum file_lock_method;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkenum mail_index_open_flags {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* Create index if it doesn't exist */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_OPEN_FLAG_CREATE = 0x01,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* Don't try to mmap() index files */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE = 0x04,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* Rely on O_EXCL when creating dotlocks */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL = 0x10,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* Don't fsync() or fdatasync() */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE = 0x20
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkenum mail_index_header_compat_flags {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkenum mail_index_header_flag {
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen /* Index file is corrupted, reopen or recreate it. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi MAIL_INDEX_HDR_FLAG_CORRUPTED = 0x0001,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_HDR_FLAG_HAVE_DIRTY = 0x0002,
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen /* fsck the index next time when opening */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_HDR_FLAG_FSCK = 0x0004
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkenum mail_index_mail_flags {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_MAIL_FLAG_DIRTY = 0x80
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#define MAIL_INDEX_FLAGS_MASK \
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk (MAIL_ANSWERED | MAIL_FLAGGED | MAIL_DELETED | MAIL_SEEN | MAIL_DRAFT)
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_header {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* major version is increased only when you can't have backwards
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen compatibility. minor version is increased when header size is
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk increased to contain new non-critical fields. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint8_t major_version;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint8_t minor_version;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen uint16_t base_header_size;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t header_size; /* base + extended header size */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t record_size;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint8_t compat_flags; /* enum mail_index_header_compat_flags */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint8_t unused[3];
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t indexid;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t flags;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t uid_validity;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t next_uid;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t messages_count;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t recent_messages_count;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t seen_messages_count;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t deleted_messages_count;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* these UIDs may not exist and may not even be unseen */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t first_recent_uid_lowwater;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t first_unseen_uid_lowwater;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t first_deleted_uid_lowwater;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t log_file_seq;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t log_file_index_int_offset;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t log_file_index_ext_offset;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint64_t sync_size;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t sync_stamp;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* daily first UIDs that have been added to index. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t day_stamp;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t day_first_uid[8];
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t log_file_mailbox_offset;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t padding;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_record {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t uid;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint8_t flags; /* enum mail_flags | enum mail_index_mail_flags */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_keywords {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mail_index *index;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk unsigned int count;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* variable sized list of keyword indexes */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk unsigned int idx[1];
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkenum mail_index_sync_type {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_SYNC_TYPE_APPEND = 0x01,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD = 0x08,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE = 0x10,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET = 0x20
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk#define MAIL_INDEX_SYNC_MASK_ALL 0xff
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomistruct mail_index_sync_rec {
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi uint32_t uid1, uid2;
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi enum mail_index_sync_type type;
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi /* MAIL_INDEX_SYNC_TYPE_FLAGS: */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi uint8_t add_flags;
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi uint8_t remove_flags;
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk /* MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD, .._REMOVE: */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk unsigned int keyword_idx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk};
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_view_sync_rec {
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk uint32_t uid1, uid2;
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi /* keyword appends and removes are packed into one and same
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi enum mail_index_sync_type type;
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi};
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal VolkARRAY_DEFINE_TYPE(keyword_indexes, unsigned int);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_map;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_view;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_transaction;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_sync_ctx;
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_view_sync_ctx;
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid mail_index_free(struct mail_index **index);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid mail_index_set_permissions(struct mail_index *index,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mode_t mode, gid_t gid);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainenint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk enum file_lock_method lock_method);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid mail_index_close(struct mail_index *index);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Move the index into memory. Returns 0 if ok, -1 if error occurred. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkint mail_index_move_to_memory(struct mail_index *index);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_cache *mail_index_get_cache(struct mail_index *index);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Refresh index so mail_index_lookup*() will return latest values. Note that
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk immediately after this call there may already be changes, so if you need to
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk rely on validity of the returned values, use some external locking for it. */
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainenint mail_index_refresh(struct mail_index *index);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* View can be used to look into index. Sequence numbers inside view change
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk only when you synchronize it. The view acquires required locks
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk automatically, but you'll have to drop them manually. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index_view *mail_index_view_open(struct mail_index *index);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid mail_index_view_close(struct mail_index_view **view);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Returns the index for given view. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkstruct mail_index *mail_index_view_get_index(struct mail_index_view *view);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Call whenever you've done with requesting messages from view for a while. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkvoid mail_index_view_unlock(struct mail_index_view *view);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Returns number of mails in view. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkuint32_t mail_index_view_get_messages_count(struct mail_index_view *view);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Returns TRUE if we lost track of changes for some reason. */
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volkbool mail_index_view_is_inconsistent(struct mail_index_view *view);
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Transaction has to be opened to be able to modify index. You can have
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk multiple transactions open simultaneously. Committed transactions won't
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi show up until you've synchronized the view. Expunges won't show up until
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk you've synchronized the mailbox (mail_index_sync_begin).
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk If transaction is marked as hidden, the changes won't be listed when the
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk view is synchronized. Expunges can't be hidden.
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi External transactions describe changes to mailbox that have already
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi happened. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomistruct mail_index_transaction *
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomimail_index_transaction_begin(struct mail_index_view *view,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi bool hide, bool external);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomiint mail_index_transaction_commit(struct mail_index_transaction **t,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi uint32_t *log_file_seq_r,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi uoff_t *log_file_offset_r);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomivoid mail_index_transaction_rollback(struct mail_index_transaction **t);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi/* Discard all changes in the transaction. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomivoid mail_index_transaction_reset(struct mail_index_transaction *t);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi/* Returns the view transaction was created for. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomistruct mail_index_view *
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomimail_index_transaction_get_view(struct mail_index_transaction *t);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi/* Returns TRUE if the given sequence is being expunged in this transaction. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomibool mail_index_transaction_is_expunged(struct mail_index_transaction *t,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi uint32_t seq);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk/* Returns a view to transaction. Currently this differs from normal view only
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen in that it contains newly appended messages in transaction. The view can
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk still be used after transaction has been committed. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomistruct mail_index_view *
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomimail_index_transaction_open_updated_view(struct mail_index_transaction *t);
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi/* Begin synchronizing mailbox with index file. Returns 1 if ok, -1 if error.
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk If log_file_seq is not (uint32_t)-1 and index is already synchronized up
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi to the given log_file_offset, the synchronization isn't started and this
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi function returns 0. This should be done when you wish to sync your committed
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi transaction instead of doing a full mailbox synchronization.
633a1bf10559b9a8d85bfab662fa2a7ba97d45baAki Tuomi
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk mail_index_sync_next() returns all changes from previously committed
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk transactions which haven't yet been committed to the actual mailbox.
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk They're returned in ascending order and they never overlap (if we add more
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk sync types, then they might). You must go through all of them and update
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk the mailbox accordingly.
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk None of the changes actually show up in the index until after a successful
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi mail_index_sync_commit().
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi Returned sequence numbers describe the mailbox state at the beginning of
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi synchronization, ie. expunges don't affect them.
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi Changes done to the returned transaction are expected to describe the
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi mailbox's current state. */
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomiint mail_index_sync_begin(struct mail_index *index,
6eb1a7a7ae2c1dfff6731956ade08f9a4a7c791aAki Tuomi struct mail_index_sync_ctx **ctx_r,
381daab1e3b56a0bc94d2191cf62beba0df51af9Pascal Volk struct mail_index_view **view_r,
struct mail_index_transaction **trans_r,
uint32_t log_file_seq, uoff_t log_file_offset,
bool sync_recent, bool sync_dirty);
/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
int mail_index_sync_next(struct mail_index_sync_ctx *ctx,
struct mail_index_sync_rec *sync_rec);
/* Returns TRUE if there's more to sync. */
bool mail_index_sync_have_more(struct mail_index_sync_ctx *ctx);
/* Reset syncing to initial state after mail_index_sync_begin(), so you can
go through all the sync records again with mail_index_sync_next(). */
void mail_index_sync_reset(struct mail_index_sync_ctx *ctx);
/* Commit synchronization by writing all changes to mail index file. */
int mail_index_sync_commit(struct mail_index_sync_ctx **ctx);
/* Rollback synchronization - none of the changes listed by sync_next() are
actually written to index file. */
void mail_index_sync_rollback(struct mail_index_sync_ctx **ctx);
/* Mark index file corrupted. Invalidates all views. */
void mail_index_mark_corrupted(struct mail_index *index);
/* Check and fix any found problems. If index is broken beyond repair, it's
marked corrupted and 0 is returned. Otherwise returns -1 if there was some
I/O error or 1 if everything went ok. */
int mail_index_fsck(struct mail_index *index);
/* Synchronize changes in view. You have to go through all records, or view
will be marked inconsistent. Only sync_mask type records are
synchronized. */
int mail_index_view_sync_begin(struct mail_index_view *view,
enum mail_index_sync_type sync_mask,
struct mail_index_view_sync_ctx **ctx_r);
/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
int mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
struct mail_index_view_sync_rec *sync_rec);
void
mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
const ARRAY_TYPE(seq_range) **expunges_r);
void mail_index_view_sync_end(struct mail_index_view_sync_ctx **ctx);
/* Returns the index header. */
const struct mail_index_header *
mail_index_get_header(struct mail_index_view *view);
/* Returns the given message. Returns -1 if error, 1 if ok, 0 if mail was
expunged but data was returned from some older index. */
int mail_index_lookup(struct mail_index_view *view, uint32_t seq,
const struct mail_index_record **rec_r);
int mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
struct mail_index_map **map_r,
const struct mail_index_record **rec_r);
/* Note that returned keyword indexes aren't sorted. */
int mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
ARRAY_TYPE(keyword_indexes) *keyword_idx);
/* Returns the UID for given message. May be slightly faster than
mail_index_lookup()->uid. */
int mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
uint32_t *uid_r);
/* Convert UID range to sequence range. If no UIDs are found, sequences are
set to 0. Note that any of the returned sequences may have been expunged
already. */
int mail_index_lookup_uid_range(struct mail_index_view *view,
uint32_t first_uid, uint32_t last_uid,
uint32_t *first_seq_r, uint32_t *last_seq_r);
/* Find first mail with (mail->flags & flags_mask) == flags. Useful mostly for
taking advantage of lowwater-fields in headers. */
int mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
uint8_t flags_mask, uint32_t *seq_r);
/* Append a new record to index. */
void mail_index_append(struct mail_index_transaction *t, uint32_t uid,
uint32_t *seq_r);
/* Assigns UIDs for appended mails all at once. UID must have been given as 0
for mail_index_append(). Returns the next unused UID. */
void mail_index_append_assign_uids(struct mail_index_transaction *t,
uint32_t first_uid, uint32_t *next_uid_r);
/* Expunge record from index. Note that this doesn't affect sequence numbers
until transaction is committed and mailbox is synced. */
void mail_index_expunge(struct mail_index_transaction *t, uint32_t seq);
/* Update flags in index. */
void mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq,
enum modify_type modify_type,
enum mail_flags flags);
void mail_index_update_flags_range(struct mail_index_transaction *t,
uint32_t seq1, uint32_t seq2,
enum modify_type modify_type,
enum mail_flags flags);
/* Lookup a keyword, returns TRUE if found, FALSE if not. If autocreate is
TRUE, the keyword is automatically created and TRUE is always returned. */
bool mail_index_keyword_lookup(struct mail_index *index,
const char *keyword, bool autocreate,
unsigned int *idx_r);
/* Return a pointer to array of NULL-terminated list of keywords. Note that
the array contents (and thus pointers inside it) may change after calling
mail_index_keywords_create() or mail_index_sync_begin(). */
const ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index);
/* Create a keyword list structure. It's freed automatically at the end of
the transaction. */
struct mail_keywords *
mail_index_keywords_create(struct mail_index_transaction *t,
const char *const keywords[]);
struct mail_keywords *
mail_index_keywords_create_from_indexes(struct mail_index_transaction *t,
const ARRAY_TYPE(keyword_indexes)
*keyword_indexes);
/* Free the keywords. */
void mail_index_keywords_free(struct mail_keywords **keywords);
/* Update keywords for given message. */
void mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq,
enum modify_type modify_type,
struct mail_keywords *keywords);
/* Update field in header. If prepend is TRUE, the header change is visible
before message syncing begins. */
void mail_index_update_header(struct mail_index_transaction *t,
size_t offset, const void *data, size_t size,
bool prepend);
/* Returns the full error message for last error. This message may
contain paths etc. so it shouldn't be shown to users. */
const char *mail_index_get_error_message(struct mail_index *index);
/* Reset the error message. */
void mail_index_reset_error(struct mail_index *index);
/* Apply changes in MAIL_INDEX_SYNC_TYPE_FLAGS typed sync records to given
flags variable. */
void mail_index_sync_flags_apply(const struct mail_index_sync_rec *sync_rec,
uint8_t *flags);
/* Apply changes in MAIL_INDEX_SYNC_TYPE_KEYWORD_* typed sync records to given
keywords array. Returns TRUE If something was changed. */
bool mail_index_sync_keywords_apply(const struct mail_index_sync_rec *sync_rec,
ARRAY_TYPE(keyword_indexes) *keywords);
/* register index extension. name is a unique identifier for the extension.
returns unique identifier for the name. */
uint32_t mail_index_ext_register(struct mail_index *index, const char *name,
uint32_t default_hdr_size,
uint16_t default_record_size,
uint16_t default_record_align);
/* Resize existing extension data. If size is grown, the new data will be
zero-filled. If size is shrinked, the data is simply dropped. */
void mail_index_ext_resize(struct mail_index_transaction *t, uint32_t ext_id,
uint32_t hdr_size, uint16_t record_size,
uint16_t record_align);
/* Reset extension records and header. Any updates for this extension which
were issued before the writer had seen this reset are discarded. reset_id is
used to figure this out, so it must be different every time. */
void mail_index_ext_reset(struct mail_index_transaction *t, uint32_t ext_id,
uint32_t reset_id);
/* Returns extension header. */
int mail_index_get_header_ext(struct mail_index_view *view, uint32_t ext_id,
const void **data_r, size_t *data_size_r);
int mail_index_map_get_header_ext(struct mail_index_view *view,
struct mail_index_map *map, uint32_t ext_id,
const void **data_r, size_t *data_size_r);
/* Returns the wanted extension record for given message. If it doesn't exist,
*data_r is set to NULL. Return values are same as for mail_index_lookup(). */
int mail_index_lookup_ext(struct mail_index_view *view, uint32_t seq,
uint32_t ext_id, const void **data_r);
int mail_index_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
uint32_t ext_id, struct mail_index_map **map_r,
const void **data_r);
/* Get current extension sizes. Returns 1 if ok, 0 if extension doesn't exist
in view. Any of the _r parameters may be NULL. */
int mail_index_ext_get_size(struct mail_index_view *view,
uint32_t ext_id, struct mail_index_map *map,
uint32_t *hdr_size_r, uint16_t *record_size_r,
uint16_t *record_align_r);
/* Update extension header field. */
void mail_index_update_header_ext(struct mail_index_transaction *t,
uint32_t ext_id, size_t offset,
const void *data, size_t size);
/* Update extension record. If old_data_r is non-NULL and the record extension
was already updated in this transaction, it's set to contain the data it's
now overwriting. */
void mail_index_update_ext(struct mail_index_transaction *t, uint32_t seq,
uint32_t ext_id, const void *data, void *old_data);
#endif