Beispiel #1
0
ucl_object_t *
rspamd_log_errorbuf_export (const rspamd_logger_t *logger)
{
	struct rspamd_logger_error_elt *cpy, *cur;
	ucl_object_t *top = ucl_object_typed_new (UCL_ARRAY);
	guint i;

	if (logger->errlog == NULL) {
		return top;
	}

	cpy = g_malloc0_n (logger->errlog->max_elts,
			sizeof (*cpy) + logger->errlog->elt_len);
	memcpy (cpy, logger->errlog->elts, logger->errlog->max_elts *
			(sizeof (*cpy) + logger->errlog->elt_len));

	for (i = 0; i < logger->errlog->max_elts; i ++) {
		cur = (struct rspamd_logger_error_elt *)((guchar *)cpy +
				i * ((sizeof (*cpy) + logger->errlog->elt_len)));
		if (cur->completed) {
			ucl_object_t *obj = ucl_object_typed_new (UCL_OBJECT);

			ucl_object_insert_key (obj, ucl_object_fromdouble (cur->ts),
					"ts", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromint (cur->pid),
					"pid", 0, false);
			ucl_object_insert_key (obj,
					ucl_object_fromstring (g_quark_to_string (cur->ptype)),
					"type", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromstring (cur->id),
					"id", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromstring (cur->module),
					"module", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromstring (cur->message),
					"message", 0, false);

			ucl_array_append (top, obj);
		}
	}

	ucl_object_array_sort (top, rspamd_log_errlog_cmp);
	g_free (cpy);

	return top;
}
Beispiel #2
0
static ucl_object_t *
new_dynamic_elt (ucl_object_t *arr, const gchar *name, gdouble value)
{
	ucl_object_t *n;

	n = ucl_object_typed_new (UCL_OBJECT);
	ucl_object_insert_key (n, ucl_object_fromstring (name), "name",
		sizeof ("name") - 1, false);
	ucl_object_insert_key (n, ucl_object_fromdouble (value), "value",
		sizeof ("value") - 1, false);

	ucl_array_append (arr, n);

	return n;
}
Beispiel #3
0
static ucl_object_t*
new_dynamic_metric (const gchar *metric_name, ucl_object_t *top)
{
	ucl_object_t *metric;

	metric = ucl_object_typed_new (UCL_OBJECT);

	ucl_object_insert_key (metric, ucl_object_fromstring (metric_name),
			"metric", sizeof ("metric") - 1, true);
	ucl_object_insert_key (metric, ucl_object_typed_new (UCL_ARRAY),
			"actions", sizeof ("actions") - 1, false);
	ucl_object_insert_key (metric, ucl_object_typed_new (UCL_ARRAY),
			"symbols", sizeof ("symbols") - 1, false);

	ucl_array_append (top, metric);

	return metric;
}
Beispiel #4
0
static void
rspamd_symbols_cache_counters_cb (gpointer v, gpointer ud)
{
	struct counters_cbdata *cbd = ud;
	ucl_object_t *obj, *top;
	struct cache_item *item = v, *parent;

	top = cbd->top;

	if (item->type != SYMBOL_TYPE_CALLBACK) {
		obj = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (obj, ucl_object_fromstring (item->symbol),
				"symbol", 0, false);

		if (item->type == SYMBOL_TYPE_VIRTUAL && item->parent != -1) {
			g_assert (item->parent < (gint)cbd->cache->items_by_id->len);
			parent = g_ptr_array_index (cbd->cache->items_by_id,
					item->parent);
			ucl_object_insert_key (obj, ucl_object_fromdouble (item->weight),
					"weight", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromint (item->frequency),
					"frequency", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromdouble (parent->avg_time),
					"time", 0, false);
		}
		else {
			ucl_object_insert_key (obj, ucl_object_fromdouble (item->weight),
					"weight", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromint (item->frequency),
					"frequency", 0, false);
			ucl_object_insert_key (obj, ucl_object_fromdouble (item->avg_time),
					"time", 0, false);
		}

		ucl_array_append (top, obj);
	}
}
Beispiel #5
0
static void
rspamadm_rescore (gint argc, gchar **argv) {

	GOptionContext *context;
	GError *error = NULL;
	lua_State *L;
	ucl_object_t *obj;

	context = g_option_context_new (
			"rescore - Estimate optimal symbol weights from log files");

	g_option_context_set_summary (context,
			"Summary:\n Rspamd administration utility version "
					RVERSION
					"\n Release id: "
					RID);

	g_option_context_add_main_entries (context, entries, NULL);
	g_option_context_set_ignore_unknown_options (context, TRUE);

	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		rspamd_fprintf (stderr, "option parsing failed: %s\n", error->message);
		g_error_free (error);
		exit (EXIT_FAILURE);
	}

	if (!HAS_TORCH) {
		rspamd_fprintf (stderr, "Torch is not enabled. "
				"Use -DENABLE_TORCH=ON option while running cmake.\n");
		exit (EXIT_FAILURE);
	}

	if (logdir == NULL) {
		rspamd_fprintf (stderr, "Please specify log directory.\n");
		exit (EXIT_FAILURE);
	}

	L = rspamd_lua_init ();
	rspamd_lua_set_path (L, NULL, NULL);

	obj = ucl_object_typed_new (UCL_OBJECT);

	ucl_object_insert_key (obj, ucl_object_fromstring (logdir),
			"logdir", 0, false);
	ucl_object_insert_key (obj, ucl_object_fromstring (output),
			"output", 0, false);
	ucl_object_insert_key (obj, ucl_object_fromdouble (threshold),
			"threshold", 0, false);
	ucl_object_insert_key (obj, ucl_object_fromint (iters),
			"iters", 0, false);
	ucl_object_insert_key (obj, ucl_object_frombool (score_diff),
			"diff", 0, false);

	rspamadm_execute_lua_ucl_subr (L,
			argc,
			argv,
			obj,
			"rescore");

	lua_close (L);
	ucl_object_unref (obj);
}
Beispiel #6
0
static void
rspamadm_statconvert (gint argc, gchar **argv)
{
	GOptionContext *context;
	GError *error = NULL;
	lua_State *L;
	ucl_object_t *obj;

	context = g_option_context_new (
			"statconvert - converts statistics from sqlite3 to redis");
	g_option_context_set_summary (context,
			"Summary:\n  Rspamd administration utility version "
					RVERSION
					"\n  Release id: "
					RID);
	g_option_context_add_main_entries (context, entries, NULL);
	g_option_context_set_ignore_unknown_options (context, TRUE);

	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		rspamd_fprintf (stderr, "option parsing failed: %s\n", error->message);
		g_error_free (error);
		exit (1);
	}

	if (!source_db) {
		rspamd_fprintf (stderr, "source db is missing\n");
		exit (1);
	}
	if (!redis_host) {
		rspamd_fprintf (stderr, "redis host is missing\n");
		exit (1);
	}
	if (!symbol) {
		rspamd_fprintf (stderr, "symbol is missing\n");
		exit (1);
	}

	L = rspamd_lua_init ();

	obj = ucl_object_typed_new (UCL_OBJECT);
	ucl_object_insert_key (obj, ucl_object_fromstring (source_db),
			"source_db", 0, false);
	ucl_object_insert_key (obj, ucl_object_fromstring (redis_host),
			"redis_host", 0, false);
	ucl_object_insert_key (obj, ucl_object_fromstring (symbol),
			"symbol", 0, false);

	if (cache_db != NULL) {
		ucl_object_insert_key (obj, ucl_object_fromstring (cache_db),
				"cache_db", 0, false);
	}

	rspamadm_execute_lua_ucl_subr (L,
			argc,
			argv,
			obj,
			rspamadm_script_stat_convert);

	lua_close (L);
	ucl_object_unref (obj);
}
Beispiel #7
0
/* Called when we have connected to the redis server and got keys to check */
static void
rspamd_redis_stat_keys (redisAsyncContext *c, gpointer r, gpointer priv)
{
	struct rspamd_redis_stat_cbdata *cbdata = priv;
	redisReply *reply = r, *elt;
	gchar **pk, *k;
	guint i, processed = 0;


	if (cbdata->wanna_die) {
		return;
	}

	cbdata->inflight --;

	if (c->err == 0 && r != NULL) {
		if (reply->type == REDIS_REPLY_ARRAY) {
			g_ptr_array_set_size (cbdata->cur_keys, reply->elements);

			for (i = 0; i < reply->elements; i ++) {
				elt = reply->element[i];

				if (elt->type == REDIS_REPLY_STRING) {
					pk = (gchar **)&g_ptr_array_index (cbdata->cur_keys, i);
					*pk = g_malloc (elt->len + 1);
					rspamd_strlcpy (*pk, elt->str, elt->len + 1);
					processed ++;
				}
			}

			if (processed) {
				for (i = 0; i < cbdata->cur_keys->len; i ++) {
					k = (gchar *)g_ptr_array_index (cbdata->cur_keys, i);

					if (k) {
						redisAsyncCommand (cbdata->redis, rspamd_redis_stat_key,
								cbdata,
								"HLEN %s",
								k);
						redisAsyncCommand (cbdata->redis, rspamd_redis_stat_learns,
								cbdata,
								"HGET %s learns",
								k);
						cbdata->inflight += 2;
					}
				}
			}
		}

		/* Set up the required keys */
		ucl_object_insert_key (cbdata->cur,
				ucl_object_typed_new (UCL_INT), "revision", 0, false);
		ucl_object_insert_key (cbdata->cur,
				ucl_object_typed_new (UCL_INT), "used", 0, false);
		ucl_object_insert_key (cbdata->cur,
				ucl_object_typed_new (UCL_INT), "total", 0, false);
		ucl_object_insert_key (cbdata->cur,
				ucl_object_typed_new (UCL_INT), "size", 0, false);
		ucl_object_insert_key (cbdata->cur,
				ucl_object_fromstring (cbdata->elt->ctx->stcf->symbol),
				"symbol", 0, false);
		ucl_object_insert_key (cbdata->cur, ucl_object_fromstring ("redis"),
				"type", 0, false);
		ucl_object_insert_key (cbdata->cur, ucl_object_fromint (0),
				"languages", 0, false);
		ucl_object_insert_key (cbdata->cur, ucl_object_fromint (processed),
				"users", 0, false);

		rspamd_upstream_ok (cbdata->selected);
	}
	else {
		if (c->errstr) {
			msg_err ("cannot get keys to gather stat: %s", c->errstr);
		}
		else {
			msg_err ("cannot get keys to gather stat: unknown error");
		}
		rspamd_upstream_fail (cbdata->selected);
		rspamd_redis_async_cbdata_cleanup (cbdata);
	}

	if (cbdata->inflight == 0) {
		rspamd_redis_async_cbdata_cleanup (cbdata);
	}
}
Beispiel #8
0
int
main (int argc, char **argv)
{
	ucl_object_t *obj, *cur, *ar, *ar1, *ref, *test_obj, *comments;
	ucl_object_iter_t it;
	const ucl_object_t *found, *it_obj, *test;
	struct ucl_emitter_functions *fn;
	FILE *out;
	unsigned char *emitted;
	const char *fname_out = NULL;
	struct ucl_parser *parser;
	int ret = 0;

	switch (argc) {
	case 2:
		fname_out = argv[1];
		break;
	}


	if (fname_out != NULL) {
		out = fopen (fname_out, "w");
		if (out == NULL) {
			exit (-errno);
		}
	}
	else {
		out = stdout;
	}

	obj = ucl_object_typed_new (UCL_OBJECT);

	/* Keys replacing */
	cur = ucl_object_fromstring_common ("value1", 0, UCL_STRING_TRIM);
	ucl_object_insert_key (obj, cur, "key0", 0, false);
	cur = ucl_object_fromdouble (0.1);
	assert (ucl_object_replace_key (obj, cur, "key0", 0, false));

	/* Create some strings */
	cur = ucl_object_fromstring_common ("  test string    ", 0, UCL_STRING_TRIM);
	ucl_object_insert_key (obj, cur, "key1", 0, false);
	cur = ucl_object_fromstring_common ("  test \nstring\n\r\n\b\t\f\\\"    ", 0,
			UCL_STRING_TRIM | UCL_STRING_ESCAPE);
	ucl_object_insert_key (obj, cur, "key2", 0, false);
	cur = ucl_object_fromstring_common ("  test string    \n", 0, 0);
	ucl_object_insert_key (obj, cur, "key3", 0, false);
	/* Array of numbers */
	ar = ucl_object_typed_new (UCL_ARRAY);
	cur = ucl_object_fromint (10);
	ucl_array_append (ar, cur);
	assert (ucl_array_index_of (ar, cur) == 0);
	cur = ucl_object_fromdouble (10.1);
	ucl_array_append (ar, cur);
	assert (ucl_array_index_of (ar, cur) == 1);
	cur = ucl_object_fromdouble (9.999);
	ucl_array_prepend (ar, cur);
	assert (ucl_array_index_of (ar, cur) == 0);

	ar1 = ucl_object_copy (ar);
	cur = ucl_object_fromstring ("abc");
	ucl_array_prepend (ar1, cur);
	cur = ucl_object_fromstring ("cde");
	ucl_array_prepend (ar1, cur);
	cur = ucl_object_fromstring ("аАаБаВ"); /* UTF8 */
	ucl_array_prepend (ar1, cur);
	cur = ucl_object_fromstring ("а•аБаВ"); /* UTF8 */
	ucl_array_prepend (ar1, cur);
/*
 * This is ususally broken or fragile as utf collate is far from perfect
	cur = ucl_object_fromstring ("б‘аБаВ");
	ucl_array_prepend (ar1, cur);
	cur = ucl_object_fromstring ("ааБаВ"); // hello to @bapt
	ucl_array_prepend (ar1, cur);
*/
	cur = ucl_object_fromstring ("№Ÿ˜Ž"); /* everybody likes emoji in the code */
	ucl_array_prepend (ar1, cur);

	ucl_object_array_sort (ar1, ucl_object_compare_qsort);

	/* Removing from an array */
	cur = ucl_object_fromdouble (1.0);
	ucl_array_append (ar, cur);
	cur = ucl_array_delete (ar, cur);
	assert (ucl_object_todouble (cur) == 1.0);
	ucl_object_unref (cur);
	cur = ucl_object_fromdouble (2.0);
	ucl_array_append (ar, cur);
	cur = ucl_array_pop_last (ar);
	assert (ucl_object_todouble (cur) == 2.0);
	ucl_object_unref (cur);
	cur = ucl_object_fromdouble (3.0);
	ucl_array_prepend (ar, cur);
	cur = ucl_array_pop_first (ar);
	assert (ucl_object_todouble (cur) == 3.0);
	ucl_object_unref (cur);

	ucl_object_insert_key (obj, ar, "key4", 0, false);
	cur = ucl_object_frombool (true);
	/* Ref object to test refcounts */
	ref = ucl_object_ref (cur);
	ucl_object_insert_key (obj, cur, "key4", 0, false);
	/* Empty strings */
	cur = ucl_object_fromstring_common ("      ", 0, UCL_STRING_TRIM);
	ucl_object_insert_key (obj, cur, "key5", 0, false);
	cur = ucl_object_fromstring_common ("", 0, UCL_STRING_ESCAPE);
	ucl_object_insert_key (obj, cur, "key6", 0, false);
	cur = ucl_object_fromstring_common ("   \n", 0, UCL_STRING_ESCAPE);
	ucl_object_insert_key (obj, cur, "key7", 0, false);
	/* Numbers and booleans */
	cur = ucl_object_fromstring_common ("1mb", 0, UCL_STRING_ESCAPE | UCL_STRING_PARSE);
	ucl_object_insert_key (obj, cur, "key8", 0, false);
	cur = ucl_object_fromstring_common ("3.14", 0, UCL_STRING_PARSE);
	ucl_object_insert_key (obj, cur, "key9", 0, false);
	cur = ucl_object_fromstring_common ("true", 0, UCL_STRING_PARSE);
	ucl_object_insert_key (obj, cur, "key10", 0, false);
	cur = ucl_object_fromstring_common ("  off  ", 0, UCL_STRING_PARSE | UCL_STRING_TRIM);
	ucl_object_insert_key (obj, cur, "key11", 0, false);
	cur = ucl_object_fromstring_common ("*****@*****.**", 0, UCL_STRING_PARSE_INT);
	ucl_object_insert_key (obj, cur, "key12", 0, false);
	cur = ucl_object_fromstring_common ("#test", 0, UCL_STRING_PARSE_INT);
	ucl_object_insert_key (obj, cur, "key13", 0, false);
	cur = ucl_object_frombool (true);
	ucl_object_insert_key (obj, cur, "k=3", 0, false);
	ucl_object_insert_key (obj, ar1, "key14", 0, false);
	cur = ucl_object_new_userdata (ud_dtor, ud_emit, NULL);
	ucl_object_insert_key (obj, cur, "key15", 0, false);

	/* More tests for keys */
	cur = ucl_object_fromlstring ("test", 3);
	ucl_object_insert_key (obj, cur, "key16", 0, false);
	test = ucl_object_lookup_any (obj, "key100", "key200", "key300", "key16", NULL);
	assert (test == cur);
	test = ucl_object_lookup_len (obj, "key160", 5);
	assert (test == cur);
	cur = ucl_object_pop_key (obj, "key16");
	assert (test == cur);
	test = ucl_object_pop_key (obj, "key16");
	assert (test == NULL);
	test = ucl_object_lookup_len (obj, "key160", 5);
	assert (test == NULL);
	/* Objects merging tests */
	test_obj = ucl_object_new_full (UCL_OBJECT, 2);
	ucl_object_insert_key (test_obj, cur, "key16", 0, true);
	ucl_object_merge (obj, test_obj, true);
	ucl_object_unref (test_obj);
	/* Array merging test */
	test_obj = ucl_object_new_full (UCL_ARRAY, 3);
	ucl_array_append (test_obj, ucl_object_fromstring ("test"));
	ucl_array_merge (test_obj, ar1, false);
	ucl_object_insert_key (obj, test_obj, "key17", 0, true);
	/* Object deletion */
	cur = ucl_object_fromstring ("test");
	ucl_object_insert_key (obj, cur, "key18", 0, true);
	assert (ucl_object_delete_key (obj, "key18"));
	assert (!ucl_object_delete_key (obj, "key18"));
	cur = ucl_object_fromlstring ("test", 4);
	ucl_object_insert_key (obj, cur, "key18\0\0", 7, true);
	assert (ucl_object_lookup_len (obj, "key18\0\0", 7) == cur);
	assert (ucl_object_lookup (obj, "key18") == NULL);
	assert (ucl_object_lookup_len (obj, "key18\0\1", 7) == NULL);
	assert (ucl_object_delete_keyl (obj, "key18\0\0", 7));

	/* Comments */

	comments = ucl_object_typed_new (UCL_OBJECT);
	found = ucl_object_lookup (obj, "key17");
	test = ucl_object_lookup (obj, "key16");
	ucl_comments_add (comments, found, "# test comment");
	assert (ucl_comments_find (comments, found) != NULL);
	assert (ucl_comments_find (comments, test) == NULL);
	ucl_comments_move (comments, found, test);
	assert (ucl_comments_find (comments, found) == NULL);
	assert (ucl_comments_find (comments, test) != NULL);

	/* Array replace */
	ar1 = ucl_object_typed_new (UCL_ARRAY);
	cur = ucl_object_fromstring ("test");
	cur = ucl_elt_append (cur, ucl_object_fromstring ("test1"));
	ucl_array_append (ar1, cur);
	test = ucl_array_replace_index (ar1, ucl_object_fromstring ("test2"), 0);
	assert (test == cur);

	/* Try to find using path */
	/* Should exist */
	found = ucl_object_lookup_path (obj, "key4.1");
	assert (found != NULL && ucl_object_toint (found) == 10);
	/* . should be ignored */
	found = ucl_object_lookup_path (obj, ".key4.1");
	assert (found != NULL && ucl_object_toint (found) == 10);
	/* moar dots... */
	found = ucl_object_lookup_path (obj, ".key4........1...");
	assert (found != NULL && ucl_object_toint (found) == 10);
	/* No such index */
	found = ucl_object_lookup_path (obj, ".key4.3");
	assert (found == NULL);
	/* No such key */
	found = ucl_object_lookup_path (obj, "key9..key1");
	assert (found == NULL);

	/* Test iteration */
	it = ucl_object_iterate_new (obj);
	it_obj = ucl_object_iterate_safe (it, true);
	/* key0 = 0.1 */
	assert (ucl_object_type (it_obj) == UCL_FLOAT);
	it_obj = ucl_object_iterate_safe (it, true);
	/* key1 = "" */
	assert (ucl_object_type (it_obj) == UCL_STRING);
	it_obj = ucl_object_iterate_safe (it, true);
	/* key2 = "" */
	assert (ucl_object_type (it_obj) == UCL_STRING);
	it_obj = ucl_object_iterate_safe (it, true);
	/* key3 = "" */
	assert (ucl_object_type (it_obj) == UCL_STRING);
	it_obj = ucl_object_iterate_safe (it, true);
	/* key4 = ([float, int, float], boolean) */
	ucl_object_iterate_reset (it, it_obj);
	it_obj = ucl_object_iterate_safe (it, true);
	assert (ucl_object_type (it_obj) == UCL_FLOAT);
	it_obj = ucl_object_iterate_safe (it, true);
	assert (ucl_object_type (it_obj) == UCL_INT);
	it_obj = ucl_object_iterate_safe (it, true);
	assert (ucl_object_type (it_obj) == UCL_FLOAT);
	it_obj = ucl_object_iterate_safe (it, true);
	assert (ucl_object_type (it_obj) == UCL_BOOLEAN);
	ucl_object_iterate_free (it);

	fn = ucl_object_emit_memory_funcs (&emitted);
	assert (ucl_object_emit_full (obj, UCL_EMIT_CONFIG, fn, comments));
	fprintf (out, "%s\n", emitted);
	ucl_object_emit_funcs_free (fn);
	ucl_object_unref (obj);
	ucl_object_unref (comments);

	parser = ucl_parser_new (UCL_PARSER_NO_IMPLICIT_ARRAYS);

	if (ucl_parser_add_chunk_full (parser, emitted, strlen (emitted),
			3, UCL_DUPLICATE_ERROR, UCL_PARSE_UCL)) {
		/* Should fail due to duplicate */
		assert (0);
	}
	else {
		assert (ucl_parser_get_error (parser) != NULL);
		ucl_parser_clear_error (parser);
		ucl_parser_free (parser);
		parser = ucl_parser_new (0);
		ucl_parser_add_chunk_full (parser, emitted, strlen (emitted),
					3, UCL_DUPLICATE_MERGE, UCL_PARSE_UCL);
	}

	assert (ucl_parser_get_column (parser) == 0);
	assert (ucl_parser_get_linenum (parser) != 0);
	ucl_parser_clear_error (parser);
	assert (ucl_parser_get_error_code (parser) == 0);
	obj = ucl_parser_get_object (parser);
	ucl_parser_free (parser);
	ucl_object_free (obj);

	if (emitted != NULL) {
		free (emitted);
	}
	fclose (out);

	/* Ref should still be accessible */
	ref->value.iv = 100500;
	ucl_object_unref (ref);

	return ret;
}
Beispiel #9
0
static void
rspamadm_statconvert (gint argc, gchar **argv, const struct rspamadm_command *cmd)
{
	GOptionContext *context;
	GError *error = NULL;
	ucl_object_t *obj;

	context = g_option_context_new (
			"statconvert - converts statistics from sqlite3 to redis");
	g_option_context_set_summary (context,
			"Summary:\n  Rspamd administration utility version "
					RVERSION
					"\n  Release id: "
					RID);
	g_option_context_add_main_entries (context, entries, NULL);
	g_option_context_set_ignore_unknown_options (context, TRUE);

	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		rspamd_fprintf (stderr, "option parsing failed: %s\n", error->message);
		g_error_free (error);
		exit (1);
	}

	if (config_file) {
		/* Load config file, assuming that it has all information required */
		struct ucl_parser *parser;

		parser = ucl_parser_new (0);
		rspamd_ucl_add_conf_variables (parser, ucl_vars);

		if (!ucl_parser_add_file (parser, config_file)) {
			msg_err ("ucl parser error: %s", ucl_parser_get_error (parser));
			ucl_parser_free (parser);

			exit (EXIT_FAILURE);
		}

		obj = ucl_parser_get_object (parser);
		ucl_parser_free (parser);
	}
	else {
		/* We need to get all information from the command line */
		ucl_object_t *classifier, *statfile_ham, *statfile_spam, *tmp, *redis;

		/* Check arguments sanity */
		if (spam_db == NULL) {
			msg_err ("No spam-db specified");
			exit (EXIT_FAILURE);
		}
		if (ham_db == NULL) {
			msg_err ("No ham-db specified");
			exit (EXIT_FAILURE);
		}
		if (redis_host == NULL) {
			msg_err ("No redis-host specified");
			exit (EXIT_FAILURE);
		}
		if (symbol_ham == NULL) {
			msg_err ("No symbol-ham specified");
			exit (EXIT_FAILURE);
		}
		if (symbol_spam == NULL) {
			msg_err ("No symbol-spam specified");
			exit (EXIT_FAILURE);
		}

		obj = ucl_object_typed_new (UCL_OBJECT);

		classifier = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (obj, classifier, "classifier", 0, false);
		/* Now we need to create "bayes" key in it */
		tmp = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (classifier, tmp, "bayes", 0, false);
		classifier = tmp;
		ucl_object_insert_key (classifier, ucl_object_fromstring ("sqlite3"),
				"backend", 0, false);

		if (cache_db != NULL) {
			ucl_object_t *cache;

			cache = ucl_object_typed_new (UCL_OBJECT);
			ucl_object_insert_key (cache, ucl_object_fromstring ("sqlite3"),
					"type", 0, false);
			ucl_object_insert_key (cache, ucl_object_fromstring (cache_db),
					"file", 0, false);

			ucl_object_insert_key (classifier, cache, "cache", 0, false);
		}

		statfile_ham = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (statfile_ham, ucl_object_fromstring (symbol_ham),
				"symbol", 0, false);
		ucl_object_insert_key (statfile_ham, ucl_object_frombool (false),
				"spam", 0, false);
		ucl_object_insert_key (statfile_ham, ucl_object_fromstring (ham_db),
				"db", 0, false);

		statfile_spam = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (statfile_spam, ucl_object_fromstring (symbol_spam),
				"symbol", 0, false);
		ucl_object_insert_key (statfile_spam, ucl_object_frombool (true),
				"spam", 0, false);
		ucl_object_insert_key (statfile_spam, ucl_object_fromstring (spam_db),
				"db", 0, false);

		DL_APPEND (statfile_ham, statfile_spam);
		ucl_object_insert_key (classifier, statfile_ham,
				"statfile", 0, false);

		/* Deal with redis */

		redis = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (obj, redis, "redis", 0, false);

		ucl_object_insert_key (redis, ucl_object_fromstring (redis_host),
				"servers", 0, false);

		if (redis_db) {
			ucl_object_insert_key (redis, ucl_object_fromstring (redis_db),
					"dbname", 0, false);
		}

		if (redis_password) {
			ucl_object_insert_key (redis, ucl_object_fromstring (redis_password),
					"password", 0, false);
		}
	}

	ucl_object_insert_key (obj, ucl_object_frombool (reset_previous),
			"reset_previous", 0, false);

	if (expire != 0) {
		ucl_object_insert_key (obj, ucl_object_fromdouble (expire),
				"expire", 0, false);
	}

	rspamadm_execute_lua_ucl_subr (argc,
			argv,
			obj,
			"stat_convert",
			TRUE);

	ucl_object_unref (obj);
}
Beispiel #10
0
static ucl_object_t *
_iterate_python (PyObject *obj)
{
	if (obj == Py_None) {
		return ucl_object_new();
	}
	else if (PyBool_Check (obj)) {
		return ucl_object_frombool (obj == Py_True);
	}
#if PY_MAJOR_VERSION < 3
	else if (PyInt_Check (obj)) {
		return ucl_object_fromint (PyInt_AsLong (obj));
	}
#endif
	else if (PyLong_Check (obj)) {
		return ucl_object_fromint (PyLong_AsLong (obj));
	}
	else if (PyFloat_Check (obj)) {
		return ucl_object_fromdouble (PyFloat_AsDouble (obj));
	}
	else if (PyUnicode_Check (obj)) {
		ucl_object_t *ucl_str;
		PyObject *str = PyUnicode_AsASCIIString(obj);
		ucl_str = ucl_object_fromstring (PyBytes_AsString (str));
		Py_DECREF(str);
		return ucl_str;
	}
#if PY_MAJOR_VERSION < 3
	else if (PyString_Check (obj)) {
		return ucl_object_fromstring (PyString_AsString (obj));
	}
#endif
	else if (PyDict_Check(obj)) {
		PyObject *key, *value;
		Py_ssize_t pos = 0;
		ucl_object_t *top, *elm;
		char *keystr = NULL;

		top = ucl_object_typed_new (UCL_OBJECT);

		while (PyDict_Next(obj, &pos, &key, &value)) {
			elm = _iterate_python(value);
			
			if (PyUnicode_Check(key)) {
				PyObject *keyascii = PyUnicode_AsASCIIString(key);
				keystr = PyBytes_AsString(keyascii);
				Py_DECREF(keyascii);
			}
#if PY_MAJOR_VERSION < 3
			else if (PyString_Check(key)) {
				keystr = PyString_AsString(key);
			}
#endif
			else {
				PyErr_SetString(PyExc_TypeError, "Unknown key type");
				return NULL;
			}

			ucl_object_insert_key (top, elm, keystr, 0, true);
		}

		return top;
	}
	else if (PySequence_Check(obj)) {
		PyObject *value;
		Py_ssize_t len, pos;
		ucl_object_t *top, *elm;

		len  = PySequence_Length(obj);
		top = ucl_object_typed_new (UCL_ARRAY);

		for (pos = 0; pos < len; pos++) {
			value = PySequence_GetItem(obj, pos);
			elm = _iterate_python(value);
			ucl_array_append(top, elm);
		}

		return top;
	}
	else {
		PyErr_SetString(PyExc_TypeError, "Unhandled object type");
		return NULL;
	}

	return NULL;
}