Cleanup client's code.
Update manual page for client.
Make 'bayes' as the default classifier for client learning operations.
-.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07)
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
.\" ========================================================================
.\"
.IX Title "rspamc 1"
-.TH rspamc 1 "2011-03-15" "rspamd-0.3.8" "Rspamd documentation"
+.TH rspamc 1 "2012-10-02" "rspamd-0.5.2" "Rspamd documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
-.SH "NAME"
+.SH "RSPAMC"
.IX Header "RSPAMC"
rspamc \- a simple client for rspamd spam filtering system
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
-rspamc [\fB\-h\fR \fIhost[:port]\fR] [\fB\-p\fR] [\fB\-v\fR]
-[\fB\-i\fR \fIip\fR] [\fB\-s\fR \fIstatfile\fR] [\fB\-w\fR \fIweight\fR]
+rspamc [\fB\-h\fR \fIhost[:port]\fR] [\fB\-p\fR] [\fB\-v\fR] [\fB\-b\fR \fIbind_address\fR] [\fB\-u\fR \fIuser\fR]
+[\fB\-F\fR \fIfrom\fR] [\fB\-r\fR \fIrcpt\fR] [\fB\-d\fR \fIdeliver-to\fR]
+[\fB\-i\fR \fIip\fR] [\fB\-c\fR \fIclassifier\fR] [\fB\-w\fR \fIweight\fR]
[\fB\-P\fR \fIpassword\fR] [\fB\-f\fR \fIflag\fR] [\fB\-t\fR \fItimeout\fR] [command] [file [file ...]]
.PP
rspamc [\fB\-\-help\fR]
.IP "\fB\-h\fR \fIhost[:port]\fR, \fB\-\-connect\fR \fIhost[:port]\fR" 4
.IX Item "-h host[:port], --connect host[:port]"
Specify host and port for connecting to rspamd server. Default host is \fIlocalhost\fR and
-default port is \fI11333\fR for checking messages and \fI11334\fR for learning and statistic.
+default port is \fI11333\fR for checking messages and \fI11334\fR for learning and statistic.
+Also it is possible to specify a unix socket for all operations (for example:
+\&\fBrspamc\fR \fB\-h\fR /path/to/soket)
+.IP "\fB\-b\fR \fIlocal_ip\fR, \fB\-\-bind\fR \fIlocal_ip\fR" 4
+.IX Item "-b local_ip, --bind local_ip"
+Specify explicit \s-1IP\s0 address to bind a client for operations.
+.IP "\fB\-u\fR \fIuser\fR, \fB\-\-user\fR \fIuser\fR" 4
+.IX Item "-u user, --user user"
+Specify username for connection with rspamd server.
+.IP "\fB\-F\fR \fIfrom_addr\fR, \fB\-\-from\fR \fIfrom_addr\fR" 4
+.IX Item "-F from_addr, --from from_addr"
+Specify \s-1SMTP\s0 \s-1FROM\s0 address for connection with rspamd server.
+.IP "\fB\-r\fR \fIrcpt_addr\fR, \fB\-\-rcpt\fR \fIrcpt_addr\fR" 4
+.IX Item "-r rcpt_addr, --rcpt rcpt_addr"
+Specify \s-1SMTP\s0 \s-1RCPT\s0 \s-1TO\s0 address for connection with rspamd server.
+.IP "\fB\-d\fR \fIdeliver_addr\fR, \fB\-\-deliver\fR \fIdeliver_addr\fR" 4
+.IX Item "-d deliver_addr, --deliver deliver_addr"
+Specify real delivery address for connection with rspamd server.
.IP "\fB\-p\fR, \fB\-\-pass\-all\fR" 4
.IX Item "-p, --pass-all"
Pass all filters when checking messages. Ignored in case of learning.
.IP "\fB\-P\fR \fIpassword\fR, \fB\-\-password\fR \fIpassword\fR" 4
.IX Item "-P password, --password password"
Specify controller's password. Mandatory option for learning.
-.IP "\fB\-s\fR \fIstatfile\fR, \fB\-\-statfile\fR \fIstatfile\fR" 4
-.IX Item "-s statfile, --statfile statfile"
-Specify statfile's symbol to learn message. Mandatory option for learning.
+.IP "\fB\-c\fR \fIclassifier\fR, \fB\-\-classifier\fR \fIclassifier\fR" 4
+.IX Item "-c classifier, --classifier classifier"
+Specify classifier to learn message. Mandatory option for learning. Bayes classifier is used by default if this option is omitted.
.IP "\fB\-i\fR \fIip\fR, \fB\-\-ip\fR \fIip\fR" 4
.IX Item "-i ip, --ip ip"
Add \s-1IP\s0 header when scanning message. Useful for checking messages and emulating that client comes from
Learn files:
.PP
.Vb 1
-\& rspamc \-P pass \-s BAYES_SPAM file1 file2 file3
+\& rspamc \-P pass learn_spam file1 file2 file3
.Ve
.PP
Add fuzzy hash to set 2:
.Vb 1
\& rspamc uptime
.Ve
+.PP
+Add custom rule's weight:
+.PP
+.Vb 1
+\& rspamc add_symbol test 1.5
+.Ve
+.PP
+Add custom action's weight:
+.PP
+.Vb 1
+\& rspamc add_action reject 7.1
+.Ve
.SH "AUTHOR"
.IX Header "AUTHOR"
Vsevolod Stakhov <vsevolod@highsecure.ru>
.SH "COPYRIGHT AND LICENSE"
.IX Header "COPYRIGHT AND LICENSE"
-Copyright 2011 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
+Copyright 2011\-2012 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
.PP
This program is free software; you may redistribute it and/or modify it
under the terms of \s-1BSD\s0 license.
=head1 SYNOPSIS
-rspamc [B<-h> I<host[:port]>] [B<-p>] [B<-v>]
-[B<-i> I<ip>] [B<-s> I<statfile>] [B<-w> I<weight>]
+rspamc [B<-h> I<host[:port]>] [B<-p>] [B<-v>] [B<-b> I<bind_address>] [B<-u> I<user>]
+[B<-F> I<from>] [B<-r> I<rcpt>] [B<-d> I<deliver-to>]
+[B<-i> I<ip>] [B<-c> I<classifier>] [B<-w> I<weight>]
[B<-P> I<password>] [B<-f> I<flag>] [B<-t> I<timeout>] [command] [file [file ...]]
rspamc [B<--help>]
Specify host and port for connecting to rspamd server. Default host is I<localhost> and
default port is I<11333> for checking messages and I<11334> for learning and statistic.
+Also it is possible to specify a unix socket for all operations (for example:
+B<rspamc> B<-h> /path/to/soket)
+
+=item B<-b> I<local_ip>, B<--bind> I<local_ip>
+
+Specify explicit IP address to bind a client for operations.
+
+=item B<-u> I<user>, B<--user> I<user>
+
+Specify username for connection with rspamd server.
+
+=item B<-F> I<from_addr>, B<--from> I<from_addr>
+
+Specify SMTP FROM address for connection with rspamd server.
+
+=item B<-r> I<rcpt_addr>, B<--rcpt> I<rcpt_addr>
+
+Specify SMTP RCPT TO address for connection with rspamd server.
+
+=item B<-d> I<deliver_addr>, B<--deliver> I<deliver_addr>
+
+Specify real delivery address for connection with rspamd server.
=item B<-p>, B<--pass-all>
Specify controller's password. Mandatory option for learning.
-=item B<-s> I<statfile>, B<--statfile> I<statfile>
+=item B<-c> I<classifier>, B<--classifier> I<classifier>
-Specify statfile's symbol to learn message. Mandatory option for learning.
+Specify classifier to learn message. Mandatory option for learning. Bayes classifier is used by default if this option is omitted.
=item B<-i> I<ip>, B<--ip> I<ip>
Learn files:
- rspamc -P pass -s BAYES_SPAM file1 file2 file3
+ rspamc -P pass learn_spam file1 file2 file3
Add fuzzy hash to set 2:
rspamc uptime
+Add custom rule's weight:
+
+ rspamc add_symbol test 1.5
+
+Add custom action's weight:
+
+ rspamc add_action reject 7.1
+
=head1 AUTHOR
Vsevolod Stakhov <vsevolod@highsecure.ru>
=head1 COPYRIGHT AND LICENSE
-Copyright 2011 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
+Copyright 2011-2012 by Vsevolod Stakhov <vsevolod@highsecure.ru>.
This program is free software; you may redistribute it and/or modify it
under the terms of BSD license.
-.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07)
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
.\"
.\" Standard preamble:
.\" ========================================================================
.\" ========================================================================
.\"
.IX Title "rspamd 8"
-.TH rspamd 8 "2011-03-15" "rspamd-0.3.8" "Rspamd documentation"
+.TH rspamd 8 "2012-10-02" "rspamd-0.5.2" "Rspamd documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
-.SH "NAME"
+.SH "RSPAMD"
.IX Header "RSPAMD"
rspamd \- main daemon for rspamd spam filtering system
.SH "SYNOPSIS"
static gchar *deliver_to = NULL;
static gchar *rcpt = NULL;
static gchar *user = NULL;
-static gchar *classifier = NULL;
+static gchar *classifier = "bayes";
static gchar *local_addr = NULL;
static gint weight = 1;
static gint flag;
RSPAMC_COMMAND_FUZZY_ADD,
RSPAMC_COMMAND_FUZZY_DEL,
RSPAMC_COMMAND_STAT,
- RSPAMC_COMMAND_UPTIME
+ RSPAMC_COMMAND_UPTIME,
+ RSPAMC_COMMAND_ADD_SYMBOL,
+ RSPAMC_COMMAND_ADD_ACTION
};
/*
else if (g_ascii_strcasecmp (cmd, "UPTIME") == 0) {
return RSPAMC_COMMAND_UPTIME;
}
+ else if (g_ascii_strcasecmp (cmd, "ADD_SYMBOL") == 0) {
+ return RSPAMC_COMMAND_ADD_SYMBOL;
+ }
+ else if (g_ascii_strcasecmp (cmd, "ADD_ACTION") == 0) {
+ return RSPAMC_COMMAND_ADD_ACTION;
+ }
return RSPAMC_COMMAND_UNKNOWN;
}
struct rspamd_result *res;
GHashTable *opts;
+ /* Add server */
+ add_rspamd_server (FALSE);
/* Init options hash */
opts = g_hash_table_new (g_str_hash, g_str_equal);
add_options (opts);
exit (EXIT_FAILURE);
}
+ /* Add server */
+ add_rspamd_server (TRUE);
params = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (params, "Classifier", classifier);
gchar valuebuf[sizeof("65535")], flagbuf[sizeof("65535")];
struct rspamd_controller_result *res;
+ /* Add server */
+ add_rspamd_server (TRUE);
+
params = g_hash_table_new (g_str_hash, g_str_equal);
rspamd_snprintf (valuebuf, sizeof (valuebuf), "%d", weight);
rspamd_snprintf (flagbuf, sizeof (flagbuf), "%d", flag);
}
static void
-rspamd_do_controller_simple_command (gchar *command)
+rspamd_do_controller_simple_command (gchar *command, GHashTable *kwattrs)
{
GError *err = NULL;
GList *results, *cur;
struct rspamd_controller_result *res;
-
/* Add server */
add_rspamd_server (TRUE);
- results = rspamd_controller_command_simple (client, command, password, NULL, &err);
+ results = rspamd_controller_command_simple (client, command, password, kwattrs, &err);
if (results == NULL || err != NULL) {
if (err != NULL) {
fprintf (stderr, "cannot perform command: %s\n", err->message);
gint
main (gint argc, gchar **argv, gchar **env)
{
- enum rspamc_command cmd;
- gint i;
- struct in_addr ina;
+ enum rspamc_command cmd;
+ gint i;
+ struct in_addr ina;
+ GHashTable *kwattrs;
+
+ kwattrs = g_hash_table_new (g_str_hash, g_str_equal);
read_cmd_line (&argc, &argv);
fuzzy_rspamd_stdin (TRUE);
break;
case RSPAMC_COMMAND_STAT:
- rspamd_do_controller_simple_command ("stat");
+ rspamd_do_controller_simple_command ("stat", NULL);
break;
case RSPAMC_COMMAND_UPTIME:
- rspamd_do_controller_simple_command ("uptime");
+ rspamd_do_controller_simple_command ("uptime", NULL);
break;
default:
fprintf (stderr, "invalid arguments\n");
}
}
else {
- add_rspamd_server (FALSE);
scan_rspamd_file (argv[1]);
}
}
else {
if ((cmd = check_rspamc_command (argv[1])) != RSPAMC_COMMAND_UNKNOWN) {
/* In case of command read arguments starting from 2 */
- switch (cmd) {
- case RSPAMC_COMMAND_SYMBOLS:
- /* Add server */
- add_rspamd_server (FALSE);
- break;
- default:
- add_rspamd_server (TRUE);
- break;
- }
- for (i = 2; i < argc; i ++) {
- if (tty) {
- printf ("\033[1m");
+ if (cmd == RSPAMC_COMMAND_ADD_SYMBOL || cmd == RSPAMC_COMMAND_ADD_ACTION) {
+ if (argc < 4 || argc > 5) {
+ fprintf (stderr, "invalid arguments\n");
+ exit (EXIT_FAILURE);
}
- PRINT_FUNC ("Results for file: %s\n\n", argv[i]);
- if (tty) {
- printf ("\033[0m");
+ if (argc == 5) {
+ g_hash_table_insert (kwattrs, "metric", argv[2]);
+ g_hash_table_insert (kwattrs, "name", argv[3]);
+ g_hash_table_insert (kwattrs, "value", argv[4]);
}
- switch (cmd) {
- case RSPAMC_COMMAND_SYMBOLS:
- scan_rspamd_file (argv[i]);
- break;
- case RSPAMC_COMMAND_LEARN_SPAM:
- if (classifier != NULL) {
- learn_rspamd_file (TRUE, argv[i]);
- }
- else {
- fprintf (stderr, "no classifier specified\n");
- exit (EXIT_FAILURE);
+ else {
+ g_hash_table_insert (kwattrs, "name", argv[2]);
+ g_hash_table_insert (kwattrs, "value", argv[3]);
+ }
+ rspamd_do_controller_simple_command (cmd == RSPAMC_COMMAND_ADD_SYMBOL ? "add_symbol" : "add_action", kwattrs);
+ }
+ else {
+ for (i = 2; i < argc; i ++) {
+ if (tty) {
+ printf ("\033[1m");
}
- break;
- case RSPAMC_COMMAND_LEARN_HAM:
- if (classifier != NULL) {
- learn_rspamd_file (FALSE, argv[i]);
+ PRINT_FUNC ("Results for file: %s\n\n", argv[i]);
+ if (tty) {
+ printf ("\033[0m");
}
- else {
- fprintf (stderr, "no classifier specified\n");
+ switch (cmd) {
+ case RSPAMC_COMMAND_SYMBOLS:
+ scan_rspamd_file (argv[i]);
+ break;
+ case RSPAMC_COMMAND_LEARN_SPAM:
+ if (classifier != NULL) {
+ learn_rspamd_file (TRUE, argv[i]);
+ }
+ else {
+ fprintf (stderr, "no classifier specified\n");
+ exit (EXIT_FAILURE);
+ }
+ break;
+ case RSPAMC_COMMAND_LEARN_HAM:
+ if (classifier != NULL) {
+ learn_rspamd_file (FALSE, argv[i]);
+ }
+ else {
+ fprintf (stderr, "no classifier specified\n");
+ exit (EXIT_FAILURE);
+ }
+ 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);
}
- 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);
}
}
}
rspamd_client_close (client);
+ g_hash_table_destroy (kwattrs);
+
return 0;
}
{
GList *cur;
struct dynamic_cfg_metric *metric = NULL;
- struct dynamic_cfg_symbol *sym;
+ struct dynamic_cfg_symbol *sym = NULL;
if (cfg->dynamic_conf == NULL) {
msg_info ("dynamic conf is disabled");
sym = cur->data;
if (g_ascii_strcasecmp (sym->name, symbol) == 0) {
sym->value = value;
+ msg_debug ("change value of action %s to %.2f", symbol, value);
break;
}
sym = NULL;
sym->name = g_strdup (symbol);
sym->value = value;
metric->symbols = g_list_prepend (metric->symbols, sym);
+ msg_debug ("create symbol %s in metric %s", symbol, metric_name);
}
}
else {
metric->symbols = g_list_prepend (metric->symbols, sym);
metric->name = g_strdup (metric_name);
cfg->current_dynamic_conf = g_list_prepend (cfg->current_dynamic_conf, metric);
+ msg_debug ("create metric %s for symbol %s", metric_name, symbol);
}
apply_dynamic_conf (cfg->current_dynamic_conf, cfg);
{
GList *cur;
struct dynamic_cfg_metric *metric = NULL;
- struct dynamic_cfg_action *act;
+ struct dynamic_cfg_action *act = NULL;
gint real_act;
if (cfg->dynamic_conf == NULL) {
}
if (metric != NULL) {
- /* Search for a symbol */
- cur = metric->symbols;
+ /* Search for an action */
+ cur = metric->actions;
while (cur) {
act = cur->data;
if ((gint)act->action == real_act) {
act->value = value;
+ msg_debug ("change value of action %s to %.2f", action, value);
break;
}
act = NULL;
}
if (act == NULL) {
/* Action not found, insert it */
- act = g_slice_alloc (sizeof (struct dynamic_cfg_symbol));
+ act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
act->action = real_act;
act->value = value;
- metric->actions = g_list_prepend (metric->symbols, act);
+ metric->actions = g_list_prepend (metric->actions, act);
+ msg_debug ("create action %s in metric %s", action, metric_name);
}
}
else {
/* Metric not found, create it */
metric = g_slice_alloc0 (sizeof (struct dynamic_cfg_metric));
- act = g_slice_alloc (sizeof (struct dynamic_cfg_symbol));
+ act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
act->action = real_act;
act->value = value;
- metric->actions = g_list_prepend (metric->symbols, act);
+ metric->actions = g_list_prepend (metric->actions, act);
metric->name = g_strdup (metric_name);
cfg->current_dynamic_conf = g_list_prepend (cfg->current_dynamic_conf, metric);
+ msg_debug ("create metric %s for action %s", metric_name, action);
}
apply_dynamic_conf (cfg->current_dynamic_conf, cfg);