From: Timo Sirainen Date: Mon, 7 Jun 2010 16:06:17 +0000 (+0100) Subject: lib-storage: Plugin API changed to run plugin functions in correct order. X-Git-Tag: 2.0.beta6~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=539977f9257bd8985be5a8093658da266ae9cd19;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Plugin API changed to run plugin functions in correct order. Previously the hooks were run in correct order, but the functions they overrode were run in reverse order. This caused problems when multiple plugins were used. --HG-- branch : HEAD --- diff --git a/src/lib-storage/mail-storage-hooks.c b/src/lib-storage/mail-storage-hooks.c index 94448c10fe..2038950bda 100644 --- a/src/lib-storage/mail-storage-hooks.c +++ b/src/lib-storage/mail-storage-hooks.c @@ -125,6 +125,7 @@ void hook_mail_user_created(struct mail_user *user) 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); @@ -155,6 +156,7 @@ void hook_mail_storage_created(struct mail_storage *storage) { 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); @@ -165,6 +167,7 @@ void hook_mailbox_list_created(struct mailbox_list *list) { 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); @@ -175,6 +178,7 @@ void hook_mailbox_allocated(struct mailbox *box) { 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); @@ -190,3 +194,15 @@ void hook_mailbox_opened(struct mailbox *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); + } +} diff --git a/src/lib-storage/mail-storage-hooks.h b/src/lib-storage/mail-storage-hooks.h index a6c24ce124..ae8583e91d 100644 --- a/src/lib-storage/mail-storage-hooks.h +++ b/src/lib-storage/mail-storage-hooks.h @@ -7,6 +7,7 @@ struct mail_storage; struct mail_namespace; struct mailbox_list; struct mailbox; +struct mail; struct mail_storage_hooks { void (*mail_user_created)(struct mail_user *user); @@ -16,6 +17,7 @@ struct mail_storage_hooks { 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); @@ -35,5 +37,6 @@ void hook_mail_storage_created(struct mail_storage *storage); 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 diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index c951b5bbd6..82a0b6658a 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -61,7 +61,7 @@ struct mail_storage { 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; @@ -219,7 +219,7 @@ struct mailbox { struct mail_storage *storage; struct mailbox_list *list; - struct mailbox_vfuncs v; + struct mailbox_vfuncs v, *vlast; /* private: */ pool_t pool; @@ -327,7 +327,7 @@ union mail_module_context { 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; diff --git a/src/lib-storage/mail-user.h b/src/lib-storage/mail-user.h index 67d8e2a47a..355d7eae30 100644 --- a/src/lib-storage/mail-user.h +++ b/src/lib-storage/mail-user.h @@ -13,7 +13,7 @@ struct mail_user_vfuncs { struct mail_user { pool_t pool; - struct mail_user_vfuncs v; + struct mail_user_vfuncs v, *vlast; int refcount; const char *username; diff --git a/src/lib-storage/mail.c b/src/lib-storage/mail.c index 993f6673ea..e376235c8b 100644 --- a/src/lib-storage/mail.c +++ b/src/lib-storage/mail.c @@ -15,7 +15,14 @@ struct mail *mail_alloc(struct mailbox_transaction_context *t, 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) diff --git a/src/lib-storage/mailbox-list-private.h b/src/lib-storage/mailbox-list-private.h index a2603d5c25..467d659398 100644 --- a/src/lib-storage/mailbox-list-private.h +++ b/src/lib-storage/mailbox-list-private.h @@ -88,7 +88,7 @@ struct mailbox_list { 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; diff --git a/src/plugins/acl/acl-mailbox-list.c b/src/plugins/acl/acl-mailbox-list.c index 661d6b77b6..efde55ec7d 100644 --- a/src/plugins/acl/acl-mailbox-list.c +++ b/src/plugins/acl/acl-mailbox-list.c @@ -502,10 +502,12 @@ acl_mailbox_list_create_dir(struct mailbox_list *list, const char *name, 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); } @@ -526,6 +528,7 @@ static void acl_storage_rights_ctx_init(struct acl_storage_rights_context *ctx, 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; @@ -558,12 +561,13 @@ static void acl_mailbox_list_init_default(struct mailbox_list *list) } 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); diff --git a/src/plugins/acl/acl-mailbox.c b/src/plugins/acl/acl-mailbox.c index c70af184bb..e1a4dc032c 100644 --- a/src/plugins/acl/acl-mailbox.c +++ b/src/plugins/acl/acl-mailbox.c @@ -20,6 +20,7 @@ struct acl_mailbox { union mailbox_module_context module_ctx; struct acl_object *aclobj; bool skip_acl_checks; + bool acl_enabled; }; struct acl_transaction_context { @@ -335,28 +336,24 @@ static void acl_mail_expunge(struct mail *_mail) 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, @@ -502,6 +499,7 @@ static int acl_mailbox_open(struct mailbox *box) 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) { @@ -510,24 +508,25 @@ void acl_mailbox_allocated(struct mailbox *box) } 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); } diff --git a/src/plugins/acl/acl-plugin.c b/src/plugins/acl/acl-plugin.c index 39b3afc769..6fbf70d2ab 100644 --- a/src/plugins/acl/acl-plugin.c +++ b/src/plugins/acl/acl-plugin.c @@ -12,7 +12,8 @@ const char *acl_plugin_version = DOVECOT_VERSION; 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) diff --git a/src/plugins/acl/acl-plugin.h b/src/plugins/acl/acl-plugin.h index 457f95389a..634f9897c6 100644 --- a/src/plugins/acl/acl-plugin.h +++ b/src/plugins/acl/acl-plugin.h @@ -43,6 +43,7 @@ void acl_mail_namespace_storage_added(struct mail_namespace *ns); 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, diff --git a/src/plugins/acl/acl-storage.c b/src/plugins/acl/acl-storage.c index 89057f94be..8b305eda3c 100644 --- a/src/plugins/acl/acl-storage.c +++ b/src/plugins/acl/acl-storage.c @@ -26,11 +26,13 @@ static void acl_user_deinit(struct mail_user *user) 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; diff --git a/src/plugins/expire/expire-plugin.c b/src/plugins/expire/expire-plugin.c index 008f36c7cc..ba938119f8 100644 --- a/src/plugins/expire/expire-plugin.c +++ b/src/plugins/expire/expire-plugin.c @@ -179,26 +179,22 @@ static void expire_mail_expunge(struct mail *_mail) 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) @@ -224,17 +220,18 @@ expire_copy(struct mail_save_context *ctx, struct mail *mail) 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); } @@ -290,9 +287,12 @@ static void expire_mail_namespaces_created(struct mail_namespace *ns) } 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 @@ -308,7 +308,8 @@ static void expire_mail_namespaces_created(struct mail_namespace *ns) 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) diff --git a/src/plugins/fts-solr/fts-solr-plugin.c b/src/plugins/fts-solr/fts-solr-plugin.c index ff7dc7ec70..e6971cfb16 100644 --- a/src/plugins/fts-solr/fts-solr-plugin.c +++ b/src/plugins/fts-solr/fts-solr-plugin.c @@ -49,7 +49,6 @@ static void fts_solr_mail_user_create(struct mail_user *user, const char *env) 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; diff --git a/src/plugins/fts/fts-plugin.c b/src/plugins/fts/fts-plugin.c index 25bd33941b..2499044bf4 100644 --- a/src/plugins/fts/fts-plugin.c +++ b/src/plugins/fts/fts-plugin.c @@ -9,7 +9,8 @@ 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) diff --git a/src/plugins/fts/fts-plugin.h b/src/plugins/fts/fts-plugin.h index 13533dfd83..a44008bb61 100644 --- a/src/plugins/fts/fts-plugin.h +++ b/src/plugins/fts/fts-plugin.h @@ -2,6 +2,7 @@ #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); diff --git a/src/plugins/fts/fts-storage.c b/src/plugins/fts/fts-storage.c index b30ee92f91..c82720be17 100644 --- a/src/plugins/fts/fts-storage.c +++ b/src/plugins/fts/fts-storage.c @@ -951,29 +951,24 @@ static int fts_mail_get_special(struct mail *_mail, enum mail_fetch_field field, 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) @@ -1092,23 +1087,25 @@ fts_transaction_commit(struct mailbox_transaction_context *t, 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); } diff --git a/src/plugins/lazy-expunge/lazy-expunge-plugin.c b/src/plugins/lazy-expunge/lazy-expunge-plugin.c index 9513d23d67..fcd41c8980 100644 --- a/src/plugins/lazy-expunge/lazy-expunge-plugin.c +++ b/src/plugins/lazy-expunge/lazy-expunge-plugin.c @@ -208,25 +208,23 @@ lazy_expunge_transaction_rollback(struct mailbox_transaction_context *ctx) 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 @@ -471,23 +469,24 @@ static void lazy_expunge_mailbox_allocated(struct mailbox *box) 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; } } @@ -515,8 +514,6 @@ static void lazy_expunge_mail_namespace_storage_added(struct mail_namespace *ns) 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); } @@ -562,7 +559,6 @@ static void lazy_expunge_mail_user_created(struct mail_user *user) 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); @@ -576,7 +572,8 @@ static struct mail_storage_hooks lazy_expunge_mail_storage_hooks = { .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) diff --git a/src/plugins/listescape/listescape-plugin.c b/src/plugins/listescape/listescape-plugin.c index 36c8f83ff6..ea0d3b450f 100644 --- a/src/plugins/listescape/listescape-plugin.c +++ b/src/plugins/listescape/listescape-plugin.c @@ -265,10 +265,12 @@ static bool listescape_is_valid_create_name(struct mailbox_list *list, 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); } @@ -276,6 +278,7 @@ static void listescape_mail_storage_created(struct mail_storage *storage) 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; @@ -285,15 +288,16 @@ static void listescape_mail_namespace_storage_added(struct mail_namespace *ns) 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' ? diff --git a/src/plugins/mbox-snarf/mbox-snarf-plugin.c b/src/plugins/mbox-snarf/mbox-snarf-plugin.c index 6b20a8c731..df36b79d44 100644 --- a/src/plugins/mbox-snarf/mbox-snarf-plugin.c +++ b/src/plugins/mbox-snarf/mbox-snarf-plugin.c @@ -169,12 +169,14 @@ static void 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); } diff --git a/src/plugins/notify/notify-storage.c b/src/plugins/notify/notify-storage.c index ddd5cb6523..83913cb012 100644 --- a/src/plugins/notify/notify-storage.c +++ b/src/plugins/notify/notify-storage.c @@ -71,27 +71,20 @@ notify_mail_update_keywords(struct mail *_mail, enum modify_type modify_type, 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 @@ -224,25 +217,27 @@ notify_mailbox_rename(struct mailbox *src, struct mailbox *dest, 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) diff --git a/src/plugins/quota/quota-plugin.c b/src/plugins/quota/quota-plugin.c index b2731bfb88..43da3a9a32 100644 --- a/src/plugins/quota/quota-plugin.c +++ b/src/plugins/quota/quota-plugin.c @@ -13,7 +13,8 @@ static struct mail_storage_hooks quota_mail_storage_hooks = { .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) diff --git a/src/plugins/quota/quota-plugin.h b/src/plugins/quota/quota-plugin.h index 9ae4faa2bc..22ed6ef3fb 100644 --- a/src/plugins/quota/quota-plugin.h +++ b/src/plugins/quota/quota-plugin.h @@ -6,6 +6,7 @@ struct module; struct mailbox; +struct mail; #define QUOTA_USER_CONTEXT(obj) \ MODULE_CONTEXT(obj, quota_user_module) @@ -24,6 +25,7 @@ void quota_mail_user_created(struct mail_user *user); 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); diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index 8ca52af123..2207f8c8f3 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -113,26 +113,22 @@ quota_mailbox_transaction_rollback(struct mailbox_transaction_context *ctx) 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) @@ -389,25 +385,26 @@ static void quota_mailbox_free(struct mailbox *box) 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); } @@ -436,14 +433,16 @@ static void quota_user_deinit(struct mail_user *user) 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); @@ -490,9 +489,12 @@ void quota_mail_namespace_storage_added(struct mail_namespace *ns) } 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 */ diff --git a/src/plugins/trash/trash-plugin.c b/src/plugins/trash/trash-plugin.c index 6a7b0ff87a..d1d9f2a1de 100644 --- a/src/plugins/trash/trash-plugin.c +++ b/src/plugins/trash/trash-plugin.c @@ -312,7 +312,6 @@ trash_mail_namespaces_created(struct mail_namespace *namespaces) 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) { diff --git a/src/plugins/virtual/virtual-storage.c b/src/plugins/virtual/virtual-storage.c index 7a82b928fc..ce4d931e3e 100644 --- a/src/plugins/virtual/virtual-storage.c +++ b/src/plugins/virtual/virtual-storage.c @@ -389,13 +389,15 @@ virtual_list_get_mailbox_flags(struct mailbox_list *list, 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); } diff --git a/src/plugins/zlib/zlib-plugin.c b/src/plugins/zlib/zlib-plugin.c index c7924a6568..af80dc44ac 100644 --- a/src/plugins/zlib/zlib-plugin.c +++ b/src/plugins/zlib/zlib-plugin.c @@ -168,25 +168,22 @@ static int zlib_permail_get_stream(struct mail *_mail, 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 * @@ -292,19 +289,19 @@ zlib_mail_save_compress_begin(struct mail_save_context *ctx, 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; } } @@ -352,18 +349,20 @@ static int zlib_mailbox_open(struct mailbox *box) 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) @@ -372,7 +371,6 @@ 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') { @@ -395,7 +393,8 @@ static void zlib_mail_user_created(struct mail_user *user) 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)