mail_user_add_plugin_hooks(user);
+ user->vlast = &user->v;
array_foreach(&user->hooks, hooks) {
if ((*hooks)->mail_user_created != NULL)
(*hooks)->mail_user_created(user);
{
const struct mail_storage_hooks *const *hooks;
+ storage->vlast = &storage->v;
array_foreach(&storage->user->hooks, hooks) {
if ((*hooks)->mail_storage_created != NULL)
(*hooks)->mail_storage_created(storage);
{
const struct mail_storage_hooks *const *hooks;
+ list->vlast = &list->v;
array_foreach(&list->ns->user->hooks, hooks) {
if ((*hooks)->mailbox_list_created != NULL)
(*hooks)->mailbox_list_created(list);
{
const struct mail_storage_hooks *const *hooks;
+ box->vlast = &box->v;
array_foreach(&box->storage->user->hooks, hooks) {
if ((*hooks)->mailbox_allocated != NULL)
(*hooks)->mailbox_allocated(box);
(*hooks)->mailbox_opened(box);
}
}
+
+void hook_mail_allocated(struct mail *mail)
+{
+ const struct mail_storage_hooks *const *hooks;
+ struct mail_private *pmail = (struct mail_private *)mail;
+
+ pmail->vlast = &pmail->v;
+ array_foreach(&mail->box->storage->user->hooks, hooks) {
+ if ((*hooks)->mail_allocated != NULL)
+ (*hooks)->mail_allocated(mail);
+ }
+}
struct mail_namespace;
struct mailbox_list;
struct mailbox;
+struct mail;
struct mail_storage_hooks {
void (*mail_user_created)(struct mail_user *user);
void (*mailbox_list_created)(struct mailbox_list *list);
void (*mailbox_allocated)(struct mailbox *box);
void (*mailbox_opened)(struct mailbox *box);
+ void (*mail_allocated)(struct mail *mail);
};
void mail_storage_hooks_init(void);
void hook_mailbox_list_created(struct mailbox_list *list);
void hook_mailbox_allocated(struct mailbox *box);
void hook_mailbox_opened(struct mailbox *box);
+void hook_mail_allocated(struct mail *mail);
#endif
const char *name;
enum mail_storage_class_flags class_flags;
- struct mail_storage_vfuncs v;
+ struct mail_storage_vfuncs v, *vlast;
/* private: */
pool_t pool;
struct mail_storage *storage;
struct mailbox_list *list;
- struct mailbox_vfuncs v;
+ struct mailbox_vfuncs v, *vlast;
/* private: */
pool_t pool;
struct mail_private {
struct mail mail;
- struct mail_vfuncs v;
+ struct mail_vfuncs v, *vlast;
enum mail_fetch_field wanted_fields;
struct mailbox_header_lookup_ctx *wanted_headers;
struct mail_user {
pool_t pool;
- struct mail_user_vfuncs v;
+ struct mail_user_vfuncs v, *vlast;
int refcount;
const char *username;
enum mail_fetch_field wanted_fields,
struct mailbox_header_lookup_ctx *wanted_headers)
{
- return t->box->v.mail_alloc(t, wanted_fields, wanted_headers);
+ struct mail *mail;
+
+ T_BEGIN {
+ mail = t->box->v.mail_alloc(t, wanted_fields, wanted_headers);
+ hook_mail_allocated(mail);
+ } T_END;
+
+ return mail;
}
void mail_free(struct mail **mail)
enum mailbox_list_properties props;
size_t mailbox_name_max_length;
- struct mailbox_list_vfuncs v;
+ struct mailbox_list_vfuncs v, *vlast;
/* private: */
pool_t pool;
static void acl_mailbox_list_init_shared(struct mailbox_list *list)
{
struct acl_mailbox_list *alist;
+ struct mailbox_list_vfuncs *v = list->vlast;
alist = p_new(list->pool, struct acl_mailbox_list, 1);
- alist->module_ctx.super = list->v;
- list->v.iter_init = acl_mailbox_list_iter_init_shared;
+ alist->module_ctx.super = *v;
+ list->vlast = &alist->module_ctx.super;
+ v->iter_init = acl_mailbox_list_iter_init_shared;
MODULE_CONTEXT_SET(list, acl_mailbox_list_module, alist);
}
static void acl_mailbox_list_init_default(struct mailbox_list *list)
{
struct acl_user *auser = ACL_USER_CONTEXT(list->ns->user);
+ struct mailbox_list_vfuncs *v = list->vlast;
struct acl_mailbox_list *alist;
struct acl_backend *backend;
struct mail_namespace *ns;
}
alist = p_new(list->pool, struct acl_mailbox_list, 1);
- alist->module_ctx.super = list->v;
- list->v.iter_init = acl_mailbox_list_iter_init;
- list->v.iter_next = acl_mailbox_list_iter_next;
- list->v.iter_deinit = acl_mailbox_list_iter_deinit;
- list->v.get_mailbox_name_status = acl_get_mailbox_name_status;
- list->v.create_mailbox_dir = acl_mailbox_list_create_dir;
+ alist->module_ctx.super = *v;
+ list->vlast = &alist->module_ctx.super;
+ v->iter_init = acl_mailbox_list_iter_init;
+ v->iter_next = acl_mailbox_list_iter_next;
+ v->iter_deinit = acl_mailbox_list_iter_deinit;
+ v->get_mailbox_name_status = acl_get_mailbox_name_status;
+ v->create_mailbox_dir = acl_mailbox_list_create_dir;
acl_storage_rights_ctx_init(&alist->rights, backend);
MODULE_CONTEXT_SET(list, acl_mailbox_list_module, alist);
union mailbox_module_context module_ctx;
struct acl_object *aclobj;
bool skip_acl_checks;
+ bool acl_enabled;
};
struct acl_transaction_context {
amail->super.expunge(_mail);
}
-static struct mail *
-acl_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+void acl_mail_allocated(struct mail *_mail)
{
- struct acl_mailbox *abox = ACL_CONTEXT(t->box);
+ struct acl_mailbox *abox = ACL_CONTEXT(_mail->box);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
union mail_module_context *amail;
- struct mail *_mail;
- struct mail_private *mail;
- _mail = abox->module_ctx.super.
- mail_alloc(t, wanted_fields, wanted_headers);
- mail = (struct mail_private *)_mail;
+ if (abox == NULL || !abox->acl_enabled)
+ return;
amail = p_new(mail->pool, union mail_module_context, 1);
- amail->super = mail->v;
+ amail->super = *v;
+ mail->vlast = &amail->super;
- mail->v.update_flags = acl_mail_update_flags;
- mail->v.update_keywords = acl_mail_update_keywords;
- mail->v.expunge = acl_mail_expunge;
+ v->update_flags = acl_mail_update_flags;
+ v->update_keywords = acl_mail_update_keywords;
+ v->expunge = acl_mail_expunge;
MODULE_CONTEXT_SET_SELF(mail, acl_mail_module, amail);
- return _mail;
}
static int acl_save_get_flags(struct mailbox *box, enum mail_flags *flags,
void acl_mailbox_allocated(struct mailbox *box)
{
struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
+ struct mailbox_vfuncs *v = box->vlast;
struct acl_mailbox *abox;
if (alist == NULL) {
}
abox = p_new(box->pool, struct acl_mailbox, 1);
- abox->module_ctx.super = box->v;
+ abox->module_ctx.super = *v;
+ box->vlast = &abox->module_ctx.super;
abox->aclobj = acl_object_init_from_name(alist->rights.backend,
mailbox_get_name(box));
if ((box->flags & MAILBOX_FLAG_IGNORE_ACLS) == 0) {
- box->v.is_readonly = acl_is_readonly;
- box->v.allow_new_keywords = acl_allow_new_keywords;
- box->v.open = acl_mailbox_open;
- box->v.free = acl_mailbox_free;
- box->v.create = acl_mailbox_create;
- box->v.update = acl_mailbox_update;
- box->v.delete = acl_mailbox_delete;
- box->v.rename = acl_mailbox_rename;
- box->v.mail_alloc = acl_mail_alloc;
- box->v.save_begin = acl_save_begin;
- box->v.keywords_create = acl_keywords_create;
- box->v.copy = acl_copy;
- box->v.transaction_commit = acl_transaction_commit;
+ abox->acl_enabled = TRUE;
+ v->is_readonly = acl_is_readonly;
+ v->allow_new_keywords = acl_allow_new_keywords;
+ v->open = acl_mailbox_open;
+ v->free = acl_mailbox_free;
+ v->create = acl_mailbox_create;
+ v->update = acl_mailbox_update;
+ v->delete = acl_mailbox_delete;
+ v->rename = acl_mailbox_rename;
+ v->save_begin = acl_save_begin;
+ v->keywords_create = acl_keywords_create;
+ v->copy = acl_copy;
+ v->transaction_commit = acl_transaction_commit;
}
MODULE_CONTEXT_SET(box, acl_storage_module, abox);
}
static struct mail_storage_hooks acl_mail_storage_hooks = {
.mail_user_created = acl_mail_user_created,
.mail_namespace_storage_added = acl_mail_namespace_storage_added,
- .mailbox_allocated = acl_mailbox_allocated
+ .mailbox_allocated = acl_mailbox_allocated,
+ .mail_allocated = acl_mail_allocated
};
void acl_plugin_init(struct module *module)
void acl_mail_user_created(struct mail_user *list);
void acl_mailbox_allocated(struct mailbox *box);
+void acl_mail_allocated(struct mail *mail);
struct acl_backend *acl_mailbox_list_get_backend(struct mailbox_list *list);
int acl_mailbox_list_have_right(struct mailbox_list *list, const char *name,
static void acl_mail_user_create(struct mail_user *user, const char *env)
{
+ struct mail_user_vfuncs *v = user->vlast;
struct acl_user *auser;
auser = p_new(user->pool, struct acl_user, 1);
- auser->module_ctx.super = user->v;
- user->v.deinit = acl_user_deinit;
+ auser->module_ctx.super = *v;
+ user->vlast = &auser->module_ctx.super;
+ v->deinit = acl_user_deinit;
auser->acl_lookup_dict = acl_lookup_dict_init(user);
auser->acl_env = env;
xpr_mail->super.expunge(_mail);
}
-static struct mail *
-expire_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+static void expire_mail_allocated(struct mail *_mail)
{
- struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(t->box);
+ struct expire_mailbox *xpr_box = EXPIRE_CONTEXT(_mail->box);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
union mail_module_context *xpr_mail;
- struct mail *_mail;
- struct mail_private *mail;
- _mail = xpr_box->module_ctx.super.
- mail_alloc(t, wanted_fields, wanted_headers);
- mail = (struct mail_private *)_mail;
+ if (xpr_box == NULL)
+ return;
xpr_mail = p_new(mail->pool, union mail_module_context, 1);
- xpr_mail->super = mail->v;
+ xpr_mail->super = *v;
+ mail->vlast = &xpr_mail->super;
- mail->v.expunge = expire_mail_expunge;
+ v->expunge = expire_mail_expunge;
MODULE_CONTEXT_SET_SELF(mail, expire_mail_module, xpr_mail);
- return _mail;
}
static int expire_save_finish(struct mail_save_context *ctx)
static void expire_mailbox_allocate_init(struct mailbox *box)
{
+ struct mailbox_vfuncs *v = box->vlast;
struct expire_mailbox *xpr_box;
xpr_box = p_new(box->pool, struct expire_mailbox, 1);
- xpr_box->module_ctx.super = box->v;
+ xpr_box->module_ctx.super = *v;
+ box->vlast = &xpr_box->module_ctx.super;
- box->v.transaction_begin = expire_mailbox_transaction_begin;
- box->v.transaction_commit = expire_mailbox_transaction_commit;
- box->v.transaction_rollback = expire_mailbox_transaction_rollback;
- box->v.mail_alloc = expire_mail_alloc;
- box->v.save_finish = expire_save_finish;
- box->v.copy = expire_copy;
+ v->transaction_begin = expire_mailbox_transaction_begin;
+ v->transaction_commit = expire_mailbox_transaction_commit;
+ v->transaction_rollback = expire_mailbox_transaction_rollback;
+ v->save_finish = expire_save_finish;
+ v->copy = expire_copy;
MODULE_CONTEXT_SET(box, expire_storage_module, xpr_box);
}
} else if (dict_uri == NULL) {
i_error("expire plugin: expire_dict setting missing");
} else {
+ struct mail_user_vfuncs *v = user->vlast;
+
euser = p_new(user->pool, struct expire_mail_user, 1);
- euser->module_ctx.super = user->v;
- user->v.deinit = expire_mail_user_deinit;
+ euser->module_ctx.super = *v;
+ user->vlast = &euser->module_ctx.super;
+ v->deinit = expire_mail_user_deinit;
euser->set = expire_set_init(expire_get_patterns(user));
/* we're using only shared dictionary, the username
static struct mail_storage_hooks expire_mail_storage_hooks = {
.mail_namespaces_created = expire_mail_namespaces_created,
- .mailbox_allocated = expire_mailbox_allocated
+ .mailbox_allocated = expire_mailbox_allocated,
+ .mail_allocated = expire_mail_allocated
};
void expire_plugin_init(struct module *module)
struct fts_solr_user *fuser;
fuser = p_new(user->pool, struct fts_solr_user, 1);
- fuser->module_ctx.super = user->v;
if (fts_solr_plugin_init_settings(user, &fuser->set, env) < 0) {
/* invalid settings, disabling */
return;
const char *fts_plugin_version = DOVECOT_VERSION;
static struct mail_storage_hooks fts_mail_storage_hooks = {
- .mailbox_allocated = fts_mailbox_allocated
+ .mailbox_allocated = fts_mailbox_allocated,
+ .mail_allocated = fts_mail_allocated
};
void fts_plugin_init(struct module *module)
#define FTS_PLUGIN_H
void fts_mailbox_allocated(struct mailbox *box);
+void fts_mail_allocated(struct mail *mail);
void fts_plugin_init(struct module *module);
void fts_plugin_deinit(void);
return fmail->module_ctx.super.get_special(_mail, field, value_r);
}
-static struct mail *
-fts_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+void fts_mail_allocated(struct mail *_mail)
{
- struct fts_mailbox *fbox = FTS_CONTEXT(t->box);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
+ struct fts_mailbox *fbox = FTS_CONTEXT(_mail->box);
struct fts_mail *fmail;
- struct mail *_mail;
- struct mail_private *mail;
- _mail = fbox->module_ctx.super.
- mail_alloc(t, wanted_fields, wanted_headers);
- if (fbox->backend_substr != NULL || fbox->backend_fast != NULL) {
- mail = (struct mail_private *)_mail;
+ if (fbox == NULL ||
+ (fbox->backend_substr == NULL && fbox->backend_fast == NULL))
+ return;
- fmail = p_new(mail->pool, struct fts_mail, 1);
- fmail->module_ctx.super = mail->v;
+ fmail = p_new(mail->pool, struct fts_mail, 1);
+ fmail->module_ctx.super = *v;
+ mail->vlast = &fmail->module_ctx.super;
- mail->v.expunge = fts_mail_expunge;
- mail->v.get_special = fts_mail_get_special;
- MODULE_CONTEXT_SET(mail, fts_mail_module, fmail);
- }
- return _mail;
+ v->expunge = fts_mail_expunge;
+ v->get_special = fts_mail_get_special;
+ MODULE_CONTEXT_SET(mail, fts_mail_module, fmail);
}
static void fts_box_backends_init(struct mailbox *box)
static void fts_mailbox_init(struct mailbox *box, const char *env)
{
+ struct mailbox_vfuncs *v = box->vlast;
struct fts_mailbox *fbox;
fbox = i_new(struct fts_mailbox, 1);
fbox->virtual = strcmp(box->storage->name, "virtual") == 0;
fbox->env = env;
- fbox->module_ctx.super = box->v;
- box->v.free = fts_mailbox_free;
- box->v.search_init = fts_mailbox_search_init;
- box->v.search_next_nonblock = fts_mailbox_search_next_nonblock;
- box->v.search_next_update_seq = fbox->virtual ?
+ fbox->module_ctx.super = *v;
+ box->vlast = &fbox->module_ctx.super;
+
+ v->free = fts_mailbox_free;
+ v->search_init = fts_mailbox_search_init;
+ v->search_next_nonblock = fts_mailbox_search_next_nonblock;
+ v->search_next_update_seq = fbox->virtual ?
fts_mailbox_search_next_update_seq_virtual :
fts_mailbox_search_next_update_seq;
- box->v.search_deinit = fts_mailbox_search_deinit;
- box->v.mail_alloc = fts_mail_alloc;
- box->v.transaction_begin = fts_transaction_begin;
- box->v.transaction_rollback = fts_transaction_rollback;
- box->v.transaction_commit = fts_transaction_commit;
+ v->search_deinit = fts_mailbox_search_deinit;
+ v->transaction_begin = fts_transaction_begin;
+ v->transaction_rollback = fts_transaction_rollback;
+ v->transaction_commit = fts_transaction_commit;
MODULE_CONTEXT_SET(box, fts_storage_module, fbox);
}
lazy_expunge_transaction_free(lt);
}
-static struct mail *
-lazy_expunge_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+static void lazy_expunge_mail_allocated(struct mail *_mail)
{
- union mailbox_module_context *mbox = LAZY_EXPUNGE_CONTEXT(t->box);
+ struct lazy_expunge_transaction *lt =
+ LAZY_EXPUNGE_CONTEXT(_mail->transaction);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
union mail_module_context *mmail;
- struct mail *_mail;
- struct mail_private *mail;
- _mail = mbox->super.mail_alloc(t, wanted_fields, wanted_headers);
- mail = (struct mail_private *)_mail;
+ if (lt == NULL)
+ return;
mmail = p_new(mail->pool, union mail_module_context, 1);
- mmail->super = mail->v;
+ mmail->super = *v;
+ mail->vlast = &mmail->super;
- mail->v.expunge = lazy_expunge_mail_expunge;
+ v->expunge = lazy_expunge_mail_expunge;
MODULE_CONTEXT_SET_SELF(mail, lazy_expunge_mail_module, mmail);
- return _mail;
}
static int
struct lazy_expunge_mailbox_list *llist =
LAZY_EXPUNGE_LIST_CONTEXT(box->list);
union mailbox_module_context *mbox;
+ struct mailbox_vfuncs *v = box->vlast;
if (llist == NULL)
return;
mbox = p_new(box->pool, union mailbox_module_context, 1);
- mbox->super = box->v;
+ mbox->super = *v;
+ box->vlast = &mbox->super;
MODULE_CONTEXT_SET_SELF(box, lazy_expunge_mail_storage_module, mbox);
if (!llist->internal_namespace) {
- box->v.transaction_begin = lazy_expunge_transaction_begin;
- box->v.transaction_commit = lazy_expunge_transaction_commit;
- box->v.transaction_rollback = lazy_expunge_transaction_rollback;
- box->v.mail_alloc = lazy_expunge_mail_alloc;
- box->v.delete = lazy_expunge_mailbox_delete;
- box->v.rename = lazy_expunge_mailbox_rename;
+ v->transaction_begin = lazy_expunge_transaction_begin;
+ v->transaction_commit = lazy_expunge_transaction_commit;
+ v->transaction_rollback = lazy_expunge_transaction_rollback;
+ v->delete = lazy_expunge_mailbox_delete;
+ v->rename = lazy_expunge_mailbox_rename;
} else {
- box->v.rename = lazy_expunge_mailbox_rename;
+ v->rename = lazy_expunge_mailbox_rename;
}
}
if (luser != NULL && ns->type == NAMESPACE_PRIVATE) {
llist = p_new(list->pool, struct lazy_expunge_mailbox_list, 1);
- llist->module_ctx.super = list->v;
-
MODULE_CONTEXT_SET(list, lazy_expunge_mailbox_list_module,
llist);
}
env = mail_user_plugin_getenv(user, "lazy_expunge");
if (env != NULL) {
luser = p_new(user->pool, struct lazy_expunge_mail_user, 1);
- luser->module_ctx.super = user->v;
luser->env = env;
MODULE_CONTEXT_SET(user, lazy_expunge_mail_user_module, luser);
.mail_user_created = lazy_expunge_mail_user_created,
.mail_namespaces_created = lazy_expunge_mail_namespaces_created,
.mail_namespace_storage_added = lazy_expunge_mail_namespace_storage_added,
- .mailbox_allocated = lazy_expunge_mailbox_allocated
+ .mailbox_allocated = lazy_expunge_mailbox_allocated,
+ .mail_allocated = lazy_expunge_mail_allocated
};
void lazy_expunge_plugin_init(struct module *module)
static void listescape_mail_storage_created(struct mail_storage *storage)
{
struct listescape_mail_storage *mstorage;
+ struct mail_storage_vfuncs *v = storage->vlast;
mstorage = p_new(storage->pool, struct listescape_mail_storage, 1);
- mstorage->module_ctx.super = storage->v;
- storage->v.mailbox_alloc = listescape_mailbox_alloc;
+ mstorage->module_ctx.super = *v;
+ storage->vlast = &mstorage->module_ctx.super;
+ v->mailbox_alloc = listescape_mailbox_alloc;
MODULE_CONTEXT_SET(storage, listescape_storage_module, mstorage);
}
static void listescape_mail_namespace_storage_added(struct mail_namespace *ns)
{
struct mailbox_list *list = ns->list;
+ struct mailbox_list_vfuncs *v = list->vlast;
struct listescape_mailbox_list *mlist;
const char *env;
ns->real_sep = ns->sep;
mlist = p_new(list->pool, struct listescape_mailbox_list, 1);
- mlist->module_ctx.super = list->v;
+ mlist->module_ctx.super = *v;
+ list->vlast = &mlist->module_ctx.super;
mlist->list_name = str_new(list->pool, 256);
- list->v.iter_init = listescape_mailbox_list_iter_init;
- list->v.iter_next = listescape_mailbox_list_iter_next;
- list->v.iter_deinit = listescape_mailbox_list_iter_deinit;
- list->v.set_subscribed = listescape_set_subscribed;
- list->v.get_mailbox_name_status = listescape_get_mailbox_name_status;
- list->v.is_valid_existing_name = listescape_is_valid_existing_name;
- list->v.is_valid_create_name = listescape_is_valid_create_name;
+ v->iter_init = listescape_mailbox_list_iter_init;
+ v->iter_next = listescape_mailbox_list_iter_next;
+ v->iter_deinit = listescape_mailbox_list_iter_deinit;
+ v->set_subscribed = listescape_set_subscribed;
+ v->get_mailbox_name_status = listescape_get_mailbox_name_status;
+ v->is_valid_existing_name = listescape_is_valid_existing_name;
+ v->is_valid_create_name = listescape_is_valid_create_name;
env = mail_user_plugin_getenv(list->ns->user, "listescape_char");
mlist->escape_char = env != NULL && *env != '\0' ?
mbox_snarf_mail_storage_create(struct mail_storage *storage, const char *path)
{
struct mbox_snarf_mail_storage *mstorage;
+ struct mail_storage_vfuncs *v = storage->vlast;
path = mail_user_home_expand(storage->user, path);
mstorage = p_new(storage->pool, struct mbox_snarf_mail_storage, 1);
mstorage->snarf_inbox_path = p_strdup(storage->pool, path);
- mstorage->module_ctx.super = storage->v;
- storage->v.mailbox_alloc = mbox_snarf_mailbox_alloc;
+ mstorage->module_ctx.super = *v;
+ storage->vlast = &mstorage->module_ctx.super;
+ v->mailbox_alloc = mbox_snarf_mailbox_alloc;
MODULE_CONTEXT_SET(storage, mbox_snarf_storage_module, mstorage);
}
notify_contexts_mail_update_keywords(_mail, old_keywords);
}
-static struct mail *
-notify_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+static void notify_mail_allocated(struct mail *_mail)
{
- union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
union mail_module_context *lmail;
- struct mail *_mail;
- struct mail_private *mail;
-
- _mail = lbox->super.mail_alloc(t, wanted_fields, wanted_headers);
- mail = (struct mail_private *)_mail;
lmail = p_new(mail->pool, union mail_module_context, 1);
- lmail->super = mail->v;
+ lmail->super = *v;
+ mail->vlast = &lmail->super;
- mail->v.expunge = notify_mail_expunge;
- mail->v.update_flags = notify_mail_update_flags;
- mail->v.update_keywords = notify_mail_update_keywords;
+ v->expunge = notify_mail_expunge;
+ v->update_flags = notify_mail_update_flags;
+ v->update_keywords = notify_mail_update_keywords;
MODULE_CONTEXT_SET_SELF(mail, notify_mail_module, lmail);
- return _mail;
}
static int
static void notify_mailbox_allocated(struct mailbox *box)
{
+ struct mailbox_vfuncs *v = box->vlast;
union mailbox_module_context *lbox;
lbox = p_new(box->pool, union mailbox_module_context, 1);
- lbox->super = box->v;
-
- box->v.mail_alloc = notify_mail_alloc;
- box->v.copy = notify_copy;
- box->v.save_begin = notify_save_begin;
- box->v.save_finish = notify_save_finish;
- box->v.transaction_begin = notify_transaction_begin;
- box->v.transaction_commit = notify_transaction_commit;
- box->v.transaction_rollback = notify_transaction_rollback;
- box->v.delete = notify_mailbox_delete;
- box->v.rename = notify_mailbox_rename;
+ lbox->super = *v;
+ box->vlast = &lbox->super;
+
+ v->copy = notify_copy;
+ v->save_begin = notify_save_begin;
+ v->save_finish = notify_save_finish;
+ v->transaction_begin = notify_transaction_begin;
+ v->transaction_commit = notify_transaction_commit;
+ v->transaction_rollback = notify_transaction_rollback;
+ v->delete = notify_mailbox_delete;
+ v->rename = notify_mailbox_rename;
MODULE_CONTEXT_SET_SELF(box, notify_storage_module, lbox);
}
static struct mail_storage_hooks notify_mail_storage_hooks = {
- .mailbox_allocated = notify_mailbox_allocated
+ .mailbox_allocated = notify_mailbox_allocated,
+ .mail_allocated = notify_mail_allocated
};
void notify_plugin_init_storage(struct module *module)
.mail_user_created = quota_mail_user_created,
.mail_namespaces_created = quota_mail_namespaces_created,
.mail_namespace_storage_added = quota_mail_namespace_storage_added,
- .mailbox_allocated = quota_mailbox_allocated
+ .mailbox_allocated = quota_mailbox_allocated,
+ .mail_allocated = quota_mail_allocated
};
void quota_plugin_init(struct module *module)
struct module;
struct mailbox;
+struct mail;
#define QUOTA_USER_CONTEXT(obj) \
MODULE_CONTEXT(obj, quota_user_module)
void quota_mail_namespace_storage_added(struct mail_namespace *ns);
void quota_mail_namespaces_created(struct mail_namespace *namespaces);
void quota_mailbox_allocated(struct mailbox *box);
+void quota_mail_allocated(struct mail *mail);
void quota_plugin_init(struct module *module);
void quota_plugin_deinit(void);
quota_transaction_rollback(&qt);
}
-static struct mail *
-quota_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+void quota_mail_allocated(struct mail *_mail)
{
- struct quota_mailbox *qbox = QUOTA_CONTEXT(t->box);
+ struct quota_mailbox *qbox = QUOTA_CONTEXT(_mail->box);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
union mail_module_context *qmail;
- struct mail *_mail;
- struct mail_private *mail;
- _mail = qbox->module_ctx.super.
- mail_alloc(t, wanted_fields, wanted_headers);
- mail = (struct mail_private *)_mail;
+ if (qbox == NULL)
+ return;
qmail = p_new(mail->pool, union mail_module_context, 1);
- qmail->super = mail->v;
+ qmail->super = *v;
+ mail->vlast = &qmail->super;
- mail->v.expunge = quota_mail_expunge;
+ v->expunge = quota_mail_expunge;
MODULE_CONTEXT_SET_SELF(mail, quota_mail_module, qmail);
- return _mail;
}
static int quota_check(struct mailbox_transaction_context *t, struct mail *mail)
void quota_mailbox_allocated(struct mailbox *box)
{
+ struct mailbox_vfuncs *v = box->vlast;
struct quota_mailbox *qbox;
if (QUOTA_LIST_CONTEXT(box->list) == NULL)
return;
qbox = p_new(box->pool, struct quota_mailbox, 1);
- qbox->module_ctx.super = box->v;
-
- box->v.transaction_begin = quota_mailbox_transaction_begin;
- box->v.transaction_commit = quota_mailbox_transaction_commit;
- box->v.transaction_rollback = quota_mailbox_transaction_rollback;
- box->v.mail_alloc = quota_mail_alloc;
- box->v.save_begin = quota_save_begin;
- box->v.save_finish = quota_save_finish;
- box->v.copy = quota_copy;
- box->v.sync_notify = quota_mailbox_sync_notify;
- box->v.sync_deinit = quota_mailbox_sync_deinit;
- box->v.delete = quota_mailbox_delete;
- box->v.free = quota_mailbox_free;
+ qbox->module_ctx.super = *v;
+ box->vlast = &qbox->module_ctx.super;
+
+ v->transaction_begin = quota_mailbox_transaction_begin;
+ v->transaction_commit = quota_mailbox_transaction_commit;
+ v->transaction_rollback = quota_mailbox_transaction_rollback;
+ v->save_begin = quota_save_begin;
+ v->save_finish = quota_save_finish;
+ v->copy = quota_copy;
+ v->sync_notify = quota_mailbox_sync_notify;
+ v->sync_deinit = quota_mailbox_sync_deinit;
+ v->delete = quota_mailbox_delete;
+ v->free = quota_mailbox_free;
MODULE_CONTEXT_SET(box, quota_storage_module, qbox);
}
void quota_mail_user_created(struct mail_user *user)
{
+ struct mail_user_vfuncs *v = user->vlast;
struct quota_user *quser;
struct quota_settings *set;
set = quota_user_read_settings(user);
if (set != NULL) {
quser = p_new(user->pool, struct quota_user, 1);
- quser->module_ctx.super = user->v;
- user->v.deinit = quota_user_deinit;
+ quser->module_ctx.super = *v;
+ user->vlast = &quser->module_ctx.super;
+ v->deinit = quota_user_deinit;
quser->quota = quota_init(set, user);
MODULE_CONTEXT_SET(user, quota_user_module, quser);
}
if (add) {
+ struct mailbox_list_vfuncs *v = list->vlast;
+
qlist = p_new(list->pool, struct quota_mailbox_list, 1);
- qlist->module_ctx.super = list->v;
- list->v.deinit = quota_mailbox_list_deinit;
+ qlist->module_ctx.super = *v;
+ list->vlast = &qlist->module_ctx.super;
+ v->deinit = quota_mailbox_list_deinit;
MODULE_CONTEXT_SET(list, quota_mailbox_list_module, qlist);
/* register to owner's quota roots */
i_error("trash plugin: quota plugin not initialized");
} else {
tuser = p_new(user->pool, struct trash_user, 1);
- tuser->module_ctx.super = user->v;
MODULE_CONTEXT_SET(user, trash_user_module, tuser);
if (read_configuration(user, env) == 0) {
static void virtual_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
struct mailbox_list *list)
{
+ struct mailbox_list_vfuncs *v = list->vlast;
struct virtual_mailbox_list *mlist;
mlist = p_new(list->pool, struct virtual_mailbox_list, 1);
- mlist->module_ctx.super = list->v;
+ mlist->module_ctx.super = *v;
+ list->vlast = &mlist->module_ctx.super;
list->ns->flags |= NAMESPACE_FLAG_NOQUOTA;
- list->v.get_mailbox_flags = virtual_list_get_mailbox_flags;
+ v->get_mailbox_flags = virtual_list_get_mailbox_flags;
MODULE_CONTEXT_SET(list, virtual_mailbox_list_module, mlist);
}
return index_mail_init_stream(imail, hdr_size, body_size, stream_r);
}
-static struct mail *
-zlib_permail_mail_alloc(struct mailbox_transaction_context *t,
- enum mail_fetch_field wanted_fields,
- struct mailbox_header_lookup_ctx *wanted_headers)
+static void zlib_mail_allocated(struct mail *_mail)
{
- union mailbox_module_context *zbox = ZLIB_CONTEXT(t->box);
+ struct zlib_transaction_context *zt = ZLIB_CONTEXT(_mail->transaction);
+ struct mail_private *mail = (struct mail_private *)_mail;
+ struct mail_vfuncs *v = mail->vlast;
union mail_module_context *zmail;
- struct mail *_mail;
- struct mail_private *mail;
- _mail = zbox->super.mail_alloc(t, wanted_fields, wanted_headers);
- mail = (struct mail_private *)_mail;
+ if (zt == NULL)
+ return;
zmail = p_new(mail->pool, union mail_module_context, 1);
- zmail->super = mail->v;
+ zmail->super = *v;
+ mail->vlast = &zmail->super;
- mail->v.get_stream = zlib_permail_get_stream;
+ v->get_stream = zlib_permail_get_stream;
MODULE_CONTEXT_SET_SELF(mail, zlib_mail_module, zmail);
- return _mail;
}
static struct mailbox_transaction_context *
return 0;
}
-static void zlib_permail_alloc_init(struct mailbox *box)
+static void
+zlib_permail_alloc_init(struct mailbox *box, struct mailbox_vfuncs *v)
{
struct zlib_user *zuser = ZLIB_USER_CONTEXT(box->storage->user);
- box->v.mail_alloc = zlib_permail_mail_alloc;
- box->v.transaction_begin = zlib_mailbox_transaction_begin;
- box->v.transaction_rollback = zlib_mailbox_transaction_rollback;
- box->v.transaction_commit = zlib_mailbox_transaction_commit;
+ v->transaction_begin = zlib_mailbox_transaction_begin;
+ v->transaction_rollback = zlib_mailbox_transaction_rollback;
+ v->transaction_commit = zlib_mailbox_transaction_commit;
if (zuser->save_handler == NULL) {
- box->v.save_begin = zlib_mail_save_begin;
- box->v.save_finish = zlib_mail_save_finish;
+ v->save_begin = zlib_mail_save_begin;
+ v->save_finish = zlib_mail_save_finish;
} else {
- box->v.save_begin = zlib_mail_save_compress_begin;
+ v->save_begin = zlib_mail_save_compress_begin;
}
}
static void zlib_mailbox_allocated(struct mailbox *box)
{
+ struct mailbox_vfuncs *v = box->vlast;
union mailbox_module_context *zbox;
zbox = p_new(box->pool, union mailbox_module_context, 1);
- zbox->super = box->v;
- box->v.open = zlib_mailbox_open;
+ zbox->super = *v;
+ box->vlast = &zbox->super;
+ v->open = zlib_mailbox_open;
MODULE_CONTEXT_SET_SELF(box, zlib_storage_module, zbox);
if (strcmp(box->storage->name, "maildir") == 0 ||
strcmp(box->storage->name, "mdbox") == 0 ||
strcmp(box->storage->name, "dbox") == 0)
- zlib_permail_alloc_init(box);
+ zlib_permail_alloc_init(box, v);
}
static void zlib_mail_user_created(struct mail_user *user)
const char *name;
zuser = p_new(user->pool, struct zlib_user, 1);
- zuser->module_ctx.super = user->v;
name = mail_user_plugin_getenv(user, "zlib_save");
if (name != NULL && *name != '\0') {
static struct mail_storage_hooks zlib_mail_storage_hooks = {
.mail_user_created = zlib_mail_user_created,
- .mailbox_allocated = zlib_mailbox_allocated
+ .mailbox_allocated = zlib_mailbox_allocated,
+ .mail_allocated = zlib_mail_allocated
};
void zlib_plugin_init(struct module *module)