mail-index.h revision c5d2bb4d0904c08e025a6756554ced79d702a041
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen#ifndef __MAIL_INDEX_H
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen#define __MAIL_INDEX_H
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#include "message-parser.h"
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen#include "imap-util.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAIL_INDEX_VERSION 2
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define INDEX_FILE_PREFIX ".imap.index"
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenenum mail_index_header_compat {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_COMPAT_LITTLE_ENDIAN = 0x01
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen};
92c49f3005f4dff1a6f576fffa8112ef6d1cae7fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenenum mail_index_header_flag {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Rebuild flag is set while index is being rebuilt or when
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen some error is noticed in the index file. If this flag is set,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen the index shouldn't be used before rebuilding it. */
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen MAIL_INDEX_FLAG_REBUILD = 0x01,
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen MAIL_INDEX_FLAG_FSCK = 0x02,
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen MAIL_INDEX_FLAG_CACHE_FIELDS = 0x04,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen MAIL_INDEX_FLAG_COMPRESS = 0x08,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen MAIL_INDEX_FLAG_COMPRESS_DATA = 0x10,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen MAIL_INDEX_FLAG_REBUILD_TREE = 0x20,
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainen MAIL_INDEX_FLAG_DIRTY_MESSAGES = 0x40,
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS = 0x80
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainenenum mail_data_field {
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen DATA_FIELD_LOCATION = 0x00000001,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen DATA_FIELD_ENVELOPE = 0x00000002,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen DATA_FIELD_BODY = 0x00000004,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen DATA_FIELD_BODYSTRUCTURE = 0x00000008,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen DATA_FIELD_MD5 = 0x00000010,
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen DATA_FIELD_MESSAGEPART = 0x00000020,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen DATA_FIELD_LAST = 0x00000040,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen DATA_FIELD_MAX_BITS = 6,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen /* separate from above, but in same bitmask */
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen DATA_HDR_INTERNAL_DATE = 0x40000000,
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen DATA_HDR_VIRTUAL_SIZE = 0x20000000,
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen DATA_HDR_HEADER_SIZE = 0x10000000,
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen DATA_HDR_BODY_SIZE = 0x08000000
baebb412a9a5a44b1756e01cfa3b99f5d8a846b6Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define IS_BODYSTRUCTURE_FIELD(field) \
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen (((field) & (DATA_FIELD_BODY | DATA_FIELD_BODYSTRUCTURE | \
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen DATA_FIELD_MESSAGEPART)) != 0)
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenenum mail_index_mail_flag {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen /* If binary flags are set, it's not checked whether mail is
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen missing CRs. So this flag may be set as an optimization for
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen regular non-binary mails as well if it's known that it contains
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen valid CR+LF line breaks. */
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen INDEX_MAIL_FLAG_BINARY_HEADER = 0x0001,
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen INDEX_MAIL_FLAG_BINARY_BODY = 0x0002,
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen /* Currently this means with mbox format that message flags have
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen been changed in index, but not written into mbox file yet. */
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen INDEX_MAIL_FLAG_DIRTY = 0x0004
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen};
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenenum mail_lock_type {
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen MAIL_LOCK_UNLOCK = 0,
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen MAIL_LOCK_SHARED,
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen MAIL_LOCK_EXCLUSIVE
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen};
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainen
12c6ef6f1268ed4d5b63709bb4215c481b4f078cTimo Sirainenenum mail_lock_notify_type {
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen /* Mailbox is locked, will abort in secs_left */
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen MAIL_LOCK_NOTIFY_MAILBOX_ABORT,
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen /* Mailbox lock looks stale, will override in secs_left */
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen MAIL_LOCK_NOTIFY_MAILBOX_OVERRIDE,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Index is locked, will abort in secs_left */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_LOCK_NOTIFY_INDEX_ABORT
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenenum mail_index_error {
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen /* No errors */
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen MAIL_INDEX_ERROR_NONE,
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen /* Internal error, see get_error_text() for more information. */
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen MAIL_INDEX_ERROR_INTERNAL,
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen /* Index is now in inconsistent state with the previous known state,
46ec792dd4ccf6c34706c4774228301fafde6aa9Timo Sirainen meaning that the message IDs etc. may have changed - only way to
4c6ddf2491104f917d00e6900e833e80ea02c7b6Timo Sirainen recover this would be to fully close the mailbox and reopen it.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen With IMAP this would mean a forced disconnection since we can't do
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen forced CLOSE. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_ERROR_INCONSISTENT,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* We ran out of available disk space. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_ERROR_DISKSPACE,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Mail index locking timeouted */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_ERROR_INDEX_LOCK_TIMEOUT,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Mailbox locking timeouted */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen MAIL_INDEX_ERROR_MAILBOX_LOCK_TIMEOUT
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainentypedef void (*mail_lock_notify_callback_t)
ddbdc644a15f56f4b43596f1b8c0fc196c101445Timo Sirainen (enum mail_lock_notify_type notify_type,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int secs_left, void *context);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenstruct mail_index_header {
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen unsigned char compat_data[8];
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen /* 0 = version
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen 1 = flags,
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen 2 = sizeof(unsigned int),
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen 3 = sizeof(time_t),
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen 4 = sizeof(uoff_t),
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen 5 = MEM_ALIGN_SIZE */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
f059a046515f4b2b15a6c2a10a6f12f6166e39a5Timo Sirainen unsigned int indexid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int sync_id; /* re-mmap() when changed, required only
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if file size is changed */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int flags;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int cache_fields;
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen uoff_t used_file_size;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen unsigned int first_hole_index;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen unsigned int first_hole_records;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen unsigned int uid_validity;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int next_uid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int messages_count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int seen_messages_count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int deleted_messages_count;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int last_nonrecent_uid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* these UIDs may not exist and may not even be unseen */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int first_unseen_uid_lowwater;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int first_deleted_uid_lowwater;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen};
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainenstruct mail_index_data_header {
d3d769026fae5d21c2d29614d3bc4579e8d79e81Timo Sirainen unsigned int indexid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int reserved; /* for alignment mostly */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uoff_t used_file_size;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uoff_t deleted_space;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index_record {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int uid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int msg_flags; /* enum mail_flags */
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen unsigned int index_flags; /* enum mail_index_mail_flag */
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen unsigned int data_fields; /* enum mail_data_field */
c7fca6cbb32388556d9f6d8313486cc4e4a3c058Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uoff_t data_position;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index_data_record_header {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int data_size; /* including this header */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen time_t internal_date;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen uoff_t virtual_size;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen uoff_t header_size;
5a9e240ebf8d0daaf029973973b52e415148070bTimo Sirainen uoff_t body_size;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainenstruct mail_index_data_record {
a75907609d7c410c9e17beedfafbf28b4439fa8aTimo Sirainen unsigned int field; /* enum mail_data_field */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int full_field_size;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen char data[MEM_ALIGN_SIZE]; /* variable size */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen};
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define SIZEOF_MAIL_INDEX_DATA \
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (sizeof(struct mail_index_data_record) - MEM_ALIGN_SIZE)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define DATA_RECORD_SIZE(rec) \
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (SIZEOF_MAIL_INDEX_DATA + (rec)->full_field_size)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstruct mail_index {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* If fast is TRUE, compressing and cache updates are not performed.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen Note that opening same index twice in the same process is a bad
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen idea since they share the same file locks. As soon one of the
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen indexes is closed, the locks in second index are dropped which
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen especially hurts modify log since it keeps locks all the time. */
05e55893a799de645fc8cd2203d6013f0e0f1b79Timo Sirainen int (*open)(struct mail_index *index, int update_recent, int fast);
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen int (*open_or_create)(struct mail_index *index,
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen int update_recent, int fast);
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen /* Free index from memory. */
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen void (*free)(struct mail_index *index);
2aac7ca853f63b62ea79ef8eae9ded83ed6063a5Timo Sirainen
9ddd3d7d8651985e373a6c48e0ddc76b8a4ef1c7Timo Sirainen /* Lock/unlock index. May block. Note that unlocking must not
4de2a17e0a2aed3b57a6c1057329b6a132b56ae2Timo Sirainen reset error from get_last_error() as unlocking can be done as
5d2e7ec2ea725c8a6a63f56b771e746f93e782ecTimo Sirainen a cleanup after some other function failed. Index is always
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen mmap()ed after set_lock() succeeds.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen Trying to change a shared lock into exclusive lock is a fatal
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen error, since it may create a deadlock. Even though operating
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen system should detect it and fail, it's not a good idea to even
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen let it happen. Better ways to do this would be to a) mark the
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen data to be updated later, b) use try_lock() if the update is
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen preferred but not required, c) unlock + lock again, but make
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen sure that won't create race conditions. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*set_lock)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_lock_type lock_type);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen /* Try locking the index. Returns TRUE if the lock was got and
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen FALSE if lock isn't possible to get currently or some other error
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen occured. Never blocks. */
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen int (*try_lock)(struct mail_index *index,
bdb9f7f7fbf828fb85a393bd2803167b1bb8ff0dTimo Sirainen enum mail_lock_type lock_type);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* If we have to wait for the lock, the given lock notify function
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen is called once in a while. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void (*set_lock_notify_callback)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen mail_lock_notify_callback_t callback,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void *context);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen /* Rebuild the whole index. Note that this changes the indexid
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen so all the other files must also be rebuilt after this call.
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen Index MUST NOT have shared lock, but exclusive lock or no lock at
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen all is fine. Note that this function may leave the index
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen exclusively locked, and always sets index->inconsistent = TRUE. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*rebuild)(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Verify that the index is valid. If anything invalid is found,
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen index is set inconsistent and to be rebuilt at next open.
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen Same locking issues as with rebuild(). */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*fsck)(struct mail_index *index);
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen /* Synchronize the index with the mailbox. Index must not have shared
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen lock when calling this function. The data_lock_type specifies what
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen lock should be set to data file (mbox file). This function may
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen leave the index in ANY locking state. If changes is non-NULL, it's
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen set to TRUE if any changes were noticed. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*sync_and_lock)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_lock_type data_lock_type, int *changes);
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen
6303191abcb37164f435ccdc56e9dbddf1288851Timo Sirainen /* Returns the index header (never fails). The index needs to be
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen locked before calling this function, and must be kept locked as
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen long as you keep using the returned structure. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_header *(*get_header)(struct mail_index *index);
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen /* sequence -> data lookup. The index needs to be locked before calling
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen this function, and must be kept locked as long as you keep using
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen the returned structure. */
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen struct mail_index_record *(*lookup)(struct mail_index *index,
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen unsigned int seq);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Return the next record after specified record, or NULL if it was
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen last record. The index must be locked all the time between
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen lookup() and last next() call. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *(*next)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* Find first existing UID in range. Sequence number is also retrieved
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen if seq_r is non-NULL. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen struct mail_index_record *(*lookup_uid_range)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int first_uid,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int last_uid,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen unsigned int *seq_r);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* Find field from specified record, or NULL if it's not in index.
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen Makes sure that the field ends with \0. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen const char *(*lookup_field)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_data_field field);
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen /* Find field from specified record, or NULL if it's not in index. */
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen const void *(*lookup_field_raw)(struct mail_index *index,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct mail_index_record *rec,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen enum mail_data_field field,
6fdfa4d4cf14d1d7764d7faa8258f112e39c8dbeTimo Sirainen size_t *size);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Mark the fields to be cached later. If any of them is already
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen set in hdr->cache_fields, mark the caching to happen next time
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen index is opened. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void (*cache_fields_later)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_data_field field);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Open mail file and return it as mmap()ed IStream. If we fail,
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen we return NULL and set deleted = TRUE if failure was because the
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen mail was just deleted (ie. not an error). internal_date is set
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if it's non-NULL. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct istream *(*open_mail)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen time_t *internal_date, int *deleted);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Returns internal date of message, or (time_t)-1 if error occured. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen time_t (*get_internal_date)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen /* Expunge a mail from index. Tree and modifylog is also updated. The
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen index must be exclusively locked before calling this function.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen If seq is 0, the modify log isn't updated. This is useful if
cec3230c9b2a96bac1ea42c69475e8aea4b91eabTimo Sirainen after append() something goes wrong and you wish to delete the
cec3230c9b2a96bac1ea42c69475e8aea4b91eabTimo Sirainen mail immediately. If external_change is TRUE, the modify log is
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen always written.
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen Note that the sequence numbers also update immediately after this
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen call, so if you want to delete messages 1..4 just call this
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen function 4 times with seq being 1. */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen int (*expunge)(struct mail_index *index, struct mail_index_record *rec,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int seq, int external_change);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainen /* Update mail flags. The index must be exclusively locked before
cec3230c9b2a96bac1ea42c69475e8aea4b91eabTimo Sirainen calling this function. This shouldn't be called in the middle of
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen update_begin() as it may modify location field. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*update_flags)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int seq, enum mail_flags flags,
54533aa265f5c87730022cc7576090bc51370f97Timo Sirainen int external_change);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Append a new record to index. The index must be exclusively
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen locked before calling this function. rec->uid is updated in
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen append_end(). */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *(*append_begin)(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*append_end)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Updating fields happens by calling update_begin(), one or more
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen update_field()s and finally update_end() which does the actual
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen updating. The index must be exclusively locked all this time.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen update_begin() and update_field() functions cannot fail.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen The extra_space parameter for update_field() specifies the amount
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen of extra empty space we should leave after the value, so that if
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen the field grows in future it could be expanded without copying it
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen to end of file. When the field already exists, the extra_space
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen is ignored.
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen The files may not actually be updated until after you've unlocked
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen the file. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_update *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (*update_begin)(struct mail_index *index,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_index_record *rec);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int (*update_end)(struct mail_index_update *update);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void (*update_field)(struct mail_index_update *update,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_data_field field,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *value, size_t extra_space);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen /* Just remember that full_field_size will be MEM_ALIGNed, so
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen it may differer from the given size parameter. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void (*update_field_raw)(struct mail_index_update *update,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_data_field field,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const void *value, size_t size);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Returns the last error code. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_index_error (*get_last_error)(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* Returns the full error message for last error. This message may
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen contain paths etc. so it shouldn't be shown to users. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *(*get_last_error_text)(struct mail_index *index);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* private: */
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct mail_index_data *data;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_tree *tree;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_modify_log *modifylog;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_custom_flags *custom_flags;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen char *dir; /* directory where to place the index files */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen char *filepath; /* index file path */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen char *mailbox_path; /* file/directory for mailbox location */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen enum mail_data_field default_cache_fields, never_cache_fields;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int indexid;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen unsigned int sync_id;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* updated whenever exclusive lock is set/unset */
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen unsigned int excl_lock_counter;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen int mbox_fd;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen struct istream *mbox_stream;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen enum mail_lock_type mbox_lock_type;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen dev_t mbox_dotlock_dev;
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen ino_t mbox_dotlock_ino;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen /* these counters can be used to check that we've synced the mailbox
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen after locking it */
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int mbox_lock_counter;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen unsigned int mbox_sync_counter;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen /* last mbox sync: */
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen uoff_t mbox_size;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen dev_t mbox_dev;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen ino_t mbox_ino;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen int fd; /* opened index file */
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen char *error; /* last error message */
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen void *mmap_base;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen size_t mmap_used_length;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen size_t mmap_full_length;
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen struct mail_index_header *header;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_lock_type lock_type;
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen time_t file_sync_stamp;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int first_recent_uid;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen mail_lock_notify_callback_t lock_notify_cb;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen void *lock_notify_context;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen /* these fields are OR'ed to the fields in index header once we
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen get around grabbing exclusive lock */
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int set_flags;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_data_field set_cache_fields;
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen unsigned int anon_mmap:1;
45155bb1250cf5a120278f349465aded513a100fTimo Sirainen unsigned int opened:1;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int mail_read_mmaped:1;
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen unsigned int inconsistent:1;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int nodiskspace:1;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int index_lock_timeout:1;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int mailbox_lock_timeout:1;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen};
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen#ifdef DEV_T_STRUCT
12cf3d0e03fc70fb0c8b91bc8fd83b4e14d7cdefTimo Sirainen/* we can't initialize dev_t as 0, and we don't know what it actually
12cf3d0e03fc70fb0c8b91bc8fd83b4e14d7cdefTimo Sirainen contains, so don't initialize them. gcc's -W option should be disabled
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen with this or we get warnings.. */
12cf3d0e03fc70fb0c8b91bc8fd83b4e14d7cdefTimo Sirainen# define MAIL_INDEX_PRIVATE_FILL 0
4e35bae013cee5a06d281776a347b534b958aaa4Timo Sirainen#else
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainen/* needed to remove annoying warnings about not initializing all struct
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen members.. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAIL_INDEX_PRIVATE_FILL \
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen 0, 0
bb8d0ec26bdd548624d7a7424071cca693b72f55Timo Sirainen#endif
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* defaults - same as above but prefixed with mail_index_. */
4ead43ecc06d10047998966c4dc0b142ecce4b66Timo Sirainenint mail_index_open(struct mail_index *index, int update_recent, int fast);
506e41a4efbc7f4bba93cd295ca4dba18ed3cf09Timo Sirainenint mail_index_open_or_create(struct mail_index *index,
506e41a4efbc7f4bba93cd295ca4dba18ed3cf09Timo Sirainen int update_recent, int fast);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_set_lock(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_lock_type lock_type);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_try_lock(struct mail_index *index,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen enum mail_lock_type lock_type);
1d4f710106fb498750456724628da6063e012e6dTimo Sirainenvoid mail_index_set_lock_notify_callback(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen mail_lock_notify_callback_t callback,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen void *context);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_fsck(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenstruct mail_index_header *mail_index_get_header(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenstruct mail_index_record *mail_index_lookup(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int seq);
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainenstruct mail_index_record *mail_index_next(struct mail_index *index,
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainen struct mail_index_record *rec);
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainenstruct mail_index_record *
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainenmail_index_lookup_uid_range(struct mail_index *index, unsigned int first_uid,
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainen unsigned int last_uid, unsigned int *seq_r);
88c92ce2caa8f9fa34708471c6ed4e974d5a7953Timo Sirainenconst char *mail_index_lookup_field(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen struct mail_index_record *rec,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_data_field field);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenconst void *mail_index_lookup_field_raw(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen struct mail_index_record *rec,
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen enum mail_data_field field,
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen size_t *size);
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainenvoid mail_index_cache_fields_later(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_data_field field);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_expunge(struct mail_index *index, struct mail_index_record *rec,
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen unsigned int seq, int external_change);
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainenint mail_index_update_flags(struct mail_index *index,
f77ffa31038d46ca9c6d24d93e3d76c9aa8d4d0cTimo Sirainen struct mail_index_record *rec,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen unsigned int seq, enum mail_flags flags,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen int external_change);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenstruct mail_index_record *mail_index_append_begin(struct mail_index *index);
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainenint mail_index_append_end(struct mail_index *index,
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainen struct mail_index_record *rec);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenstruct mail_index_update *
1d4f710106fb498750456724628da6063e012e6dTimo Sirainenmail_index_update_begin(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen struct mail_index_record *rec);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_update_end(struct mail_index_update *update);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenvoid mail_index_update_field(struct mail_index_update *update,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_data_field field,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen const char *value, size_t extra_space);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenvoid mail_index_update_field_raw(struct mail_index_update *update,
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainen enum mail_data_field field,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen const void *value, size_t size);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainentime_t mail_get_internal_date(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen struct mail_index_record *rec);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenenum mail_index_error mail_index_get_last_error(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenconst char *mail_index_get_last_error_text(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen/* INTERNAL: */
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenvoid mail_index_init(struct mail_index *index, const char *dir);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_mmap_update(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenvoid mail_index_init_header(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen struct mail_index_header *hdr);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenvoid mail_index_close(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_fmdatasync(struct mail_index *index, size_t size);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenint mail_index_verify_hole_range(struct mail_index *index);
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenvoid mail_index_mark_flag_changes(struct mail_index *index,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen struct mail_index_record *rec,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_flags old_flags,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen enum mail_flags new_flags);
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainenvoid mail_index_update_headers(struct mail_index_update *update,
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen struct istream *input,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen enum mail_data_field cache_fields,
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen message_header_callback_t header_cb,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen void *context);
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenint mail_index_update_cache(struct mail_index *index);
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainenint mail_index_compress(struct mail_index *index);
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainenint mail_index_compress_data(struct mail_index *index);
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainenint mail_index_truncate(struct mail_index *index);
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen/* Maximum allowed UID number. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define MAX_ALLOWED_UID 4294967295U /* 2^32 - 1 */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen/* Max. mmap()ed size for a message */
8372fc7efb6d64dff2e5f55fb4a3822c56869cfeTimo Sirainen#define MAIL_MMAP_BLOCK_SIZE (1024*256)
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen/* Block size when read()ing message. */
1d4f710106fb498750456724628da6063e012e6dTimo Sirainen#define MAIL_READ_BLOCK_SIZE (1024*8)
89795c6bbbc52bb382e88bc8617d22092223e9a5Timo Sirainen
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen/* Delete unused non-local temp files after 24h. Just to be sure we don't
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen delete it too early. The temp files don't harm much anyway. */
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen#define TEMP_FILE_TIMEOUT (60*24)
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen/* number of records to always keep allocated in index file,
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen either used or unused */
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen#define INDEX_MIN_RECORDS_COUNT 64
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen/* when empty space in index file gets full, grow the file n% larger */
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen#define INDEX_GROW_PERCENTAGE 10
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen/* ftruncate() the index file when only n% of it is in use */
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen#define INDEX_TRUNCATE_PERCENTAGE 30
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen/* don't truncate whole file anyway, keep n% of the empty space */
434abef12f61881a5cfa28d27193d0854a9639a0Timo Sirainen#define INDEX_TRUNCATE_KEEP_PERCENTAGE 10
434abef12f61881a5cfa28d27193d0854a9639a0Timo Sirainen/* Compress the file when deleted space reaches n% of total size */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#define INDEX_COMPRESS_PERCENTAGE 50
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen/* uoff_t to index file for given record */
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen#define INDEX_FILE_POSITION(index, ptr) \
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen ((uoff_t) ((char *) (ptr) - (char *) ((index)->mmap_base)))
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen/* record for given index */
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen#define INDEX_RECORD_AT(index, idx) \
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen ((struct mail_index_record *) \
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen ((char *) index->mmap_base + sizeof(struct mail_index_header)) + (idx))
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen/* returns the next record after last one */
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen#define INDEX_END_RECORD(index) \
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen ((struct mail_index_record *) \
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen ((char *) (index)->mmap_base + (index)->mmap_used_length))
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen/* index number for uoff_t position */
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen#define INDEX_POSITION_INDEX(pos) \
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen (((pos) - sizeof(struct mail_index_header)) / \
b4b87fa19d26aadb2ea9e8a9ae7af6cfdaab4cfbTimo Sirainen sizeof(struct mail_index_record))
b4b87fa19d26aadb2ea9e8a9ae7af6cfdaab4cfbTimo Sirainen
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen/* index number for given record */
3ffb7fd86484c474b42f3f1e981ab0f7168b5df9Timo Sirainen#define INDEX_RECORD_INDEX(index, ptr) \
3ffb7fd86484c474b42f3f1e981ab0f7168b5df9Timo Sirainen INDEX_POSITION_INDEX(INDEX_FILE_POSITION(index, ptr))
6998ca95b4947c90647ac5d4794ebd6311acada2Timo Sirainen
6998ca95b4947c90647ac5d4794ebd6311acada2Timo Sirainen/* mark the index corrupted */
6998ca95b4947c90647ac5d4794ebd6311acada2Timo Sirainen#define INDEX_MARK_CORRUPTED(index) \
6998ca95b4947c90647ac5d4794ebd6311acada2Timo Sirainen STMT_START { (index)->set_flags |= MAIL_INDEX_FLAG_REBUILD; } STMT_END
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen/* get number of records in mmaped index */
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen#define MAIL_INDEX_RECORD_COUNT(index) \
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen ((index->mmap_used_length - sizeof(struct mail_index_header)) / \
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen sizeof(struct mail_index_record))
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen/* minimum size for index file */
28dae6a0064e79f86da091625b0f2b92336a2a91Timo Sirainen#define INDEX_FILE_MIN_SIZE \
3ffb7fd86484c474b42f3f1e981ab0f7168b5df9Timo Sirainen (sizeof(struct mail_index_header) + \
3ffb7fd86484c474b42f3f1e981ab0f7168b5df9Timo Sirainen INDEX_MIN_RECORDS_COUNT * sizeof(struct mail_index_record))
7c849dbc7be089175c1a83a84ee7249ed695810dTimo Sirainen
7c849dbc7be089175c1a83a84ee7249ed695810dTimo Sirainen/* enum mail_lock_type to fcntl() lock type */
38318f5e82662615cd88e99e398efe4a630ce020Timo Sirainen#define MAIL_LOCK_TO_FLOCK(lock_type) \
80980955bb1bbcc1bd73623fe0912f334194ddd2Timo Sirainen ((lock_type) == MAIL_LOCK_EXCLUSIVE ? F_WRLCK : \
80980955bb1bbcc1bd73623fe0912f334194ddd2Timo Sirainen (lock_type) == MAIL_LOCK_SHARED ? F_RDLCK : F_UNLCK)
843640f0ca224bb9999acb290bca5f76037ab984Timo Sirainen
843640f0ca224bb9999acb290bca5f76037ab984Timo Sirainen#endif
843640f0ca224bb9999acb290bca5f76037ab984Timo Sirainen