]> source.dussan.org Git - rspamd.git/commitdiff
Process lua files from configuration.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 26 Oct 2013 15:14:40 +0000 (16:14 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sat, 26 Oct 2013 15:14:40 +0000 (16:14 +0100)
src/cfg_rcl.c
src/cfg_xml.c

index a993a4aceaa901cec90665419221dbc4bcab2937..8cd6d2217a7d58f955cb9dfe30c33f5431b5f382 100644 (file)
@@ -24,6 +24,7 @@
 #include "cfg_rcl.h"
 #include "main.h"
 #include "settings.h"
+#include "lua/lua_common.h"
 
 /*
  * Common section handlers
@@ -506,6 +507,115 @@ rspamd_rcl_worker_handler (struct config_file *cfg, ucl_object_t *obj,
        return TRUE;
 }
 
+static void
+rspamd_rcl_set_lua_globals (struct config_file *cfg, lua_State *L)
+{
+       struct config_file           **pcfg;
+
+       /* First check for global variable 'config' */
+       lua_getglobal (L, "config");
+       if (lua_isnil (L, -1)) {
+               /* Assign global table to set up attributes */
+               lua_newtable (L);
+               lua_setglobal (L, "config");
+       }
+
+       lua_getglobal (L, "metrics");
+       if (lua_isnil (L, -1)) {
+               lua_newtable (L);
+               lua_setglobal (L, "metrics");
+       }
+
+       lua_getglobal (L, "composites");
+       if (lua_isnil (L, -1)) {
+               lua_newtable (L);
+               lua_setglobal (L, "composites");
+       }
+
+       lua_getglobal (L, "classifiers");
+       if (lua_isnil (L, -1)) {
+               lua_newtable (L);
+               lua_setglobal (L, "classifiers");
+       }
+
+       pcfg = lua_newuserdata (L, sizeof (struct config_file *));
+       lua_setclass (L, "rspamd{config}", -1);
+       *pcfg = cfg;
+       lua_setglobal (L, "rspamd_config");
+
+       /* Clear stack from globals */
+       lua_pop (L, 4);
+}
+
+static gboolean
+rspamd_rcl_lua_handler (struct config_file *cfg, ucl_object_t *obj,
+               gpointer ud, struct rspamd_rcl_section *section, GError **err)
+{
+       const gchar *lua_src = ucl_object_tostring (obj);
+       gchar *cur_dir, *lua_dir, *lua_file, *tmp1, *tmp2;
+       lua_State *L = cfg->lua_state;
+
+       tmp1 = g_strdup (lua_src);
+       tmp2 = g_strdup (lua_src);
+       lua_dir = dirname (tmp1);
+       lua_file = basename (tmp2);
+       if (lua_dir && lua_file) {
+               cur_dir = g_malloc (PATH_MAX);
+               if (getcwd (cur_dir, PATH_MAX) != NULL && chdir (lua_dir) != -1) {
+                       /* Load file */
+                       if (luaL_loadfile (L, lua_file) != 0) {
+                               g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot load lua file %s: %s",
+                                               lua_src, lua_tostring (L, -1));
+                               if (chdir (cur_dir) == -1) {
+                                       msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
+                               }
+                               g_free (cur_dir);
+                               g_free (tmp1);
+                               g_free (tmp2);
+                               return FALSE;
+                       }
+                       rspamd_rcl_set_lua_globals (cfg, L);
+                       /* Now do it */
+                       if (lua_pcall (L, 0, LUA_MULTRET, 0) != 0) {
+                               g_set_error (err, CFG_RCL_ERROR, EINVAL, "cannot init lua file %s: %s",
+                                               lua_src, lua_tostring (L, -1));
+                               if (chdir (cur_dir) == -1) {
+                                       msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
+                               }
+                               g_free (cur_dir);
+                               g_free (tmp1);
+                               g_free (tmp2);
+                               return FALSE;
+                       }
+               }
+               else {
+                       g_set_error (err, CFG_RCL_ERROR, ENOENT, "cannot chdir to %s: %s",
+                                       lua_src, strerror (errno));
+                       if (chdir (cur_dir) == -1) {
+                               msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
+                       }
+                       g_free (cur_dir);
+                       g_free (tmp1);
+                       g_free (tmp2);
+                       return FALSE;
+
+               }
+               if (chdir (cur_dir) == -1) {
+                       msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
+               }
+               g_free (cur_dir);
+               g_free (tmp1);
+               g_free (tmp2);
+       }
+       else {
+               g_set_error (err, CFG_RCL_ERROR, ENOENT, "cannot find to %s: %s",
+                                                       lua_src, strerror (errno));
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 /**
  * Fake handler to parse default options only, uses struct cfg_file as pointer
  * for default handlers
@@ -653,6 +763,12 @@ rspamd_rcl_config_init (void)
        rspamd_rcl_add_default_handler (sub, "max_core", rspamd_rcl_parse_struct_integer,
                        G_STRUCT_OFFSET (struct worker_conf, rlimit_maxcore), RSPAMD_CL_FLAG_INT_32);
 
+       /**
+        * Lua handler
+        */
+       sub = rspamd_rcl_add_section (&new, "lua", rspamd_rcl_lua_handler, UCL_STRING,
+                       FALSE, TRUE);
+
        return new;
 }
 
