aboutsummaryrefslogtreecommitdiffstats
path: root/src/cfg_utils.c
diff options
context:
space:
mode:
authorcebka@lenovo-laptop <cebka@lenovo-laptop>2010-01-13 16:35:17 +0300
committercebka@lenovo-laptop <cebka@lenovo-laptop>2010-01-13 16:35:17 +0300
commitfc70f10e7c2a7b0aeb5da7b28c64131b03538e76 (patch)
treeb1c8ad0c8772f035a4b2fe2fc5dd43dff439f927 /src/cfg_utils.c
parentd544f1d5770f56bf8b2b75ca7a04ac5441069e68 (diff)
downloadrspamd-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.c107
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
*/