summaryrefslogtreecommitdiffstats
path: root/src/plugins/virtual/virtual-storage.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/plugins/virtual/virtual-storage.h251
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