mail-index.h revision aa38d1a0945f0bc13a225d043f53fad2eec666b1
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen#ifndef __MAIL_INDEX_H
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen#define __MAIL_INDEX_H
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen#include "mail-types.h"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen#define MAIL_INDEX_MAJOR_VERSION 7
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAIL_INDEX_MINOR_VERSION 0
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen#define MAIL_INDEX_HEADER_MIN_SIZE 120
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainenenum mail_index_open_flags {
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen /* Create index if it doesn't exist */
b55f914c0ade77252cfd798ea8eb9a84bda56315Timo Sirainen MAIL_INDEX_OPEN_FLAG_CREATE = 0x01,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen /* Open the index as fast as possible - do only minimal checks and
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen delay opening cache/log files unless they're needed. */
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen MAIL_INDEX_OPEN_FLAG_FAST = 0x02,
92c49f3005f4dff1a6f576fffa8112ef6d1cae7fTimo Sirainen /* Don't try to mmap() index files */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE = 0x04,
1d2c463d23f09f15727edae9c78b07ec6a7a27daTimo Sirainen /* Don't try to write() to mmap()ed index files. Required for the few
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen OSes that don't have unified buffer cache
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (currently OpenBSD <= 3.5) */
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen MAIL_INDEX_OPEN_FLAG_MMAP_NO_WRITE = 0x08
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen
1d4f710106fb498750456724628da6063e012e6dTimo Sirainenenum mail_index_lock_method {
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen MAIL_INDEX_LOCK_FCNTL,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen MAIL_INDEX_LOCK_FLOCK,
0b3e92b6043435c5aa9f1cf1d04b632f3e19abd9Phil Carmody MAIL_INDEX_LOCK_DOTLOCK
0b3e92b6043435c5aa9f1cf1d04b632f3e19abd9Phil Carmody};
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainenenum mail_index_header_compat_flags {
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen};
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainenenum mail_index_header_flag {
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen /* Index file is corrupted, reopen or recreate it. */
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen MAIL_INDEX_HDR_FLAG_CORRUPTED = 0x0001,
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen MAIL_INDEX_HDR_FLAG_HAVE_DIRTY = 0x0002
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen};
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainenenum mail_index_mail_flags {
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen MAIL_INDEX_MAIL_FLAG_DIRTY = 0x80
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen};
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainenenum mail_index_error {
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen /* No errors */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_ERROR_NONE,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Internal error, see get_error_text() for more information. */
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen MAIL_INDEX_ERROR_INTERNAL,
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen /* We ran out of available disk space. */
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen MAIL_INDEX_ERROR_DISKSPACE
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen};
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen#define MAIL_INDEX_FLAGS_MASK \
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen (MAIL_ANSWERED | MAIL_FLAGGED | MAIL_DELETED | MAIL_SEEN | MAIL_DRAFT)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainenstruct mail_index_header {
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen /* major version is increased only when you can't have backwards
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen compatibility. minor version is increased when header size is
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen increased to contain new non-critical fields. */
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint8_t major_version;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint8_t minor_version;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint16_t base_header_size;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint32_t header_size; /* base + extended header size */
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint32_t record_size;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen /* 0 = flags
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen 1 = sizeof(uoff_t)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen 2 = sizeof(time_t)
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen 3 = unused */
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint8_t compat_data[4];
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint32_t indexid;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint32_t flags;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen
ed16ab579bd058ec5e2b5d02bb41fdadd9e05b31Timo Sirainen uint32_t uid_validity;
7a94f950fd1dcc81537acfc8adb030b5e703d722Timo Sirainen uint32_t next_uid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t messages_count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t recent_messages_count;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen uint32_t seen_messages_count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t deleted_messages_count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* these UIDs may not exist and may not even be unseen */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t first_recent_uid_lowwater;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen uint32_t first_unseen_uid_lowwater;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen uint32_t first_deleted_uid_lowwater;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen /* We have internal and external sync offsets. External changes are
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen synced into index somewhat more often, so int_offset <= ext_offset */
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen uint32_t log_file_seq;
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen uint32_t log_file_int_offset;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t log_file_ext_offset;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen uint64_t sync_size;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen uint32_t sync_stamp;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen /* daily first UIDs that have been added to index. */
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen uint32_t day_stamp;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen uint32_t day_first_uid[8];
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen};
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenstruct mail_index_record {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen uint32_t uid;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen uint8_t flags; /* enum mail_flags | enum mail_index_mail_flags */
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen};
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenstruct mail_keywords {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen struct mail_index *index;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen unsigned int count;
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen /* variable sized list of keyword indexes */
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen unsigned int idx[1];
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen};
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenenum mail_index_sync_type {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen MAIL_INDEX_SYNC_TYPE_APPEND = 0x01,
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen MAIL_INDEX_SYNC_TYPE_EXPUNGE = 0x02,
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen MAIL_INDEX_SYNC_TYPE_FLAGS = 0x04,
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD = 0x08,
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_REMOVE = 0x10,
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET = 0x20
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAIL_INDEX_SYNC_MASK_ALL 0xff
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index_sync_rec {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t uid1, uid2;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_index_sync_type type;
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen /* MAIL_INDEX_SYNC_TYPE_FLAGS: */
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen uint8_t add_flags;
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen uint8_t remove_flags;
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen /* MAIL_INDEX_SYNC_TYPE_KEYWORD_ADD, .._REMOVE: */
4c6ddf2491104f917d00e6900e833e80ea02c7b6Timo Sirainen unsigned int keyword_idx;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index_map;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index_view;
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenstruct mail_index_transaction;
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainenstruct mail_index_sync_ctx;
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Boschstruct mail_index_view_sync_ctx;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index *mail_index_alloc(const char *dir, const char *prefix);
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Boschvoid mail_index_free(struct mail_index *index);
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Boschvoid mail_index_set_permissions(struct mail_index *index,
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch mode_t mode, gid_t gid);
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Boschint mail_index_open(struct mail_index *index, enum mail_index_open_flags flags,
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch enum mail_index_lock_method lock_method);
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Boschvoid mail_index_close(struct mail_index *index);
c12d96f12cac9af464ab2e59046bd59b0c06b4eaTimo Sirainen
c12d96f12cac9af464ab2e59046bd59b0c06b4eaTimo Sirainenstruct mail_cache *mail_index_get_cache(struct mail_index *index);
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Refresh index so mail_index_lookup*() will return latest values. Note that
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen immediately after this call there may already be changes, so if you need to
a05fec120ecd8c4ed6331c42100cba42adf22893Stephan Bosch rely on validity of the returned values, use some external locking for it. */
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainenint mail_index_refresh(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen/* View can be used to look into index. Sequence numbers inside view change
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen only when you synchronize it. The view acquires required locks
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen automatically, but you'll have to drop them manually. */
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainenstruct mail_index_view *mail_index_view_open(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_view_close(struct mail_index_view *view);
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen/* Returns the index for given view. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index *mail_index_view_get_index(struct mail_index_view *view);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Call whenever you've done with requesting messages from view for a while. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_view_unlock(struct mail_index_view *view);
9132f9df4e12ed5293c70957813aa3736444a13cTimo Sirainen/* Returns number of mails in view. */
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainenuint32_t mail_index_view_get_messages_count(struct mail_index_view *view);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns TRUE if we lost track of changes for some reason. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_view_is_inconsistent(struct mail_index_view *view);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Transaction has to be opened to be able to modify index. You can have
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen multiple transactions open simultaneously. Note that committed transactions
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen won't show up until you've synchronized mailbox (mail_index_sync_begin). */
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainenstruct mail_index_transaction *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_index_transaction_begin(struct mail_index_view *view,
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen int hide, int external);
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainenint mail_index_transaction_commit(struct mail_index_transaction *t,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t *log_file_seq_r,
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen uoff_t *log_file_offset_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_transaction_rollback(struct mail_index_transaction *t);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns a view to transaction. Currently this differs from normal view only
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen in that it contains newly appended messages in transaction. The view can
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen still be used after transaction has been committed. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index_view *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_index_transaction_open_updated_view(struct mail_index_transaction *t);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Begin synchronizing mailbox with index file. This call locks the index
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen exclusively against other modifications. Returns 1 if ok, -1 if error.
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen If log_file_seq is not (uint32_t)-1 and index is already synchronized up
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen to given log_file_offset, the synchronization isn't started and this
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen function returns 0. This should be done when you wish to sync your previous
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen transaction instead of doing a full mailbox synchronization.
a117008f03ad9e2d54258b30d3fb03ffa502a448Timo Sirainen
a117008f03ad9e2d54258b30d3fb03ffa502a448Timo Sirainen mail_index_sync_next() returns all changes from previously committed
6da2d4faed507f513c68b94bb56a13caeeb3ff4aTimo Sirainen transactions which haven't yet been committed to the actual mailbox.
6da2d4faed507f513c68b94bb56a13caeeb3ff4aTimo Sirainen They're returned in ascending order and they never overlap (if we add more
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sync types, then they might). You must go through all of them and update
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen the mailbox accordingly.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen None of the changes actually show up in index until after successful
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_sync_commit().
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen Returned sequence numbers describe the mailbox state at the beginning of
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen synchronization, ie. expunges don't affect them.
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen You may create a new transaction for the returned view. That transaction
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen acts as "external mailbox changes" transaction. Any changes done there are
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen expected to describe mailbox's current state. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_sync_begin(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_sync_ctx **ctx_r,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_view **view_r,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t log_file_seq, uoff_t log_file_offset,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int sync_recent, int sync_dirty);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_sync_next(struct mail_index_sync_ctx *ctx,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_sync_rec *sync_rec);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns 1 if there's more to sync, 0 if not. */
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainenint mail_index_sync_have_more(struct mail_index_sync_ctx *ctx);
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen/* Reset syncing to initial state after mail_index_sync_begin(), so you can
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen go through all the sync records again with mail_index_sync_next(). */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_sync_reset(struct mail_index_sync_ctx *ctx);
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen/* Commit synchronization by writing all changes to mail index file. */
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainenint mail_index_sync_commit(struct mail_index_sync_ctx *ctx);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Rollback synchronization - none of the changes listed by sync_next() are
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen actually written to index file. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_sync_rollback(struct mail_index_sync_ctx *ctx);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Mark index file corrupted. Invalidates all views. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_mark_corrupted(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Check and fix any found problems. If index is broken beyond repair, it's
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen marked corrupted and 0 is returned. Otherwise returns -1 if there was some
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen I/O error or 1 if everything went ok. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_fsck(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Synchronize changes in view. You have to go through all records, or view
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen will be marked inconsistent. Only sync_mask type records are
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen synchronized. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_index_sync_type sync_mask,
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch struct mail_index_view_sync_ctx **ctx_r);
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch/* Returns -1 if error, 0 if sync is finished, 1 if record was filled. */
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen struct mail_index_sync_rec *sync_rec);
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainenconst uint32_t *
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen unsigned int *count_r);
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx);
9ddd3d7d8651985e373a6c48e0ddc76b8a4ef1c7Timo Sirainen
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen/* Returns the index header. */
5d2e7ec2ea725c8a6a63f56b771e746f93e782ecTimo Sirainenconst struct mail_index_header *
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainenmail_index_get_header(struct mail_index_view *view);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns the given message. Returns -1 if error, 1 if ok, 0 if mail was
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen expunged but data was returned from some older index. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup(struct mail_index_view *view, uint32_t seq,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const struct mail_index_record **rec_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup_full(struct mail_index_view *view, uint32_t seq,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_map **map_r,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const struct mail_index_record **rec_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup_keywords(struct mail_index_view *view, uint32_t seq,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen array_t *keyword_idx);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns the UID for given message. May be slightly faster than
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen mail_index_lookup()->uid. */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenint mail_index_lookup_uid(struct mail_index_view *view, uint32_t seq,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen uint32_t *uid_r);
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen/* Convert UID range to sequence range. If no UIDs are found, sequences are
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen set to 0. Note that any of the returned sequences may have been expunged
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen already. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup_uid_range(struct mail_index_view *view,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t first_uid, uint32_t last_uid,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t *first_seq_r, uint32_t *last_seq_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Find first mail with (mail->flags & flags_mask) == flags. Useful mostly for
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen taking advantage of lowwater-fields in headers. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup_first(struct mail_index_view *view, enum mail_flags flags,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint8_t flags_mask, uint32_t *seq_r);
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Append a new record to index. */
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainenvoid mail_index_append(struct mail_index_transaction *t, uint32_t uid,
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen uint32_t *seq_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Assigns UIDs for appended mails all at once. UID must have been given as 0
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen for mail_index_append(). Returns the next unused UID. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_append_assign_uids(struct mail_index_transaction *t,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t first_uid, uint32_t *next_uid_r);
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen/* Expunge record from index. Note that this doesn't affect sequence numbers
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen until transaction is committed and mailbox is synced. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_expunge(struct mail_index_transaction *t, uint32_t seq);
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen/* Update flags in index. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_update_flags(struct mail_index_transaction *t, uint32_t seq,
fa02962b74d39e8d74c4c307c0210791b2f0a1caTimo Sirainen enum modify_type modify_type,
fa02962b74d39e8d74c4c307c0210791b2f0a1caTimo Sirainen enum mail_flags flags);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_update_flags_range(struct mail_index_transaction *t,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t seq1, uint32_t seq2,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum modify_type modify_type,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_flags flags);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen/* Lookup a keyword, returns TRUE if found, FALSE if not. If autocreate is
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen TRUE, the keyword is automatically created and TRUE is always returned. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_keyword_lookup(struct mail_index *index,
c7eb1ffb7c73cb5d9c1316bbecd02947441a40d4Timo Sirainen const char *keyword, int autocreate,
2f90189c6ee66a17f7bf838a8eb8a69868630fb8Timo Sirainen unsigned int *idx_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Return a pointer to array of NULL-terminated list of keywords. Note that
b6b7a17731a917958b6479920b3fac5ca991db6aTimo Sirainen the array contents (and thus pointers inside it) may change after calling
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_index_keywords_create() or mail_index_sync_begin(). */
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainenconst array_t *mail_index_get_keywords(struct mail_index *index);
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen/* Create a keyword list structure. It's freed automatically at the end of
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen the transaction. */
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainenstruct mail_keywords *
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainenmail_index_keywords_create(struct mail_index_transaction *t,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *const keywords[]);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_keywords *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenmail_index_keywords_create_from_indexes(struct mail_index_transaction *t,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const array_t *keyword_indexes);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Free the keywords. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_keywords_free(struct mail_keywords *keywords);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen/* Update keywords for given message. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenvoid mail_index_update_keywords(struct mail_index_transaction *t, uint32_t seq,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen enum modify_type modify_type,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen struct mail_keywords *keywords);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Update field in header. If prepend is TRUE, the header change is visible
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen before message syncing begins. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenvoid mail_index_update_header(struct mail_index_transaction *t,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen size_t offset, const void *data, size_t size,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen int prepend);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Returns the last error code. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenenum mail_index_error mail_index_get_last_error(struct mail_index *index);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen/* Returns the full error message for last error. This message may
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen contain paths etc. so it shouldn't be shown to users. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenconst char *mail_index_get_error_message(struct mail_index *index);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen/* Reset the error message. */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenvoid mail_index_reset_error(struct mail_index *index);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Apply changes in MAIL_INDEX_SYNC_TYPE_FLAGS typed sync records to given
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen flags variable. */
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainenvoid mail_index_sync_flags_apply(const struct mail_index_sync_rec *sync_rec,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint8_t *flags);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Apply changes in MAIL_INDEX_SYNC_TYPE_KEYWORD_* typed sync records to given
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen keywords array. Returns TRUE If something was changed. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_sync_keywords_apply(const struct mail_index_sync_rec *sync_rec,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen array_t *keywords);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
73f021723bffa0841bbdf371882b463a449f1ea9Timo Sirainen/* register index extension. name is a unique identifier for the extension.
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen returns unique identifier for the name. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenuint32_t mail_index_ext_register(struct mail_index *index, const char *name,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t default_hdr_size,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint16_t default_record_size,
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen uint16_t default_record_align);
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen/* Get current extension sizes. Returns 1 if ok, 0 if extension doesn't exist
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen in view. */
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainenint mail_index_ext_get_size(struct mail_index_view *view, uint32_t ext_id,
717bb0dbaf4bd3f745669570647845e6d493bfe0Timo Sirainen uint32_t *hdr_size_r, uint16_t *record_size_r,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint16_t *record_align_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Resize existing extension data. If size is grown, the new data will be
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen zero-filled. If size is shrinked, the data is simply dropped. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_ext_resize(struct mail_index_transaction *t, uint32_t ext_id,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t hdr_size, uint16_t record_size,
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen uint16_t record_align);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Reset extension records and header. Any updates for this extension which
5da4bfdce070b54ce8dfcd1bf6249798cda86bd6Timo Sirainen were issued before the writer had seen this reset are discarded. reset_id is
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen used to figure this out, so it must be different every time. */
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainenvoid mail_index_ext_reset(struct mail_index_transaction *t, uint32_t ext_id,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t reset_id);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen/* Returns extension header. */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenint mail_index_get_header_ext(struct mail_index_view *view, uint32_t ext_id,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const void **data_r, size_t *data_size_r);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenint mail_index_map_get_header_ext(struct mail_index_view *view,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_map *map, uint32_t ext_id,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const void **data_r, size_t *data_size_r);
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen/* Returns the wanted extension record for given message. If it doesn't exist,
cec3230c9b2a96bac1ea42c69475e8aea4b91eabTimo Sirainen *data_r is set to NULL. Return values are same as for mail_index_lookup(). */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup_ext(struct mail_index_view *view, uint32_t seq,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t ext_id, const void **data_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint mail_index_lookup_ext_full(struct mail_index_view *view, uint32_t seq,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t ext_id, struct mail_index_map **map_r,
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen const void **data_r);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Update extension header field. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_update_header_ext(struct mail_index_transaction *t,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t ext_id, size_t offset,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const void *data, size_t size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* Update extension record. If old_data_r is non-NULL and the record extension
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen was already updated in this transaction, it's set to contain the data it's
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen now overwriting. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid mail_index_update_ext(struct mail_index_transaction *t, uint32_t seq,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uint32_t ext_id, const void *data, void *old_data);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#endif
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen