mail-storage-private.h revision 306b3f41b05da642d87e7ca7a1496efce9f5902f
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen#ifndef MAIL_STORAGE_PRIVATE_H
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#define MAIL_STORAGE_PRIVATE_H
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen#include "module-context.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "file-lock.h"
0536ccb51d41e3078c3a9fa33e509fb4b2420f95Timo Sirainen#include "mail-storage.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "mail-storage-hooks.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "mail-storage-settings.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen#include "mail-index-private.h"
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen/* Block size when read()ing message header. */
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen#define MAIL_READ_HDR_BLOCK_SIZE (1024*4)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Block size when read()ing message (header and) body. */
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen#define MAIL_READ_FULL_BLOCK_SIZE IO_BLOCK_SIZE
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mail_storage_module_register {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen unsigned int id;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mail_module_register {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen unsigned int id;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mail_storage_vfuncs {
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen const struct setting_parser_info *(*get_setting_parser_info)(void);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct mail_storage *(*alloc)(void);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*create)(struct mail_storage *storage, struct mail_namespace *ns,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen const char **error_r);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen void (*destroy)(struct mail_storage *storage);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen void (*add_list)(struct mail_storage *storage,
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen struct mailbox_list *list);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen void (*get_list_settings)(const struct mail_namespace *ns,
2c25e1360d4b5cc55eda969a3a7204d950de5a8fTimo Sirainen struct mailbox_list_settings *set);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen bool (*autodetect)(const struct mail_namespace *ns,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mailbox_list_settings *set);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mailbox *(*mailbox_alloc)(struct mail_storage *storage,
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen struct mailbox_list *list,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const char *vname,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen enum mailbox_flags flags);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen int (*purge)(struct mail_storage *storage);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen};
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenunion mail_storage_module_context {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_storage_vfuncs super;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_storage_module_register *reg;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenenum mail_storage_class_flags {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* mailboxes are files, not directories */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE = 0x01,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen /* root_dir points to a unique directory */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT = 0x02,
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* mailbox_open_stream() is supported */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS = 0x04,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* never use quota for this storage (e.g. virtual mailboxes) */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen MAIL_STORAGE_CLASS_FLAG_NOQUOTA = 0x08,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* Storage doesn't need a mail root directory */
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen MAIL_STORAGE_CLASS_FLAG_NO_ROOT = 0x10,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* Storage uses one file per message */
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen MAIL_STORAGE_CLASS_FLAG_FILE_PER_MSG = 0x20
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mail_binary_cache {
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct timeout *to;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mailbox *box;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen uint32_t uid;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
af81f402ddc897c74c1e85abd02879612ce44882Timo Sirainen uoff_t orig_physical_pos;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen bool include_hdr;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct istream *input;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uoff_t size;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen};
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainenstruct mail_storage {
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen const char *name;
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainen enum mail_storage_class_flags class_flags;
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen struct mail_storage_vfuncs v, *vlast;
9e095dd6a77097356aca8216356d4d71ef1bea45Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* private: */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen pool_t pool;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_storage *prev, *next;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* counting number of times mail_storage_create() has returned this
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen same storage. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int refcount;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* counting number of objects (e.g. mailbox) that have a pointer
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen to this storage. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int obj_refcount;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* Linked list of all mailboxes in the storage */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mailbox *mailboxes;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen const char *unique_root_dir;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen char *error_string;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen enum mail_error error;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const struct mail_storage *storage_class;
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen struct mail_user *user;
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen const char *temp_path_prefix;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen const struct mail_storage_settings *set;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen enum mail_storage_flags flags;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen struct mail_storage_callbacks callbacks;
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen void *callback_context;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_binary_cache binary_cache;
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen /* Module-specific contexts. See mail_storage_module_id. */
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen ARRAY_DEFINE(module_contexts, union mail_storage_module_context *);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen};
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainenstruct mail_attachment_part {
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen struct message_part *part;
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen const char *content_type, *content_disposition;
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen};
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainenstruct mailbox_vfuncs {
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen bool (*is_readonly)(struct mailbox *box);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen int (*enable)(struct mailbox *box, enum mailbox_feature features);
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen int (*exists)(struct mailbox *box, bool auto_boxes,
67c24901ac5e1521e38a91efc452faeb3e2135a1Timo Sirainen enum mailbox_existence *existence_r);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*open)(struct mailbox *box);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen void (*close)(struct mailbox *box);
e11a64ffc7f08b4cb05bcc27668d154d33d0c2e0Timo Sirainen void (*free)(struct mailbox *box);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen int (*create)(struct mailbox *box, const struct mailbox_update *update,
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen bool directory);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen int (*update)(struct mailbox *box, const struct mailbox_update *update);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen int (*delete)(struct mailbox *box);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*rename)(struct mailbox *src, struct mailbox *dest,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen bool rename_children);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen
c09f9f95db314e7482c95e502e1c56ed6c555797Timo Sirainen int (*get_status)(struct mailbox *box, enum mailbox_status_items items,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen struct mailbox_status *status_r);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*get_metadata)(struct mailbox *box,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen enum mailbox_metadata_items items,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct mailbox_metadata *metadata_r);
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen int (*set_subscribed)(struct mailbox *box, bool set);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen /* Lookup sync extension record and figure out if it mailbox has
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen changed since. Returns 1 = yes, 0 = no, -1 = error. */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*list_index_has_changed)(struct mailbox *box,
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen struct mail_index_view *list_view,
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen uint32_t seq);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* Update the sync extension record. */
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen void (*list_index_update_sync)(struct mailbox *box,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_index_transaction *trans,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uint32_t seq);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
b3142c8e513bc78da821fa70f479016148fa95e5Timo Sirainen struct mailbox_sync_context *
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen (*sync_init)(struct mailbox *box,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen enum mailbox_sync_flags flags);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen bool (*sync_next)(struct mailbox_sync_context *ctx,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mailbox_sync_rec *sync_rec_r);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*sync_deinit)(struct mailbox_sync_context *ctx,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct mailbox_sync_status *status_r);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen /* Called once for each expunge. Called one or more times for
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen flag/keyword changes. Once the sync is finished, called with
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen uid=0 and sync_type=0. */
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen void (*sync_notify)(struct mailbox *box, uint32_t uid,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen enum mailbox_sync_type sync_type);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen void (*notify_changes)(struct mailbox *box);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mailbox_transaction_context *
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen (*transaction_begin)(struct mailbox *box,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen enum mailbox_transaction_flags flags);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen int (*transaction_commit)(struct mailbox_transaction_context *t,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mail_transaction_commit_changes *changes_r);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen void (*transaction_rollback)(struct mailbox_transaction_context *t);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen enum mail_flags (*get_private_flags_mask)(struct mailbox *box);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mail *
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen (*mail_alloc)(struct mailbox_transaction_context *t,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen enum mail_fetch_field wanted_fields,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mail_search_context *
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen (*search_init)(struct mailbox_transaction_context *t,
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen struct mail_search_args *args,
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen const enum mail_sort_type *sort_program,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen enum mail_fetch_field wanted_fields,
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen struct mailbox_header_lookup_ctx *wanted_headers);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen int (*search_deinit)(struct mail_search_context *ctx);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen bool (*search_next_nonblock)(struct mail_search_context *ctx,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct mail **mail_r, bool *tryagain_r);
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen /* Internal search function which updates ctx->seq */
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen bool (*search_next_update_seq)(struct mail_search_context *ctx);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_save_context *
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainen (*save_alloc)(struct mailbox_transaction_context *t);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen int (*save_begin)(struct mail_save_context *ctx, struct istream *input);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen int (*save_continue)(struct mail_save_context *ctx);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen int (*save_finish)(struct mail_save_context *ctx);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen void (*save_cancel)(struct mail_save_context *ctx);
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen int (*copy)(struct mail_save_context *ctx, struct mail *mail);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* Called during transaction commit/rollback if saving was done */
e11a64ffc7f08b4cb05bcc27668d154d33d0c2e0Timo Sirainen int (*transaction_save_commit_pre)(struct mail_save_context *save_ctx);
e11a64ffc7f08b4cb05bcc27668d154d33d0c2e0Timo Sirainen void (*transaction_save_commit_post)
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen (struct mail_save_context *save_ctx,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_index_transaction_commit_result *result_r);
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen void (*transaction_save_rollback)(struct mail_save_context *save_ctx);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen bool (*is_inconsistent)(struct mailbox *box);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenunion mailbox_module_context {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mailbox_vfuncs super;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_storage_module_register *reg;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen};
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
fe363b433b8038a69b55169da9dca27892ad7d18Timo Sirainenstruct mail_msgpart_partial_cache {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uint32_t uid;
dd62b77c932d1b518f2a3e4bf80e36542becc256Timo Sirainen uoff_t physical_start;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen uoff_t physical_pos, virtual_pos;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen};
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstruct mailbox {
7ef5ca6fb59a318c821a852ae48a2edbb671d7ddTimo Sirainen const char *name;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen /* mailbox's virtual name (from mail_namespace_get_vname()) */
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen const char *vname;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct mail_storage *storage;
a94936bafd127680184da114c6a177b37ff656e5Timo Sirainen struct mailbox_list *list;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen
da2aa032ccfa8e7e4a4380ef738014549f4d2c2dTimo Sirainen struct mailbox_vfuncs v, *vlast;
9511a40d933181045343110c8101b75887062aaeTimo Sirainen/* private: */
9511a40d933181045343110c8101b75887062aaeTimo Sirainen pool_t pool, metadata_pool;
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen /* Linked list of all mailboxes in this storage */
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen struct mailbox *prev, *next;
411d6baa37f31d90730e90c4a28c43e1974bbe58Timo Sirainen
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen /* these won't be set until mailbox is opened: */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct mail_index *index;
struct mail_index_view *view;
struct mail_cache *cache;
/* Private per-user index/view for shared mailboxes. These are synced
against the primary index and used to store per-user flags.
These are non-NULL only when mailbox has per-user flags. */
struct mail_index *index_pvt;
struct mail_index_view *view_pvt;
/* Filled lazily by mailbox_get_permissions() */
struct mailbox_permissions _perm;
/* Filled lazily by mailbox_get_path() */
const char *_path;
/* default vfuncs for new struct mails. */
const struct mail_vfuncs *mail_vfuncs;
/* Mailbox settings, or NULL if defaults */
const struct mailbox_settings *set;
/* If non-zero, fail mailbox_open() with this error. mailbox_alloc()
can set this to force open to fail. */
enum mail_error open_error;
struct istream *input;
const char *index_prefix;
enum mailbox_flags flags;
unsigned int transaction_count;
enum mailbox_feature enabled_features;
struct mail_msgpart_partial_cache partial_cache;
struct mail_index_view *tmp_sync_view;
/* Mailbox notification settings: */
mailbox_notify_callback_t *notify_callback;
void *notify_context;
/* Increased by one for each new struct mailbox. */
unsigned int generation_sequence;
/* Saved search results */
ARRAY_DEFINE(search_results, struct mail_search_result *);
/* Module-specific contexts. See mail_storage_module_id. */
ARRAY_DEFINE(module_contexts, union mailbox_module_context *);
/* When FAST open flag is used, the mailbox isn't actually opened until
it's synced for the first time. */
unsigned int opened:1;
/* Mailbox was deleted while we had it open. */
unsigned int mailbox_deleted:1;
/* Mailbox is being created */
unsigned int creating:1;
/* Mailbox is being deleted */
unsigned int deleting:1;
/* Delete mailbox only if it's empty */
unsigned int deleting_must_be_empty:1;
/* Mailbox was already marked as deleted within this allocation. */
unsigned int marked_deleted:1;
/* TRUE if this is an INBOX for this user */
unsigned int inbox_user:1;
/* TRUE if this is an INBOX for this namespace (user or shared) */
unsigned int inbox_any:1;
/* When copying to this mailbox, require that mailbox_copy() uses
mailbox_save_*() to actually save a new physical copy rather than
simply incrementing a reference count (e.g. via hard link) */
unsigned int disable_reflink_copy_to:1;
/* Don't allow creating any new keywords */
unsigned int disallow_new_keywords:1;
/* Mailbox has been synced at least once */
unsigned int synced:1;
};
struct mail_vfuncs {
void (*close)(struct mail *mail);
void (*free)(struct mail *mail);
void (*set_seq)(struct mail *mail, uint32_t seq, bool saving);
bool (*set_uid)(struct mail *mail, uint32_t uid);
void (*set_uid_cache_updates)(struct mail *mail, bool set);
bool (*prefetch)(struct mail *mail);
void (*precache)(struct mail *mail);
void (*add_temp_wanted_fields)(struct mail *mail,
enum mail_fetch_field fields,
struct mailbox_header_lookup_ctx *headers);
enum mail_flags (*get_flags)(struct mail *mail);
const char *const *(*get_keywords)(struct mail *mail);
const ARRAY_TYPE(keyword_indexes) *
(*get_keyword_indexes)(struct mail *mail);
uint64_t (*get_modseq)(struct mail *mail);
int (*get_parts)(struct mail *mail,
struct message_part **parts_r);
int (*get_date)(struct mail *mail, time_t *date_r, int *timezone_r);
int (*get_received_date)(struct mail *mail, time_t *date_r);
int (*get_save_date)(struct mail *mail, time_t *date_r);
int (*get_virtual_size)(struct mail *mail, uoff_t *size_r);
int (*get_physical_size)(struct mail *mail, uoff_t *size_r);
int (*get_first_header)(struct mail *mail, const char *field,
bool decode_to_utf8, const char **value_r);
int (*get_headers)(struct mail *mail, const char *field,
bool decode_to_utf8, const char *const **value_r);
int (*get_header_stream)(struct mail *mail,
struct mailbox_header_lookup_ctx *headers,
struct istream **stream_r);
int (*get_stream)(struct mail *mail, bool get_body,
struct message_size *hdr_size,
struct message_size *body_size,
struct istream **stream_r);
int (*get_binary_stream)(struct mail *mail,
const struct message_part *part,
bool include_hdr, uoff_t *size_r,
bool *binary_r, struct istream **stream_r);
int (*get_special)(struct mail *mail, enum mail_fetch_field field,
const char **value_r);
struct mail *(*get_real_mail)(struct mail *mail);
void (*update_flags)(struct mail *mail, enum modify_type modify_type,
enum mail_flags flags);
void (*update_keywords)(struct mail *mail, enum modify_type modify_type,
struct mail_keywords *keywords);
void (*update_modseq)(struct mail *mail, uint64_t min_modseq);
void (*update_pop3_uidl)(struct mail *mail, const char *uidl);
void (*expunge)(struct mail *mail);
void (*set_cache_corrupted)(struct mail *mail,
enum mail_fetch_field field);
int (*istream_opened)(struct mail *mail, struct istream **input);
};
union mail_module_context {
struct mail_vfuncs super;
struct mail_module_register *reg;
};
struct mail_private {
struct mail mail;
struct mail_vfuncs v, *vlast;
uint32_t seq_pvt;
/* initial wanted fields/headers, set by mail_alloc(): */
enum mail_fetch_field wanted_fields;
struct mailbox_header_lookup_ctx *wanted_headers;
pool_t pool;
ARRAY_DEFINE(module_contexts, union mail_module_context *);
};
struct mailbox_list_context {
struct mail_storage *storage;
enum mailbox_list_flags flags;
bool failed;
};
union mailbox_transaction_module_context {
struct mail_storage_module_register *reg;
};
struct mailbox_transaction_stats {
unsigned long open_lookup_count;
unsigned long stat_lookup_count;
unsigned long fstat_lookup_count;
/* number of files we've opened and read */
unsigned long files_read_count;
/* number of bytes we've had to read from files */
unsigned long long files_read_bytes;
/* number of cache lookup hits */
unsigned long cache_hit_count;
};
struct mailbox_transaction_context {
struct mailbox *box;
enum mailbox_transaction_flags flags;
union mail_index_transaction_module_context module_ctx;
struct mail_index_transaction_vfuncs super;
int mail_ref_count;
struct mail_index_transaction *itrans;
/* view contains all changes done within this transaction */
struct mail_index_view *view;
/* for private index updates: */
struct mail_index_transaction *itrans_pvt;
struct mail_index_view *view_pvt;
struct mail_cache_view *cache_view;
struct mail_cache_transaction_ctx *cache_trans;
struct mail_transaction_commit_changes *changes;
ARRAY_DEFINE(module_contexts,
union mailbox_transaction_module_context *);
struct mail_save_context *save_ctx;
/* these statistics are never reset by mail-storage API: */
struct mailbox_transaction_stats stats;
/* Set to TRUE to update stats_* fields */
unsigned int stats_track:1;
/* We've done some non-transactional (e.g. dovecot-uidlist updates) */
unsigned int nontransactional_changes:1;
};
union mail_search_module_context {
struct mail_storage_module_register *reg;
};
struct mail_search_context {
struct mailbox_transaction_context *transaction;
struct mail_search_args *args;
struct mail_search_sort_program *sort_program;
enum mail_fetch_field wanted_fields;
struct mailbox_header_lookup_ctx *wanted_headers;
/* if non-NULL, specifies that a search resulting is being updated.
this can be used as a search optimization: if searched message
already exists in search result, it's not necessary to check if
static data matches. */
struct mail_search_result *update_result;
/* add matches to these search results */
ARRAY_DEFINE(results, struct mail_search_result *);
uint32_t seq;
uint32_t progress_cur, progress_max;
ARRAY_DEFINE(module_contexts, union mail_search_module_context *);
unsigned int seen_lost_data:1;
unsigned int progress_hidden:1;
};
struct mail_save_context {
struct mailbox_transaction_context *transaction;
struct mail *dest_mail;
enum mail_flags flags;
struct mail_keywords *keywords;
uint64_t min_modseq;
time_t received_date, save_date;
int received_tz_offset;
uint32_t uid;
char *guid, *pop3_uidl, *from_envelope;
struct ostream *output;
unsigned int pop3_order;
struct mail_save_attachment *attach;
/* returns TRUE if message part is an attachment. */
bool (*part_is_attachment)(struct mail_save_context *ctx,
const struct mail_attachment_part *part);
/* mail was copied using saving */
unsigned int copying_via_save:1;
/* mail is being saved, not copied */
unsigned int saving:1;
/* mail is being moved - ignore quota */
unsigned int moving:1;
};
struct mailbox_sync_context {
struct mailbox *box;
enum mailbox_sync_flags flags;
};
struct mailbox_header_lookup_ctx {
struct mailbox *box;
pool_t pool;
int refcount;
unsigned int count;
const char *const *name;
unsigned int *idx;
};
/* Modules should use do "my_id = mail_storage_module_id++" and
use objects' module_contexts[id] for their own purposes. */
extern struct mail_storage_module_register mail_storage_module_register;
/* Storage's module_id for mail_index. */
extern struct mail_module_register mail_module_register;
#define MAIL_STORAGE_CONTEXT(obj) \
MODULE_CONTEXT(obj, mail_storage_mail_index_module)
extern MODULE_CONTEXT_DEFINE(mail_storage_mail_index_module,
&mail_index_module_register);
void mail_storage_obj_ref(struct mail_storage *storage);
void mail_storage_obj_unref(struct mail_storage *storage);
/* Set error message in storage. Critical errors are logged with i_error(),
but user sees only "internal error" message. */
void mail_storage_clear_error(struct mail_storage *storage);
void mail_storage_set_error(struct mail_storage *storage,
enum mail_error error, const char *string);
void mail_storage_set_critical(struct mail_storage *storage,
const char *fmt, ...) ATTR_FORMAT(2, 3);
void mail_storage_set_internal_error(struct mail_storage *storage);
void mail_storage_set_index_error(struct mailbox *box);
bool mail_storage_set_error_from_errno(struct mail_storage *storage);
void mail_storage_copy_list_error(struct mail_storage *storage,
struct mailbox_list *list);
/* Returns TRUE if everything should already be in memory after this call. */
bool mail_prefetch(struct mail *mail);
void mail_set_aborted(struct mail *mail);
void mail_set_expunged(struct mail *mail);
void mail_set_seq_saving(struct mail *mail, uint32_t seq);
void mailbox_set_deleted(struct mailbox *box);
int mailbox_mark_index_deleted(struct mailbox *box, bool del);
/* Easy wrapper for getting mailbox's MAILBOX_LIST_PATH_TYPE_MAILBOX */
const char *mailbox_get_path(struct mailbox *box) ATTR_PURE;
/* Get mailbox permissions. */
const struct mailbox_permissions *mailbox_get_permissions(struct mailbox *box);
/* Force permissions to be refreshed on next lookup */
void mailbox_refresh_permissions(struct mailbox *box);
/* Returns -1 if error, 0 if failed with EEXIST, 1 if ok */
int mailbox_create_fd(struct mailbox *box, const char *path, int flags,
int *fd_r);
unsigned int mail_storage_get_lock_timeout(struct mail_storage *storage,
unsigned int secs);
void mail_storage_free_binary_cache(struct mail_storage *storage);
#endif