diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-03-03 13:44:50 +0300 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2009-03-03 13:44:50 +0300 |
commit | 3ff032cf72164dc9aa8575c0a631f7c7b0079f46 (patch) | |
tree | 98a7b11bf70232a6c0825591957352f2d4acc9b9 /src/protocol.c | |
parent | f972cde13ca98f6ed992a288826467abf04c888a (diff) | |
download | rspamd-3ff032cf72164dc9aa8575c0a631f7c7b0079f46.tar.gz rspamd-3ff032cf72164dc9aa8575c0a631f7c7b0079f46.zip |
* New rspamd protocol (changed replies)
* Add ability to attach string lists to symbols
* Check destructors and do not add identical destructors (argument and function) to pool's destructors
* Remove 2 warnings when building with gmime22
* Attach url names to surbl symbols
* Fix bug with blocking on read (I think it is linux specific thought)
Diffstat (limited to 'src/protocol.c')
-rw-r--r-- | src/protocol.c | 157 |
1 files changed, 95 insertions, 62 deletions
diff --git a/src/protocol.c b/src/protocol.c index 9999dc279..598c851c6 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -22,7 +22,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" #include "main.h" +#include "cfg_file.h" /* Max line size as it is defined in rfc2822 */ #define OUTBUFSIZ 1000 @@ -348,112 +350,145 @@ show_url_header (struct worker_task *task) } static void -show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data) +metric_symbols_callback (gpointer key, gpointer value, void *user_data) { struct worker_task *task = (struct worker_task *)user_data; - int r; + int r = 0; char outbuf[OUTBUFSIZ]; - struct metric_result *metric_res = (struct metric_result *)metric_value; - int is_spam = 0; + struct symbol *s = (struct symbol *)value; + GList *cur; - if (metric_res->score >= metric_res->metric->required_score) { - is_spam = 1; - } - if (task->proto == SPAMC_PROTO) { - r = snprintf (outbuf, sizeof (outbuf), "Spam: %s ; %.2f / %.2f" CRLF, - (is_spam) ? "True" : "False", metric_res->score, metric_res->metric->required_score); + if (s->options) { + r = snprintf (outbuf, OUTBUFSIZ, "Symbol: %s; ", (char *)key); + cur = s->options; + while (cur) { + if (g_list_next (cur)) { + r += snprintf (outbuf + r, OUTBUFSIZ - r, "%s,", (char *)cur->data); + } + else { + r += snprintf (outbuf + r, OUTBUFSIZ - r, "%s" CRLF, (char *)cur->data); + } + cur = g_list_next (cur); + } + /* End line with CRLF strictly */ + if (r >= OUTBUFSIZ - 1) { + outbuf[OUTBUFSIZ - 2] = '\r'; + outbuf[OUTBUFSIZ - 1] = '\n'; + } } else { - r = snprintf (outbuf, sizeof (outbuf), "%s: %s ; %.2f / %.2f" CRLF, (char *)metric_name, - (is_spam) ? "True" : "False", metric_res->score, metric_res->metric->required_score); + r = snprintf (outbuf, OUTBUFSIZ, "Symbol: %s" CRLF, (char *)key); } + rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE); } -static int -write_check_reply (struct worker_task *task) +static void +show_metric_symbols (struct metric_result *metric_res, struct worker_task *task) { - int r; + int r = 0; + GList *symbols, *cur; char outbuf[OUTBUFSIZ]; - struct metric_result *metric_res; - r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK"); - rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE); if (task->proto == SPAMC_PROTO) { - /* Ignore metrics, just write report for 'default' metric */ - metric_res = g_hash_table_lookup (task->results, "default"); - if (metric_res == NULL) { - return -1; - } - else { - show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)task); + symbols = g_hash_table_get_keys (metric_res->symbols); + cur = symbols; + while (cur) { + if (g_list_next (cur) != NULL) { + r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s,", (char *)cur->data); + } + else { + r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s" CRLF, (char *)cur->data); + } + cur = g_list_next (cur); } + g_list_free (symbols); + rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE); } else { - /* Write result for each metric separately */ - g_hash_table_foreach (task->results, show_metric_result, task); - /* URL stat */ - show_url_header (task); + g_hash_table_foreach (metric_res->symbols, metric_symbols_callback, task); } - rspamd_dispatcher_write (task->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE); - - return 0; } static void -show_metric_symbols (gpointer metric_name, gpointer metric_value, void *user_data) +show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data) { struct worker_task *task = (struct worker_task *)user_data; - int r = 0; + int r; char outbuf[OUTBUFSIZ]; - GList *symbols = NULL, *cur; struct metric_result *metric_res = (struct metric_result *)metric_value; - - if (task->proto == RSPAMC_PROTO) { - r = snprintf (outbuf, sizeof (outbuf), "%s: ", (char *)metric_name); + struct metric *m; + int is_spam = 0; + + if (metric_name == NULL || metric_value == NULL) { + m = g_hash_table_lookup (task->cfg->metrics, "default"); + if (task->proto == SPAMC_PROTO) { + r = snprintf (outbuf, sizeof (outbuf), "Spam: False ; 0 / %.2f" CRLF, + m != NULL ? m->required_score : 0); + } + else { + r = snprintf (outbuf, sizeof (outbuf), "Metric: default; False; 0 / %.2f" CRLF, + m != NULL ? m->required_score : 0); + } } - - symbols = g_hash_table_get_keys (metric_res->symbols); - cur = symbols; - while (cur) { - if (g_list_next (cur) != NULL) { - r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s,", (char *)cur->data); + else { + if (metric_res->score >= metric_res->metric->required_score) { + is_spam = 1; + } + if (task->proto == SPAMC_PROTO) { + r = snprintf (outbuf, sizeof (outbuf), "Spam: %s ; %.2f / %.2f" CRLF, + (is_spam) ? "True" : "False", metric_res->score, metric_res->metric->required_score); } else { - r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s", (char *)cur->data); + r = snprintf (outbuf, sizeof (outbuf), "Metric: %s; %s; %.2f / %.2f" CRLF, (char *)metric_name, + (is_spam) ? "True" : "False", metric_res->score, metric_res->metric->required_score); } - cur = g_list_next (cur); } - g_list_free (symbols); - msg_debug ("show_metric_symbols: write symbols line: %s", outbuf); - outbuf[r++] = '\r'; outbuf[r++] = '\n'; rspamd_dispatcher_write (task->dispatcher, outbuf, r, FALSE); + + if (task->cmd == CMD_SYMBOLS && metric_value != NULL) { + show_metric_symbols (metric_res, task); + } } static int -write_symbols_reply (struct worker_task *task) +write_check_reply (struct worker_task *task) { + int r; + char outbuf[OUTBUFSIZ]; struct metric_result *metric_res; - - /* First of all write normal results by calling write_check_reply */ - if (write_check_reply (task) == -1) { - return -1; - } - /* Now write symbols */ + + r = snprintf (outbuf, sizeof (outbuf), "%s 0 %s" CRLF, (task->proto == SPAMC_PROTO) ? SPAMD_REPLY_BANNER : RSPAMD_REPLY_BANNER, "OK"); + rspamd_dispatcher_write (task->dispatcher, outbuf, r, TRUE); if (task->proto == SPAMC_PROTO) { /* Ignore metrics, just write report for 'default' metric */ metric_res = g_hash_table_lookup (task->results, "default"); if (metric_res == NULL) { - return -1; + /* Implicit metric result */ + show_metric_result (NULL, NULL, (void *)task); } else { - show_metric_symbols ((gpointer)"default", (gpointer)metric_res, (void *)task); + show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)task); } } else { + /* Show default metric first */ + metric_res = g_hash_table_lookup (task->results, "default"); + if (metric_res == NULL) { + /* Implicit metric result */ + show_metric_result (NULL, NULL, (void *)task); + } + else { + show_metric_result ((gpointer)"default", (gpointer)metric_res, (void *)task); + } + g_hash_table_remove (task->results, "default"); + /* Write result for each metric separately */ - g_hash_table_foreach (task->results, show_metric_symbols, task); + g_hash_table_foreach (task->results, show_metric_result, task); + /* URL stat */ + show_url_header (task); } + rspamd_dispatcher_write (task->dispatcher, CRLF, sizeof (CRLF) - 1, FALSE); return 0; } @@ -498,10 +533,8 @@ write_reply (struct worker_task *task) case CMD_REPORT_IFSPAM: case CMD_REPORT: case CMD_CHECK: - return write_check_reply (task); - break; case CMD_SYMBOLS: - return write_symbols_reply (task); + return write_check_reply (task); break; case CMD_PROCESS: return write_process_reply (task); |