index 68ea5e3fdd9cb1e3d7d5502608ae80abc8b98ff4..4e3757bad221af463609587cdac1b08af4f853d6 100644 (file)
@@ -755,126 +755,6 @@ process_attrs (const gchar **attribute_names, const gchar **attribute_values, uc
 
 /* Handlers */
 
-static void
-set_lua_globals (struct config_file *cfg, lua_State *L)
-{
-       struct config_file           **pcfg;
-
-       /* First check for global variable 'config' */
-       lua_getglobal (L, "config");
-       if (lua_isnil (L, -1)) {
-               /* Assign global table to set up attributes */
-               lua_newtable (L);
-               lua_setglobal (L, "config");
-       }
-
-       lua_getglobal (L, "metrics");
-       if (lua_isnil (L, -1)) {
-               lua_newtable (L);
-               lua_setglobal (L, "metrics");
-       }
-
-       lua_getglobal (L, "composites");
-       if (lua_isnil (L, -1)) {
-               lua_newtable (L);
-               lua_setglobal (L, "composites");
-       }
-
-       lua_getglobal (L, "classifiers");
-       if (lua_isnil (L, -1)) {
-               lua_newtable (L);
-               lua_setglobal (L, "classifiers");
-       }
-
-       pcfg = lua_newuserdata (L, sizeof (struct config_file *));
-       lua_setclass (L, "rspamd{config}", -1);
-       *pcfg = cfg;
-       lua_setglobal (L, "rspamd_config");
-
-       /* Clear stack from globals */
-       lua_pop (L, 4);
-}
-
-/* Handle lua tag */
-gboolean
-handle_lua (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
-{
-       gchar                        *val, *cur_dir, *lua_dir, *lua_file, *tmp1, *tmp2;
-       lua_State                    *L = cfg->lua_state;
-
-       /* Now config tables can be used for configuring rspamd */
-       /* First check "src" attribute */
-       if (attrs != NULL && (val = g_hash_table_lookup (attrs, "src")) != NULL) {
-               /* Chdir */
-               tmp1 = g_strdup (val);
-               tmp2 = g_strdup (val);
-               lua_dir = dirname (tmp1);
-               lua_file = basename (tmp2);
-               if (lua_dir && lua_file) {
-                       cur_dir = g_malloc (PATH_MAX);
-                       if (getcwd (cur_dir, PATH_MAX) != NULL && chdir (lua_dir) != -1) {
-                               /* Load file */
-                               if (luaL_loadfile (L, lua_file) != 0) {
-                                       msg_err ("cannot load lua file %s: %s", val, lua_tostring (L, -1));
-                                       if (chdir (cur_dir) == -1) {
-                                               msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
-                                       }
-                                       g_free (cur_dir);
-                                       g_free (tmp1);
-                                       g_free (tmp2);
-                                       return FALSE;
-                               }
-                               set_lua_globals (cfg, L);
-                               /* Now do it */
-                               if (lua_pcall (L, 0, LUA_MULTRET, 0) != 0) {
-                                       msg_err ("init of %s failed: %s", val, lua_tostring (L, -1));
-                                       if (chdir (cur_dir) == -1) {
-                                               msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
-                                       }
-                                       g_free (cur_dir);
-                                       g_free (tmp1);
-                                       g_free (tmp2);
-                                       return FALSE;
-                               }
-                       }
-                       else {
-                               msg_err ("cannot chdir to %s: %s", lua_dir, strerror (errno));;
-                               if (chdir (cur_dir) == -1) {
-                                       msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
-                               }
-                               g_free (cur_dir);
-                               g_free (tmp1);
-                               g_free (tmp2);
-                               return FALSE;
-                       
-                       }
-                       if (chdir (cur_dir) == -1) {
-                               msg_err ("cannot chdir to %s: %s", cur_dir, strerror (errno));;
-                       }
-                       g_free (cur_dir);
-                       g_free (tmp1);
-                       g_free (tmp2);
-               }
-               else {
-                       msg_err ("directory for file %s does not exists", val);
-               }
-       }
-       else if (data != NULL && *data != '\0') {
-               /* Try to load a string */
-               if (luaL_loadstring (L, data) != 0) {
-                       msg_err ("cannot load lua chunk: %s", lua_tostring (L, -1));
-                       return FALSE;
-               }
-               set_lua_globals (cfg, L);
-               /* Now do it */
-               if (lua_pcall (L, 0, LUA_MULTRET, 0) != 0) {
-                       msg_err ("init of lua chunk failed: %s", lua_tostring (L, -1));
-                       return FALSE;
-               }
-
-       }
-       return TRUE;
-}
 
 /* Modules section */
 gboolean 
@@ -1082,12 +962,23 @@ rspamd_xml_start_element (GMarkupParseContext *context, const gchar *element_nam
                        rspamd_strlcpy (ud->section_name[ud->nested], element_name, MAX_NAME);
                        if (ud->nested == 0) {
                                /* Top object */
-                               obj = ucl_object_new ();
-                               obj->type = UCL_OBJECT;
-                               ud->parent_pointer[0] = obj;
-                               ud->cfg->rcl_obj = ucl_object_insert_key (ud->cfg->rcl_obj, obj, element_name, 0, true);
-                               process_attrs (attribute_names, attribute_values, obj);
-                               ud->nested ++;
+
+                               if (g_ascii_strcasecmp (element_name, "lua") == 0 &&
+                                               extract_attr ("src", attribute_names, attribute_values, &res)) {
+                                       /* Lua is 'special' tag */
+                                       obj = ucl_object_fromstring (res);
+                                       ud->cfg->rcl_obj = ucl_object_insert_key (ud->cfg->rcl_obj, obj, element_name, 0, true);
+                                       ud->parent_pointer[0] = obj;
+                                       ud->nested ++;
+                               }
+                               else {
+                                       obj = ucl_object_new ();
+                                       obj->type = UCL_OBJECT;
+                                       ud->parent_pointer[0] = obj;
+                                       ud->cfg->rcl_obj = ucl_object_insert_key (ud->cfg->rcl_obj, obj, element_name, 0, true);
+                                       process_attrs (attribute_names, attribute_values, obj);
+                                       ud->nested ++;
+                               }
                        }
                        else {
                                tobj = ucl_object_new ();
@@ -1160,10 +1051,11 @@ rspamd_xml_text (GMarkupParseContext *context, const gchar *text, gsize text_len
                return;
        }
 
+
        top = ud->parent_pointer[ud->nested - 1];
        ud->parent_pointer[ud->nested - 1] =
                        ucl_object_insert_key (top, ucl_object_fromstring_common (text, text_len, UCL_STRING_PARSE),
-                       ud->section_name[ud->nested], 0, true);
+                                       ud->section_name[ud->nested], 0, true);
 }
 
 void