summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-01 22:01:19 +0300
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2011-02-01 22:01:19 +0300
commit295619fdc102e5528a5370a0dcd58bef9c7dc371 (patch)
treeda48d33f1cb9648f91dd399863dc6ff6bca67c65 /src
parent2a383446ab6254777693544e5acda2a805947f81 (diff)
downloadrspamd-295619fdc102e5528a5370a0dcd58bef9c7dc371.tar.gz
rspamd-295619fdc102e5528a5370a0dcd58bef9c7dc371.zip
* Implement controller interface inside librspamdclient/rspamc
* REMOVE perl client (at last) Fixed some stupid moments in a controller's protocol Change version to 0.3.5
Diffstat (limited to 'src')
-rw-r--r--src/client/rspamc.c259
-rw-r--r--src/controller.c17
-rw-r--r--src/plugins/fuzzy_check.c20
3 files changed, 266 insertions, 30 deletions
diff --git a/src/client/rspamc.c b/src/client/rspamc.c
index 1bae2970c..874c72074 100644
--- a/src/client/rspamc.c
+++ b/src/client/rspamc.c
@@ -34,7 +34,8 @@ static gchar *connect_str = "localhost";
static gchar *password;
static gchar *statfile;
static gchar *ip;
-static gdouble weight;
+static gint weight = 1;
+static gint flag;
static gboolean pass_all;
static gboolean tty = FALSE;
@@ -43,7 +44,8 @@ static GOptionEntry entries[] =
{ "connect", 'h', 0, G_OPTION_ARG_STRING, &connect_str, "Specify host and port", NULL },
{ "password", 'P', 0, G_OPTION_ARG_STRING, &password, "Specify control password", NULL },
{ "statfile", 's', 0, G_OPTION_ARG_STRING, &statfile, "Statfile to learn (symbol name)", NULL },
- { "weight", 'w', 0, G_OPTION_ARG_DOUBLE, &weight, "Weight for fuzzy operations", NULL },
+ { "weight", 'w', 0, G_OPTION_ARG_INT, &weight, "Weight for fuzzy operations", NULL },
+ { "flag", 'f', 0, G_OPTION_ARG_INT, &flag, "Flag for fuzzy operations", NULL },
{ "pass", 'p', 0, G_OPTION_ARG_NONE, &pass_all, "Pass all filters", NULL },
{ "ip", 'i', 0, G_OPTION_ARG_STRING, &ip, "Emulate that message was received from specified ip address", NULL },
{ NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL }
@@ -52,7 +54,10 @@ static GOptionEntry entries[] =
enum rspamc_command {
RSPAMC_COMMAND_UNKNOWN = 0,
RSPAMC_COMMAND_SYMBOLS,
- RSPAMC_COMMAND_LEARN
+ RSPAMC_COMMAND_LEARN,
+ RSPAMC_COMMAND_FUZZY_ADD,
+ RSPAMC_COMMAND_FUZZY_DEL,
+ RSPAMC_COMMAND_STAT
};
/*
@@ -93,6 +98,15 @@ check_rspamc_command (const gchar *cmd)
else if (g_ascii_strcasecmp (cmd, "LEARN") == 0) {
return RSPAMC_COMMAND_LEARN;
}
+ else if (g_ascii_strcasecmp (cmd, "FUZZY_ADD") == 0) {
+ return RSPAMC_COMMAND_FUZZY_ADD;
+ }
+ else if (g_ascii_strcasecmp (cmd, "FUZZY_DEL") == 0) {
+ return RSPAMC_COMMAND_FUZZY_DEL;
+ }
+ else if (g_ascii_strcasecmp (cmd, "STAT") == 0) {
+ return RSPAMC_COMMAND_STAT;
+ }
return RSPAMC_COMMAND_UNKNOWN;
}
@@ -282,6 +296,7 @@ scan_rspamd_stdin ()
exit (EXIT_FAILURE);
}
print_rspamd_result (res);
+ rspamd_free_result (res);
}
static void
@@ -302,9 +317,197 @@ scan_rspamd_file (const gchar *file)
g_hash_table_destroy (opts);
if (err != NULL) {
fprintf (stderr, "cannot scan message: %s\n", err->message);
- exit (EXIT_FAILURE);
}
print_rspamd_result (res);
+ if (res) {
+ rspamd_free_result (res);
+ }
+}
+
+static void
+learn_rspamd_stdin ()
+{
+ gchar *in_buf;
+ gint r = 0, len;
+ GError *err = NULL;
+
+ if (password == NULL || statfile == NULL) {
+ fprintf (stderr, "cannot learn message without password and symbol name\n");
+ exit (EXIT_FAILURE);
+ }
+ /* Add server */
+ add_rspamd_server (TRUE);
+
+ /* Allocate input buffer */
+ len = BUFSIZ;
+ in_buf = g_malloc (len);
+
+ /* Read stdin */
+ while (!feof (stdin)) {
+ r += fread (in_buf + r, 1, len - r, stdin);
+ if (len - r < len / 2) {
+ /* Grow buffer */
+ len *= 2;
+ in_buf = g_realloc (in_buf, len);
+ }
+ }
+ if (!rspamd_learn_memory (in_buf, r, statfile, password, &err)) {
+ if (err != NULL) {
+ fprintf (stderr, "cannot learn message: %s\n", err->message);
+ }
+ else {
+ fprintf (stderr, "cannot learn message\n");
+ }
+ exit (EXIT_FAILURE);
+ }
+ else {
+ if (tty) {
+ printf ("\033[1m");
+ }
+ PRINT_FUNC ("Results for host: %s: learn ok\n", connect_str);
+ if (tty) {
+ printf ("\033[0m");
+ }
+ }
+}
+
+static void
+learn_rspamd_file (const gchar *file)
+{
+ GError *err = NULL;
+
+ if (password == NULL || statfile == NULL) {
+ fprintf (stderr, "cannot learn message without password and symbol name\n");
+ exit (EXIT_FAILURE);
+ }
+ /* Add server */
+ add_rspamd_server (TRUE);
+
+ if (!rspamd_learn_file (file, statfile, password, &err)) {
+ if (err != NULL) {
+ fprintf (stderr, "cannot learn message: %s\n", err->message);
+ }
+ else {
+ fprintf (stderr, "cannot learn message\n");
+ }
+ }
+ else {
+ if (tty) {
+ printf ("\033[1m");
+ }
+ PRINT_FUNC ("learn ok\n");
+ if (tty) {
+ printf ("\033[0m");
+ }
+ }
+}
+
+static void
+fuzzy_rspamd_stdin (gboolean delete)
+{
+ gchar *in_buf;
+ gint r = 0, len;
+ GError *err = NULL;
+
+ if (password == NULL) {
+ fprintf (stderr, "cannot learn message without password\n");
+ exit (EXIT_FAILURE);
+ }
+ /* Add server */
+ add_rspamd_server (TRUE);
+
+ /* Allocate input buffer */
+ len = BUFSIZ;
+ in_buf = g_malloc (len);
+
+ /* Read stdin */
+ while (!feof (stdin)) {
+ r += fread (in_buf + r, 1, len - r, stdin);
+ if (len - r < len / 2) {
+ /* Grow buffer */
+ len *= 2;
+ in_buf = g_realloc (in_buf, len);
+ }
+ }
+ if (!rspamd_fuzzy_memory (in_buf, r, password, weight, flag, delete, &err)) {
+ if (err != NULL) {
+ fprintf (stderr, "cannot learn message: %s\n", err->message);
+ }
+ else {
+ fprintf (stderr, "cannot learn message\n");
+ }
+ exit (EXIT_FAILURE);
+ }
+ else {
+ if (tty) {
+ printf ("\033[1m");
+ }
+ PRINT_FUNC ("Results for host: %s: learn ok\n", connect_str);
+ if (tty) {
+ printf ("\033[0m");
+ }
+ }
+}
+
+static void
+fuzzy_rspamd_file (const gchar *file, gboolean delete)
+{
+ GError *err = NULL;
+
+ if (password == NULL) {
+ fprintf (stderr, "cannot learn message without password\n");
+ exit (EXIT_FAILURE);
+ }
+ /* Add server */
+ add_rspamd_server (TRUE);
+
+ if (!rspamd_fuzzy_file (file, password, weight, flag, delete, &err)) {
+ if (err != NULL) {
+ fprintf (stderr, "cannot learn message: %s\n", err->message);
+ }
+ else {
+ fprintf (stderr, "cannot learn message\n");
+ }
+ }
+ else {
+ if (tty) {
+ printf ("\033[1m");
+ }
+ PRINT_FUNC ("learn ok\n");
+ if (tty) {
+ printf ("\033[0m");
+ }
+ }
+}
+
+static void
+rspamd_do_stat ()
+{
+ GError *err = NULL;
+ GString *res;
+
+ /* Add server */
+ add_rspamd_server (TRUE);
+
+ res = rspamd_get_stat (&err);
+ if (res == NULL) {
+ if (err != NULL) {
+ fprintf (stderr, "cannot learn message: %s\n", err->message);
+ }
+ else {
+ fprintf (stderr, "cannot learn message\n");
+ }
+ exit (EXIT_FAILURE);
+ }
+ if (tty) {
+ printf ("\033[1m");
+ }
+ PRINT_FUNC ("Results for host: %s\n\n", connect_str);
+ if (tty) {
+ printf ("\033[0m");
+ }
+ res = g_string_append_c (res, '\0');
+ printf ("%s\n", res->str);
}
gint
@@ -326,11 +529,24 @@ main (gint argc, gchar **argv, gchar **env)
/* One argument is whether command or filename */
if ((cmd = check_rspamc_command (argv[1])) != RSPAMC_COMMAND_UNKNOWN) {
/* In case of command read stdin */
- if (cmd == RSPAMC_COMMAND_SYMBOLS) {
+ switch (cmd) {
+ case RSPAMC_COMMAND_SYMBOLS:
scan_rspamd_stdin ();
- }
- else {
- /* XXX: implement this */
+ break;
+ case RSPAMC_COMMAND_LEARN:
+ learn_rspamd_stdin ();
+ break;
+ case RSPAMC_COMMAND_FUZZY_ADD:
+ fuzzy_rspamd_stdin (FALSE);
+ break;
+ case RSPAMC_COMMAND_FUZZY_DEL:
+ fuzzy_rspamd_stdin (TRUE);
+ break;
+ case RSPAMC_COMMAND_STAT:
+ rspamd_do_stat ();
+ default:
+ fprintf (stderr, "invalid arguments\n");
+ exit (EXIT_FAILURE);
}
}
else {
@@ -341,11 +557,29 @@ main (gint argc, gchar **argv, gchar **env)
if ((cmd = check_rspamc_command (argv[1])) != RSPAMC_COMMAND_UNKNOWN) {
/* In case of command read arguments starting from 2 */
for (i = 2; i < argc; i ++) {
- if (cmd == RSPAMC_COMMAND_SYMBOLS) {
- scan_rspamd_file (argv[i]);
+ if (tty) {
+ printf ("\033[1m");
}
- else {
- /* XXX: implement this */
+ PRINT_FUNC ("Results for file: %s\n\n", argv[i]);
+ if (tty) {
+ printf ("\033[0m");
+ }
+ switch (cmd) {
+ case RSPAMC_COMMAND_SYMBOLS:
+ scan_rspamd_file (argv[i]);
+ break;
+ case RSPAMC_COMMAND_LEARN:
+ learn_rspamd_file (argv[i]);
+ break;
+ case RSPAMC_COMMAND_FUZZY_ADD:
+ fuzzy_rspamd_file (argv[i], FALSE);
+ break;
+ case RSPAMC_COMMAND_FUZZY_DEL:
+ fuzzy_rspamd_file (argv[i], TRUE);
+ break;
+ default:
+ fprintf (stderr, "invalid arguments\n");
+ exit (EXIT_FAILURE);
}
}
}
@@ -356,6 +590,7 @@ main (gint argc, gchar **argv, gchar **env)
}
}
+ rspamd_client_close ();
return 0;
}
diff --git a/src/controller.c b/src/controller.c
index a39ec21cb..d204a1aa0 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -836,7 +836,7 @@ controller_read_socket (f_str_t * in, void *arg)
/* Handle messages without text */
if (tokens == NULL) {
- i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn failed, no tokens can be extracted (no text data)" CRLF);
+ i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn failed, no tokens can be extracted (no text data)" CRLF END);
msg_info ("learn failed for message <%s>, no tokens to extract", task->message_id);
free_task (task, FALSE);
if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) {
@@ -860,12 +860,12 @@ controller_read_socket (f_str_t * in, void *arg)
session->learn_symbol, tokens, session->in_class, &sum,
session->learn_multiplier, &err)) {
if (err) {
- i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn failed, learn classifier error: %s" CRLF, err->message);
+ i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn failed, learn classifier error: %s" CRLF END, err->message);
msg_info ("learn failed for message <%s>, learn error: %s", task->message_id, err->message);
g_error_free (err);
}
else {
- i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn failed, unknown learn classifier error" CRLF);
+ i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn failed, unknown learn classifier error" CRLF END);
msg_info ("learn failed for message <%s>, unknown learn error", task->message_id);
}
free_task (task, FALSE);
@@ -882,7 +882,7 @@ controller_read_socket (f_str_t * in, void *arg)
task->message_id, session->learn_symbol, sum);
statfile_pool_plan_invalidate (session->worker->srv->statfile_pool, DEFAULT_STATFILE_INVALIDATE_TIME, DEFAULT_STATFILE_INVALIDATE_JITTER);
free_task (task, FALSE);
- i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn ok, sum weight: %.2f" CRLF, sum);
+ i = rspamd_snprintf (out_buf, sizeof (out_buf), "learn ok, sum weight: %.2f" CRLF END, sum);
if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) {
return FALSE;
}
@@ -902,7 +902,7 @@ controller_read_socket (f_str_t * in, void *arg)
msg_warn ("processing of message failed");
free_task (task, FALSE);
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF END);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return FALSE;
}
@@ -920,7 +920,7 @@ controller_read_socket (f_str_t * in, void *arg)
c.begin = part->content->data;
c.len = part->content->len;
if (!session->learn_classifier->tokenizer->tokenize_func (session->learn_classifier->tokenizer, session->session_pool, &c, &tokens)) {
- i = rspamd_snprintf (out_buf, sizeof (out_buf), "weights failed, tokenizer error" CRLF);
+ i = rspamd_snprintf (out_buf, sizeof (out_buf), "weights failed, tokenizer error" CRLF END);
free_task (task, FALSE);
if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) {
return FALSE;
@@ -933,7 +933,7 @@ controller_read_socket (f_str_t * in, void *arg)
/* Handle messages without text */
if (tokens == NULL) {
- i = rspamd_snprintf (out_buf, sizeof (out_buf), "weights failed, no tokens can be extracted (no text data)" CRLF);
+ i = rspamd_snprintf (out_buf, sizeof (out_buf), "weights failed, no tokens can be extracted (no text data)" CRLF END);
free_task (task, FALSE);
if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) {
return FALSE;
@@ -956,13 +956,14 @@ controller_read_socket (f_str_t * in, void *arg)
i += rspamd_snprintf (out_buf + i, sizeof (out_buf) - i, "%s: %G" CRLF, w->name, w->weight);
cur = g_list_next (cur);
}
+ i += rspamd_snprintf (out_buf + i, sizeof (out_buf) - i, END);
if (i != 0) {
if (!rspamd_dispatcher_write (session->dispatcher, out_buf, i, FALSE, FALSE)) {
return FALSE;
}
}
else {
- if (!rspamd_dispatcher_write (session->dispatcher, "weights failed: classifier error", 0, FALSE, TRUE)) {
+ if (!rspamd_dispatcher_write (session->dispatcher, "weights failed: classifier error" CRLF END, 0, FALSE, TRUE)) {
return FALSE;
}
}
diff --git a/src/plugins/fuzzy_check.c b/src/plugins/fuzzy_check.c
index e47beee17..f81d549a7 100644
--- a/src/plugins/fuzzy_check.c
+++ b/src/plugins/fuzzy_check.c
@@ -567,7 +567,7 @@ fuzzy_learn_callback (gint fd, short what, void *arg)
else if (buf[0] == 'O' && buf[1] == 'K') {
msg_info ("added fuzzy hash '%s' to list: %d for message <%s>",
fuzzy_to_string (session->h), session->flag, session->task->message_id);
- r = rspamd_snprintf (buf, sizeof (buf), "OK" CRLF);
+ r = rspamd_snprintf (buf, sizeof (buf), "OK" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE)) {
return;
}
@@ -575,7 +575,7 @@ fuzzy_learn_callback (gint fd, short what, void *arg)
}
else {
msg_info ("cannot add fuzzy hash for message <%s>", session->task->message_id);
- r = rspamd_snprintf (buf, sizeof (buf), "ERR" CRLF);
+ r = rspamd_snprintf (buf, sizeof (buf), "ERR" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE)) {
return;
}
@@ -591,7 +591,7 @@ fuzzy_learn_callback (gint fd, short what, void *arg)
err:
msg_err ("got error in IO with server %s:%d, %d, %s", session->server->name, session->server->port, errno, strerror (errno));
- r = rspamd_snprintf (buf, sizeof (buf), "Error" CRLF);
+ r = rspamd_snprintf (buf, sizeof (buf), "Error" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->session->dispatcher, buf, r, FALSE, FALSE)) {
return;
}
@@ -741,7 +741,7 @@ register_fuzzy_controller_call (struct controller_session *session, struct worke
if ((sock = make_udp_socket (&selected->addr, selected->port, FALSE, TRUE)) == -1) {
msg_warn ("cannot connect to %s, %d, %s", selected->name, errno, strerror (errno));
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "no hashes written" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "no hashes written" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return FALSE;
}
@@ -810,7 +810,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
msg_warn ("processing of message failed");
free_task (task, FALSE);
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot process message" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
msg_warn ("write error");
}
@@ -829,7 +829,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
if (! register_fuzzy_controller_call (session, task, part->fuzzy, cmd, value, flag, saved)) {
/* Cannot write hash */
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return;
}
@@ -853,7 +853,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
if (! register_fuzzy_controller_call (session, task, &fake_fuzzy, cmd, value, flag, saved)) {
/* Cannot write hash */
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return;
}
@@ -883,7 +883,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
if (! register_fuzzy_controller_call (session, task, &fake_fuzzy, cmd, value, flag, saved)) {
/* Cannot write hash */
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "cannot write fuzzy hash" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return;
}
@@ -905,7 +905,7 @@ fuzzy_process_handler (struct controller_session *session, f_str_t * in)
if (*saved == 0) {
session->state = STATE_REPLY;
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "no hashes written" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "no hashes written" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return;
}
@@ -923,7 +923,7 @@ fuzzy_controller_handler (gchar **args, struct controller_session *session, gint
arg = args[0];
if (!arg || *arg == '\0') {
msg_info ("empty content length");
- r = rspamd_snprintf (out_buf, sizeof (out_buf), "fuzzy command requires length as argument" CRLF);
+ r = rspamd_snprintf (out_buf, sizeof (out_buf), "fuzzy command requires length as argument" CRLF "END" CRLF);
if (! rspamd_dispatcher_write (session->dispatcher, out_buf, r, FALSE, FALSE)) {
return;
}