diff options
author | cebka@lenovo-laptop <cebka@lenovo-laptop> | 2010-01-13 16:35:17 +0300 |
---|---|---|
committer | cebka@lenovo-laptop <cebka@lenovo-laptop> | 2010-01-13 16:35:17 +0300 |
commit | fc70f10e7c2a7b0aeb5da7b28c64131b03538e76 (patch) | |
tree | b1c8ad0c8772f035a4b2fe2fc5dd43dff439f927 /src/cfg_utils.c | |
parent | d544f1d5770f56bf8b2b75ca7a04ac5441069e68 (diff) | |
download | rspamd-fc70f10e7c2a7b0aeb5da7b28c64131b03538e76.tar.gz rspamd-fc70f10e7c2a7b0aeb5da7b28c64131b03538e76.zip |
* Add ability to add normalizers for statfiles (custom functions written in lua or simple internal normalizer)
Diffstat (limited to 'src/cfg_utils.c')
-rw-r--r-- | src/cfg_utils.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/cfg_utils.c b/src/cfg_utils.c index a5d842a68..ca12a22d0 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -31,6 +31,9 @@ #include "filter.h" #include "settings.h" #include "classifiers/classifiers.h" +#ifdef WITH_LUA +#include "lua/lua_common.h" +#endif #define DEFAULT_SCORE 10.0 @@ -653,6 +656,110 @@ check_worker_conf (struct config_file *cfg, struct worker_conf *c) return c; } + +static double +internal_normalizer_func (double score, void *data) +{ + double max = *(double *)data; + + if (score < 0) { + return score; + } + else if (score > 0.001 && score > 1) { + return 1; + } + else if (score > 1 && score < max / 2.) { + return MIN(max, score * score); + } + else if (score < max) { + return score; + } + else if (score > max) { + return max; + } + + return score; +} + +static gboolean +parse_internal_normalizer (struct config_file *cfg, struct statfile *st, const char *line) +{ + double *max; + char *err; + + /* Line contains maximum value for internal normalizer */ + max = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); + + errno = 0; + *max = strtod (line, &err); + + if (errno != 0 || *err != '\0') { + msg_err ("cannot parse max number for internal normalizer"); + return FALSE; + } + + st->normalizer = internal_normalizer_func; + st->normalizer_data = (void *)max; + return TRUE; +} + +#ifdef WITH_LUA +static gboolean +parse_lua_normalizer (struct config_file *cfg, struct statfile *st, const char *line) +{ + char *code_begin; + GList *params = NULL; + int len; + + code_begin = strchr (line, ':'); + + if (code_begin == NULL) { + /* Just function name without code */ + params = g_list_prepend (g_list_prepend (NULL, NULL), memory_pool_strdup (cfg->cfg_pool, line)); + } + else { + /* Postpone actual code load as lua libraries are not loaded */ + /* Put code to list */ + params = g_list_prepend (NULL, code_begin + 1); + /* Put function name */ + len = code_begin - line; + code_begin = memory_pool_alloc (cfg->cfg_pool, len + 1); + g_strlcpy (code_begin, line, len + 1); + params = g_list_prepend (params, code_begin); + } + memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)g_list_free, params); + st->normalizer = lua_normalizer_func; + st->normalizer_data = params; + return TRUE; +} +#endif + + +gboolean +parse_normalizer (struct config_file *cfg, struct statfile *st, const char *line) +{ + char *params_begin; + + params_begin = strchr (line, ':'); + if (params_begin == NULL) { + msg_err ("no parameters are specified for normalizer %s", line); + return FALSE; + } + + /* Try to guess normalizer */ + if (g_ascii_strncasecmp (line, "internal", sizeof ("points")) == 0) { + return parse_internal_normalizer (cfg, st, params_begin + 1); + } +#ifdef WITH_LUA + else if (g_ascii_strncasecmp (line, "points", sizeof ("points")) == 0) { + return parse_lua_normalizer (cfg, st, params_begin + 1); + } +#endif + + msg_err ("unknown normalizer %s", line); + return FALSE; +} + /* * vi:ts=4 */ |