aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cfg_file.h11
-rw-r--r--src/cfg_utils.c93
-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
6 files changed, 178 insertions, 165 deletions
diff --git a/src/cfg_file.h b/src/cfg_file.h
index 89e4870db..e7e122977 100644
--- a/src/cfg_file.h
+++ b/src/cfg_file.h
@@ -348,8 +348,7 @@ struct config_file {
GList *workers; /**< linked list of all workers params */
struct rspamd_worker_cfg_parser *wrk_parsers; /**< hash for worker config parsers, indexed by worker quarks */
gchar *filters_str; /**< string of filters */
- GHashTable* modules_opts; /**< hash for module options indexed by module name */
- GHashTable* modules_metas; /**< hash for module meta options indexed by module name*/
+ rspamd_cl_object_t *rcl_obj; /**< rcl object */
GHashTable* variables; /**< hash of $variables defined in config, indexed by variable name */
GHashTable* metrics; /**< hash of metrics indexed by metric name */
GList* symbols_groups; /**< groups of symbols */
@@ -449,7 +448,8 @@ void free_config (struct config_file *cfg);
* @param opt_name name of option to get
* @return module value or NULL if option does not defined
*/
-gchar* get_module_opt (struct config_file *cfg, gchar *module_name, gchar *opt_name);
+rspamd_cl_object_t* get_module_opt (struct config_file *cfg, const gchar *module_name,
+ const gchar *opt_name);
/**
* Parse limit
@@ -535,11 +535,6 @@ gboolean parse_normalizer (struct config_file *cfg, struct statfile *st, const g
gboolean read_xml_config (struct config_file *cfg, const gchar *filename);
/*
- * Check modules configuration for semantic validity
- */
-gboolean check_modules_config (struct config_file *cfg);
-
-/*
* Register symbols of classifiers inside metrics
*/
void insert_classifier_symbols (struct config_file *cfg);
diff --git a/src/cfg_utils.c b/src/cfg_utils.c
index e7e57cd8a..906f4406f 100644
--- a/src/cfg_utils.c
+++ b/src/cfg_utils.c
@@ -241,8 +241,6 @@ init_defaults (struct config_file *cfg)
cfg->max_diff = 20480;
cfg->max_statfile_size = DEFAULT_STATFILE_SIZE;
- cfg->modules_opts = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
- cfg->modules_metas = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
cfg->variables = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
cfg->metrics = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
cfg->c_modules = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
@@ -267,9 +265,7 @@ free_config (struct config_file *cfg)
struct symbols_group *gr;
remove_all_maps (cfg);
- g_hash_table_remove_all (cfg->modules_opts);
- g_hash_table_unref (cfg->modules_opts);
- g_hash_table_unref (cfg->modules_metas);
+ rspamd_cl_obj_unref (cfg->rcl_obj);
g_hash_table_remove_all (cfg->variables);
g_hash_table_unref (cfg->variables);
g_hash_table_remove_all (cfg->metrics);
@@ -303,51 +299,17 @@ free_config (struct config_file *cfg)
memory_pool_delete (cfg->cfg_pool);
}
-gchar *
-get_module_opt (struct config_file *cfg, gchar *module_name, gchar *opt_name)
+rspamd_cl_object_t *
+get_module_opt (struct config_file *cfg, const gchar *module_name, const gchar *opt_name)
{
- GList *cur_opt;
- struct module_opt *cur;
- static gchar numbuf[64];
+ rspamd_cl_object_t *res = NULL, *sec;
- cur_opt = g_hash_table_lookup (cfg->modules_opts, module_name);
- if (cur_opt == NULL) {
- return NULL;
+ sec = rspamd_cl_obj_get_key (cfg->rcl_obj, module_name);
+ if (sec != NULL) {
+ res = rspamd_cl_obj_get_key (cfg->rcl_obj, opt_name);
}
- while (cur_opt) {
- cur = cur_opt->data;
- if (strcmp (cur->param, opt_name) == 0) {
- /* Check if it is lua variable */
- if (! cur->is_lua) {
- /* Plain variable */
- return cur->value;
- }
- else {
- /* Check type */
- switch (cur->lua_type) {
- case LUA_VAR_NUM:
- /* numbuf is static, so it is safe to return it "as is" */
- snprintf (numbuf, sizeof (numbuf), "%f", *(double *)cur->actual_data);
- return numbuf;
- case LUA_VAR_BOOLEAN:
- snprintf (numbuf, sizeof (numbuf), "%s", *(gboolean *)cur->actual_data ? "yes" : "no");
- return numbuf;
- case LUA_VAR_STRING:
- return (gchar *)cur->actual_data;
- case LUA_VAR_FUNCTION:
- msg_info ("option %s is dynamic, so it cannot be aqquired statically", opt_name);
- return NULL;
- case LUA_VAR_UNKNOWN:
- msg_info ("option %s has unknown type, maybe there is error in LUA code", opt_name);
- return NULL;
- }
- }
- }
- cur_opt = g_list_next (cur_opt);
- }
-
- return NULL;
+ return res;
}
guint64
@@ -696,7 +658,6 @@ post_load_config (struct config_file *cfg)
struct metric *def_metric;
g_hash_table_foreach (cfg->variables, substitute_all_variables, cfg);
- g_hash_table_foreach (cfg->modules_opts, substitute_module_variables, cfg);
fill_cfg_params (cfg);
#ifdef HAVE_CLOCK_GETTIME
@@ -1043,44 +1004,6 @@ read_xml_config (struct config_file *cfg, const gchar *filename)
}
static void
-modules_config_callback (gpointer key, gpointer value, gpointer ud)
-{
- extern GHashTable *module_options;
- GHashTable *cur_module;
- GList *cur;
- struct module_opt *opt;
- const gchar *mname = key;
- gboolean *res = ud;
-
- if ((cur_module = g_hash_table_lookup (module_options, mname)) == NULL) {
- msg_warn ("module %s has not registered any options but is presented in configuration", mname);
- *res = FALSE;
- return;
- }
-
- cur = value;
- while (cur) {
- opt = cur->data;
-
- if (!opt->is_lua && !check_module_option (mname, opt->param, opt->value)) {
- *res = FALSE;
- return;
- }
-
- cur = g_list_next (cur);
- }
-}
-
-gboolean
-check_modules_config (struct config_file *cfg)
-{
- gboolean res = TRUE;
-
- g_hash_table_foreach (cfg->modules_opts, modules_config_callback, &res);
- return res;
-}
-
-static void
symbols_classifiers_callback (gpointer key, gpointer value, gpointer ud)
{
struct config_file *cfg = ud;
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);
+ }
+}