]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Plugin API changed to run plugin functions in correct order.
authorTimo Sirainen <tss@iki.fi>
Mon, 7 Jun 2010 16:06:17 +0000 (17:06 +0100)
committerTimo Sirainen <tss@iki.fi>
Mon, 7 Jun 2010 16:06:17 +0000 (17:06 +0100)
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

26 files changed:
src/lib-storage/mail-storage-hooks.c
src/lib-storage/mail-storage-hooks.h
src/lib-storage/mail-storage-private.h
src/lib-storage/mail-user.h
src/lib-storage/mail.c
src/lib-storage/mailbox-list-private.h
src/plugins/acl/acl-mailbox-list.c
src/plugins/acl/acl-mailbox.c
src/plugins/acl/acl-plugin.c
src/plugins/acl/acl-plugin.h
src/plugins/acl/acl-storage.c
src/plugins/expire/expire-plugin.c
src/plugins/fts-solr/fts-solr-plugin.c
src/plugins/fts/fts-plugin.c
src/plugins/fts/fts-plugin.h
src/plugins/fts/fts-storage.c
src/plugins/lazy-expunge/lazy-expunge-plugin.c
src/plugins/listescape/listescape-plugin.c
src/plugins/mbox-snarf/mbox-snarf-plugin.c
src/plugins/notify/notify-storage.c
src/plugins/quota/quota-plugin.c
src/plugins/quota/quota-plugin.h
src/plugins/quota/quota-storage.c
src/plugins/trash/trash-plugin.c
src/plugins/virtual/virtual-storage.c
src/plugins/zlib/zlib-plugin.c

index 94448c10fe747ff8d3fe2dd2d4295d43b48ccbb9..2038950bda91a836e438a8d5a5ef5c2a2d747640 100644 (file)
@@ -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);
+       }
+}
index a6c24ce124f8581c3c752a3fad01d5c2171b21a2..ae8583e91d2bc909e747ee4779de879b0996683e 100644 (file)
@@ -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
index c951b5bbd642302c1a04cfa88e4347e0e822b51d..82a0b6658ab9948699906728f13fd301dfc34f01 100644 (file)
@@ -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;
index 67d8e2a47a034511ffa486a06fee9a833e920d19..355d7eae303c7376ad44376a393bf0c107db24da 100644 (file)
@@ -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;
index 993f6673ea84e7c04d68d9492a01b2d4dee664ad..e376235c8b199ef335baca67294e9b8707fdca9d 100644 (file)
@@ -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)
index a2603d5c25a7c9ebc3e3179376b4b6b87c77a370..467d6593987996ed0bca04d3a7a0cd5688265226 100644 (file)
@@ -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;
index 661d6b77b622197644077ca486ae3631a2a61136..efde55ec7d203999e3d4928b02111dcab146ef9d 100644 (file)
@@ -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);
index c70af184bb2fa34b12aeda4ae62d94bd7aea0125..e1a4dc032c9ec5fc160ce543897a05494b549da2 100644 (file)
@@ -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);
 }
index 39b3afc76921ece050b6d61c24d7d2fbe51a397a..6fbf70d2abb94110adbc0a271758d06c20e0528d 100644 (file)
@@ -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)
index 457f95389ac32425cc9d2d5de6b6e1da4df9abfb..634f9897c636353ce878245929b996e6cb4040f8 100644 (file)
@@ -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,
index 89057f94be6530cb9580e07831f7f9103db40e79..8b305eda3c38dbd93a8258f41103826981de468d 100644 (file)
@@ -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;
index 008f36c7ccfe197170cb37a72ea85145a3d71de8..ba938119f893b0b1d7ff0184071c12c2620a6dd2 100644 (file)
@@ -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)
index ff7dc7ec70bfc653f16c5fd285bc223d28fb5bd2..e6971cfb164812082f65397882470c5d0948855d 100644 (file)
@@ -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;
index 25bd33941b45859428c50435b7492ce9594bd83c..2499044bf4a28c604313f9184452aec88d756056 100644 (file)
@@ -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)
index 13533dfd83b96f614a3afd336f4105a682650428..a44008bb610d2b8768bccc441fc037cb49c62623 100644 (file)
@@ -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);
index b30ee92f91a76d144e5e4206d6d7b23dfa45e443..c82720be17e8622e901c2237a3016bd5f2bb28a0 100644 (file)
@@ -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);
 }
index 9513d23d67764cc6458e0854117b1f8980b9662a..fcd41c8980487be5260a25953691a9322ebac404 100644 (file)
@@ -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)
index 36c8f83ff6e197549c0f58c6e4de65b0ea5218b0..ea0d3b450f46dcc8e9b0e6413183d773d7c64558 100644 (file)
@@ -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' ?
index 6b20a8c7317ebef7525de688d777e3c0cc480e05..df36b79d44b4210227c23ea57d56a3fb9affc8ca 100644 (file)
@@ -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);
 }
index ddd5cb65237741f645bd81bb2a5d3a79298dcffb..83913cb012287c2f9ca04a0670dd71bd38ff45ff 100644 (file)
@@ -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)
index b2731bfb88d41037567e52b5b62155da902c8c18..43da3a9a3255c5e231886c5f751e64f84a0fec18 100644 (file)
@@ -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)
index 9ae4faa2bc5c1d669e0f013bb1f8e1b6f0cc691b..22ed6ef3fb4d1e1e67da9fb5c5d4ac8da7c2cc0d 100644 (file)
@@ -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);
index 8ca52af123c887653c15d6dac1be575f7e9b870b..2207f8c8f3bb3ee5ddfd0d105ca98052ca04771c 100644 (file)
@@ -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 */
index 6a7b0ff87a58c173533ac17cf34e421829335e02..d1d9f2a1dec0b3a45bee30b579554cf465707509 100644 (file)
@@ -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) {
index 7a82b928fc2d41b8420667c36396503284b6416c..ce4d931e3eaade3c3102fa30f9e1cb0e7b128cd1 100644 (file)
@@ -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);
 }
index c7924a65683feefd9f627c7ee0def4b98b07afb9..af80dc44acd59ddb10823023edcaea6d25686263 100644 (file)
@@ -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)