]> source.dussan.org Git - rspamd.git/commitdiff
Add prefix expansion function.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 27 Feb 2015 14:41:07 +0000 (14:41 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 27 Feb 2015 14:41:07 +0000 (14:41 +0000)
src/libstat/CMakeLists.txt
src/libstat/backends/redis.c
src/libstat/stat_process.c

index 5d7184316446e407b9104120e88d8b5b68b15433..bf9aa94e40ca3e811460ed1f7766de427aeb4cef 100644 (file)
@@ -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)
                                
index 9ace23f70cc1bfe474a19fdeba793203288cb79e..9d05bc591eac61139214666dd66b7a40dbd4021f 100644 (file)
@@ -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 ++;
index 164aaee85cdaa155277d5b199ff12c52bb030c3f..311eaa0ea5e0b8ad87c5f02980fd813e3071d48f 100644 (file)
@@ -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);