diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
commit | f7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch) | |
tree | a3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/plugins/mail-lua/mail-lua-plugin.c | |
parent | Initial commit. (diff) | |
download | dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip |
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/plugins/mail-lua/mail-lua-plugin.c')
-rw-r--r-- | src/plugins/mail-lua/mail-lua-plugin.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/plugins/mail-lua/mail-lua-plugin.c b/src/plugins/mail-lua/mail-lua-plugin.c new file mode 100644 index 0000000..146d95b --- /dev/null +++ b/src/plugins/mail-lua/mail-lua-plugin.c @@ -0,0 +1,167 @@ +/* Copyright (c) 2018 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "module-dir.h" +#include "mail-lua-plugin.h" +#include "mail-storage-lua.h" +#include "mail-storage-private.h" +#include "mail-storage-hooks.h" +#include "dlua-script-private.h" + +#define MAIL_LUA_SCRIPT "mail_lua_script" +#define MAIL_LUA_USER_CREATED_FN "mail_user_created" +#define MAIL_LUA_USER_DEINIT_FN "mail_user_deinit" +#define MAIL_LUA_USER_DEINIT_PRE_FN "mail_user_deinit_pre" +#define MAIL_LUA_USER_CONTEXT(obj) \ + MODULE_CONTEXT(obj, mail_lua_user_module) + +static MODULE_CONTEXT_DEFINE_INIT(mail_lua_user_module, + &mail_user_module_register); + +struct mail_lua_user_context { + union mail_user_module_context module_ctx; + struct dlua_script *script; +}; + +static int mail_lua_call_hook(struct dlua_script *script, + struct mail_user *user, + const char *hook, + const char **error_r) +{ + const char *error; + + if (!dlua_script_has_function(script, hook)) + return 0; + + if (user->mail_debug) + e_debug(user->event, "mail-lua: Calling %s(user)", hook); + + dlua_push_mail_user(script->L, user); + + if (dlua_pcall(script->L, hook, 1, 2, &error) < 0) { + *error_r = t_strdup_printf("%s(user) failed: %s", hook, error); + return -1; + } + + int ret = lua_tonumber(script->L, -2); + const char *errmsg = lua_tostring(script->L, -1); + + if (ret < 0) { + *error_r = t_strdup_printf("%s(user) failed: %s", + hook, errmsg); + } + + lua_pop(script->L, 2); + (void)lua_gc(script->L, LUA_GCCOLLECT, 0); + + return ret < 0 ? -1 : 1; +} + +static void mail_lua_user_deinit_pre(struct mail_user *user) +{ + struct mail_lua_user_context *luser = MAIL_LUA_USER_CONTEXT(user); + const char *error; + + if (luser == NULL) + return; + + if (mail_lua_call_hook(luser->script, user, MAIL_LUA_USER_DEINIT_PRE_FN, + &error) < 0) { + e_error(user->event, "mail-lua: %s", error); + } + + luser->module_ctx.super.deinit_pre(user); +} + +static void mail_lua_user_deinit(struct mail_user *user) +{ + struct mail_lua_user_context *luser = MAIL_LUA_USER_CONTEXT(user); + const char *error; + + if (luser == NULL) + return; + + luser->module_ctx.super.deinit(user); + + if (mail_lua_call_hook(luser->script, user, MAIL_LUA_USER_DEINIT_FN, + &error) < 0) { + e_error(user->event, "mail-lua: %s", error); + } + + dlua_script_unref(&luser->script); +} + +static void mail_lua_user_created(struct mail_user *user) +{ + struct mail_lua_user_context *luser; + struct mail_user_vfuncs *v = user->vlast; + struct dlua_script *script; + const char *error; + const char *script_fn = mail_user_plugin_getenv(user, MAIL_LUA_SCRIPT); + int ret; + + if (script_fn == NULL) + return; + + if (dlua_script_create_file(script_fn, &script, user->event, &error) < 0) { + user->error = p_strdup_printf(user->pool, "dlua_script_create_file(%s) failed: %s", + script_fn, error); + return; + } + + dlua_dovecot_register(script); + dlua_register_mail_storage(script); + + /* init */ + if (dlua_script_init(script, &error) < 0) { + user->error = p_strdup_printf(user->pool, "dlua_script_init(%s) failed: %s", + script_fn, error); + dlua_script_unref(&script); + return; + } + + /* call postlogin hook */ + if ((ret = mail_lua_call_hook(script, user, MAIL_LUA_USER_CREATED_FN, + &error)) <= 0) { + if (ret < 0) + user->error = p_strdup(user->pool, error); + dlua_script_unref(&script); + return; + } + + luser = p_new(user->pool, struct mail_lua_user_context, 1); + luser->module_ctx.super = *v; + v->deinit_pre = mail_lua_user_deinit_pre; + v->deinit = mail_lua_user_deinit; + luser->script = script; + user->vlast = &luser->module_ctx.super; + + MODULE_CONTEXT_SET(user, mail_lua_user_module, luser); +} + +bool mail_lua_plugin_get_script(struct mail_user *user, + struct dlua_script **script_r) +{ + struct mail_lua_user_context *luser = MAIL_LUA_USER_CONTEXT(user); + if (luser != NULL) { + *script_r = luser->script; + return TRUE; + } + return FALSE; +} + +static const struct mail_storage_hooks mail_lua_hooks = { + .mail_user_created = mail_lua_user_created, +}; + +void mail_lua_plugin_init(struct module *module) +{ + mail_storage_hooks_add(module, &mail_lua_hooks); +} + +void mail_lua_plugin_deinit(void) +{ + mail_storage_hooks_remove(&mail_lua_hooks); +} + +const char *mail_lua_plugin_dependencies[] = { NULL }; |