]> source.dussan.org Git - rspamd.git/commitdiff
* Add ability to add descriptions for symbols
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 15 Feb 2011 14:59:12 +0000 (17:59 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 15 Feb 2011 14:59:12 +0000 (17:59 +0300)
lib/librspamdclient.c
lib/librspamdclient.h
src/cfg_utils.c
src/cfg_xml.c
src/client/rspamc.c
src/filter.h
src/lua/lua_cfg_file.c
src/protocol.c
src/protocol.h

index ef4518e51816f85225c6b5955a4db37494561f82..c1143d0be0d52c887d3230462b8a21b9ac585578 100644 (file)
@@ -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) {
index 2d2efc16425399c2806417098470b34869edf498..1e7f70187b464099ea56500e4f986bf9d2ec2101 100644 (file)
@@ -8,6 +8,7 @@
  */
 struct rspamd_symbol {
        gchar *name;                /**< name */
+       gchar *description;             /**< description */
        double weight;                  /**< weight */
        GList *options;                 /**< List of options (as const gchar *) */
 };
index 2685d128109f0960fe04aa197342e92b607bb48a..f4cf48529df822fc09b5a8857bf37287238d4174 100644 (file)
@@ -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;
index a85b77777baaa7b6416d6f96740b2f44a47ff416..aa91bfda0cba829e1bd3489906136355b7a62a71 100644 (file)
@@ -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) {
index 9424c4bb4933eaa69c68873f3a776105c2ac073e..ff43bbc16e6af6678236278a2e0d78e4dcd09927 100644 (file)
@@ -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");
index 2540d95e9cbf007584d11aa40bb6d826a15906d2..2a1d97edd78cb92822a35c3b70030193c51bb032 100644 (file)
@@ -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       */
 };
index 6ec48ebef0d2c9aae6a31ffe0999bfcc2980e6a0..eff2c138a6280111fba60aafa9c3b538f0760660 100644 (file)
@@ -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 */
index e430fd03b37d912c50bab94edd235e94174eeefe..ca49c5ecf22c600bfe8f40b20af83ea610da91bc 100644 (file)
@@ -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] == ',') {
index 05e25c45afe6558549f138bc960fa9d4984d9a41..0d2a0207bed77f44e7a1eb1c5d5506661895b268 100644 (file)
@@ -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