mail-index.h revision 893e5bbd5184ec5c21f47c67c8ea6efbea41f7d0
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen#ifndef __MAIL_INDEX_H
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define __MAIL_INDEX_H
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "mail-types.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "seq-range-array.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define MAIL_INDEX_MAJOR_VERSION 7
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define MAIL_INDEX_MINOR_VERSION 1
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#define MAIL_INDEX_HEADER_MIN_SIZE 120
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschenum file_lock_method;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschenum mail_index_open_flags {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* Create index if it doesn't exist */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MAIL_INDEX_OPEN_FLAG_CREATE = 0x01,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* Don't try to mmap() index files */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE = 0x04,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* Rely on O_EXCL when creating dotlocks */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch MAIL_INDEX_OPEN_FLAG_DOTLOCK_USE_EXCL = 0x10,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* Don't fsync() or fdatasync() */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch MAIL_INDEX_OPEN_FLAG_FSYNC_DISABLE = 0x20
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch};
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschenum mail_index_header_compat_flags {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch};
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschenum mail_index_header_flag {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* Index file is corrupted, reopen or recreate it. */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch MAIL_INDEX_HDR_FLAG_CORRUPTED = 0x0001,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch MAIL_INDEX_HDR_FLAG_HAVE_DIRTY = 0x0002,
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* fsck the index next time when opening */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch MAIL_INDEX_HDR_FLAG_FSCK = 0x0004
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch};
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschenum mail_index_mail_flags {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch MAIL_INDEX_MAIL_FLAG_DIRTY = 0x80
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch};
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch#define MAIL_INDEX_FLAGS_MASK \
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch (MAIL_ANSWERED | MAIL_FLAGGED | MAIL_DELETED | MAIL_SEEN | MAIL_DRAFT)
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Boschstruct mail_index_header {
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch /* major version is increased only when you can't have backwards
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch compatibility. minor version is increased when header size is
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch increased to contain new non-critical fields. */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint8_t major_version;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint8_t minor_version;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint16_t base_header_size;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint32_t header_size; /* base + extended header size */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint32_t record_size;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint8_t compat_flags; /* enum mail_index_header_compat_flags */
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint8_t unused[3];
6ee9ce5ed955a1283dc22ad28980bf9cc23d4c4eStephan Bosch
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint32_t indexid;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch uint32_t flags;
de96afeeaa5242cffe89f1966457e935806b5746Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t uid_validity;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t next_uid;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t messages_count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t recent_messages_count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t seen_messages_count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t deleted_messages_count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* these UIDs may not exist and may not even be unseen */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t first_recent_uid_lowwater;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t first_unseen_uid_lowwater;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t first_deleted_uid_lowwater;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t log_file_seq;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* non-external records between tail..head haven't been committed to
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch mailbox yet. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t log_file_tail_offset;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t log_file_head_offset;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint64_t sync_size;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t sync_stamp;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* daily first UIDs that have been added to index. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t day_stamp;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t day_first_uid[8];
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_index_record {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t uid;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint8_t flags; /* enum mail_flags | enum mail_index_mail_flags */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_keywords {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_index *index;
c275cef636c79e1d08b3a82462c4abdca6f8cef3Martti Rannanjärvi unsigned int count;
7944646fad6aa1e7c649c3d33e454c516b0220b6Timo Sirainen
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen /* variable sized list of keyword indexes */
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen unsigned int idx[1];
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen};
b99130e4cf4af4e6b103b949456222f3a2dff424Timo Sirainen
c275cef636c79e1d08b3a82462c4abdca6f8cef3Martti Rannanjärvienum mail_index_sync_type {
5d31e4b38ef03b002e2ab245a7f8a4c0da3dd03dTimo Sirainen MAIL_INDEX_SYNC_TYPE_APPEND = 0x01,
5d31e4b38ef03b002e2ab245a7f8a4c0da3dd03dTimo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04,
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD = 0x08,
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE = 0x10,
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET = 0x20
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch};
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Boschenum mail_index_sync_flags {
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch /* Resync all dirty messages' flags. */
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch MAIL_INDEX_SYNC_FLAG_FLUSH_DIRTY = 0x01,
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch /* Drop recent flags from all messages */
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch MAIL_INDEX_SYNC_FLAG_DROP_RECENT = 0x02
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch};
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Boschenum mail_index_view_sync_flags {
4c4c4a740bbb1b674d4b0dae009d1919f8ad96b7Stephan Bosch /* Don't sync expunges */
4219de12b28f1936219e27501b9c4b27a4f8d53cStephan Bosch MAIL_INDEX_VIEW_SYNC_FLAG_NOEXPUNGES = 0x01
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_index_sync_rec {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t uid1, uid2;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mail_index_sync_type type;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
9d746c6785d17e421c3f3c74cf29d059ae2ab233Stephan Bosch /* MAIL_INDEX_SYNC_TYPE_FLAGS: */
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch uint8_t add_flags;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch uint8_t remove_flags;
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch
fe2b0e3de834dd40b698bb579adc5357d5789ec9Stephan Bosch /* MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD, .._REMOVE: */
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Bosch unsigned int keyword_idx;
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Bosch};
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Bosch
94d1b08c9e20d637db568a3eab3dfc2b9e96e62aStephan Boschstruct mail_index_view_sync_rec {
ad03049781fc14807248007d524be4daf06c3ee2Stephan Bosch uint32_t uid1, uid2;
486c7c8d9e725e0227c7723aa43b7fce724eb9eeStephan Bosch /* keyword appends and removes are packed into one and same
e47c2f17d8136c4d972d1074a3f84ba2ecef4fdcStephan Bosch MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mail_index_sync_type type;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch};
b66def5dadd3e7c250313a938d26ad113663f86bStephan Bosch
b66def5dadd3e7c250313a938d26ad113663f86bStephan BoschARRAY_DEFINE_TYPE(keyword_indexes, unsigned int);
5257840e8d31a6cb7051703b4cb0931c82aba638Stephan Bosch
5257840e8d31a6cb7051703b4cb0931c82aba638Stephan Boschstruct mail_index;
5257840e8d31a6cb7051703b4cb0931c82aba638Stephan Boschstruct mail_index_map;
5257840e8d31a6cb7051703b4cb0931c82aba638Stephan Boschstruct mail_index_view;
a8c4e79ff50fac21b05a7368b052583d410ca15cTimo Sirainenstruct mail_index_transaction;
70505f4839520ac67895992621c97d2480c22e7fTimo Sirainenstruct mail_index_sync_ctx;
93cc87bb22386e020cee1093b6bd59295e0b33f0Stephan Boschstruct mail_index_view_sync_ctx;
c972eaa3565e849df71b44cf0cd45d38c5567d07Stephan Bosch
c972eaa3565e849df71b44cf0cd45d38c5567d07Stephan Boschstruct mail_index *mail_index_alloc(const char *dir, const char *prefix);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid mail_index_free(struct mail_index **index);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_set_permissions(struct mail_index *index,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch mode_t mode, gid_t gid);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum file_lock_method lock_method);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid mail_index_close(struct mail_index *index);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Move the index into memory. Returns 0 if ok, -1 if error occurred. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint mail_index_move_to_memory(struct mail_index *index);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_cache *mail_index_get_cache(struct mail_index *index);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Refresh index so mail_index_lookup*() will return latest values. Note that
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch immediately after this call there may already be changes, so if you need to
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch rely on validity of the returned values, use some external locking for it. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint mail_index_refresh(struct mail_index *index);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* View can be used to look into index. Sequence numbers inside view change
f9d2a1f21ad65262bc630f0834d7eead06a1bac3Timo Sirainen only when you synchronize it. The view acquires required locks
f9d2a1f21ad65262bc630f0834d7eead06a1bac3Timo Sirainen automatically, but you'll have to drop them manually. */
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Boschstruct mail_index_view *mail_index_view_open(struct mail_index *index);
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Boschvoid mail_index_view_close(struct mail_index_view **view);
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch/* Returns the index for given view. */
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Boschstruct mail_index *mail_index_view_get_index(struct mail_index_view *view);
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch/* Call whenever you've done with requesting messages from view for a while. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_view_unlock(struct mail_index_view *view);
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch/* Returns number of mails in view. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschuint32_t mail_index_view_get_messages_count(struct mail_index_view *view);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns TRUE if we lost track of changes for some reason. */
9dc01e0d10a61cab14867b26bf0d2d1dcf8ad978Timo Sirainenbool mail_index_view_is_inconsistent(struct mail_index_view *view);
9dc01e0d10a61cab14867b26bf0d2d1dcf8ad978Timo Sirainen
ebe0f5e387744621b73c4db79d5891ccbe0a1321Stephan Bosch/* Transaction has to be opened to be able to modify index. You can have
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch multiple transactions open simultaneously. Committed transactions won't
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch show up until you've synchronized the view. Expunges won't show up until
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch you've synchronized the mailbox (mail_index_sync_begin).
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
aacf2a69acc59e9382578d6f4e030788abc79706Timo Sirainen If transaction is marked as hidden, the changes won't be listed when the
aacf2a69acc59e9382578d6f4e030788abc79706Timo Sirainen view is synchronized. Expunges can't be hidden.
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch External transactions describe changes to mailbox that have already
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch happened. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_index_transaction *
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Boschmail_index_transaction_begin(struct mail_index_view *view,
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch bool hide, bool external);
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Boschint mail_index_transaction_commit(struct mail_index_transaction **t,
6ab81c81be13f33486746deeffe02a1ef2bcc821Stephan Bosch uint32_t *log_file_seq_r,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uoff_t *log_file_offset_r);
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainenvoid mail_index_transaction_rollback(struct mail_index_transaction **t);
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen/* Discard all changes in the transaction. */
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainenvoid mail_index_transaction_reset(struct mail_index_transaction *t);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns the view transaction was created for. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_index_view *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschmail_index_transaction_get_view(struct mail_index_transaction *t);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns TRUE if the given sequence is being expunged in this transaction. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschbool mail_index_transaction_is_expunged(struct mail_index_transaction *t,
636d0f43138468f8efe685a681326b123f660e49Timo Sirainen uint32_t seq);
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns a view to transaction. Currently this differs from normal view only
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch in that it contains newly appended messages in transaction. The view can
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch still be used after transaction has been committed. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mail_index_view *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschmail_index_transaction_open_updated_view(struct mail_index_transaction *t);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Begin synchronizing mailbox with index file. Returns 1 if ok, -1 if error.
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch If log_file_seq is not (uint32_t)-1 and index is already synchronized up
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch to the given log_file_offset, the synchronization isn't started and this
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch function returns 0. This should be done when you wish to sync your committed
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch transaction instead of doing a full mailbox synchronization.
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch mail_index_sync_next() returns all changes from previously committed
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch transactions which haven't yet been committed to the actual mailbox.
fc94140acba51adafedafbc8491a3223a51db7a8Stephan Bosch They're returned in ascending order and they never overlap (if we add more
636d0f43138468f8efe685a681326b123f660e49Timo Sirainen sync types, then they might). You must go through all of them and update
636d0f43138468f8efe685a681326b123f660e49Timo Sirainen the mailbox accordingly.
636d0f43138468f8efe685a681326b123f660e49Timo Sirainen
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch None of the changes actually show up in the index until after a successful
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch mail_index_sync_commit().
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch Returned sequence numbers describe the mailbox state at the beginning of
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch synchronization, ie. expunges don't affect them.
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch Changes done to the returned transaction are expected to describe the
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch mailbox's current state. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint mail_index_sync_begin(struct mail_index *index,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_index_sync_ctx **ctx_r,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_index_view **view_r,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_index_transaction **trans_r,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch uint32_t log_file_seq, uoff_t log_file_offset,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mail_index_sync_flags flags);
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
fb1be3de0159d6a10e916ad992e2bc53be64c6d5Timo Sirainenint mail_index_sync_next(struct mail_index_sync_ctx *ctx,
fb1be3de0159d6a10e916ad992e2bc53be64c6d5Timo Sirainen struct mail_index_sync_rec *sync_rec);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns TRUE if there's more to sync. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschbool mail_index_sync_have_more(struct mail_index_sync_ctx *ctx);
856ae2ad98cee79b2719911a3cc131d7f4ec8a90Timo Sirainen/* Reset syncing to initial state after mail_index_sync_begin(), so you can
856ae2ad98cee79b2719911a3cc131d7f4ec8a90Timo Sirainen go through all the sync records again with mail_index_sync_next(). */
1a9a35a6b307f8d5b25345af55e40a99162b4072Timo Sirainenvoid mail_index_sync_reset(struct mail_index_sync_ctx *ctx);
1a9a35a6b307f8d5b25345af55e40a99162b4072Timo Sirainen/* Commit synchronization by writing all changes to mail index file. */
1a9a35a6b307f8d5b25345af55e40a99162b4072Timo Sirainenint mail_index_sync_commit(struct mail_index_sync_ctx **ctx);
1a9a35a6b307f8d5b25345af55e40a99162b4072Timo Sirainen/* Rollback synchronization - none of the changes listed by sync_next() are
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch actually written to index file. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid mail_index_sync_rollback(struct mail_index_sync_ctx **ctx);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch/* Mark index file corrupted. Invalidates all views. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid mail_index_mark_corrupted(struct mail_index *index);
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Bosch/* Check and fix any found problems. If index is broken beyond repair, it's
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch marked corrupted and 0 is returned. Otherwise returns -1 if there was some
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch I/O error or 1 if everything went ok. */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint mail_index_fsck(struct mail_index *index);
35f3b7e05afecacd0332c210c6e253911c2813d8Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Synchronize changes in view. You have to go through all records, or view
856ae2ad98cee79b2719911a3cc131d7f4ec8a90Timo Sirainen will be marked inconsistent. Only sync_mask type records are
856ae2ad98cee79b2719911a3cc131d7f4ec8a90Timo Sirainen synchronized. */
35f3b7e05afecacd0332c210c6e253911c2813d8Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mail_index_view_sync_flags flags,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_index_view_sync_ctx **ctx_r);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
17cd0e0963f2fb0e66d49703e8cd0bda1b842468Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
17cd0e0963f2fb0e66d49703e8cd0bda1b842468Timo Sirainen struct mail_index_view_sync_rec *sync_rec);
a991cfe2157e58ee43bc580f517ce9ef0dfb7acfStephan Boschvoid
17cd0e0963f2fb0e66d49703e8cd0bda1b842468Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
17cd0e0963f2fb0e66d49703e8cd0bda1b842468Timo Sirainen const ARRAY_TYPE(seq_range) **expunges_r);
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx **ctx);
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen/* Returns the index header. */
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainenconst struct mail_index_header *
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainenmail_index_get_header(struct mail_index_view *view);
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen/* Returns the given message. Returns -1 if error, 1 if ok, 0 if mail was
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen expunged but data was returned from some older index. */
5d31e4b38ef03b002e2ab245a7f8a4c0da3dd03dTimo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
5d31e4b38ef03b002e2ab245a7f8a4c0da3dd03dTimo Sirainen const struct mail_index_record **rec_r);
5d31e4b38ef03b002e2ab245a7f8a4c0da3dd03dTimo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
5d31e4b38ef03b002e2ab245a7f8a4c0da3dd03dTimo Sirainen struct mail_index_map **map_r,
c275cef636c79e1d08b3a82462c4abdca6f8cef3Martti Rannanjärvi const struct mail_index_record **rec_r);
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainen/* Note that returned keyword indexes aren't sorted. */
ba1c847d0af4afe4787ed470d0c818e948e184e2Timo Sirainenint mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen ARRAY_TYPE(keyword_indexes) *keyword_idx);
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen/* Returns the UID for given message. May be slightly faster than
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainen mail_index_lookup()->uid. */
415e16c3dc185578695b7d88e561a52de6c8b1b1Timo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint32_t *uid_r);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Convert UID range to sequence range. If no UIDs are found, sequences are
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch set to 0. Note that any of the returned sequences may have been expunged
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch already. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschint mail_index_lookup_uid_range(struct mail_index_view *view,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint32_t first_uid, uint32_t last_uid,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint32_t *first_seq_r, uint32_t *last_seq_r);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Find first mail with (mail->flags & flags_mask) == flags. Useful mostly for
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch taking advantage of lowwater-fields in headers. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint8_t flags_mask, uint32_t *seq_r);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Append a new record to index. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_append(struct mail_index_transaction *t, uint32_t uid,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint32_t *seq_r);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Assigns UIDs for appended mails all at once. UID must have been given as 0
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch for mail_index_append(). Returns the next unused UID. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_append_assign_uids(struct mail_index_transaction *t,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint32_t first_uid, uint32_t *next_uid_r);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Expunge record from index. Note that this doesn't affect sequence numbers
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch until transaction is committed and mailbox is synced. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_expunge(struct mail_index_transaction *t, uint32_t seq);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Update flags in index. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch enum modify_type modify_type,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch enum mail_flags flags);
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_update_flags_range(struct mail_index_transaction *t,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch uint32_t seq1, uint32_t seq2,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch enum modify_type modify_type,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch enum mail_flags flags);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Reset the index before committing this transaction. This is usually done
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch only when UIDVALIDITY changes. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschvoid mail_index_reset(struct mail_index_transaction *t);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Lookup a keyword, returns TRUE if found, FALSE if not. If autocreate is
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch TRUE, the keyword is automatically created and TRUE is always returned. */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschbool mail_index_keyword_lookup(struct mail_index *index,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch const char *keyword, bool autocreate,
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch unsigned int *idx_r);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* Return a pointer to array of NULL-terminated list of keywords. Note that
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch the array contents (and thus pointers inside it) may change after calling
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch mail_index_keywords_create() or mail_index_sync_begin(). */
fca68889b287d8eed4babe72a231bd6079da012dStephan Boschconst ARRAY_TYPE(keywords) *mail_index_get_keywords(struct mail_index *index);
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch
fca68889b287d8eed4babe72a231bd6079da012dStephan Bosch/* 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);
/* Discard existing extension updates and write new updates using the given
reset_id. The difference to mail_index_ext_reset() is that this doesn't
clear any existing record or header data. */
void mail_index_ext_set_reset_id(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