diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-02-27 14:41:07 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-02-27 14:41:07 +0000 |
commit | 60f838ed65c4a64fb9acadb5d19f325cda5fae72 (patch) | |
tree | 9e202e47a602ea202e944ffa9189a9b275e5d8ad | |
parent | 8a20f3344a67762fa0b72fa05f4b777170e78471 (diff) | |
download | rspamd-60f838ed65c4a64fb9acadb5d19f325cda5fae72.tar.gz rspamd-60f838ed65c4a64fb9acadb5d19f325cda5fae72.zip |
Add prefix expansion function.
-rw-r--r-- | src/libstat/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/libstat/backends/redis.c | 208 | ||||
-rw-r--r-- | src/libstat/stat_process.c | 2 |
3 files changed, 211 insertions, 2 deletions
diff --git a/src/libstat/CMakeLists.txt b/src/libstat/CMakeLists.txt index 5d7184316..bf9aa94e4 100644 --- a/src/libstat/CMakeLists.txt +++ b/src/libstat/CMakeLists.txt @@ -7,7 +7,8 @@ SET(TOKENIZERSSRC ${CMAKE_CURRENT_SOURCE_DIR}/tokenizers/tokenizers.c SET(CLASSIFIERSSRC ${CMAKE_CURRENT_SOURCE_DIR}/classifiers/bayes.c) -SET(BACKENDSSRC ${CMAKE_CURRENT_SOURCE_DIR}/backends/mmaped_file.c) +SET(BACKENDSSRC ${CMAKE_CURRENT_SOURCE_DIR}/backends/mmaped_file.c + ${CMAKE_CURRENT_SOURCE_DIR}/backends/redis.c) SET(CACHESSRC ${CMAKE_CURRENT_SOURCE_DIR}/learn_cache/sqlite3_cache.c) diff --git a/src/libstat/backends/redis.c b/src/libstat/backends/redis.c index 9ace23f70..9d05bc591 100644 --- a/src/libstat/backends/redis.c +++ b/src/libstat/backends/redis.c @@ -23,6 +23,7 @@ #include "config.h" #include "main.h" +#include "stat_internal.h" #include "hiredis.h" #include "upstream.h" @@ -47,6 +48,208 @@ struct redis_stat_runtime { gchar *redis_object_expanded; }; +#define GET_TASK_ELT(task, elt) (task == NULL ? NULL : (task)->elt) + +static gsize +rspamd_redis_expand_object (const gchar *pattern, + struct rspamd_statfile_config *stcf, + struct rspamd_task *task, + gchar **target) +{ + gsize tlen = 0; + const gchar *p = pattern, *elt; + InternetAddressList *ia; + InternetAddress *iaelt; + InternetAddressMailbox *imb; + gchar *d, *end; + enum { + just_char, + percent_char, + mod_char + } state = just_char; + + g_assert (stcf != NULL); + + /* Length calculation */ + while (*p) { + switch (state) { + case just_char: + if (*p == '%') { + state = percent_char; + } + else { + tlen ++; + } + p ++; + break; + case percent_char: + switch (*p) { + case '%': + tlen ++; + state = just_char; + break; + case 'f': + if (task) { + elt = rspamd_task_get_sender (task); + if (elt) { + tlen += strlen (elt); + } + } + break; + case 'u': + elt = GET_TASK_ELT (task, user); + if (elt) { + tlen += strlen (elt); + } + break; + case 'r': + ia = GET_TASK_ELT (task, rcpt_envelope); + if (ia != NULL) { + iaelt = internet_address_list_get_address (ia, 0); + imb = INTERNET_ADDRESS_IS_MAILBOX (iaelt) ? + INTERNET_ADDRESS_MAILBOX (iaelt) : NULL; + + elt = (imb ? internet_address_mailbox_get_addr (imb) : NULL); + + if (elt) { + tlen += strlen (elt); + } + } + break; + case 'l': + if (stcf->label) { + tlen += strlen (stcf->label); + } + break; + case 's': + if (stcf->symbol) { + tlen += strlen (stcf->symbol); + } + break; + default: + state = just_char; + tlen ++; + break; + } + + if (state == percent_char) { + state = mod_char; + } + p ++; + break; + + case mod_char: + switch (*p) { + case 'd': + p ++; + state = just_char; + break; + default: + state = just_char; + break; + } + break; + } + } + + if (target == NULL) { + return tlen; + } + + *target = rspamd_mempool_alloc (task->task_pool, tlen + 1); + d = *target; + end = d + tlen; + p = pattern; + state = just_char; + + /* Expand string */ + while (*p && d < end) { + switch (state) { + case just_char: + if (*p == '%') { + state = percent_char; + } + else { + *d++ = *p; + } + p ++; + break; + case percent_char: + switch (*p) { + case '%': + *d++ = *p; + state = just_char; + break; + case 'f': + if (task) { + elt = rspamd_task_get_sender (task); + if (elt) { + d += rspamd_strlcpy (d, elt, end - d); + } + } + break; + case 'u': + elt = GET_TASK_ELT (task, user); + if (elt) { + d += rspamd_strlcpy (d, elt, end - d); + } + break; + case 'r': + ia = GET_TASK_ELT (task, rcpt_envelope); + if (ia != NULL) { + iaelt = internet_address_list_get_address (ia, 0); + imb = INTERNET_ADDRESS_IS_MAILBOX (iaelt) ? + INTERNET_ADDRESS_MAILBOX (iaelt) : NULL; + + elt = (imb ? internet_address_mailbox_get_addr (imb) : NULL); + + if (elt) { + d += rspamd_strlcpy (d, elt, end - d); + } + } + break; + case 'l': + if (stcf->label) { + d += rspamd_strlcpy (d, stcf->label, end - d); + } + break; + case 's': + if (stcf->symbol) { + d += rspamd_strlcpy (d, stcf->symbol, end - d); + } + break; + default: + state = just_char; + *d++ = *p; + break; + } + + if (state == percent_char) { + state = mod_char; + } + p ++; + break; + + case mod_char: + switch (*p) { + case 'd': + /* TODO: not supported yet */ + p ++; + state = just_char; + break; + default: + state = just_char; + break; + } + break; + } + } + + *d = '\0'; + + return tlen; +} + gpointer rspamd_redis_init (struct rspamd_stat_ctx *ctx, struct rspamd_config *cfg) { @@ -120,6 +323,11 @@ rspamd_redis_init (struct rspamd_stat_ctx *ctx, struct rspamd_config *cfg) else { /* XXX: sanity check */ new->redis_object = ucl_object_tostring (elt); + if (rspamd_redis_expand_object (new->redis_object, stf, + NULL, NULL) == 0) { + msg_err ("statfile %s cannot write servers configuration", + stf->symbol); + } } ctx->statfiles ++; diff --git a/src/libstat/stat_process.c b/src/libstat/stat_process.c index 164aaee85..311eaa0ea 100644 --- a/src/libstat/stat_process.c +++ b/src/libstat/stat_process.c @@ -645,7 +645,7 @@ rspamd_stat_statistics (struct rspamd_config *cfg, guint64 *total_learns) continue; } - backend_runtime = bk->runtime (stcf, FALSE, bk->ctx); + backend_runtime = bk->runtime (NULL, stcf, FALSE, bk->ctx); learns += bk->total_learns (backend_runtime, bk->ctx); elt = bk->get_stat (backend_runtime, bk->ctx); |