]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Migrate lua configuration to RCL.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 2 Oct 2013 22:54:49 +0000 (23:54 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 2 Oct 2013 22:54:49 +0000 (23:54 +0100)
src/lua/lua_cfg_file.c

index 2e47a49581bd6e686445d53aadbfac0f6957f0ad..4f7a3bca5b83a4af1fa22cb86458a8e488639321 100644 (file)
  * 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;
-               (*opt)->param = memory_pool_strdup (pool, name);
-               *options = g_list_prepend (*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 gchar                          *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 through module table */
-       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, param, cur, -1, TRUE);
-                       g_hash_table_insert (cfg->modules_opts, (gpointer)param, cur_opt);
-               }
-       }
-       
-       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 a single item in 'metrics' table */
 static void
 lua_process_metric (lua_State *L, const gchar *name, struct config_file *cfg)
@@ -182,122 +117,6 @@ lua_process_metric (lua_State *L, const gchar *name, struct config_file *cfg)
        }
 }
 
-/* Process single element */
-void
-lua_process_element (struct config_file *cfg, const gchar *name,
-               const gchar *module_name, struct module_opt *opt, gint idx, gboolean allow_meta)
-{
-       lua_State                            *L = cfg->lua_state;
-       gint                                  t;
-       double                              *num;
-       gboolean                             *flag;
-       GList                                *module_metas, *cur_meta;
-       struct module_meta_opt              *meta_opt, *new = NULL;
-       const gchar                         *meta_name;
-       struct module_opt                   *new_opt;
-       
-       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 = memory_pool_strdup (cfg->cfg_pool, name);
-                       opt->lua_type = LUA_VAR_FUNCTION;
-                       break;
-               case LUA_TTABLE:
-                       /* Handle meta option if possible */
-                       if (!allow_meta) {
-                               msg_warn ("meta options cannot be nested");
-                               return;
-                       }
-                       /* Meta option should not be handled by a normal option */
-                       opt->lua_type = LUA_VAR_UNKNOWN;
-                       module_metas = g_hash_table_lookup (cfg->modules_metas, module_name);
-                       cur_meta = module_metas;
-                       while (cur_meta) {
-                               meta_opt = cur_meta->data;
-                               if (g_ascii_strcasecmp (meta_opt->name, name) == 0) {
-                                       new = meta_opt;
-                                       break;
-                               }
-                               cur_meta = g_list_next (cur_meta);
-                       }
-                       if (new == NULL) {
-                               new = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct module_meta_opt));
-                               new->name = memory_pool_strdup (cfg->cfg_pool, name);
-                               module_metas = g_list_prepend (module_metas, new);
-                               g_hash_table_insert (cfg->modules_metas, (gpointer)module_name, module_metas);
-                       }
-                       /* Now iterate through the table */
-                       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 */
-                               meta_name = luaL_checkstring (L, -2);
-                               if (meta_name != NULL) {
-                                       lua_check_element (cfg->cfg_pool, meta_name, &new->options, &new_opt);
-                                       lua_process_element (cfg, meta_name, module_name, new_opt, -1, FALSE);
-                               }
-                       }
-                       break;
-               case LUA_TNIL:
-               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, key, opt, -1, TRUE);
-               }
-               cur = g_list_next (cur);
-       }
-
-}
-
 /* Do post load initialization based on lua */
 void
 lua_post_load_config (struct config_file *cfg)
@@ -306,6 +125,8 @@ lua_post_load_config (struct config_file *cfg)
        const gchar                          *name, *val;
        gchar                                *sym;
        struct expression                    *expr, *old_expr;
+       rspamd_cl_object_t                   *obj;
+       gsize                                 keylen;
 
        /* First check all module options that may be overriden in 'config' global */
        lua_getglobal (L, "config");
@@ -315,9 +136,15 @@ lua_post_load_config (struct config_file *cfg)
                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);
+                       name = luaL_checklstring (L, -2, &keylen);
                        if (name != NULL && lua_istable (L, -1)) {
-                               lua_process_module (L, name, cfg);
+                               obj = lua_rcl_obj_get (L, -1);
+                               if (obj != NULL) {
+                                       obj->key = memory_pool_alloc (cfg->cfg_pool, keylen + 1);
+                                       memcpy (obj->key, name, keylen);
+                                       obj->key[keylen] = '\0';
+                                       HASH_ADD_KEYPTR (hh, cfg->rcl_obj->value.ov, obj->key, keylen, obj);
+                               }
                        }
                }
        }
@@ -365,9 +192,6 @@ lua_post_load_config (struct config_file *cfg)
                        }
                }
        }
