bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "lib.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen#include "array.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "hook-build.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "llist.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "module-dir.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "mail-user.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "mail-namespace.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "mail-storage-private.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch#include "mailbox-list-private.h"
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstruct mail_storage_module_hooks {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct module *module;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch bool forced;
e9c433c5b8ef9a1b4246ebe10beb90fa01e05cafPhil Carmody};
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic ARRAY(struct mail_storage_module_hooks) module_hooks = ARRAY_INIT;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic ARRAY(const struct mail_storage_hooks *) internal_hooks = ARRAY_INIT;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_hooks_init(void)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!array_is_created(&module_hooks))
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch i_array_init(&module_hooks, 32);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_array_init(&internal_hooks, 8);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_hooks_deinit(void)
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* allow calling this even if mail_storage_hooks_init() hasn't been
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch called, because e.g. doveadm plugins could call
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_storage_hooks_add() even though mail storage is never
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch initialized. */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (array_is_created(&internal_hooks))
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_free(&internal_hooks);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (array_is_created(&module_hooks))
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_free(&module_hooks);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschvoid mail_storage_hooks_add(struct module *module,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *hooks)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct mail_storage_module_hooks new_hook;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_zero(&new_hook);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch new_hook.module = module;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch new_hook.hooks = hooks;
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* allow adding hooks before mail_storage_hooks_init() */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!array_is_created(&module_hooks))
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_array_init(&module_hooks, 32);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_append(&module_hooks, &new_hook, 1);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch}
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Boschvoid mail_storage_hooks_add_forced(struct module *module,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *hooks)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct mail_storage_module_hooks *hook;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch mail_storage_hooks_add(module, hooks);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch hook = array_idx_modifiable(&module_hooks,
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch array_count(&module_hooks)-1);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook->forced = TRUE;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschvoid mail_storage_hooks_remove(const struct mail_storage_hooks *hooks)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch const struct mail_storage_module_hooks *module_hook;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch unsigned int idx = UINT_MAX;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&module_hooks, module_hook) {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (module_hook->hooks == hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch idx = array_foreach_idx(&module_hooks, module_hook);
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch break;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_assert(idx != UINT_MAX);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_delete(&module_hooks, idx, 1);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_hooks_add_internal(const struct mail_storage_hooks *hooks)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch const struct mail_storage_hooks *const *existing_hooksp;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* make sure we don't add duplicate hooks */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&internal_hooks, existing_hooksp)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch i_assert(*existing_hooksp != hooks);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_append(&internal_hooks, &hooks, 1);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid mail_storage_hooks_remove_internal(const struct mail_storage_hooks *hooks)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *old_hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch unsigned int idx = UINT_MAX;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&internal_hooks, old_hooks) {
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch if (*old_hooks == hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch idx = array_foreach_idx(&internal_hooks, old_hooks);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch break;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch }
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch i_assert(idx != UINT_MAX);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_delete(&internal_hooks, idx, 1);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic int
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschmail_storage_module_hooks_cmp(const struct mail_storage_module_hooks *h1,
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_module_hooks *h2)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const char *s1 = h1->module->path, *s2 = h2->module->path;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch const char *p;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch p = strrchr(s1, '/');
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (p != NULL) s1 = p+1;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch p = strrchr(s2, '/');
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (p != NULL) s2 = p+1;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (strncmp(s1, "lib", 3) == 0)
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch s1 += 3;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (strncmp(s2, "lib", 3) == 0)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch s2 += 3;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch return strcmp(s1, s2);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschstatic void mail_user_add_plugin_hooks(struct mail_user *user)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_module_hooks *module_hook;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch ARRAY(struct mail_storage_module_hooks) tmp_hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const char *const *plugins, *name;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* first get all hooks wanted by the user */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch t_array_init(&tmp_hooks, array_count(&module_hooks));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch plugins = t_strsplit_spaces(user->set->mail_plugins, ", ");
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_foreach(&module_hooks, module_hook) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!module_hook->forced) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch name = module_get_plugin_name(module_hook->module);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (!str_array_find(plugins, name))
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch continue;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_append(&tmp_hooks, module_hook, 1);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch /* next we have to sort them by the modules' priority (based on name) */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_sort(&tmp_hooks, mail_storage_module_hooks_cmp);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch /* now that we have them in order, save them to user's hooks */
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch p_array_init(&user->hooks, user->pool,
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch array_count(&tmp_hooks) + array_count(&internal_hooks));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&tmp_hooks, module_hook)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_append(&user->hooks, &module_hook->hooks, 1);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_append_array(&user->hooks, &internal_hooks);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mail_user_created(struct mail_user *user)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct hook_build_context *ctx;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch mail_user_add_plugin_hooks(user);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch ctx = hook_build_init((void *)&user->v, sizeof(user->v));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch user->vlast = &user->v;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mail_user_created != NULL) T_BEGIN {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch (*hooks)->mail_user_created(user);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_update(ctx, user->vlast);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch user->vlast = NULL;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_deinit(&ctx);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mail_namespace_storage_added(struct mail_namespace *ns)
62aa68310d6f42467ca26880f678173bf1d26a83Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&ns->user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mail_namespace_storage_added != NULL) T_BEGIN {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (*hooks)->mail_namespace_storage_added(ns);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mail_namespaces_created(struct mail_namespace *namespaces)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_foreach(&namespaces->user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if (namespaces->user->error != NULL)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch break;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mail_namespaces_created != NULL) T_BEGIN {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (*hooks)->mail_namespaces_created(namespaces);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mail_namespaces_added(struct mail_namespace *namespaces)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&namespaces->user->hooks, hooks) {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if (namespaces->user->error != NULL)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch break;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mail_namespaces_added != NULL) T_BEGIN {
17c29e3e2246972c3d988e05d91b9286398a624fStephan Bosch (*hooks)->mail_namespaces_added(namespaces);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschvoid hook_mail_storage_created(struct mail_storage *storage)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct hook_build_context *ctx;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch ctx = hook_build_init((void *)&storage->v, sizeof(storage->v));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage->vlast = &storage->v;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&storage->user->hooks, hooks) {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch if ((*hooks)->mail_storage_created != NULL) T_BEGIN {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (*hooks)->mail_storage_created(storage);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_update(ctx, storage->vlast);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch storage->vlast = NULL;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_deinit(&ctx);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mailbox_list_created(struct mailbox_list *list)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct hook_build_context *ctx;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch ctx = hook_build_init((void *)&list->v, sizeof(list->v));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch list->vlast = &list->v;
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch array_foreach(&list->ns->user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mailbox_list_created != NULL) T_BEGIN {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (*hooks)->mailbox_list_created(list);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_update(ctx, list->vlast);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch list->vlast = NULL;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_deinit(&ctx);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mailbox_allocated(struct mailbox *box)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct hook_build_context *ctx;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch ctx = hook_build_init((void *)&box->v, sizeof(box->v));
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch box->vlast = &box->v;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&box->storage->user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mailbox_allocated != NULL) T_BEGIN {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch (*hooks)->mailbox_allocated(box);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_update(ctx, box->vlast);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch box->vlast = NULL;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_deinit(&ctx);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Boschvoid hook_mailbox_opened(struct mailbox *box)
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&box->storage->user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mailbox_opened != NULL) T_BEGIN {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch (*hooks)->mailbox_opened(box);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Boschvoid hook_mail_allocated(struct mail *mail)
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch{
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch const struct mail_storage_hooks *const *hooks;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct mail_private *pmail = (struct mail_private *)mail;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch struct hook_build_context *ctx;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch ctx = hook_build_init((void *)&pmail->v, sizeof(pmail->v));
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch pmail->vlast = &pmail->v;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch array_foreach(&mail->box->storage->user->hooks, hooks) {
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch if ((*hooks)->mail_allocated != NULL) T_BEGIN {
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch (*hooks)->mail_allocated(mail);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_update(ctx, pmail->vlast);
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch } T_END;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch }
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch pmail->vlast = NULL;
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch hook_build_deinit(&ctx);
66134fbce11778241ca9f8458ee2a0488a05bde0Stephan Bosch}
6ae6496c225238a2c55a8cd96744ad976c44a726Stephan Bosch