aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua')
-rw-r--r--src/lua/CMakeLists.txt3
-rw-r--r--src/lua/lua_common.h8
-rw-r--r--src/lua/lua_config.c80
-rw-r--r--src/lua/lua_rcl.c148
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);
+ }
+}