mbox-sync-private.h revision f140f88a5ab3e2194f214c11f9f418559e949c83
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen#ifndef MBOX_SYNC_PRIVATE_H
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#define MBOX_SYNC_PRIVATE_H
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "md5.h"
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#include "mail-index.h"
472369cba85d9f7c995dda60e7cd01d78b4a960aTimo Sirainen
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen#include <sys/stat.h>
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen
bd4e36a8cd7257cca7d1434c49a1e343ed7c5100Timo Sirainenenum mbox_sync_flags {
adb6413686e52e00dded4932babcc08ff041876bTimo Sirainen MBOX_SYNC_HEADER = 0x02,
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainen MBOX_SYNC_LOCK_READING = 0x04,
94d8e51119003d2bc5a100c663f90141f297385dTimo Sirainen MBOX_SYNC_UNDIRTY = 0x08,
e28fa207d1a097fa6e4a867f74ee0761472ef1ceTimo Sirainen MBOX_SYNC_REWRITE = 0x10,
37847ec8eaec9ad55c9df10ae109efe7b37ac573Timo Sirainen MBOX_SYNC_FORCE_SYNC = 0x20,
ef50336eefcb9ba99f73c6af37420eaf8857a39bTimo Sirainen MBOX_SYNC_READONLY = 0x40
13d98ffa534f2e7d04a832c9d0153fc9c568b878Timo Sirainen};
13d98ffa534f2e7d04a832c9d0153fc9c568b878Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstruct mbox_flag_type {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen char chr;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen enum mail_flags flag;
dc5606fb66d30a659459446b6ca1a8b4f1146052Timo Sirainen};
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenenum header_position {
5694eeb99b69dea8033ca77ad69743c6b4871370Timo Sirainen MBOX_HDR_STATUS,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MBOX_HDR_X_IMAPBASE,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MBOX_HDR_X_KEYWORDS,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MBOX_HDR_X_STATUS,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MBOX_HDR_X_UID,
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen MBOX_HDR_COUNT
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen};
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen/* kludgy. swap MAIL_RECENT with MBOX_NONRECENT_KLUDGE when writing Status
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen header, because 'O' flag means non-recent but internally we want to use
220e21750948941dc6e33b8f11b552fa21d7f81eTimo Sirainen recent flag. */
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen#define MBOX_NONRECENT_KLUDGE MAIL_RECENT
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen#define STATUS_FLAGS_MASK (MAIL_SEEN|MBOX_NONRECENT_KLUDGE)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen#define XSTATUS_FLAGS_MASK (MAIL_ANSWERED|MAIL_FLAGGED|MAIL_DRAFT|MAIL_DELETED)
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenextern struct mbox_flag_type mbox_status_flags[];
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenextern struct mbox_flag_type mbox_xstatus_flags[];
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainenstruct mbox_sync_mail {
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen /* uid=0 can mean that this mail describes an expunged area or that
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen this is a pseudo message */
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen uint32_t uid;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen uint32_t idx_seq;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen ARRAY_TYPE(keyword_indexes) keywords;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uint8_t flags;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int uid_broken:1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int expunged:1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned int pseudo:1;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uoff_t from_offset;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uoff_t body_size;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen /* following variables have a bit overloaded functionality:
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen a) space <= 0 : offset points to beginning of headers. space is the
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen amount of space missing that is required to be able to rewrite
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen the headers
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen b) space > 0 : offset points to beginning of whitespace that can
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen be removed. space is the amount of data that can be removed from
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen there. note that the message may contain more whitespace
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen elsewhere. */
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen uoff_t offset;
8a0ad174adb1eb5108511b90e97f4e5f9089b0eeTimo Sirainen off_t space;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen};
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainenstruct mbox_sync_mail_context {
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct mbox_sync_context *sync_ctx;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct mbox_sync_mail mail;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uint32_t seq;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uoff_t hdr_offset, body_offset;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen size_t header_first_change, header_last_change;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen string_t *header;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen unsigned char hdr_md5_sum[16];
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uoff_t content_length;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen size_t hdr_pos[MBOX_HDR_COUNT];
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen uint32_t parsed_uid, last_uid_updated_value;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int last_uid_value_start_pos;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int have_eoh:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int need_rewrite:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int seen_imapbase:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int updated:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int recent:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int dirty:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int imapbase_rewrite:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen unsigned int imapbase_updated:1;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen};
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenstruct mbox_sync_context {
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen struct mbox_mailbox *mbox;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen enum mbox_sync_flags flags;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct istream *input, *file_input;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen int write_fd;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen time_t orig_mtime, orig_atime;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen uoff_t orig_size;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen struct stat last_stat;
db8b0a3f74a20528d66a3c4be7df920e5c4554c2Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_index_sync_ctx *index_sync_ctx;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_index_view *sync_view;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_index_transaction *t;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen struct mail_index_header reset_hdr;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen const struct mail_index_header *hdr;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen string_t *header, *from_line;
a27e065f1a1f91c7fbdf7c2ea1c387441af0cbb3Timo Sirainen
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen /* header state: */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen uint32_t base_uid_validity, base_uid_last;
6600c05e2ab38e9f662582b63c56b0c980a03748Timo Sirainen uoff_t base_uid_last_offset;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* mail state: */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen ARRAY_DEFINE(mails, struct mbox_sync_mail);
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen struct index_sync_changes_context *sync_changes;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* per-mail pool */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen pool_t mail_keyword_pool;
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen /* used for mails[].keywords */
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainen pool_t saved_keywords_pool;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen uint32_t prev_msg_uid, next_uid, idx_next_uid;
a24519c36d5f8fa22f58b2c693ba547e8d175a54Timo Sirainen uint32_t seq, idx_seq, need_space_seq;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uint32_t last_nonrecent_uid;
1701e3f91107051b1704721bf1dc1e32491faaf9Timo Sirainen off_t expunged_space, space_diff;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int dest_first_mail:1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int first_mail_crlf_expunged:1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* global flags: */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int keep_recent:1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int readonly:1;
3fe67ec75ccae1230bb9eb9f16affc48377f6441Timo Sirainen unsigned int delay_writes:1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int renumber_uids:1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen unsigned int moved_offsets:1;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen unsigned int ext_modified:1;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen unsigned int index_reset:1;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen unsigned int errors:1;
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen};
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainen
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainenint mbox_sync_header_refresh(struct mbox_mailbox *mbox);
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainenint mbox_sync(struct mbox_mailbox *mbox, enum mbox_sync_flags flags);
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainenint mbox_sync_has_changed(struct mbox_mailbox *mbox, bool leave_dirty);
2a6dcd984104fed84bed8795ccdfabb20e41ce52Timo Sirainenint mbox_sync_has_changed_full(struct mbox_mailbox *mbox, bool leave_dirty,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen bool *empty_r);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid mbox_sync_set_critical(struct mbox_sync_context *sync_ctx,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const char *fmt, ...) ATTR_FORMAT(2, 3);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2649b237dd4690575e75a30b2bf3b39ebd37b835Timo Sirainenvoid mbox_sync_parse_next_mail(struct istream *input,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mbox_sync_mail_context *ctx);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenbool mbox_sync_parse_match_mail(struct mbox_mailbox *mbox,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mail_index_view *view, uint32_t seq);
27586e4785d56aeb76e1fd96af8db799688dc64aTimo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid mbox_sync_update_header(struct mbox_sync_mail_context *ctx);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid mbox_sync_update_header_from(struct mbox_sync_mail_context *ctx,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen const struct mbox_sync_mail *mail);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenint mbox_sync_try_rewrite(struct mbox_sync_mail_context *ctx, off_t move_diff);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenint mbox_sync_rewrite(struct mbox_sync_context *sync_ctx,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen struct mbox_sync_mail_context *mail_ctx,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uoff_t end_offset, off_t move_diff, uoff_t extra_space,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen uint32_t first_seq, uint32_t last_seq);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenint mbox_sync_seek(struct mbox_sync_context *sync_ctx, uoff_t from_offset);
1c1cecd3dfaf71b0c9499b044023e631841e88aaTimo Sirainenvoid mbox_sync_file_update_ext_modified(struct mbox_sync_context *sync_ctx);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenvoid mbox_sync_file_updated(struct mbox_sync_context *sync_ctx, bool dirty);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainenint mbox_move(struct mbox_sync_context *sync_ctx,
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen uoff_t dest, uoff_t source, uoff_t size);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkvoid mbox_sync_move_buffer(struct mbox_sync_mail_context *ctx,
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk size_t pos, size_t need, size_t have);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volkvoid mbox_sync_headers_add_space(struct mbox_sync_mail_context *ctx,
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk size_t size);
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk#endif
7920a47321690c932ffd4d286cd16b4048d22d41Timo Sirainen