-
-       /* Now parse all lua params */
-       g_hash_table_foreach (cfg->modules_opts, lua_module_callback, cfg);
 }
 
 /* Handle lua dynamic config param */
@@ -375,108 +199,9 @@ gboolean
 lua_handle_param (struct worker_task *task, gchar *mname, gchar *optname, enum lua_var_type expected_type, gpointer *res)
 {
        lua_State                            *L = task->cfg->lua_state;
-       GList                                *cur;
-       struct module_opt                    *opt;
-       struct worker_task                  **ptask;
-       double                                num_res;
-       gboolean                              bool_res;
-       gchar                                *str_res;
 
-       if ((cur = g_hash_table_lookup (task->cfg->modules_opts, mname)) == NULL) {
-               *res = NULL;
-               return FALSE;
-       }
+       /* xxx: Adopt this for rcl */
        
-       /* Search for specified option */
-       while (cur) {
-               opt = cur->data;
-               if (opt->is_lua && g_ascii_strcasecmp (opt->param, optname) == 0) {
-                       if (opt->lua_type == expected_type) {
-                               /* Just push pointer to res */
-                               *res = opt->actual_data;
-                               return TRUE;
-                       }
-                       else if (opt->lua_type == LUA_VAR_FUNCTION) {
-                               /* Call specified function and expect result of given expected_type */
-                               /* First check function in config table */
-                               lua_getglobal (L, "config");
-                               if (lua_istable (L, -1)) {
-                                       lua_pushstring (L, mname);
-                                       lua_gettable (L, -2);
-                                       if (lua_isnil (L, -1)) {
-                                               /* Try to get global variable */
-                                               lua_getglobal (L, opt->actual_data);
-                                       }
-                                       else {
-                                               /* Call local function in table */
-                                               lua_pushstring (L, opt->actual_data);
-                                               lua_gettable (L, -2);
-                                       }
-                               }
-                               else {
-                                       /* Try to get global variable */
-                                       lua_getglobal (L, opt->actual_data);
-                               }
-                               if (lua_isnil (L, -1)) {
-                                       msg_err ("function with name %s is not defined", (gchar *)opt->actual_data);
-                                       return FALSE;
-                               }
-                               /* Now we got function in top of stack */
-                               ptask = lua_newuserdata (L, sizeof (struct worker_task *));
-                               lua_setclass (L, "rspamd{task}", -1);
-                               *ptask = task;
-                               /* Call function */
-                               if (lua_pcall (L, 1, 1, 0) != 0) {
-                                       msg_info ("call to %s failed: %s", (gchar *)opt->actual_data, lua_tostring (L, -1));
-                                       *res = NULL;
-                                       return FALSE;
-                               }
-                               /* Get result of specified type */
-                               switch (expected_type) {
-                                       case LUA_VAR_NUM:
-                                               if (!lua_isnumber (L, -1)) {
-                                                       lua_pop (L, 1);
-                                                       *res = NULL;
-                                                       return FALSE;
-                                               }
-                                               num_res = lua_tonumber (L, -1);
-                                               *res = memory_pool_alloc (task->task_pool, sizeof (double));
-                                               **(double **)res = num_res;
-                                               lua_pop (L, 1);
-                                               return TRUE;
-                                       case LUA_VAR_BOOLEAN:
-                                               if (!lua_isboolean (L, -1)) {
-                                                       lua_pop (L, 1);
-                                                       *res = NULL;
-                                                       return FALSE;
-                                               }
-                                               bool_res = lua_toboolean (L, -1);
-                                               *res = memory_pool_alloc (task->task_pool, sizeof (gboolean));
-                                               **(gboolean **)res = bool_res;
-                                               lua_pop (L, 1);
-                                               return TRUE;
-                                       case LUA_VAR_STRING:
-                                               if (!lua_isstring (L, -1)) {
-                                                       lua_pop (L, 1);
-                                                       *res = NULL;
-                                                       return FALSE;
-                                               }
-                                               str_res = memory_pool_strdup (task->task_pool, lua_tostring (L, -1));
-                                               *res = str_res;
-                                               lua_pop (L, 1);
-                                               return TRUE;
-                                       case LUA_VAR_FUNCTION:
-                                       case LUA_VAR_UNKNOWN:
-                                               lua_pop (L, 1);
-                                               msg_err ("cannot expect function or unknown types");
-                                               *res = NULL;
-                                               return FALSE;
-                               }
-                       }
-               }
-               cur = g_list_next (cur);
-       }
-
        /* Option not found */
        *res = NULL;
        return FALSE;