mail-storage-private.h revision ccc895c0358108d2304239063e940b7d75f364ab
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#ifndef __MAIL_STORAGE_PRIVATE_H
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen#define __MAIL_STORAGE_PRIVATE_H
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen#include "module-context.h"
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen#include "file-lock.h"
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen#include "mail-storage.h"
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen#include "mail-index-private.h"
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen/* Called after mail storage has been created */
2ed2459dbd183bb371da4a0aecb2d2b74ae7c815Timo Sirainenextern void (*hook_mail_storage_created)(struct mail_storage *storage);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen/* Called after mailbox has been opened */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainenextern void (*hook_mailbox_opened)(struct mailbox *box);
ac4e6609cbdca594db1b1c02afb1e372ab22e060Timo Sirainen
ac4e6609cbdca594db1b1c02afb1e372ab22e060Timo Sirainenstruct mail_storage_module_register {
ac4e6609cbdca594db1b1c02afb1e372ab22e060Timo Sirainen unsigned int id;
ac4e6609cbdca594db1b1c02afb1e372ab22e060Timo Sirainen};
ac4e6609cbdca594db1b1c02afb1e372ab22e060Timo Sirainen
ac4e6609cbdca594db1b1c02afb1e372ab22e060Timo Sirainenstruct mail_module_register {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen unsigned int id;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen};
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainenstruct mail_storage_vfuncs {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen void (*class_init)(void);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen void (*class_deinit)(void);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen struct mail_storage *
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen (*create)(const char *data, const char *user,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen enum mail_storage_flags flags,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen enum file_lock_method lock_method);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen void (*destroy)(struct mail_storage *storage);
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen bool (*autodetect)(const char *data, enum mail_storage_flags flags);
2ed2459dbd183bb371da4a0aecb2d2b74ae7c815Timo Sirainen
2ed2459dbd183bb371da4a0aecb2d2b74ae7c815Timo Sirainen void (*set_callbacks)(struct mail_storage *storage,
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen struct mail_storage_callbacks *callbacks,
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen void *context);
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen struct mailbox *(*mailbox_open)(struct mail_storage *storage,
910fa4e4204a73d3d24c03f3059dd24e727ca057Timo Sirainen const char *name,
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen struct istream *input,
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen enum mailbox_open_flags flags);
4321f6c969e7b8f6b243ff5bb6b8d297921676f6Timo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen int (*mailbox_create)(struct mail_storage *storage, const char *name,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen bool directory);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
56b134799a457fd55830355f4c8d746d6bb5206fTimo Sirainen const char *(*get_last_error)(struct mail_storage *storage,
56b134799a457fd55830355f4c8d746d6bb5206fTimo Sirainen bool *syntax_error_r,
56b134799a457fd55830355f4c8d746d6bb5206fTimo Sirainen bool *temporary_error_r);
a69dfb7f6f1a804a0c91fd5e506b78dd499cccd4Timo Sirainen};
2898ad0028a9b0c30df96dd6b68930fd4dc57527Timo Sirainen
2898ad0028a9b0c30df96dd6b68930fd4dc57527Timo Sirainenunion mail_storage_module_context {
a0cd302bcb827678f9c9c2ca1d0a3f0d3c0b3563Timo Sirainen struct mail_storage_vfuncs super;
a0cd302bcb827678f9c9c2ca1d0a3f0d3c0b3563Timo Sirainen struct mail_storage_module_register *reg;
a0cd302bcb827678f9c9c2ca1d0a3f0d3c0b3563Timo Sirainen};
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainenstruct mail_storage {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen const char *name;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen bool mailbox_is_file;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen struct mail_storage_vfuncs v;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen
7b85f7d35b2192bdff734d7d2891630bc30b2518Timo Sirainen/* private: */
9e9f0cf3cc3ce546e8a433990c92dd9be6665df6Timo Sirainen pool_t pool;
7b85f7d35b2192bdff734d7d2891630bc30b2518Timo Sirainen
7b85f7d35b2192bdff734d7d2891630bc30b2518Timo Sirainen char *error;
7b85f7d35b2192bdff734d7d2891630bc30b2518Timo Sirainen struct mailbox_list *list;
9e9f0cf3cc3ce546e8a433990c92dd9be6665df6Timo Sirainen
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen const char *user; /* name of user accessing the storage */
enum mail_storage_flags flags;
enum file_lock_method lock_method;
struct mail_storage_callbacks *callbacks;
void *callback_context;
/* Module-specific contexts. See mail_storage_module_id. */
ARRAY_DEFINE(module_contexts, union mail_storage_module_context *);
/* IMAP: Give a BAD reply instead of NO */
unsigned int syntax_error:1;
/* Internal temporary error, as opposed to visible user errors like
"permission denied" or "out of disk space" */
unsigned int temporary_error:1;
};
struct mailbox_vfuncs {
bool (*is_readonly)(struct mailbox *box);
bool (*allow_new_keywords)(struct mailbox *box);
int (*close)(struct mailbox *box);
int (*get_status)(struct mailbox *box, enum mailbox_status_items items,
struct mailbox_status *status);
struct mailbox_sync_context *
(*sync_init)(struct mailbox *box,
enum mailbox_sync_flags flags);
int (*sync_next)(struct mailbox_sync_context *ctx,
struct mailbox_sync_rec *sync_rec_r);
int (*sync_deinit)(struct mailbox_sync_context *ctx,
enum mailbox_status_items status_items,
struct mailbox_status *status_r);
void (*notify_changes)(struct mailbox *box, unsigned int min_interval,
mailbox_notify_callback_t *callback,
void *context);
struct mailbox_transaction_context *
(*transaction_begin)(struct mailbox *box,
enum mailbox_transaction_flags flags);
int (*transaction_commit)(struct mailbox_transaction_context *t,
enum mailbox_sync_flags flags);
void (*transaction_rollback)(struct mailbox_transaction_context *t);
struct mail_keywords *
(*keywords_create)(struct mailbox_transaction_context *t,
const char *const keywords[]);
void (*keywords_free)(struct mailbox_transaction_context *t,
struct mail_keywords *keywords);
int (*get_uids)(struct mailbox *box, uint32_t uid1, uint32_t uid2,
uint32_t *seq1_r, uint32_t *seq2_r);
struct mail *
(*mail_alloc)(struct mailbox_transaction_context *t,
enum mail_fetch_field wanted_fields,
struct mailbox_header_lookup_ctx *wanted_headers);
struct mailbox_header_lookup_ctx *
(*header_lookup_init)(struct mailbox *box,
const char *const headers[]);
void (*header_lookup_deinit)(struct mailbox_header_lookup_ctx *ctx);
struct mail_search_context *
(*search_init)(struct mailbox_transaction_context *t,
const char *charset, struct mail_search_arg *args,
const enum mail_sort_type *sort_program);
int (*search_deinit)(struct mail_search_context *ctx);
int (*search_next_nonblock)(struct mail_search_context *ctx,
struct mail *mail, bool *tryagain_r);
/* Internal search function which updates ctx->seq */
int (*search_next_update_seq)(struct mail_search_context *ctx);
int (*save_init)(struct mailbox_transaction_context *t,
enum mail_flags flags,
struct mail_keywords *keywords,
time_t received_date, int timezone_offset,
const char *from_envelope, struct istream *input,
struct mail *dest_mail,
struct mail_save_context **ctx_r);
int (*save_continue)(struct mail_save_context *ctx);
int (*save_finish)(struct mail_save_context *ctx);
void (*save_cancel)(struct mail_save_context *ctx);
int (*copy)(struct mailbox_transaction_context *t, struct mail *mail,
enum mail_flags flags, struct mail_keywords *keywords,
struct mail *dest_mail);
bool (*is_inconsistent)(struct mailbox *box);
};
union mailbox_module_context {
struct mailbox_vfuncs super;
struct mail_storage_module_register *reg;
};
struct mailbox {
char *name;
struct mail_storage *storage;
struct mailbox_vfuncs v;
/* private: */
pool_t pool;
unsigned int transaction_count;
/* 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;
};
struct mail_vfuncs {
void (*free)(struct mail *mail);
int (*set_seq)(struct mail *mail, uint32_t seq);
int (*set_uid)(struct mail *mail, uint32_t uid);
enum mail_flags (*get_flags)(struct mail *mail);
const char *const *(*get_keywords)(struct mail *mail);
const struct message_part *(*get_parts)(struct mail *mail);
time_t (*get_date)(struct mail *mail, int *timezone);
time_t (*get_received_date)(struct mail *mail);
time_t (*get_save_date)(struct mail *mail);
uoff_t (*get_virtual_size)(struct mail *mail);
uoff_t (*get_physical_size)(struct mail *mail);
const char *(*get_first_header)(struct mail *mail, const char *field);
const char *const *(*get_headers)(struct mail *mail, const char *field);
struct istream *
(*get_header_stream)(struct mail *mail,
struct mailbox_header_lookup_ctx *headers);
struct istream *(*get_stream)(struct mail *mail,
struct message_size *hdr_size,
struct message_size *body_size);
const char *(*get_special)(struct mail *mail,
enum mail_fetch_field field);
int (*update_flags)(struct mail *mail, enum modify_type modify_type,
enum mail_flags flags);
int (*update_keywords)(struct mail *mail, enum modify_type modify_type,
struct mail_keywords *keywords);
int (*expunge)(struct mail *mail);
};
union mail_module_context {
struct mail_vfuncs super;
struct mail_module_register *reg;
};
struct mail_private {
struct mail mail;
struct mail_vfuncs v;
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_context {
struct mailbox *box;
ARRAY_DEFINE(module_contexts,
union mailbox_transaction_module_context *);
};
union mail_search_module_context {
struct mail_storage_module_register *reg;
};
struct mail_search_context {
struct mailbox_transaction_context *transaction;
char *charset;
struct mail_search_arg *args;
struct mail_search_sort_program *sort_program;
uint32_t seq;
ARRAY_DEFINE(module_contexts, union mail_search_module_context *);
};
struct mail_save_context {
struct mailbox_transaction_context *transaction;
struct mail *dest_mail;
};
struct mailbox_sync_context {
struct mailbox *box;
};
struct mailbox_header_lookup_ctx {
struct mailbox *box;
};
/* 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);
/* 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,
const char *fmt, ...) __attr_format__(2, 3);
void mail_storage_set_syntax_error(struct mail_storage *storage,
const char *fmt, ...) __attr_format__(2, 3);
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);
const char *mail_storage_class_get_last_error(struct mail_storage *storage,
bool *syntax_error_r);
enum mailbox_list_flags
mail_storage_get_list_flags(enum mail_storage_flags storage_flags);
bool mail_storage_errno2str(const char **error_r);
#endif