diff options
Diffstat (limited to 'src/lua')
-rw-r--r-- | src/lua/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/lua/lua_common.h | 8 | ||||
-rw-r--r-- | src/lua/lua_config.c | 80 | ||||
-rw-r--r-- | src/lua/lua_rcl.c | 148 |
4 files changed, 167 insertions, 72 deletions
diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt index 765d3041d..762c9a10d 100644 --- a/src/lua/CMakeLists.txt +++ b/src/lua/CMakeLists.txt @@ -15,7 +15,8 @@ SET(LUASRC lua_common.c lua_session.c lua_buffer.c lua_dns.c - lua_rsa.c) + lua_rsa.c + lua_rcl.c) ADD_LIBRARY(rspamd-lua ${LINK_TYPE} ${LUASRC}) SET_TARGET_PROPERTIES(rspamd-lua PROPERTIES VERSION ${RSPAMD_VERSION}) diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index d03fba0ce..c83433d81 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -6,6 +6,7 @@ #include "main.h" #include "cfg_file.h" +#include "rcl/rcl.h" #include <lua.h> #include <lauxlib.h> #include <lualib.h> @@ -102,6 +103,13 @@ struct lua_locked_state* init_lua_locked (struct config_file *cfg); void free_lua_locked (struct lua_locked_state *st); /** + * Push an rcl object to lua + * @param L lua state + * @param obj object to push + */ +gint lua_rcl_obj_push (lua_State *L, rspamd_cl_object_t *obj); + +/** * Open libraries functions */ gint luaopen_message (lua_State *L); diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 1da50ad19..d3b7c6af9 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -153,17 +153,17 @@ static gint lua_config_get_module_opt (lua_State * L) { struct config_file *cfg = lua_check_config (L); - const gchar *mname, *optname, *val; + const gchar *mname, *optname; + rspamd_cl_object_t *obj; if (cfg) { mname = luaL_checkstring (L, 2); optname = luaL_checkstring (L, 3); if (mname && optname) { - val = get_module_opt (cfg, (gchar *)mname, (gchar *)optname); - if (val) { - lua_pushstring (L, val); - return 1; + obj = get_module_opt (cfg, mname, optname); + if (obj) { + return lua_rcl_obj_push (L, obj); } } } @@ -186,82 +186,20 @@ lua_config_get_mempool (lua_State * L) } static gint -opt_compare (gconstpointer a, gconstpointer b) -{ - const struct module_opt *o1 = a, - *o2 = b; - - return g_ascii_strcasecmp (o1->param, o2->param); -} - -static gint lua_config_get_all_opt (lua_State * L) { struct config_file *cfg = lua_check_config (L); const gchar *mname; - GList *cur_opt, *next_opt; - struct module_opt *opt, *tmp; - gint i; + rspamd_cl_object_t *obj; if (cfg) { mname = luaL_checkstring (L, 2); if (mname) { - cur_opt = g_hash_table_lookup (cfg->modules_opts, mname); - if (cur_opt == NULL) { - lua_pushnil (L); - return 1; + obj = rspamd_cl_obj_get_key (cfg->rcl_obj, mname); + if (obj != NULL) { + return lua_rcl_obj_push (L, obj); } - /* Sort options in alphabet order by param name */ - cur_opt = g_list_sort (cur_opt, opt_compare); - g_hash_table_insert (cfg->modules_opts, (gpointer)mname, cur_opt); - - lua_newtable (L); - while (cur_opt) { - opt = cur_opt->data; - next_opt = g_list_next (cur_opt); - if (next_opt) { - tmp = next_opt->data; - if (g_ascii_strcasecmp (tmp->param, opt->param) == 0) { - /* We have some common values */ - lua_pushstring (L, opt->param); - lua_newtable (L); - /* Now stack looks like: - * table - parent associated table of options - * key - string key of this option - * table - array of values, beginig from 1 - */ - - for (i = 1; ; i++) { - lua_pushinteger (L, i); - lua_pushstring (L, opt->value); - lua_settable (L, -3); - - cur_opt = g_list_next (cur_opt); - if (!cur_opt) { - break; - } - tmp = cur_opt->data; - if (g_ascii_strcasecmp (tmp->param, opt->param) != 0) { - break; - } - opt = tmp; - } - /* Now set index in parent table */ - lua_settable (L, -3); - /* Now continue in outter cycle */ - continue; - } - else { - lua_set_table_index (L, opt->param, opt->value); - } - } - else { - lua_set_table_index (L, opt->param, opt->value); - } - cur_opt = next_opt; - } - return 1; } } lua_pushnil (L); diff --git a/src/lua/lua_rcl.c b/src/lua/lua_rcl.c new file mode 100644 index 000000000..c992b553e --- /dev/null +++ b/src/lua/lua_rcl.c @@ -0,0 +1,148 @@ +/* Copyright (c) 2013, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "lua_common.h" +#include "rcl/rcl.h" + +/** + * @file lua rcl bindings + */ + +static gint lua_rcl_obj_push_array (lua_State *L, rspamd_cl_object_t *obj); +static gint lua_rcl_obj_push_simple (lua_State *L, rspamd_cl_object_t *obj); + +/** + * Push a single element of an object to lua + * @param L + * @param key + * @param obj + */ +static void +lua_rcl_obj_push_elt (lua_State *L, const char *key, rspamd_cl_object_t *obj) +{ + lua_pushstring (L, key); + lua_push_obj_simple (L, obj); + lua_settable (L, -3); +} + +/** + * Push a single object to lua + * @param L + * @param obj + * @return + */ +static gint +lua_rcl_obj_push_obj (lua_State *L, rspamd_cl_object_t *obj) +{ + rspamd_cl_object_t *cur, *tmp; + + if (obj->next != NULL) { + /* Actually we need to push this as an array */ + return lua_rcl_obj_push_array (L, obj); + } + + lua_newtable (L); + HASH_ITER (hh, obj, cur, tmp) { + lua_rcl_obj_push_elt (L, obj->key, obj); + } + + return 1; +} + +/** + * Push an array to lua as table indexed by integers + * @param L + * @param obj + * @return + */ +static gint +lua_rcl_obj_push_array (lua_State *L, rspamd_cl_object_t *obj) +{ + rspamd_cl_object_t *cur; + gint i = 1; + + lua_newtable (L); + + LL_FOREACH (obj, cur) { + lua_rcl_obj_push (L, cur); + lua_rawseti (L, -2, i); + i ++; + } + + return 1; +} + +/** + * Push a simple object to lua depending on its actual type + */ +static gint +lua_rcl_obj_push_simple (lua_State *L, rspamd_cl_object_t *obj) +{ + if (obj->next != NULL) { + /* Actually we need to push this as an array */ + return lua_rcl_obj_push_array (L, obj); + } + + switch (obj->type) { + case RSPAMD_CL_BOOLEAN: + lua_pushboolean (L, rspamd_cl_obj_toboolean (obj)); + break; + case RSPAMD_CL_STRING: + lua_pushstring (L, rspamd_cl_obj_tostring (obj)); + break; + case RSPAMD_CL_INT: +#if LUA_VERSION_NUM >= 501 + lua_pushinteger (L, rspamd_cl_obj_toint (obj)); +#else + lua_pushnumber (L, rspamd_cl_obj_toint (obj)); +#endif + break; + case RSPAMD_CL_FLOAT: + case RSPAMD_CL_TIME: + lua_pushnumber (L, rspamd_cl_obj_todouble (obj)); + break; + default: + lua_pushnil (L); + break; + } + + return 1; +} + +/** + * Push an object to lua + * @param L lua state + * @param obj object to push + */ +gint +lua_rcl_obj_push (lua_State *L, rspamd_cl_object_t *obj) +{ + switch (obj->type) { + case RSPAMD_CL_OBJECT: + return lua_rcl_obj_push_obj (L, obj->value.ov); + case RSPAMD_CL_ARRAY: + return lua_rcl_obj_push_array (L, obj->value.ov); + default: + return lua_rcl_obj_push_simple (L, obj); + } +} |