mail-storage-hooks.c revision c36fa596c3a1524006d3f7aeae54ebc49911716a
/* Copyright (c) 2009-2010 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.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;
};
static ARRAY_DEFINE(module_hooks,
struct mail_storage_module_hooks) = ARRAY_INIT;
static ARRAY_DEFINE(internal_hooks,
const struct mail_storage_hooks *) = ARRAY_INIT;
void mail_storage_hooks_init(void)
{
}
void mail_storage_hooks_deinit(void)
{
}
const struct mail_storage_hooks *hooks)
{
struct mail_storage_module_hooks new_hook;
}
{
const struct mail_storage_module_hooks *module_hook;
unsigned int idx = -1U;
break;
}
}
}
{
}
{
const struct mail_storage_hooks *const *old_hooks;
unsigned int idx = -1U;
break;
}
}
}
static int
const struct mail_storage_module_hooks *h2)
{
s1 += 3;
s2 += 3;
}
{
const struct mail_storage_module_hooks *module_hook;
/* first get all hooks wanted by the user */
}
/* 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 */
}
const void *_prev_vlast,
{
/* This function 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..
The problem this function solves is:
1. First hook overrides methods A and B by updating vlast->A+B.
vlast points to v, so v->A+B gets updated.
2. Second hook overrides method B and C by updating vlast->B+C.
vlast points first hook's super struct. now, the call paths go:
B: v->B = hook1_B, which calls its super.B = hook2_B,
which calls super.B = original -> all OK
C: v->C = still the original, so hook2_C won't be called!
The idea is to detect the C situation, and update v->C = hook2_C
so that the call path goes:
C: v->C = hook2_C, which calls super.C = original
*/
void (**v)() = _v;
void (*const *prev_vlast)() = _prev_vlast;
unsigned int i, count;
for (i = 0; i < count; i++) {
continue;
if (v[i] != vlast[i]) {
/* first hook overriding any method in this object */
mask[i] = v[i];
/* first hook overriding this method object
(but earlier hooks already overrode other methods) */
v[i] = prev_vlast[i];
mask[i] = prev_vlast[i];
}
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
{
const struct mail_storage_hooks *const *hooks;
}
}
}