diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-02-15 17:59:12 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2011-02-15 17:59:12 +0300 |
commit | beab78097de6a53430bb16310e41b93d74546cb9 (patch) | |
tree | be45e11a8cbf7ed0b0640bdd3e0a2ffa290474e0 | |
parent | b3928c8e33fe8fe7b5d496c6beeb8f66dcdfa104 (diff) | |
download | rspamd-beab78097de6a53430bb16310e41b93d74546cb9.tar.gz rspamd-beab78097de6a53430bb16310e41b93d74546cb9.zip |
* Add ability to add descriptions for symbols
-rw-r--r-- | lib/librspamdclient.c | 77 | ||||
-rw-r--r-- | lib/librspamdclient.h | 1 | ||||
-rw-r--r-- | src/cfg_utils.c | 2 | ||||
-rw-r--r-- | src/cfg_xml.c | 9 | ||||
-rw-r--r-- | src/client/rspamc.c | 5 | ||||
-rw-r--r-- | src/filter.h | 3 | ||||
-rw-r--r-- | src/lua/lua_cfg_file.c | 10 | ||||
-rw-r--r-- | src/protocol.c | 28 | ||||
-rw-r--r-- | src/protocol.h | 1 |
9 files changed, 108 insertions, 28 deletions
diff --git a/lib/librspamdclient.c b/lib/librspamdclient.c index ef4518e51..c1143d0be 100644 --- a/lib/librspamdclient.c +++ b/lib/librspamdclient.c @@ -55,6 +55,7 @@ struct rspamd_connection { struct rspamd_result *result; GString *in_buf; struct rspamd_metric *cur_metric; + gint version; }; static struct rspamd_client *client = NULL; @@ -181,8 +182,10 @@ parse_rspamd_first_line (struct rspamd_connection *conn, guint len, GError **err { gchar *b = conn->in_buf->str + sizeof("RSPAMD/") - 1, *p, *c; guint remain = len - sizeof("RSPAMD/") + 1, state = 0, next_state; + gdouble dver; p = b; + c = p; while (p - b < remain) { switch (state) { case 0: @@ -190,6 +193,8 @@ parse_rspamd_first_line (struct rspamd_connection *conn, guint len, GError **err if (g_ascii_isspace (*p)) { state = 99; next_state = 1; + dver = strtod (c, NULL); + conn->version = floor (dver * 10 + 0.5); } else if (!g_ascii_isdigit (*p) && *p != '.') { goto err; @@ -330,7 +335,7 @@ parse_rspamd_metric_line (struct rspamd_connection *conn, guint len, GError **er /* Read required score */ if (g_ascii_isspace (*p) || p - b == remain - 1) { new->required_score = strtod (c, &err_str); - if (*err_str != *p) { + if (*err_str != *p && *err_str != *(p + 1)) { /* Invalid score */ goto err; } @@ -400,25 +405,36 @@ parse_rspamd_symbol_line (struct rspamd_connection *conn, guint len, GError **er struct rspamd_symbol *new; p = b; - c = b; + while (g_ascii_isspace (*p)) { + p ++; + } + c = p; while (p - b < remain) { switch (state) { case 0: /* Read symbol's name */ - if (g_ascii_isspace (*p)) { - state = 99; - next_state = 0; - } - else if (*p == ';' || *p == '(') { + if (p - b == remain - 1 || *p == ';' || *p == '(') { if (p - c <= 1) { /* Empty symbol name */ goto err; } else { + if (p - b == remain - 1) { + l = p - c + 1; + } + else { + if (*p == '(') { + next_state = 1; + } + else if (*p == ';' ) { + next_state = 2; + } + l = p - c; + } /* Create new symbol */ - sym = g_malloc (p - c + 1); - sym[p - c] = '\0'; - memcpy (sym, c, p - c); + sym = g_malloc (l + 1); + sym[l] = '\0'; + memcpy (sym, c, l); if (g_hash_table_lookup (conn->cur_metric->symbols, sym) != NULL) { /* Duplicate symbol */ @@ -429,13 +445,6 @@ parse_rspamd_symbol_line (struct rspamd_connection *conn, guint len, GError **er new->name = sym; g_hash_table_insert (conn->cur_metric->symbols, sym, new); state = 99; - if (*p == '(') { - next_state = 1; - new->weight = 0; - } - else { - next_state = 2; - } } } p ++; @@ -452,11 +461,37 @@ parse_rspamd_symbol_line (struct rspamd_connection *conn, guint len, GError **er p ++; } state = 99; - next_state = 2; + if (conn->version >= 13) { + next_state = 2; + } + else { + next_state = 3; + } } p ++; break; case 2: + /* Read description */ + if (*p == ';' || p - b == remain - 1) { + if (*p == ';') { + l = p - c; + } + else { + l = p - c + 1; + } + + if (l > 0) { + sym = g_malloc (l + 1); + sym[l] = '\0'; + memcpy (sym, c, l); + new->description = sym; + } + state = 99; + next_state = 3; + } + p ++; + break; + case 3: /* Read option */ if (*p == ',' || p - b == remain - 1) { /* Insert option into linked list */ @@ -493,8 +528,8 @@ parse_rspamd_symbol_line (struct rspamd_connection *conn, guint len, GError **er err: if (*err == NULL) { - *err = g_error_new (G_RSPAMD_ERROR, errno, "Invalid symbol line: %*s at pos: %d", - remain, b, (int)(p - b)); + *err = g_error_new (G_RSPAMD_ERROR, errno, "Invalid symbol line: %*s at pos: %d, at state: %d", + remain, b, (int)(p - b), state); } upstream_fail (&conn->server->up, conn->connection_time); return FALSE; @@ -812,7 +847,7 @@ rspamd_send_normal_command (struct rspamd_connection *c, const gchar *command, gint r; /* Write command */ - r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s RSPAMC/1.2\r\n", command); + r = rspamd_snprintf (outbuf, sizeof (outbuf), "%s RSPAMC/1.3\r\n", command); r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "Content-Length: %uz\r\n", clen); /* Iterate through headers */ if (headers != NULL) { diff --git a/lib/librspamdclient.h b/lib/librspamdclient.h index 2d2efc164..1e7f70187 100644 --- a/lib/librspamdclient.h +++ b/lib/librspamdclient.h @@ -8,6 +8,7 @@ */ struct rspamd_symbol { gchar *name; /**< name */ + gchar *description; /**< description */ double weight; /**< weight */ GList *options; /**< List of options (as const gchar *) */ }; diff --git a/src/cfg_utils.c b/src/cfg_utils.c index 2685d1281..f4cf48529 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -765,7 +765,9 @@ check_metric_conf (struct config_file *cfg, struct metric *c) c->action = METRIC_ACTION_REJECT; c->grow_factor = 1.0; c->symbols = g_hash_table_new (g_str_hash, g_str_equal); + c->descriptions = g_hash_table_new (g_str_hash, g_str_equal); memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->symbols); + memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->descriptions); } return c; diff --git a/src/cfg_xml.c b/src/cfg_xml.c index a85b77777..aa91bfda0 100644 --- a/src/cfg_xml.c +++ b/src/cfg_xml.c @@ -805,7 +805,7 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx, gboolean handle_metric_symbol (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset) { - gchar *strval, *err; + gchar *strval, *err, *desc; double *value; GList *metric_list; struct metric *metric = ctx->section_pointer; @@ -824,6 +824,13 @@ handle_metric_symbol (struct config_file *cfg, struct rspamd_xml_userdata *ctx, } } + if (attrs != NULL) { + desc = g_hash_table_lookup (attrs, "description"); + if (desc) { + g_hash_table_insert (metric->descriptions, data, memory_pool_strdup (cfg->cfg_pool, desc)); + } + } + g_hash_table_insert (metric->symbols, data, value); if ((metric_list = g_hash_table_lookup (cfg->metrics_symbols, data)) == NULL) { diff --git a/src/client/rspamc.c b/src/client/rspamc.c index 9424c4bb4..ff43bbc16 100644 --- a/src/client/rspamc.c +++ b/src/client/rspamc.c @@ -196,6 +196,7 @@ show_metric_result (gpointer key, gpointer value, gpointer ud) first = FALSE; } PRINT_FUNC ("%s(%.2f)", s->name, s->weight); + if (s->options) { PRINT_FUNC ("("); cur = g_list_first (s->options); @@ -209,7 +210,9 @@ show_metric_result (gpointer key, gpointer value, gpointer ud) cur = g_list_next (cur); } } - + if (s->description) { + PRINT_FUNC (" - \"%s\"", s->description); + } } } PRINT_FUNC ("\n"); diff --git a/src/filter.h b/src/filter.h index 2540d95e9..2a1d97edd 100644 --- a/src/filter.h +++ b/src/filter.h @@ -51,13 +51,14 @@ struct metric_action { * Common definition of metric */ struct metric { - gchar *name; /**< name of metric */ + gchar *name; /**< name of metric */ gchar *func_name; /**< name of consolidation function */ metric_cons_func func; /**< c consolidation function */ double grow_factor; /**< grow factor for metric */ double required_score; /**< required score for this metric */ double reject_score; /**< reject score for this metric */ GHashTable *symbols; /**< weights of symbols in metric */ + GHashTable *descriptions; /**< descriptions of symbols in metric */ enum rspamd_metric_action action; /**< action to do by this metric by default */ GList *actions; /**< actions that can be performed by this metric */ }; diff --git a/src/lua/lua_cfg_file.c b/src/lua/lua_cfg_file.c index 6ec48ebef..eff2c138a 100644 --- a/src/lua/lua_cfg_file.c +++ b/src/lua/lua_cfg_file.c @@ -119,7 +119,7 @@ lua_process_metric (lua_State *L, const gchar *name, struct config_file *cfg) if (lua_istable (L, -1)) { /* We got a table, so extract individual attributes */ lua_pushstring (L, "weight"); - lua_gettable (L, -1); + lua_gettable (L, -2); if (lua_isnumber (L, -1)) { score = memory_pool_alloc (cfg->cfg_pool, sizeof (double)); *score = lua_tonumber (L, -1); @@ -128,6 +128,14 @@ lua_process_metric (lua_State *L, const gchar *name, struct config_file *cfg) msg_warn ("cannot get weight of symbol: %s", symbol); continue; } + lua_pop (L, 1); + lua_pushstring (L, "description"); + lua_gettable (L, -2); + if (lua_isstring (L, -1)) { + g_hash_table_insert (metric->descriptions, + symbol, memory_pool_strdup (cfg->cfg_pool, lua_tostring (L, -1))); + } + lua_pop (L, 1); } else if (lua_isnumber (L, -1)) { /* Just got weight */ diff --git a/src/protocol.c b/src/protocol.c index e430fd03b..ca49c5ecf 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -236,6 +236,9 @@ parse_command (struct worker_task *task, f_str_t * line) else if (strncmp (token, RSPAMC_PROTO_1_2, sizeof (RSPAMC_PROTO_1_2) - 1) == 0) { task->proto_ver = 12; } + else if (strncmp (token, RSPAMC_PROTO_1_3, sizeof (RSPAMC_PROTO_1_3) - 1) == 0) { + task->proto_ver = 13; + } } } else if (g_ascii_strncasecmp (line->begin, SPAMC_GREETING, sizeof (SPAMC_GREETING) - 1) == 0) { @@ -449,6 +452,7 @@ struct metric_callback_data { gint symbols_size; gint symbols_offset; gboolean alive; + struct metric *cur_metric; }; static void @@ -637,7 +641,7 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) struct metric_callback_data *cd = (struct metric_callback_data *)user_data; struct worker_task *task = cd->task; gint r = 0; - gchar outbuf[OUTBUFSIZ]; + gchar outbuf[OUTBUFSIZ], *description; struct symbol *s = (struct symbol *)value; GList *cur; @@ -648,8 +652,17 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) cd->symbols_offset = rspamd_snprintf (cd->symbols_buf + cd->symbols_offset, cd->symbols_size - cd->symbols_offset, "%s," CRLF, (gchar *)key); } + description = g_hash_table_lookup (cd->cur_metric->descriptions, key); if (s->options) { - if (task->proto_ver >= 12) { + if (task->proto_ver >= 13) { + if (description != NULL) { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f); %s;", (gchar *)key, s->score, description); + } + else { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f);;", (gchar *)key, s->score); + } + } + else if (task->proto_ver >= 12) { r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f); ", (gchar *)key, s->score); } else { @@ -672,7 +685,15 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) } } else { - if (task->proto_ver >= 12) { + if (task->proto_ver >= 13) { + if (description != NULL) { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f); %s" CRLF, (gchar *)key, s->score, description); + } + else { + r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f);" CRLF, (gchar *)key, s->score); + } + } + else if (task->proto_ver >= 12) { r = rspamd_snprintf (outbuf, OUTBUFSIZ, "Symbol: %s(%.2f)" CRLF, (gchar *)key, s->score); } else { @@ -693,6 +714,7 @@ metric_symbols_callback (gpointer key, gpointer value, void *user_data) static gboolean show_metric_symbols (struct metric_result *metric_res, struct metric_callback_data *cd) { + cd->cur_metric = metric_res->metric; g_hash_table_foreach (metric_res->symbols, metric_symbols_callback, cd); /* Remove last , from log buf */ if (cd->log_buf[cd->log_offset - 1] == ',') { diff --git a/src/protocol.h b/src/protocol.h index 05e25c45a..0d2a0207b 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -17,6 +17,7 @@ #define RSPAMC_PROTO_1_0 "1.0" #define RSPAMC_PROTO_1_1 "1.1" #define RSPAMC_PROTO_1_2 "1.2" +#define RSPAMC_PROTO_1_3 "1.3" /* * Reply messages |