mail-storage-hooks.c revision 798530867beda2d2d9a8ec194ea701adef74e737
/* Copyright (c) 2009-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "llist.h"
#include "module-dir.h"
#include "mail-user.h"
#include "mail-namespace.h"
#include "mail-storage-private.h"
#include "mailbox-list-private.h"
struct mail_storage_module_hooks {
const struct mail_storage_hooks *hooks;
bool forced;
};
struct hook_stack {
/* Pointer to vfuncs struct. This assumes that a struct containing
function pointers equals to an array of function pointers. Not
ANSI-C, but should work in all OSes supported by Dovecot. Much
easier anyway than doing this work manually.. */
void (**vfuncs)();
/* nonzero in the areas where vfuncs has been changed */
void (**mask)();
};
struct hook_build_context {
/* size of the vfuncs struct */
/* number of function pointers in the struct */
unsigned int count;
};
void mail_storage_hooks_init(void)
{
if (!array_is_created(&module_hooks))
}
void mail_storage_hooks_deinit(void)
{
/* allow calling this even if mail_storage_hooks_init() hasn't been
called, because e.g. doveadm plugins could call
mail_storage_hooks_add() even though mail storage is never
initialized. */
if (array_is_created(&internal_hooks))
if (array_is_created(&module_hooks))
}
const struct mail_storage_hooks *hooks)
{
struct mail_storage_module_hooks new_hook;
/* allow adding hooks before mail_storage_hooks_init() */
if (!array_is_created(&module_hooks))
}
const struct mail_storage_hooks *hooks)
{
struct mail_storage_module_hooks *hook;
}
{
const struct mail_storage_module_hooks *module_hook;
break;
}
}
}
{
const struct mail_storage_hooks *const *existing_hooksp;
/* make sure we don't add duplicate hooks */
}
{
const struct mail_storage_hooks *const *old_hooks;
break;
}
}
}
static int
const struct mail_storage_module_hooks *h2)
{
const char *p;
s1 += 3;
s2 += 3;
}
{
const struct mail_storage_module_hooks *module_hook;
/* first get all hooks wanted by the user */
if (!module_hook->forced) {
continue;
}
}
/* next we have to sort them by the modules' priority (based on name) */
/* now that we have them in order, save them to user's hooks */
}
{
struct hook_stack *stack;
}
static struct hook_build_context *
{
struct hook_build_context *ctx;
return ctx;
}
static void
void (**vlast)())
{
unsigned int i;
}
}
}
static void
{
unsigned int i;
}
}
}
{
struct hook_stack *stack;
/* no vfuncs overridden */
return;
}
/* ctx->vfuncs_stack->vfuncs points to the root vfuncs,
ctx->vfuncs_stack->next->vfuncs points to the first super function
that is being called, and so on.
the previous plugin added its vfuncs to the stack tail.
vlast contains the previous plugin's super vfuncs, which is where
the next plugin should put its own vfuncs.
first we'll need to figure out what vfuncs the previous plugin
changed and update the mask */
/* now go up in the stack as long as the mask isn't set,
and update the vfuncs */
/* add vlast to stack */
}
{
const struct mail_storage_hooks *const *hooks;
struct hook_build_context *ctx;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
break;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
break;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
struct hook_build_context *ctx;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
struct hook_build_context *ctx;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
struct hook_build_context *ctx;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
} T_END;
}
}
{
const struct mail_storage_hooks *const *hooks;
struct hook_build_context *ctx;
} T_END;
}
}