diff options
Diffstat (limited to '')
-rw-r--r-- | src/plugins/virtual/virtual-storage.h | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/src/plugins/virtual/virtual-storage.h b/src/plugins/virtual/virtual-storage.h new file mode 100644 index 0000000..1f34e39 --- /dev/null +++ b/src/plugins/virtual/virtual-storage.h @@ -0,0 +1,251 @@ +#ifndef VIRTUAL_STORAGE_H +#define VIRTUAL_STORAGE_H + +#include "seq-range-array.h" +#include "index-storage.h" + +#define VIRTUAL_STORAGE_NAME "virtual" +#define VIRTUAL_SUBSCRIPTION_FILE_NAME ".virtual-subscriptions" +#define VIRTUAL_CONFIG_FNAME "dovecot-virtual" + +#define VIRTUAL_CONTEXT(obj) \ + MODULE_CONTEXT(obj, virtual_storage_module) +#define VIRTUAL_CONTEXT_REQUIRE(obj) \ + MODULE_CONTEXT_REQUIRE(obj, virtual_storage_module) + +#define VIRTUAL_MAIL_INDEX_EXT2_HEADER_VERSION 1 + +struct virtual_save_context; + +struct virtual_mail_index_header { + /* Increased by one each time the header is modified */ + uint32_t change_counter; + /* Number of mailbox records following this header. Mailbox names + follow the mailbox records - they have neither NUL terminator nor + padding. */ + uint32_t mailbox_count; + /* Highest used mailbox ID. IDs are never reused. */ + uint32_t highest_mailbox_id; + /* CRC32 of all the search parameters. If it changes, the mailbox is + rebuilt. */ + uint32_t search_args_crc32; +}; + +struct virtual_mail_index_mailbox_record { + /* Unique mailbox ID used as mailbox_id in records. */ + uint32_t id; + /* Length of this mailbox's name. */ + uint32_t name_len; + /* Synced UID validity value */ + uint32_t uid_validity; + /* Next unseen UID */ + uint32_t next_uid; + /* Synced highest modseq value */ + uint64_t highest_modseq; +}; + +struct virtual_mail_index_ext2_header { + /* Version compatibility number: + VIRTUAL_MAIL_INDEX_EXT2_HEADER_VERSION */ + uint8_t version; + /* Set to sizeof(struct virtual_mail_index_mailbox_ext2_record) when + writing. */ + uint8_t ext_record_size; + /* Set to sizeof(struct virtual_mail_index_ext2_header) when writing. */ + uint16_t hdr_size; + /* Must be the same as virtual_mail_index_header.change_counter. + If not, it means the header was modified by an older Dovecot version + and this extension header should be ignored/rewritten. */ + uint32_t change_counter; +}; + +struct virtual_mail_index_mailbox_ext2_record { + /* Synced GUID value */ + uint8_t guid[16]; +}; + +struct virtual_mail_index_record { + uint32_t mailbox_id; + uint32_t real_uid; +}; + +struct virtual_storage { + struct mail_storage storage; + + /* List of mailboxes while a virtual mailbox is being opened. + Used to track loops. */ + ARRAY_TYPE(const_string) open_stack; + + unsigned int max_open_mailboxes; +}; + +struct virtual_backend_uidmap { + uint32_t real_uid; + /* can be 0 temporarily while syncing before the UID is assigned */ + uint32_t virtual_uid; +}; + +struct virtual_backend_box { + union mailbox_module_context module_ctx; + struct virtual_mailbox *virtual_mbox; + + /* linked list for virtual_mailbox->open_backend_boxes_{head,tail} */ + struct virtual_backend_box *prev_open, *next_open; + + /* Initially zero, updated by syncing */ + uint32_t mailbox_id; + const char *name; + + unsigned int sync_mailbox_idx1; + uint32_t sync_uid_validity; + uint32_t sync_next_uid; + uint64_t sync_highest_modseq; + guid_128_t sync_guid; + /* this value is either 0 or same as sync_highest_modseq. it's kept 0 + when there are pending removes that have yet to be expunged */ + uint64_t ondisk_highest_modseq; + + struct mail_search_args *search_args; + struct mail_search_result *search_result; + + struct mailbox *box; + /* Messages currently included in the virtual mailbox, + sorted by real_uid */ + ARRAY(struct virtual_backend_uidmap) uids; + + /* temporary mail used while syncing */ + struct mail *sync_mail; + /* pending removed UIDs */ + ARRAY_TYPE(seq_range) sync_pending_removes; + /* another process expunged these UIDs. they need to be removed on + next sync. */ + ARRAY_TYPE(seq_range) sync_outside_expunges; + + /* name contains a wildcard, this is a glob for it */ + struct imap_match_glob *glob; + struct mail_namespace *ns; + /* mailbox metadata matching */ + const char *metadata_entry, *metadata_value; + + /* notify context */ + struct mailbox_list_notify *notify; + + bool open_tracked:1; + bool open_failed:1; + bool sync_seen:1; + bool wildcard:1; + bool clear_recent:1; + bool negative_match:1; + bool uids_nonsorted:1; + bool search_args_initialized:1; + bool deleted:1; + bool notify_changes_started:1; /* if the box was opened for notify_changes */ + bool first_sync:1; /* if this is the first sync after bbox was (re-)created */ +}; +ARRAY_DEFINE_TYPE(virtual_backend_box, struct virtual_backend_box *); + +struct virtual_mailbox { + struct mailbox box; + struct virtual_storage *storage; + + uint32_t virtual_ext_id; + uint32_t virtual_ext2_id; + uint32_t virtual_guid_ext_id; + + uint32_t prev_uid_validity; + uint32_t prev_change_counter; + uint32_t highest_mailbox_id; + uint32_t search_args_crc32; + guid_128_t guid; + + struct virtual_backend_box *lookup_prev_bbox; + uint32_t sync_virtual_next_uid; + + /* 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; + + bool uids_mapped:1; + bool sync_initialized:1; + bool inconsistent:1; + bool have_guid_flags_set:1; + bool have_guids:1; + bool have_save_guids:1; + bool ext_header_rewrite: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); + +int virtual_mailbox_ext_header_read(struct virtual_mailbox *mbox, + struct mail_index_view *view, + bool *broken_r); + +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_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); +void virtual_mail_set_unattached_backend_mail(struct mail *mail, + struct mail *backend_mail); + +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); + +void virtual_backend_mailbox_allocated(struct mailbox *box); +void virtual_backend_mailbox_opened(struct mailbox *box); + +#endif |