From: Vsevolod Stakhov Date: Tue, 25 Jan 2011 19:26:55 +0000 (+0300) Subject: * Make trie plugin and fix trie lua API X-Git-Tag: 0.3.7~72 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=61078f0274de4d99c153349dc01a27567c50e489;p=rspamd.git * Make trie plugin and fix trie lua API --- diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 3b81ce64e..8259ae9a4 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -89,13 +89,16 @@ LUA_FUNCTION_DEF (trie, search_text); LUA_FUNCTION_DEF (trie, search_task); static const struct luaL_reg trielib_m[] = { - LUA_INTERFACE_DEF (trie, create), LUA_INTERFACE_DEF (trie, add_pattern), LUA_INTERFACE_DEF (trie, search_text), LUA_INTERFACE_DEF (trie, search_task), {"__tostring", lua_class_tostring}, {NULL, NULL} }; +static const struct luaL_reg trielib_f[] = { + LUA_INTERFACE_DEF (trie, create), + {NULL, NULL} +}; static struct config_file * lua_check_config (lua_State * L) @@ -125,8 +128,9 @@ static rspamd_trie_t * lua_check_trie (lua_State * L) { void *ud = luaL_checkudata (L, 1, "rspamd{trie}"); + luaL_argcheck (L, ud != NULL, 1, "'trie' expected"); - return **((rspamd_trie_t ***)ud); + return *((rspamd_trie_t **)ud); } /*** Config functions ***/ @@ -749,8 +753,17 @@ luaopen_hash_table (lua_State * L) gint luaopen_trie (lua_State * L) { - lua_newclass (L, "rspamd{trie}", trielib_m); - luaL_openlib (L, "rspamd_trie", null_reg, 0); + luaL_newmetatable (L, "rspamd{trie}"); + lua_pushstring (L, "__index"); + lua_pushvalue (L, -2); + lua_settable (L, -3); + + lua_pushstring (L, "class"); + lua_pushstring (L, "rspamd{trie}"); + lua_rawset (L, -3); + + luaL_openlib (L, NULL, trielib_m, 0); + luaL_openlib(L, "rspamd_trie", trielib_f, 0); return 1; } diff --git a/src/plugins/lua/trie.lua b/src/plugins/lua/trie.lua new file mode 100644 index 000000000..d4bafe943 --- /dev/null +++ b/src/plugins/lua/trie.lua @@ -0,0 +1,102 @@ +-- Trie is rspamd module designed to define and operate with suffix trie + +local tries = {} + +local function split(str, delim, maxNb) + -- Eliminate bad cases... + if string.find(str, delim) == nil then + return { str } + end + if maxNb == nil or maxNb < 1 then + maxNb = 0 -- No limit + end + local result = {} + local pat = "(.-)" .. delim .. "()" + local nb = 0 + local lastPos + for part, pos in string.gfind(str, pat) do + nb = nb + 1 + result[nb] = part + lastPos = pos + if nb == maxNb then break end + end + -- Handle the last field + if nb ~= maxNb then + result[nb + 1] = string.sub(str, lastPos) + end + return result +end + +local function add_trie(params) + local symbol = params[1] + + file = io.open(params[2]) + if file then + local trie = {} + trie['trie'] = rspamd_trie:create(true) + num = 0 + for line in file:lines() do + trie['trie']:add_pattern(line, num) + num = num + 1 + end + + if type(rspamd_config.get_api_version) ~= 'nil' then + rspamd_config:register_virtual_symbol(symbol, 1.0) + end + file:close() + trie['symbol'] = symbol + table.insert(tries, trie) + else + local patterns = split(params[2], ',') + local trie = {} + trie['trie'] = rspamd_trie:create(true) + print (type(trie['trie'])) + for num,pattern in ipairs(patterns) do + trie['trie']:add_pattern(pattern, num) + end + if type(rspamd_config.get_api_version) ~= 'nil' then + rspamd_config:register_virtual_symbol(symbol, 1.0) + end + trie['symbol'] = symbol + table.insert(tries, trie) + end +end + +function check_trie(task) + for _,trie in ipairs(tries) do + print (type(trie['trie'])) + if trie['trie']:search_task(task) then + task:insert_result(trie['symbol'], 1) + end + end +end + +-- Registration +if type(rspamd_config.get_api_version) ~= 'nil' then + if rspamd_config:get_api_version() >= 1 then + rspamd_config:register_module_option('trie', 'rule', 'string') + end +end + +local opts = rspamd_config:get_all_opt('trie') +if opts then + local strrules = opts['rule'] + if strrules then + if type(strrules) == 'table' then + for _,value in ipairs(strrules) do + local params = split(value, ':') + add_trie(params) + end + elseif type(strrules) == 'string' then + local params = split(strrules, ':') + add_trie (params) + end + end + if table.maxn(tries) then + if type(rspamd_config.get_api_version) ~= 'nil' then + rspamd_config:register_callback_symbol('TRIE', 1.0, 'check_trie') + else + rspamd_config:register_symbol('TRIE', 1.0, 'check_trie') + end + end +end