Mercurial > dovecot > core-2.2
changeset 21741:ad2aa897a8d7
*-login: Change API for how login_plugins hook into client allocation.
The previous API worked badly when there were more than one plugin.
The current behavior works similarly to how mail_plugins work.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Wed, 15 Mar 2017 18:20:31 +0200 |
parents | 3ce8158b7fd5 |
children | 0347ed67254e |
files | src/login-common/client-common.c src/login-common/client-common.h src/login-common/main.c |
diffstat | 3 files changed, 70 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/src/login-common/client-common.c Mon Mar 13 22:52:41 2017 +0200 +++ b/src/login-common/client-common.c Wed Mar 15 18:20:31 2017 +0200 @@ -8,6 +8,7 @@ #include "ostream.h" #include "iostream-rawlog.h" #include "process-title.h" +#include "hook-build.h" #include "buffer.h" #include "str.h" #include "base64.h" @@ -29,19 +30,54 @@ static struct client *last_client = NULL; static unsigned int clients_count = 0; -static void empty_login_client_allocated_hook(struct client *client ATTR_UNUSED) +struct login_client_module_hooks { + struct module *module; + const struct login_client_hooks *hooks; +}; + +static ARRAY(struct login_client_module_hooks) module_hooks = ARRAY_INIT; + +void login_client_hooks_add(struct module *module, + const struct login_client_hooks *hooks) { + struct login_client_module_hooks *hook; + + hook = array_append_space(&module_hooks); + hook->module = module; + hook->hooks = hooks; } -static login_client_allocated_func_t *hook_client_allocated = - empty_login_client_allocated_hook; + +void login_client_hooks_remove(const struct login_client_hooks *hooks) +{ + const struct login_client_module_hooks *module_hook; + unsigned int idx = UINT_MAX; -login_client_allocated_func_t * -login_client_allocated_hook_set(login_client_allocated_func_t *new_hook) + array_foreach(&module_hooks, module_hook) { + if (module_hook->hooks == hooks) { + idx = array_foreach_idx(&module_hooks, module_hook); + break; + } + } + i_assert(idx != UINT_MAX); + + array_delete(&module_hooks, idx, 1); +} + +static void hook_login_client_allocated(struct client *client) { - login_client_allocated_func_t *old_hook = hook_client_allocated; + const struct login_client_module_hooks *module_hook; + struct hook_build_context *ctx; - hook_client_allocated = new_hook; - return old_hook; + ctx = hook_build_init((void *)&client->v, sizeof(client->v)); + client->vlast = &client->v; + array_foreach(&module_hooks, module_hook) { + if (module_hook->hooks->client_allocated != NULL) T_BEGIN { + module_hook->hooks->client_allocated(client); + hook_build_update(ctx, client->vlast); + } T_END; + } + client->vlast = NULL; + hook_build_deinit(&ctx); } static void client_idle_disconnect_timeout(struct client *client) @@ -170,7 +206,7 @@ client_idle_disconnect_timeout, client); client_open_streams(client); - hook_client_allocated(client); + hook_login_client_allocated(client); client->v.create(client, other_sets); if (auth_client_is_connected(auth_client)) @@ -842,3 +878,13 @@ { client->v.input(client); } + +void client_common_init(void) +{ + i_array_init(&module_hooks, 32); +} + +void client_common_deinit(void) +{ + array_free(&module_hooks); +}
--- a/src/login-common/client-common.h Mon Mar 13 22:52:41 2017 +0200 +++ b/src/login-common/client-common.h Wed Mar 15 18:20:31 2017 +0200 @@ -1,6 +1,8 @@ #ifndef CLIENT_COMMON_H #define CLIENT_COMMON_H +struct module; + #include "net.h" #include "login-proxy.h" #include "sasl-server.h" @@ -106,6 +108,7 @@ struct client *prev, *next; pool_t pool; struct client_vfuncs v; + struct client_vfuncs *vlast; time_t created; int refcount; @@ -191,14 +194,17 @@ struct login_module_register *reg; }; +struct login_client_hooks { + void (*client_allocated)(struct client *client); +}; + extern struct client *clients; typedef void login_client_allocated_func_t(struct client *client); -/* Sets the client allocation hook and returns the previous hook, - which the new hook should call. */ -login_client_allocated_func_t * -login_client_allocated_hook_set(login_client_allocated_func_t *new_hook); +void login_client_hooks_add(struct module *module, + const struct login_client_hooks *hooks); +void login_client_hooks_remove(const struct login_client_hooks *hooks); struct client * client_create(int fd, bool ssl, pool_t pool, @@ -259,4 +265,7 @@ void clients_destroy_all(void); void clients_destroy_all_reason(const char *reason); +void client_common_init(void); +void client_common_deinit(void); + #endif
--- a/src/login-common/main.c Mon Mar 13 22:52:41 2017 +0200 +++ b/src/login-common/main.c Wed Mar 15 18:20:31 2017 +0200 @@ -336,6 +336,7 @@ key file. */ ssl_proxy_init(); dsasl_clients_init(); + client_common_init(); /* set the number of fds we want to use. it may get increased or decreased. leave a couple of extra fds for auth sockets and such. @@ -433,6 +434,7 @@ anvil_client_deinit(&anvil); if (auth_client_to != NULL) timeout_remove(&auth_client_to); + client_common_deinit(); dsasl_clients_deinit(); login_settings_deinit(); }