c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef MAIL_TRANSACTION_LOG_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define MAIL_TRANSACTION_LOG_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen#include "mail-index.h"
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen#define MAIL_TRANSACTION_LOG_SUFFIX ".log"
4d4d585520538a752e9f0a4a1c019a2918f52e56Timo Sirainen
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#define MAIL_TRANSACTION_LOG_MAJOR_VERSION 1
92dab926b2f2270057b40a907a00cf8eb2309ed6Timo Sirainen#define MAIL_TRANSACTION_LOG_MINOR_VERSION 3
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen#define MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE 24
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen#define MAIL_TRANSACTION_LOG_VERSION_FULL(major, minor) \
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen ((major) << 8 | (minor))
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen#define MAIL_TRANSACTION_LOG_VERSION_HAVE(version, wanted_feature) \
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen ((version) >= MAIL_TRANSACTION_LOG_VERSION_##wanted_feature)
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen#define MAIL_TRANSACTION_LOG_HDR_VERSION(hdr) \
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen MAIL_TRANSACTION_LOG_VERSION_FULL((hdr)->major_version, (hdr)->minor_version)
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen#define MAIL_TRANSACTION_LOG_VERSION_COMPAT_FLAGS \
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen MAIL_TRANSACTION_LOG_VERSION_FULL(1, 2)
92dab926b2f2270057b40a907a00cf8eb2309ed6Timo Sirainen#define MAIL_TRANSACTION_LOG_VERSION_HIDE_INTERNAL_MODSEQS \
92dab926b2f2270057b40a907a00cf8eb2309ed6Timo Sirainen MAIL_TRANSACTION_LOG_VERSION_FULL(1, 3)
e0f4fbf127b192667c62af7875c4f2ca294b6c7aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_log_header {
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen uint8_t major_version;
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen uint8_t minor_version;
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen uint16_t hdr_size;
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t indexid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t file_seq;
0add8c99ca65e56dbf613595fc37c41aafff3f7fTimo Sirainen uint32_t prev_file_seq;
40ef82c46f6652412b068ebcdac7c3e74840a284Timo Sirainen uint32_t prev_file_offset;
105addcb709523868418cc3e3baad7ad3453a91eTimo Sirainen uint32_t create_stamp;
49d4afbb76f47c8904537d087bc81e43f1c0aa25Timo Sirainen uint64_t initial_modseq; /* v1.1+ (note: log's major/minor version) */
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen uint8_t compat_flags; /* enum mail_index_header_compat_flags, v1.2+ */
aef92409cf369afdd2ecd81a4f80083cd4082f46Timo Sirainen uint8_t unused[3];
b44faf865da16ac4d18eecd85a55b3fab6b9e63aTimo Sirainen uint32_t unused2; /* so that this struct is 64bit aligned */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenenum mail_transaction_type {
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen MAIL_TRANSACTION_EXPUNGE = 0x00000001,
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen MAIL_TRANSACTION_APPEND = 0x00000002,
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen MAIL_TRANSACTION_FLAG_UPDATE = 0x00000004,
56f45b3f3ae20e5c933701f4657dda5ef1916855Timo Sirainen MAIL_TRANSACTION_HEADER_UPDATE = 0x00000020,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen MAIL_TRANSACTION_EXT_INTRO = 0x00000040,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen MAIL_TRANSACTION_EXT_RESET = 0x00000080,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen MAIL_TRANSACTION_EXT_HDR_UPDATE = 0x00000100,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen MAIL_TRANSACTION_EXT_REC_UPDATE = 0x00000200,
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen MAIL_TRANSACTION_KEYWORD_UPDATE = 0x00000400,
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen MAIL_TRANSACTION_KEYWORD_RESET = 0x00000800,
c5794838af9995f50bfecb06a3cd4f9a0ac77858Timo Sirainen MAIL_TRANSACTION_EXT_ATOMIC_INC = 0x00001000,
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen MAIL_TRANSACTION_EXPUNGE_GUID = 0x00002000,
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen MAIL_TRANSACTION_MODSEQ_UPDATE = 0x00008000,
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen MAIL_TRANSACTION_EXT_HDR_UPDATE32 = 0x00010000,
651fc0f1e43fef3e02e0e7b5f498973b05f641d7Timo Sirainen MAIL_TRANSACTION_INDEX_DELETED = 0x00020000,
8872e5c991430f96138a46e36b7f3c2c40d8e5c2Timo Sirainen MAIL_TRANSACTION_INDEX_UNDELETED = 0x00040000,
e188bab0b830136d04a1dd8b55e9afefae20d930Timo Sirainen MAIL_TRANSACTION_BOUNDARY = 0x00080000,
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen MAIL_TRANSACTION_ATTRIBUTE_UPDATE = 0x00100000,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fee561b9d9162b130e662914fcebc9dd99b5c320Timo Sirainen MAIL_TRANSACTION_TYPE_MASK = 0x0fffffff,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen#define MAIL_TRANSACTION_EXT_MASK \
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen (MAIL_TRANSACTION_EXT_INTRO | MAIL_TRANSACTION_EXT_RESET | \
041d312b44f8d41f0c9a5762c23e4d146ef7302bTimo Sirainen MAIL_TRANSACTION_EXT_HDR_UPDATE | MAIL_TRANSACTION_EXT_HDR_UPDATE32 | \
041d312b44f8d41f0c9a5762c23e4d146ef7302bTimo Sirainen MAIL_TRANSACTION_EXT_REC_UPDATE | MAIL_TRANSACTION_EXT_ATOMIC_INC)
51795bfe9d05d92fe942cb451aec2b9d16d32a11Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* since we'll expunge mails based on data read from transaction log,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen try to avoid the possibility of corrupted transaction log expunging
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen messages. this value is ORed to the actual MAIL_TRANSACTION_EXPUNGE*
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen flag. if it's not present, assume corrupted log. */
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen MAIL_TRANSACTION_EXPUNGE_PROT = 0x0000cd90,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen /* Mailbox storage backend synchronization noticed this change. */
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen MAIL_TRANSACTION_EXTERNAL = 0x10000000,
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen /* This change syncs the state with another mailbox (dsync),
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen i.e. the change isn't something that a user requested locally. */
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen MAIL_TRANSACTION_SYNC = 0x20000000
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_header {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t type; /* enum mail_transaction_type */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainenstruct mail_transaction_modseq_update {
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen uint32_t uid;
19557f192d37cd54a1a090a8a26d9d47265e4413Aki Tuomi /* don't use uint64_t here. it adds extra 32 bits of padding and also
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen causes problems with CPUs that require alignment */
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen uint32_t modseq_low32;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen uint32_t modseq_high32;
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen};
ad48319996942463675b53877092ab7e13a7a75aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_expunge {
659fe5d24825b160cae512538088020d97a60239Timo Sirainen uint32_t uid1, uid2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainenstruct mail_transaction_expunge_guid {
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen uint32_t uid;
de62ce819d59a529530da4b57be1b8d6dad13d6bTimo Sirainen guid_128_t guid_128;
0c909e3461607eadcd66f4eac69b7f34e37fccf1Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_flag_update {
659fe5d24825b160cae512538088020d97a60239Timo Sirainen uint32_t uid1, uid2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t add_flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint8_t remove_flags;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen uint8_t modseq_inc_flag;
5da1aa5197a43d83f0fb3eeb83125c7cd73d1b62Timo Sirainen uint8_t padding;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen};
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenstruct mail_transaction_keyword_update {
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen uint8_t modify_type; /* enum modify_type : MODIFY_ADD / MODIFY_REMOVE */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen uint8_t padding;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen uint16_t name_size;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen /* unsigned char name[];
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen array of { uint32_t uid1, uid2; }
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainenstruct mail_transaction_keyword_reset {
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen uint32_t uid1, uid2;
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen};
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstruct mail_transaction_header_update {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen uint16_t offset;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen uint16_t size;
a928e7efabb1672b1476e597106d4b4b81ac6f3cTimo Sirainen /* unsigned char data[]; */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen};
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen
838f56174b963779a88083a0d0e85b30d2d846e7Timo Sirainenenum {
894987bf45718f8849cc3898afdfb1ac3cfa2445Timo Sirainen /* Don't shrink hdr_size, record_size or record_align but grow them
894987bf45718f8849cc3898afdfb1ac3cfa2445Timo Sirainen if necessary. */
894987bf45718f8849cc3898afdfb1ac3cfa2445Timo Sirainen MAIL_TRANSACTION_EXT_INTRO_FLAG_NO_SHRINK = 0x01
838f56174b963779a88083a0d0e85b30d2d846e7Timo Sirainen};
838f56174b963779a88083a0d0e85b30d2d846e7Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstruct mail_transaction_ext_intro {
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen /* old extension: set ext_id. don't set name.
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen new extension: ext_id = (uint32_t)-1. give name. */
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen uint32_t ext_id;
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t reset_id;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint32_t hdr_size;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint16_t record_size;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint16_t record_align;
838f56174b963779a88083a0d0e85b30d2d846e7Timo Sirainen uint16_t flags;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint16_t name_size;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* unsigned char name[]; */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen};
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainenstruct mail_transaction_ext_reset {
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen uint32_t new_reset_id;
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen uint8_t preserve_data;
6e07b4251bf6a3cf34019c351a32a65c08392e58Timo Sirainen uint8_t unused_padding[3];
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen};
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
d143077bd518de129b8d446fb58e003903e50867Timo Sirainen/* these are set for the last ext_intro */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstruct mail_transaction_ext_hdr_update {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint16_t offset;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen uint16_t size;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* unsigned char data[]; */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen};
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen/* this _update32 version should have been the only ext_hdr_update,
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen but since 16bit integers were originally used for now we'll just use this
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen only when actually needed to be backwards compatible. */
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainenstruct mail_transaction_ext_hdr_update32 {
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen uint32_t offset;
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen uint32_t size;
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen /* unsigned char data[]; */
e76f5e07be5bec4e5ca99c3e093ff7f11edbe1b7Timo Sirainen};
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstruct mail_transaction_ext_rec_update {
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen uint32_t uid;
a928e7efabb1672b1476e597106d4b4b81ac6f3cTimo Sirainen /* unsigned char data[]; */
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen};
c5794838af9995f50bfecb06a3cd4f9a0ac77858Timo Sirainenstruct mail_transaction_ext_atomic_inc {
c5794838af9995f50bfecb06a3cd4f9a0ac77858Timo Sirainen uint32_t uid;
c5794838af9995f50bfecb06a3cd4f9a0ac77858Timo Sirainen int32_t diff;
c5794838af9995f50bfecb06a3cd4f9a0ac77858Timo Sirainen};
1175f27441385a7011629f295f42708f9a3a4ffcTimo Sirainen
e188bab0b830136d04a1dd8b55e9afefae20d930Timo Sirainenstruct mail_transaction_boundary {
e188bab0b830136d04a1dd8b55e9afefae20d930Timo Sirainen uint32_t size;
e188bab0b830136d04a1dd8b55e9afefae20d930Timo Sirainen};
e188bab0b830136d04a1dd8b55e9afefae20d930Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenstruct mail_transaction_log_append_ctx {
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log *log;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen buffer_t *output;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen enum mail_transaction_type trans_flags;
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen uint64_t new_highest_modseq;
bd503f12eb667df389a99162f567bd8785798f55Timo Sirainen unsigned int transaction_count;
bd503f12eb667df389a99162f567bd8785798f55Timo Sirainen
082e82792b8ac33ad42beac510441b37a3c50737Timo Sirainen /* same as mail_index_transaction->sync_transaction */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool index_sync_transaction:1;
082e82792b8ac33ad42beac510441b37a3c50737Timo Sirainen /* same as mail_index_transaction->tail_offset_changed */
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool tail_offset_changed:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool sync_includes_this:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool want_fsync:1;
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen};
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen#define LOG_IS_BEFORE(seq1, offset1, seq2, offset2) \
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen (((offset1) < (offset2) && (seq1) == (seq2)) || (seq1) < (seq2))
0d70a702dec63d22535684fec6a7247c5f153208Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_log *
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenmail_transaction_log_alloc(struct mail_index *index);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_transaction_log_free(struct mail_transaction_log **log);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Open the transaction log. Returns 1 if ok, 0 if file doesn't exist or it's
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen is corrupted, -1 if there was some I/O error. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenint mail_transaction_log_open(struct mail_transaction_log *log);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Create, or recreate, the transaction log. Returns 0 if ok, -1 if error. */
94aa90d2d17a7aebcda5a4193a62e80ddbb169b7Timo Sirainenint mail_transaction_log_create(struct mail_transaction_log *log, bool reset);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Close all the open transactions log files. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_transaction_log_close(struct mail_transaction_log *log);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen/* Notify of indexid change */
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainenvoid mail_transaction_log_indexid_changed(struct mail_transaction_log *log);
2d49f150b4bce6f2f59a84e268e4777901c3e42cTimo Sirainen
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Returns the file seq/offset where the mailbox is currently synced at.
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen Since the log is rotated only when mailbox is fully synced, the sequence
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen points always to the latest file. This function doesn't actually find the
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen latest sync position, so you'll need to use eg. log_view_set() before
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen calling this. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_transaction_log_get_mailbox_sync_pos(struct mail_transaction_log *log,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t *file_seq_r,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uoff_t *file_offset_r);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen/* Set the current mailbox sync position. file_seq must always be the latest
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen log file's sequence. The offset written automatically to the log when
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen other transactions are being written. */
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainenvoid mail_transaction_log_set_mailbox_sync_pos(struct mail_transaction_log *log,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uint32_t file_seq,
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen uoff_t file_offset);
0d0451206a91e9f96e522075dce28a89adc2325dTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_transaction_log_view *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_transaction_log_view_open(struct mail_transaction_log *log);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainenvoid mail_transaction_log_view_close(struct mail_transaction_log_view **view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
c2378fc4d82577009b0b5125f381387e7d74ce46Timo Sirainen/* Set view boundaries. Returns -1 if error, 0 if files are lost or corrupted,
c2378fc4d82577009b0b5125f381387e7d74ce46Timo Sirainen 1 if ok. reset_r=TRUE if the whole index should be reset before applying any
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen changes. */
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainenint mail_transaction_log_view_set(struct mail_transaction_log_view *view,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen uint32_t min_file_seq, uoff_t min_file_offset,
ae8817f05005f57bba32479a610b52d083e2b6ebTimo Sirainen uint32_t max_file_seq, uoff_t max_file_offset,
1f4f81ba81bb9fa8abe2d94f344373c230066d67Timo Sirainen bool *reset_r, const char **reason_r);
6d3bb841d4ec2c12ac2d4ecf6146ef8d8a7dd731Timo Sirainen/* Scan through all of the log files that we can find.
6d3bb841d4ec2c12ac2d4ecf6146ef8d8a7dd731Timo Sirainen Returns -1 if error, 0 if ok. */
6d3bb841d4ec2c12ac2d4ecf6146ef8d8a7dd731Timo Sirainenint mail_transaction_log_view_set_all(struct mail_transaction_log_view *view);
0fa842717a8b163252e55c229c37ca0c5d7ff056Timo Sirainen/* Clear the view. If oldest_file_seq > 0, keep it and newer log files
0fa842717a8b163252e55c229c37ca0c5d7ff056Timo Sirainen referenced so we don't get desynced. */
c680a6b35b459045e92814778908da5a93922107Timo Sirainenvoid mail_transaction_log_view_clear(struct mail_transaction_log_view *view,
c680a6b35b459045e92814778908da5a93922107Timo Sirainen uint32_t oldest_file_seq);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Read next transaction record from current position. The position is updated.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Returns -1 if error, 0 if we're at end of the view, 1 if ok. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_transaction_log_view_next(struct mail_transaction_log_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_header **hdr_r,
5f78b33aa505b17e23cdf27b071a24e127b3db54Timo Sirainen const void **data_r);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen/* Mark the current view's position to the record returned previously with
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen _log_view_next(). */
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenvoid mail_transaction_log_view_mark(struct mail_transaction_log_view *view);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen/* Seek to previously marked position. */
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenvoid mail_transaction_log_view_rewind(struct mail_transaction_log_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns the position of the record returned previously with
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_next() */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *file_seq_r,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uoff_t *file_offset_r);
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainen/* Return the modseq of the change returned previously with _view_next(). */
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenuint64_t
95a1a5195d56f3cf5d1e529aad668f87ad3b979bTimo Sirainenmail_transaction_log_view_get_prev_modseq(struct mail_transaction_log_view *view);
c9c24293550541307f1bb41bba4a0fdfe2fa59e0Timo Sirainen/* Returns TRUE if we're at the end of the view window. */
c9c24293550541307f1bb41bba4a0fdfe2fa59e0Timo Sirainenbool mail_transaction_log_view_is_last(struct mail_transaction_log_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Marks the log file in current position to be corrupted. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *fmt, ...)
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainen ATTR_FORMAT(2, 3);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainenint mail_transaction_log_append_begin(struct mail_index *index,
e169102fb38ce788b76c2a344bee7d77079dea05Timo Sirainen enum mail_transaction_type flags,
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainen struct mail_transaction_log_append_ctx **ctx_r);
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainenvoid mail_transaction_log_append_add(struct mail_transaction_log_append_ctx *ctx,
77bc2bda5b781c4ffddc8a74b175cf32e9e2c2ecTimo Sirainen enum mail_transaction_type type,
40a5aeebf6b4858b93f0ddff0bf12fba769cf903Timo Sirainen const void *data, size_t size);
1279090ba03f9c176976a69ab7718f0ed77b19afTimo Sirainenint mail_transaction_log_append_commit(struct mail_transaction_log_append_ctx **ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Lock transaction log for index synchronization. Log cannot be read or
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen written to while it's locked. Returns end offset. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_transaction_log_sync_lock(struct mail_transaction_log *log,
6ded8819b9002150a95a7615e4f64f091c250464Timo Sirainen const char *lock_reason,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *file_seq_r, uoff_t *file_offset_r);
2f8da04d700cc23fcd6630226a4866e828b761bdTimo Sirainenvoid mail_transaction_log_sync_unlock(struct mail_transaction_log *log,
2f8da04d700cc23fcd6630226a4866e828b761bdTimo Sirainen const char *lock_reason);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns the current head. Works only when log is locked. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_transaction_log_get_head(struct mail_transaction_log *log,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen uint32_t *file_seq_r, uoff_t *file_offset_r);
3ee5f5427b36ea30a01561b35f4002232db7b061Timo Sirainen/* Returns the current tail from which all files are open to head. */
3ee5f5427b36ea30a01561b35f4002232db7b061Timo Sirainenvoid mail_transaction_log_get_tail(struct mail_transaction_log *log,
3ee5f5427b36ea30a01561b35f4002232db7b061Timo Sirainen uint32_t *file_seq_r);
a050ca9def13949dbaa67bd6574a41c4f397ae26Timo Sirainen/* Returns TRUE if given seq/offset is current head log's rotate point. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool mail_transaction_log_is_head_prev(struct mail_transaction_log *log,
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen uint32_t file_seq, uoff_t file_offset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
902222fb0928d1701f20a384b73f327b1d9a15ddTimo Sirainen/* Move currently opened log head file to memory (called by
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen mail_index_move_to_memory()) */
5b809b97673fb0a73aa5b9d82122612d699f6c5bTimo Sirainenint mail_transaction_log_move_to_memory(struct mail_transaction_log *log);
1be964ec6d835f95b4fdebf02add9265d58ad290Timo Sirainen/* Unlink transaction log files */
1be964ec6d835f95b4fdebf02add9265d58ad290Timo Sirainenint mail_transaction_log_unlink(struct mail_transaction_log *log);
2a6af811ea3de3cf9e2f15e446674dd21b0705f3Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#endif