aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2010-04-05 21:09:40 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2010-04-05 21:09:40 +0400
commit42baae32bc212e9287e11afa685e2de77cdf48e4 (patch)
tree1bf9ad6eeb94a0bf40e8d60ed1a0777aa23aa69d /src/lua
parent6be82def714f297d54302953286223b4afb07208 (diff)
downloadrspamd-42baae32bc212e9287e11afa685e2de77cdf48e4.tar.gz
rspamd-42baae32bc212e9287e11afa685e2de77cdf48e4.zip
* Add initial version of lua configuration system
Diffstat (limited to 'src/lua')
-rw-r--r--src/lua/CMakeLists.txt3
-rw-r--r--src/lua/lua_cfg_file.c196
-rw-r--r--src/lua/lua_common.c5
-rw-r--r--src/lua/lua_common.h9
4 files changed, 210 insertions, 3 deletions
diff --git a/src/lua/CMakeLists.txt b/src/lua/CMakeLists.txt
index d0ac4f826..c17936862 100644
--- a/src/lua/CMakeLists.txt
+++ b/src/lua/CMakeLists.txt
@@ -3,7 +3,8 @@ SET(LUASRC lua_common.c
lua_task.c
lua_message.c
lua_config.c
- lua_classifier.c)
+ lua_classifier.c
+ lua_cfg_file.c)
ADD_LIBRARY(rspamd_lua STATIC ${LUASRC})
TARGET_LINK_LIBRARIES(rspamd_lua ${LUALIB})
diff --git a/src/lua/lua_cfg_file.c b/src/lua/lua_cfg_file.c
new file mode 100644
index 000000000..1ac334299
--- /dev/null
+++ b/src/lua/lua_cfg_file.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2009, Rambler media
+ * 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 BY Rambler media ''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 Rambler 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"
+
+/*
+ * This is implementation of lua routines to handle config file params
+ */
+
+
+/* Check element with specified name in list, and append it to list if no element with such name was found */
+static void
+lua_check_element (memory_pool_t *pool, const gchar *name, GList *options, struct module_opt **opt)
+{
+ struct module_opt *cur;
+ GList *cur_opt;
+ gboolean found = FALSE;
+
+ cur_opt = options;
+
+ while (cur_opt) {
+ cur = cur_opt->data;
+
+ if (g_ascii_strcasecmp (cur->param, name) == 0) {
+ found = TRUE;
+ break;
+ }
+ cur_opt = g_list_next (cur_opt);
+ }
+
+ if (found) {
+ *opt = cur;
+ cur->is_lua = TRUE;
+ }
+ else {
+ /* New option */
+ *opt = memory_pool_alloc0 (pool, sizeof (struct module_opt));
+ (*opt)->is_lua = TRUE;
+ (void)g_list_append (options, *opt);
+ }
+}
+
+/* Process a single item in 'config' table */
+static void
+lua_process_module (lua_State *L, const gchar *param, struct config_file *cfg)
+{
+ GList *cur_opt;
+ struct module_opt *cur;
+ const char *name;
+ gboolean new_module = FALSE;
+
+ /* Get module opt structure */
+ if ((cur_opt = g_hash_table_lookup (cfg->modules_opts, param)) == NULL) {
+ new_module = TRUE;
+ }
+
+ /* Now iterate throught module table */
+ lua_gettable (L, -1);
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ /* key - -2, value - -1 */
+ name = luaL_checkstring (L, -2);
+ if (name != NULL) {
+ lua_check_element (cfg->cfg_pool, name, cur_opt, &cur);
+ lua_process_element (cfg, name, cur, -1);
+ }
+ }
+
+ if (new_module && cur_opt != NULL) {
+ /* Insert new list into a hash */
+ g_hash_table_insert (cfg->modules_opts, memory_pool_strdup (cfg->cfg_pool, param), cur_opt);
+ }
+}
+
+/* Process single element */
+void
+lua_process_element (struct config_file *cfg, const char *name, struct module_opt *opt, int idx)
+{
+ lua_State *L = cfg->lua_state;
+ int t;
+ double *num;
+ gboolean *flag;
+
+ t = lua_type (L, idx);
+ /* Handle type */
+ switch (t) {
+ case LUA_TNUMBER:
+ opt->actual_data = memory_pool_alloc (cfg->cfg_pool, sizeof (double));
+ num = (double *)opt->actual_data;
+ *num = lua_tonumber (L, idx);
+ opt->lua_type = LUA_VAR_NUM;
+ break;
+ case LUA_TBOOLEAN:
+ opt->actual_data = memory_pool_alloc (cfg->cfg_pool, sizeof (gboolean));
+ flag = (gboolean *)opt->actual_data;
+ *flag = lua_toboolean (L, idx);
+ opt->lua_type = LUA_VAR_BOOLEAN;
+ break;
+ case LUA_TSTRING:
+ opt->actual_data = memory_pool_strdup (cfg->cfg_pool, lua_tostring (L, idx));
+ opt->lua_type = LUA_VAR_STRING;
+ break;
+ case LUA_TFUNCTION:
+ opt->actual_data = (gpointer)lua_topointer (L, idx);
+ opt->lua_type = LUA_VAR_FUNCTION;
+ break;
+ case LUA_TNIL:
+ case LUA_TTABLE:
+ case LUA_TUSERDATA:
+ case LUA_TTHREAD:
+ case LUA_TLIGHTUSERDATA:
+ msg_warn ("cannot handle variables of type %s as there is nothing to do with them", lua_typename (L, t));
+ opt->lua_type = LUA_VAR_UNKNOWN;
+ break;
+ }
+}
+
+
+static void
+lua_module_callback (gpointer key, gpointer value, gpointer ud)
+{
+ struct config_file *cfg = ud;
+ lua_State *L = cfg->lua_state;
+ GList *cur;
+ struct module_opt *opt;
+
+ cur = value;
+ while (cur) {
+ opt = cur->data;
+ if (opt->is_lua && opt->actual_data == NULL) {
+ /* Try to extract variable name from config table first */
+ lua_getglobal (L, "config");
+ if (lua_istable (L, -1)) {
+ lua_pushstring (L, opt->param);
+ lua_gettable (L, -2);
+ if (lua_isnil (L, -1)) {
+ /* Try to get global variable */
+ lua_getglobal (L, opt->param);
+ }
+ }
+ else {
+ /* Try to get global variable */
+ lua_getglobal (L, opt->param);
+ }
+ lua_process_element (cfg, opt->param, opt, -1);
+ }
+ cur = g_list_next (cur);
+ }
+
+}
+
+/* Do post load initialization based on lua */
+void
+lua_post_load_config (struct config_file *cfg)
+{
+ lua_State *L = cfg->lua_state;
+ const gchar *name;
+
+ /* First check all module options that may be overriden in 'config' global */
+ lua_getglobal (L, "config");
+
+ if (lua_istable (L, -1)) {
+ /* Iterate */
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ /* 'key' is at index -2 and 'value' is at index -1 */
+ /* Key must be a string and value must be a table */
+ name = luaL_checkstring (L, -2);
+ if (name != NULL && lua_istable (L, -1)) {
+ lua_process_module (L, name, cfg);
+ }
+ }
+ }
+
+ /* Now parse all lua params */
+ g_hash_table_foreach (cfg->modules_opts, lua_module_callback, cfg);
+}
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c
index 1f39975d0..3d4e29b28 100644
--- a/src/lua/lua_common.c
+++ b/src/lua/lua_common.c
@@ -180,7 +180,7 @@ luaopen_logger (lua_State * L)
return 1;
}
-static void
+void
init_lua ()
{
if (L == NULL) {
@@ -211,7 +211,6 @@ init_lua_filters (struct config_file *cfg)
struct script_module *module;
struct statfile *st;
- init_lua ();
cur = g_list_first (cfg->script_modules);
while (cur) {
module = cur->data;
@@ -251,6 +250,8 @@ init_lua_filters (struct config_file *cfg)
}
cur = g_list_next (cur);
}
+ /* Assign state */
+ cfg->lua_state = L;
}
/* Callback functions */
diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h
index a1820d064..5de7bdc71 100644
--- a/src/lua/lua_common.h
+++ b/src/lua/lua_common.h
@@ -16,6 +16,7 @@
extern const luaL_reg null_reg[];
+/* Common utility functions */
void lua_newclass (lua_State *L, const char *classname, const struct luaL_reg *func);
void lua_setclass (lua_State *L, const char *classname, int objidx);
void lua_set_table_index (lua_State *L, const char *index, const char *value);
@@ -29,17 +30,25 @@ int luaopen_hash_table (lua_State *L);
int luaopen_textpart (lua_State *L);
int luaopen_classifier (lua_State *L);
int luaopen_statfile (lua_State * L);
+void init_lua ();
void init_lua_filters (struct config_file *cfg);
+/* Filters functions */
int lua_call_filter (const char *function, struct worker_task *task);
int lua_call_chain_filter (const char *function, struct worker_task *task, int *marks, unsigned int number);
double lua_consolidation_func (struct worker_task *task, const char *metric_name, const char *function_name);
void add_luabuf (const char *line);
+/* Classify functions */
GList *call_classifier_pre_callbacks (struct classifier_config *ccf, struct worker_task *task);
double call_classifier_post_callbacks (struct classifier_config *ccf, struct worker_task *task, double in);
double lua_normalizer_func (double score, void *params);
+/* Config file functions */
+void lua_post_load_config (struct config_file *cfg);
+void lua_process_element (struct config_file *cfg, const char *name, struct module_opt *opt, int idx);
+
+
#endif /* WITH_LUA */
#endif /* RSPAMD_LUA_H */