mail-transaction-log.h revision 6d3bb841d4ec2c12ac2d4ecf6146ef8d8a7dd731
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef MAIL_TRANSACTION_LOG_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define MAIL_TRANSACTION_LOG_H
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen#include "mail-index.h"
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen#define MAIL_TRANSACTION_LOG_SUFFIX ".log"
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen#define MAIL_TRANSACTION_LOG_MAJOR_VERSION 1
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen#define MAIL_TRANSACTION_LOG_MINOR_VERSION 2
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen#define MAIL_TRANSACTION_LOG_HEADER_MIN_SIZE 24
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainenstruct mail_transaction_log_header {
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen uint8_t major_version;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen uint8_t minor_version;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen uint16_t hdr_size;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen uint32_t indexid;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen uint32_t file_seq;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen uint32_t prev_file_seq;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen uint32_t prev_file_offset;
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen uint32_t create_stamp;
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen uint64_t initial_modseq; /* v1.1+ (note: log's major/minor version) */
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen uint8_t compat_flags; /* enum mail_index_header_compat_flags, v1.2+ */
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen uint8_t unused[3];
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen uint32_t unused2; /* so that this struct is 64bit aligned */
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen};
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenenum mail_transaction_type {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_TRANSACTION_EXPUNGE = 0x00000001,
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen MAIL_TRANSACTION_APPEND = 0x00000002,
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen MAIL_TRANSACTION_FLAG_UPDATE = 0x00000004,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_TRANSACTION_HEADER_UPDATE = 0x00000020,
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen MAIL_TRANSACTION_EXT_INTRO = 0x00000040,
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen MAIL_TRANSACTION_EXT_RESET = 0x00000080,
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen MAIL_TRANSACTION_EXT_HDR_UPDATE = 0x00000100,
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen MAIL_TRANSACTION_EXT_REC_UPDATE = 0x00000200,
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen MAIL_TRANSACTION_KEYWORD_UPDATE = 0x00000400,
8b2cf1c1bd8ddcea0525b62fd35ba76e136828a1Timo Sirainen MAIL_TRANSACTION_KEYWORD_RESET = 0x00000800,
8b2cf1c1bd8ddcea0525b62fd35ba76e136828a1Timo Sirainen MAIL_TRANSACTION_EXT_ATOMIC_INC = 0x00001000,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_TRANSACTION_EXPUNGE_GUID = 0x00002000,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_TRANSACTION_MODSEQ_UPDATE = 0x00008000,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen MAIL_TRANSACTION_EXT_HDR_UPDATE32 = 0x00010000,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_TRANSACTION_INDEX_DELETED = 0x00020000,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_TRANSACTION_INDEX_UNDELETED = 0x00040000,
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen MAIL_TRANSACTION_BOUNDARY = 0x00080000,
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen MAIL_TRANSACTION_TYPE_MASK = 0x000fffff,
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen#define MAIL_TRANSACTION_EXT_MASK \
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen (MAIL_TRANSACTION_EXT_INTRO | MAIL_TRANSACTION_EXT_RESET | \
9b7eeffb5752b500ac62ba1fd01c4a8c4ada14e9Timo Sirainen MAIL_TRANSACTION_EXT_HDR_UPDATE | MAIL_TRANSACTION_EXT_HDR_UPDATE32 | \
9b7eeffb5752b500ac62ba1fd01c4a8c4ada14e9Timo Sirainen MAIL_TRANSACTION_EXT_REC_UPDATE | MAIL_TRANSACTION_EXT_ATOMIC_INC)
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen /* since we'll expunge mails based on data read from transaction log,
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen try to avoid the possibility of corrupted transaction log expunging
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen messages. this value is ORed to the actual MAIL_TRANSACTION_EXPUNGE*
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen flag. if it's not present, assume corrupted log. */
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen MAIL_TRANSACTION_EXPUNGE_PROT = 0x0000cd90,
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen /* Mailbox synchronization noticed this change. */
b565a6a7a66fb9f224d00c06a950e3c1c585c18eTimo Sirainen MAIL_TRANSACTION_EXTERNAL = 0x10000000
b565a6a7a66fb9f224d00c06a950e3c1c585c18eTimo Sirainen};
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainen
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainenstruct mail_transaction_header {
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen uint32_t size;
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen uint32_t type; /* enum mail_transaction_type */
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Sirainen};
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainen
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainenstruct mail_transaction_modseq_update {
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainen uint32_t uid;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* don't use uint64_t here. it adds extra 32 bits of paddiong and also
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen causes problems with CPUs that require alignment */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen uint32_t modseq_low32;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen uint32_t modseq_high32;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen};
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainenstruct mail_transaction_expunge {
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainen uint32_t uid1, uid2;
f988b93c2ef773987bcdcbfb4cca39b955e3a392Timo Sirainen};
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainenstruct mail_transaction_expunge_guid {
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainen uint32_t uid;
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen guid_128_t guid_128;
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mail_transaction_flag_update {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen uint32_t uid1, uid2;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen uint8_t add_flags;
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen uint8_t remove_flags;
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen uint16_t padding;
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen};
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainenstruct mail_transaction_keyword_update {
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen uint8_t modify_type; /* enum modify_type : MODIFY_ADD / MODIFY_REMOVE */
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen uint8_t padding;
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen uint16_t name_size;
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen /* unsigned char name[];
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen array of { uint32_t uid1, uid2; }
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen */
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstruct mail_transaction_keyword_reset {
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen uint32_t uid1, uid2;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainenstruct mail_transaction_header_update {
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen uint16_t offset;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint16_t size;
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen /* unsigned char data[]; */
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen};
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainenenum {
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen /* Don't shrink hdr_size, record_size or record_align but grow them
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen if necessary. */
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen MAIL_TRANSACTION_EXT_INTRO_FLAG_NO_SHRINK = 0x01
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainenstruct mail_transaction_ext_intro {
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainen /* old extension: set ext_id. don't set name.
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen new extension: ext_id = (uint32_t)-1. give name. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uint32_t ext_id;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint32_t reset_id;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen uint32_t hdr_size;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint16_t record_size;
10ff47d5d6146995e16da00d36eca7d162064a7bTimo Sirainen uint16_t record_align;
683eebe490bbe5caec246c535a10ea9f93f5c330Timo Sirainen uint16_t flags;
683eebe490bbe5caec246c535a10ea9f93f5c330Timo Sirainen uint16_t name_size;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* unsigned char name[]; */
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen};
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstruct mail_transaction_ext_reset {
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint32_t new_reset_id;
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainen uint8_t preserve_data;
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainen uint8_t unused_padding[3];
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* these are set for the last ext_intro */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mail_transaction_ext_hdr_update {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen uint16_t offset;
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen uint16_t size;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* unsigned char data[]; */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen};
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen/* this _update32 version should have been the only ext_hdr_update,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen but since 16bit integers were originally used for now we'll just use this
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen only when actually needed to be backwards compatible. */
ceb43cc04edb94445fab8f914bc4da6d740403d1Timo Sirainenstruct mail_transaction_ext_hdr_update32 {
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen uint32_t offset;
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen uint32_t size;
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen /* unsigned char data[]; */
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen};
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenstruct mail_transaction_ext_rec_update {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen uint32_t uid;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen /* unsigned char data[]; */
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen};
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainenstruct mail_transaction_ext_atomic_inc {
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen uint32_t uid;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen int32_t diff;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen};
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenstruct mail_transaction_boundary {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen uint32_t size;
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen};
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenstruct mail_transaction_log_append_ctx {
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen struct mail_transaction_log *log;
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen buffer_t *output;
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen uint64_t new_highest_modseq;
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen unsigned int external:1;
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen unsigned int append_sync_offset:1;
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen unsigned int sync_includes_this:1;
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen unsigned int want_fsync:1;
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen};
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen#define LOG_IS_BEFORE(seq1, offset1, seq2, offset2) \
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen (((offset1) < (offset2) && (seq1) == (seq2)) || (seq1) < (seq2))
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainenstruct mail_transaction_log *
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainenmail_transaction_log_alloc(struct mail_index *index);
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainenvoid mail_transaction_log_free(struct mail_transaction_log **log);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen/* Open the transaction log. Returns 1 if ok, 0 if file doesn't exist or it's
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen is corrupted, -1 if there was some I/O error. */
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainenint mail_transaction_log_open(struct mail_transaction_log *log);
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen/* Create, or recreate, the transaction log. Returns 0 if ok, -1 if error. */
71da447014454c84828d9dface77219875554d7dTimo Sirainenint mail_transaction_log_create(struct mail_transaction_log *log, bool reset);
71da447014454c84828d9dface77219875554d7dTimo Sirainen/* Close all the open transactions log files. */
71da447014454c84828d9dface77219875554d7dTimo Sirainenvoid mail_transaction_log_close(struct mail_transaction_log *log);
71da447014454c84828d9dface77219875554d7dTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Notify of indexid change */
void mail_transaction_log_indexid_changed(struct mail_transaction_log *log);
/* Returns the file seq/offset where the mailbox is currently synced at.
Since the log is rotated only when mailbox is fully synced, the sequence
points always to the latest file. This function doesn't actually find the
latest sync position, so you'll need to use eg. log_view_set() before
calling this. */
void mail_transaction_log_get_mailbox_sync_pos(struct mail_transaction_log *log,
uint32_t *file_seq_r,
uoff_t *file_offset_r);
/* Set the current mailbox sync position. file_seq must always be the latest
log file's sequence. The offset written automatically to the log when
other transactions are being written. */
void mail_transaction_log_set_mailbox_sync_pos(struct mail_transaction_log *log,
uint32_t file_seq,
uoff_t file_offset);
struct mail_transaction_log_view *
mail_transaction_log_view_open(struct mail_transaction_log *log);
void mail_transaction_log_view_close(struct mail_transaction_log_view **view);
/* Set view boundaries. Returns -1 if error, 0 if files are lost or corrupted,
1 if ok. reset_r=TRUE if the whole index should be reset before applying any
changes. */
int mail_transaction_log_view_set(struct mail_transaction_log_view *view,
uint32_t min_file_seq, uoff_t min_file_offset,
uint32_t max_file_seq, uoff_t max_file_offset,
bool *reset_r);
/* Scan through all of the log files that we can find.
Returns -1 if error, 0 if ok. */
int mail_transaction_log_view_set_all(struct mail_transaction_log_view *view);
/* Clear the view. Keep oldest_file_seq and newer log files referenced so we
don't get desynced. */
void mail_transaction_log_view_clear(struct mail_transaction_log_view *view,
uint32_t oldest_file_seq);
/* Read next transaction record from current position. The position is updated.
Returns -1 if error, 0 if we're at end of the view, 1 if ok. */
int mail_transaction_log_view_next(struct mail_transaction_log_view *view,
const struct mail_transaction_header **hdr_r,
const void **data_r);
/* Mark the current view's position to the record returned previously with
_log_view_next(). */
void mail_transaction_log_view_mark(struct mail_transaction_log_view *view);
/* Seek to previously marked position. */
void mail_transaction_log_view_rewind(struct mail_transaction_log_view *view);
/* Returns the position of the record returned previously with
mail_transaction_log_view_next() */
void
mail_transaction_log_view_get_prev_pos(struct mail_transaction_log_view *view,
uint32_t *file_seq_r,
uoff_t *file_offset_r);
/* Return the modseq of the change returned previously with _view_next(). */
uint64_t
mail_transaction_log_view_get_prev_modseq(struct mail_transaction_log_view *view);
/* Returns TRUE if we're at the end of the view window. */
bool mail_transaction_log_view_is_last(struct mail_transaction_log_view *view);
/* Marks the log file in current position to be corrupted. */
void
mail_transaction_log_view_set_corrupted(struct mail_transaction_log_view *view,
const char *fmt, ...)
ATTR_FORMAT(2, 3);
bool
mail_transaction_log_view_is_corrupted(struct mail_transaction_log_view *view);
int mail_transaction_log_append_begin(struct mail_index *index, bool external,
struct mail_transaction_log_append_ctx **ctx_r);
void mail_transaction_log_append_add(struct mail_transaction_log_append_ctx *ctx,
enum mail_transaction_type type,
const void *data, size_t size);
int mail_transaction_log_append_commit(struct mail_transaction_log_append_ctx **ctx);
/* Lock transaction log for index synchronization. Log cannot be read or
written to while it's locked. Returns end offset. */
int mail_transaction_log_sync_lock(struct mail_transaction_log *log,
uint32_t *file_seq_r, uoff_t *file_offset_r);
void mail_transaction_log_sync_unlock(struct mail_transaction_log *log);
/* Returns the current head. Works only when log is locked. */
void mail_transaction_log_get_head(struct mail_transaction_log *log,
uint32_t *file_seq_r, uoff_t *file_offset_r);
/* Returns the current tail from which all files are open to head. */
void mail_transaction_log_get_tail(struct mail_transaction_log *log,
uint32_t *file_seq_r);
/* Returns TRUE if given seq/offset is current head log's rotate point. */
bool mail_transaction_log_is_head_prev(struct mail_transaction_log *log,
uint32_t file_seq, uoff_t file_offset);
/* Move currently opened log head file to memory (called by
mail_index_move_to_memory()) */
void mail_transaction_log_move_to_memory(struct mail_transaction_log *log);
/* Returns mtime of the transaction log head file.
If it doesn't exist, mtime_r is set to 0. */
int mail_transaction_log_get_mtime(struct mail_transaction_log *log,
time_t *mtime_r);
/* Unlink transaction log files */
int mail_transaction_log_unlink(struct mail_transaction_log *log);
#endif