aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-15 17:59:12 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-15 17:59:12 +0300
commitbeab78097de6a53430bb16310e41b93d74546cb9 (patch)
treebe45e11a8cbf7ed0b0640bdd3e0a2ffa290474e0
parentb3928c8e33fe8fe7b5d496c6beeb8f66dcdfa104 (diff)
downloadrspamd-beab78097de6a53430bb16310e41b93d74546cb9.tar.gz
rspamd-beab78097de6a53430bb16310e41b93d74546cb9.zip
* Add ability to add descriptions for symbols
-rw-r--r--lib/librspamdclient.c77
-rw-r--r--lib/librspamdclient.h1
-rw-r--r--src/cfg_utils.c2
-rw-r--r--src/cfg_xml.c9
-rw-r--r--src/client/rspamc.c5
-rw-r--r--src/filter.h3
-rw-r--r--src/lua/lua_cfg_file.c10
-rw-r--r--src/protocol.c28
-rw-r--r--src/protocol.h1
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