virtual-storage.h revision 212e9e43a7d49242446331fd43ba519eda936d60
2ronwalf#ifndef VIRTUAL_STORAGE_H
2ronwalf#define VIRTUAL_STORAGE_H
2ronwalf
2ronwalf#include "seq-range-array.h"
2ronwalf#include "index-storage.h"
2ronwalf
2ronwalf#define VIRTUAL_STORAGE_NAME "virtual"
2ronwalf#define VIRTUAL_SUBSCRIPTION_FILE_NAME ".virtual-subscriptions"
2ronwalf#define VIRTUAL_CONFIG_FNAME "dovecot-virtual"
2ronwalf
2ronwalf#define VIRTUAL_CONTEXT(obj) \
2ronwalf MODULE_CONTEXT(obj, virtual_storage_module)
2ronwalf
2ronwalfstruct virtual_save_context;
2ronwalf
2ronwalfstruct virtual_mail_index_header {
2ronwalf /* Increased by one each time the header is modified */
2ronwalf uint32_t change_counter;
2ronwalf /* Number of mailbox records following this header. Mailbox names
2ronwalf follow the mailbox records - they have neither NUL terminator nor
2ronwalf padding. */
2ronwalf uint32_t mailbox_count;
2ronwalf /* Highest used mailbox ID. IDs are never reused. */
2ronwalf uint32_t highest_mailbox_id;
2ronwalf /* CRC32 of all the search parameters. If it changes, the mailbox is
2ronwalf rebuilt. */
22daenzerorama uint32_t search_args_crc32;
2ronwalf};
2ronwalf
2ronwalfstruct virtual_mail_index_mailbox_record {
2ronwalf /* Unique mailbox ID used as mailbox_id in records. */
2ronwalf uint32_t id;
2ronwalf /* Length of this mailbox's name. */
2ronwalf uint32_t name_len;
2ronwalf /* Synced UID validity value */
2ronwalf uint32_t uid_validity;
2ronwalf /* Next unseen UID */
2ronwalf uint32_t next_uid;
2ronwalf /* Synced highest modseq value */
2ronwalf uint64_t highest_modseq;
2ronwalf};
2ronwalf
2ronwalfstruct virtual_mail_index_record {
2ronwalf uint32_t mailbox_id;
2ronwalf uint32_t real_uid;
2ronwalf};
2ronwalf
2ronwalfstruct virtual_storage {
2ronwalf struct mail_storage storage;
2ronwalf
2ronwalf /* List of mailboxes while a virtual mailbox is being opened.
2ronwalf Used to track loops. */
2ronwalf ARRAY_TYPE(const_string) open_stack;
2ronwalf
2ronwalf unsigned int max_open_mailboxes;
2ronwalf};
2ronwalf
2ronwalfstruct virtual_backend_uidmap {
2ronwalf uint32_t real_uid;
2ronwalf /* can be 0 temporarily while syncing before the UID is assigned */
2ronwalf uint32_t virtual_uid;
2ronwalf};
2ronwalf
2ronwalfstruct virtual_backend_box {
2ronwalf /* linked list for virtual_mailbox->open_backend_boxes_{head,tail} */
2ronwalf struct virtual_backend_box *prev_open, *next_open;
2ronwalf
2ronwalf /* Initially zero, updated by syncing */
2ronwalf uint32_t mailbox_id;
2ronwalf const char *name;
2ronwalf
2ronwalf unsigned int sync_mailbox_idx;
2ronwalf uint32_t sync_uid_validity;
2ronwalf uint32_t sync_next_uid;
2ronwalf uint64_t sync_highest_modseq;
2ronwalf /* this value is either 0 or same as sync_highest_modseq. it's kept 0
2ronwalf when there are pending removes that have yet to be expunged */
2ronwalf uint64_t ondisk_highest_modseq;
2ronwalf
2ronwalf struct mail_search_args *search_args;
2ronwalf struct mail_search_result *search_result;
2ronwalf
2ronwalf struct mailbox *box;
2ronwalf /* Messages currently included in the virtual mailbox,
2ronwalf sorted by real_uid */
2ronwalf ARRAY(struct virtual_backend_uidmap) uids;
2ronwalf
2ronwalf /* temporary mail used while syncing */
2ronwalf struct mail *sync_mail;
2ronwalf /* pending removed UIDs */
2ronwalf ARRAY_TYPE(seq_range) sync_pending_removes;
2ronwalf /* another process expunged these UIDs. they need to be removed on
2ronwalf next sync. */
2ronwalf ARRAY_TYPE(seq_range) sync_outside_expunges;
2ronwalf
2ronwalf /* name contains a wildcard, this is a glob for it */
2ronwalf struct imap_match_glob *glob;
2ronwalf struct mail_namespace *ns;
2ronwalf
2ronwalf unsigned int open_failed:1;
2ronwalf unsigned int sync_seen:1;
2ronwalf unsigned int wildcard:1;
2ronwalf unsigned int clear_recent:1;
2ronwalf unsigned int uids_nonsorted:1;
2ronwalf unsigned int search_args_initialized:1;
2ronwalf};
2ronwalfARRAY_DEFINE_TYPE(virtual_backend_box, struct virtual_backend_box *);
2ronwalf
2ronwalfstruct virtual_mailbox_vfuncs {
2ronwalf /* convert backend UIDs to virtual UIDs. if some backend UID doesn't
2ronwalf exist in mailbox, it's simply ignored */
2ronwalf void (*get_virtual_uids)(struct mailbox *box,
2ronwalf struct mailbox *backend_mailbox,
2ronwalf const ARRAY_TYPE(seq_range) *backend_uids,
2ronwalf ARRAY_TYPE(seq_range) *virtual_uids_r);
2ronwalf /* like get_virtual_uids(), but if a backend UID doesn't exist,
2ronwalf convert it to 0. */
2ronwalf void (*get_virtual_uid_map)(struct mailbox *box,
2ronwalf struct mailbox *backend_mailbox,
2ronwalf const ARRAY_TYPE(seq_range) *backend_uids,
2ronwalf ARRAY_TYPE(uint32_t) *virtual_uids_r);
2ronwalf void (*get_virtual_backend_boxes)(struct mailbox *box,
2ronwalf ARRAY_TYPE(mailboxes) *mailboxes,
2ronwalf bool only_with_msgs);
2ronwalf};
2ronwalf
2ronwalfstruct virtual_mailbox {
2ronwalf struct mailbox box;
2ronwalf struct virtual_storage *storage;
2ronwalf
2ronwalf uint32_t virtual_ext_id;
2ronwalf
2ronwalf uint32_t prev_uid_validity;
2ronwalf uint32_t prev_change_counter;
2ronwalf uint32_t highest_mailbox_id;
2ronwalf uint32_t search_args_crc32;
2ronwalf
2ronwalf struct virtual_backend_box *lookup_prev_bbox;
2ronwalf uint32_t sync_virtual_next_uid;
2ronwalf
2ronwalf /* Mailboxes this virtual mailbox consists of, sorted by mailbox_id */
ARRAY_TYPE(virtual_backend_box) backend_boxes;
/* backend mailbox where to save messages when saving to this mailbox */
struct virtual_backend_box *save_bbox;
/* linked list of open backend mailboxes. head will contain the oldest
accessed mailbox, tail will contain the newest. */
struct virtual_backend_box *open_backend_boxes_head;
struct virtual_backend_box *open_backend_boxes_tail;
/* number of backend mailboxes that are open currently. */
unsigned int backends_open_count;
ARRAY_TYPE(mailbox_virtual_patterns) list_include_patterns;
ARRAY_TYPE(mailbox_virtual_patterns) list_exclude_patterns;
struct virtual_mailbox_vfuncs vfuncs;
unsigned int uids_mapped:1;
unsigned int sync_initialized:1;
unsigned int inconsistent:1;
unsigned int have_guid_flags_set:1;
unsigned int have_guids:1;
unsigned int have_save_guids:1;
};
extern MODULE_CONTEXT_DEFINE(virtual_storage_module,
&mail_storage_module_register);
extern struct mail_storage virtual_storage;
extern struct mail_vfuncs virtual_mail_vfuncs;
int virtual_config_read(struct virtual_mailbox *mbox);
void virtual_config_free(struct virtual_mailbox *mbox);
struct virtual_backend_box *
virtual_backend_box_lookup_name(struct virtual_mailbox *mbox, const char *name);
struct virtual_backend_box *
virtual_backend_box_lookup(struct virtual_mailbox *mbox, uint32_t mailbox_id);
int virtual_backend_box_open(struct virtual_mailbox *mbox,
struct virtual_backend_box *bbox);
void virtual_backend_box_close(struct virtual_mailbox *mbox,
struct virtual_backend_box *bbox);
void virtual_backend_box_accessed(struct virtual_mailbox *mbox,
struct virtual_backend_box *bbox);
void virtual_backend_box_opened(struct virtual_mailbox *mbox,
struct virtual_backend_box *bbox);
void virtual_backend_box_sync_mail_unset(struct virtual_backend_box *bbox);
struct mail_search_context *
virtual_search_init(struct mailbox_transaction_context *t,
struct mail_search_args *args,
const enum mail_sort_type *sort_program,
enum mail_fetch_field wanted_fields,
struct mailbox_header_lookup_ctx *wanted_headers);
int virtual_search_deinit(struct mail_search_context *ctx);
bool virtual_search_next_nonblock(struct mail_search_context *ctx,
struct mail **mail_r, bool *tryagain_r);
bool virtual_search_next_update_seq(struct mail_search_context *ctx);
struct mail *
virtual_mail_alloc(struct mailbox_transaction_context *t,
enum mail_fetch_field wanted_fields,
struct mailbox_header_lookup_ctx *wanted_headers);
struct mail *
virtual_mail_set_backend_mail(struct mail *mail,
struct virtual_backend_box *bbox);
struct mailbox_sync_context *
virtual_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags);
struct mail_save_context *
virtual_save_alloc(struct mailbox_transaction_context *t);
int virtual_save_begin(struct mail_save_context *ctx, struct istream *input);
int virtual_save_continue(struct mail_save_context *ctx);
int virtual_save_finish(struct mail_save_context *ctx);
void virtual_save_cancel(struct mail_save_context *ctx);
void virtual_save_free(struct mail_save_context *ctx);
void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src);
#endif