#include "cfg_rcl.h"
#include "main.h"
#include "settings.h"
+#include "cfg_file.h"
#include "lua/lua_common.h"
+#include "classifiers/classifiers.h"
+#include "tokenizers/tokenizers.h"
/*
* Common section handlers
return TRUE;
}
+static gboolean
+rspamd_rcl_statfile_handler (struct config_file *cfg, ucl_object_t *obj,
+ gpointer ud, struct rspamd_rcl_section *section, GError **err)
+{
+ struct classifier_config *ccf = ud;
+ ucl_object_t *val;
+ struct statfile *st;
+ const gchar *data;
+ gdouble binlog_rotate;
+ GList *labels;
+
+ st = check_statfile_conf (cfg, NULL);
+
+ val = ucl_object_find_key (obj, "binlog");
+ if (val != NULL && ucl_object_tostring_safe (val, &data)) {
+ if (st->binlog == NULL) {
+ st->binlog = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct statfile_binlog_params));
+ }
+ if (g_ascii_strcasecmp (data, "master") == 0) {
+ st->binlog->affinity = AFFINITY_MASTER;
+ }
+ else if (g_ascii_strcasecmp (data, "slave") == 0) {
+ st->binlog->affinity = AFFINITY_SLAVE;
+ }
+ else {
+ st->binlog->affinity = AFFINITY_NONE;
+ }
+ /* Parse remaining binlog attributes */
+ val = ucl_object_find_key (obj, "binlog_rotate");
+ if (val != NULL && ucl_object_todouble_safe (val, &binlog_rotate)) {
+ st->binlog->rotate_time = binlog_rotate;
+ }
+ val = ucl_object_find_key (obj, "binlog_master");
+ if (val != NULL && ucl_object_tostring_safe (val, &data)) {
+ if (!parse_host_port (cfg->cfg_pool, data, &st->binlog->master_addr, &st->binlog->master_port)) {
+ msg_err ("cannot parse master address: %s", data);
+ return FALSE;
+ }
+ }
+ }
+
+ if (rspamd_rcl_section_parse_defaults (section, cfg, obj, st, err)) {
+ ccf->statfiles = g_list_prepend (ccf->statfiles, st);
+ if (st->label != NULL) {
+ labels = g_hash_table_lookup (ccf->labels, st->label);
+ if (labels != NULL) {
+ labels = g_list_append (labels, st);
+ }
+ else {
+ g_hash_table_insert (ccf->labels, st->label, g_list_prepend (NULL, st));
+ }
+ }
+ if (st->symbol != NULL) {
+ g_hash_table_insert (cfg->classifiers_symbols, st->symbol, st);
+ }
+ else {
+ g_set_error (err, CFG_RCL_ERROR, EINVAL, "statfile must have a symbol defined");
+ return FALSE;
+ }
+
+ if (st->path == NULL) {
+ g_set_error (err, CFG_RCL_ERROR, EINVAL, "statfile must have a path defined");
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+rspamd_rcl_classifier_handler (struct config_file *cfg, ucl_object_t *obj,
+ gpointer ud, struct rspamd_rcl_section *section, GError **err)
+{
+ ucl_object_t *val, *cur;
+ ucl_object_iter_t it = NULL;
+ const gchar *key;
+ struct classifier_config *ccf;
+ gboolean res = TRUE;
+ struct rspamd_rcl_section *stat_section;
+
+ ccf = check_classifier_conf (cfg, NULL);
+ HASH_FIND_STR (section->subsections, "statfile", stat_section);
+
+ while ((val = ucl_iterate_object (obj, &it, true)) != NULL && res) {
+ key = ucl_object_key (val);
+ if (key != NULL) {
+ if (g_ascii_strcasecmp (key, "statfile") == 0) {
+ LL_FOREACH (val, cur) {
+ res = rspamd_rcl_statfile_handler (cfg, cur, ccf, stat_section, err);
+ }
+ }
+ else if (g_ascii_strcasecmp (key, "type") == 0 && val->type == UCL_STRING) {
+ ccf->classifier = get_classifier (ucl_object_tostring (val));
+ }
+ else if (g_ascii_strcasecmp (key, "tokenizer") == 0 && val->type == UCL_STRING) {
+ ccf->tokenizer = get_tokenizer (ucl_object_tostring (val));
+ }
+ else {
+ /* Just insert a value of option to the hash */
+ g_hash_table_insert (ccf->opts, (gpointer)key, (gpointer)ucl_object_tostring_forced (val));
+ }
+ }
+ }
+
+ cfg->classifiers = g_list_prepend (cfg->classifiers, ccf);
+
+
+ return res;
+}
+
/**
* Fake handler to parse default options only, uses struct cfg_file as pointer
* for default handlers
struct rspamd_rcl_section*
rspamd_rcl_config_init (void)
{
- struct rspamd_rcl_section *new = NULL, *sub;
+ struct rspamd_rcl_section *new = NULL, *sub, *ssub;
/* TODO: add all known rspamd sections here */
/**
sub = rspamd_rcl_add_section (&new, "modules", rspamd_rcl_modules_handler, UCL_OBJECT,
FALSE, TRUE);
+ /**
+ * Classifiers handler
+ */
+ sub = rspamd_rcl_add_section (&new, "classifier", rspamd_rcl_classifier_handler, UCL_OBJECT,
+ FALSE, TRUE);
+ ssub = rspamd_rcl_add_section (&sub->subsections, "statfile", rspamd_rcl_statfile_handler,
+ UCL_OBJECT, TRUE, TRUE);
+ rspamd_rcl_add_default_handler (ssub, "symbol", rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET (struct statfile, symbol), 0);
+ rspamd_rcl_add_default_handler (ssub, "path", rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET (struct statfile, path), 0);
+ rspamd_rcl_add_default_handler (ssub, "label", rspamd_rcl_parse_struct_string,
+ G_STRUCT_OFFSET (struct statfile, label), 0);
+ rspamd_rcl_add_default_handler (ssub, "size", rspamd_rcl_parse_struct_integer,
+ G_STRUCT_OFFSET (struct statfile, size), RSPAMD_CL_FLAG_INT_SIZE);
+ rspamd_rcl_add_default_handler (ssub, "spam", rspamd_rcl_parse_struct_boolean,
+ G_STRUCT_OFFSET (struct statfile, is_spam), 0);
+
return new;
}