예제 #1
0
파일: lua_ucl.c 프로젝트: avldya/libucl
/**
 * Push an array to lua as table indexed by integers
 * @param L
 * @param obj
 * @return
 */
static int
ucl_object_lua_push_array (lua_State *L, const ucl_object_t *obj)
{
	const ucl_object_t *cur;
	ucl_object_iter_t it;
	int i = 1, nelt = 0;

	if (obj->type == UCL_ARRAY) {
		nelt = obj->len;
		it = ucl_object_iterate_new (obj);
		lua_createtable (L, nelt, 0);

		while ((cur = ucl_object_iterate_safe (it, true))) {
			ucl_object_push_lua (L, cur, false);
			lua_rawseti (L, -2, i);
			i ++;
		}
	}
	else {
		/* Optimize allocation by preallocation of table */
		LL_FOREACH (obj, cur) {
			nelt ++;
		}

		lua_createtable (L, nelt, 0);

		LL_FOREACH (obj, cur) {
			ucl_object_push_lua (L, cur, false);
			lua_rawseti (L, -2, i);
			i ++;
		}
	}
예제 #2
0
static gint
lua_util_process_message (lua_State *L)
{
	struct rspamd_config *cfg = lua_check_config (L, 1);
	const gchar *message;
	gsize mlen;
	struct rspamd_task *task;
	struct event_base *base;
	ucl_object_t *res = NULL;

	message = luaL_checklstring (L, 2, &mlen);

	if (cfg != NULL && message != NULL) {
		base = event_init ();
		rspamd_init_filters (cfg, FALSE);
		task = rspamd_task_new (NULL);
		task->cfg = cfg;
		task->ev_base = base;
		task->msg.start = rspamd_mempool_alloc (task->task_pool, mlen + 1);
		rspamd_strlcpy ((gpointer)task->msg.start, message, mlen + 1);
		task->msg.len = mlen;
		task->fin_callback = lua_util_task_fin;
		task->fin_arg = &res;
		task->resolver = dns_resolver_init (NULL, base, cfg);
		task->s = rspamd_session_create (task->task_pool, rspamd_task_fin,
					rspamd_task_restore, rspamd_task_free_hard, task);

		if (!rspamd_task_load_message (task, NULL, message, mlen)) {
			lua_pushnil (L);
		}
		else {
			if (rspamd_task_process (task, RSPAMD_TASK_PROCESS_ALL)) {
				event_base_loop (base, 0);

				if (res != NULL) {
					ucl_object_push_lua (L, res, true);

					ucl_object_unref (res);
				}
				else {
					ucl_object_push_lua (L, rspamd_protocol_write_ucl (task, NULL),
							true);
					rdns_resolver_release (task->resolver->r);
					rspamd_task_free_hard (task);
				}
			}
			else {
				lua_pushnil (L);
			}
		}

		event_base_free (base);
	}
	else {
		lua_pushnil (L);
	}

	return 1;
}
예제 #3
0
파일: lua_ucl.c 프로젝트: avldya/libucl
/**
 * Push a single element of an object to lua
 * @param L
 * @param key
 * @param obj
 */
static void
ucl_object_lua_push_element (lua_State *L, const char *key,
		const ucl_object_t *obj)
{
	lua_pushstring (L, key);
	ucl_object_push_lua (L, obj, true);
	lua_settable (L, -3);
}
예제 #4
0
static gint
lua_config_get_all_opt (lua_State * L)
{
	struct rspamd_config *cfg = lua_check_config (L);
	const gchar *mname;
	const ucl_object_t *obj;

	if (cfg) {
		mname = luaL_checkstring (L, 2);

		if (mname) {
			obj = ucl_obj_get_key (cfg->rcl_obj, mname);
			if (obj != NULL) {
				return ucl_object_push_lua (L, obj, TRUE);
			}
		}
	}
	lua_pushnil (L);
	return 1;
}
예제 #5
0
static gint
lua_config_get_module_opt (lua_State * L)
{
	struct rspamd_config *cfg = lua_check_config (L, 1);
	const gchar *mname, *optname;
	const ucl_object_t *obj;

	if (cfg) {
		mname = luaL_checkstring (L, 2);
		optname = luaL_checkstring (L, 3);

		if (mname && optname) {
			obj = rspamd_config_get_module_opt (cfg, mname, optname);
			if (obj) {
				return ucl_object_push_lua (L, obj, TRUE);
			}
		}
	}
	lua_pushnil (L);
	return 1;
}
예제 #6
0
static gint
lua_classifier_get_param (lua_State *L)
{
	struct rspamd_classifier_config *ccf = lua_check_classifier (L);
	const gchar *param;
	const ucl_object_t *value;

	param = luaL_checkstring (L, 2);

	if (ccf != NULL && param != NULL) {
		value = ucl_object_lookup (ccf->opts, param);

		if (value != NULL) {
			ucl_object_push_lua (L, value, true);
			return 1;
		}
	}

	lua_pushnil (L);

	return 1;
}
예제 #7
0
static gint
lua_config_get_all_opt (lua_State * L)
{
	struct rspamd_config *cfg = lua_check_config (L, 1);
	const gchar *mname;
	const ucl_object_t *obj, *cur, *cur_elt;
	ucl_object_iter_t it = NULL;
	gint i;

	if (cfg) {
		mname = luaL_checkstring (L, 2);

		if (mname) {
			obj = ucl_obj_get_key (cfg->rcl_obj, mname);
			/* Flatten object */
			if (obj != NULL && (ucl_object_type (obj) == UCL_OBJECT ||
					ucl_object_type (obj) == UCL_ARRAY)) {

				lua_newtable (L);
				it = ucl_object_iterate_new (obj);

				LL_FOREACH (obj, cur) {
					it = ucl_object_iterate_reset (it, cur);

					while ((cur_elt = ucl_object_iterate_safe (it, true))) {
						lua_pushstring (L, ucl_object_key (cur_elt));
						ucl_object_push_lua (L, cur_elt, true);
						lua_settable (L, -3);
					}
				}

				ucl_object_iterate_free (it);

				return 1;
			}
			else if (obj != NULL) {
예제 #8
0
static gint
lua_config_get_key (lua_State *L)
{
	struct rspamd_config *cfg = lua_check_config (L);
	const gchar *name;
	size_t namelen;
	const ucl_object_t *val;

	name = luaL_checklstring(L, 2, &namelen);
	if (name && cfg) {
		val = ucl_object_find_keyl(cfg->rcl_obj, name, namelen);
		if (val != NULL) {
			ucl_object_push_lua (L, val, val->type != UCL_ARRAY);
		}
		else {
			lua_pushnil (L);
		}
	}
	else {
		lua_pushnil (L);
	}

	return 1;
}
예제 #9
0
				LL_FOREACH (obj, cur) {
					lua_pushnumber (L, i++);
					ucl_object_push_lua (L, cur, true);
					lua_settable (L, -3);
				}
예제 #10
0
gboolean
rspamadm_execute_lua_ucl_subr (gpointer pL, gint argc, gchar **argv,
		const ucl_object_t *res, const gchar *script)
{
	lua_State *L = pL;
	gint err_idx, cb_idx, i, ret;
	GString *tb;

	g_assert (script != NULL);
	g_assert (res != NULL);
	g_assert (L != NULL);

	if (luaL_dostring (L, script) != 0) {
		msg_err ("cannot execute lua script: %s",
				lua_tostring (L, -1));
		return FALSE;
	}
	else {
		if (lua_type (L, -1) == LUA_TFUNCTION) {
			cb_idx = luaL_ref (L, LUA_REGISTRYINDEX);
		}
		else {
			msg_err ("lua script must return "
					"function and not %s",
					lua_typename (L,
							lua_type (L, -1)));
			return FALSE;
		}
	}

	lua_pushcfunction (L, &rspamd_lua_traceback);
	err_idx = lua_gettop (L);

	/* Push function */
	lua_rawgeti (L, LUA_REGISTRYINDEX, cb_idx);

	/* Push argv */
	lua_newtable (L);

	for (i = 0; i < argc; i ++) {
		lua_pushstring (L, argv[i]);
		lua_rawseti (L, -2, i + 1);
	}

	/* Push results */
	ucl_object_push_lua (L, res, TRUE);

	if ((ret = lua_pcall (L, 2, 0, err_idx)) != 0) {
		tb = lua_touserdata (L, -1);
		msg_err ("call to adm lua script failed (%d): %v", ret, tb);

		if (tb) {
			g_string_free (tb, TRUE);
		}

		lua_pop (L, 2);

		return FALSE;
	}

	/* error function */
	lua_pop (L, 1);

	luaL_unref (L, LUA_REGISTRYINDEX, cb_idx);

	return TRUE;
}
예제 #11
0
static gint
lua_worker_get_stat (lua_State *L)
{
	struct rspamd_worker *w = lua_check_worker (L, 1);

	if (w) {
		rspamd_mempool_stat_t mem_st;
		struct rspamd_stat *stat, stat_copy;
		ucl_object_t *top, *sub;
		gint i;
		guint64 spam = 0, ham = 0;

		memset (&mem_st, 0, sizeof (mem_st));
		rspamd_mempool_stat (&mem_st);
		memcpy (&stat_copy, w->srv->stat, sizeof (stat_copy));
		stat = &stat_copy;
		top = ucl_object_typed_new (UCL_OBJECT);
		ucl_object_insert_key (top, ucl_object_fromint (
				stat->messages_scanned), "scanned", 0, false);
		ucl_object_insert_key (top, ucl_object_fromint (
				stat->messages_learned), "learned", 0, false);
		if (stat->messages_scanned > 0) {
			sub = ucl_object_typed_new (UCL_OBJECT);
			for (i = METRIC_ACTION_REJECT; i <= METRIC_ACTION_NOACTION; i++) {
				ucl_object_insert_key (sub,
						ucl_object_fromint (stat->actions_stat[i]),
						rspamd_action_to_str (i), 0, false);
				if (i < METRIC_ACTION_GREYLIST) {
					spam += stat->actions_stat[i];
				}
				else {
					ham += stat->actions_stat[i];
				}
			}
			ucl_object_insert_key (top, sub, "actions", 0, false);
		}
		else {
			sub = ucl_object_typed_new (UCL_OBJECT);
			for (i = METRIC_ACTION_REJECT; i <= METRIC_ACTION_NOACTION; i++) {
				ucl_object_insert_key (sub,
						0,
						rspamd_action_to_str (i), 0, false);
			}
			ucl_object_insert_key (top, sub, "actions", 0, false);
		}
		ucl_object_insert_key (top, ucl_object_fromint (
				spam), "spam_count", 0, false);
		ucl_object_insert_key (top, ucl_object_fromint (
				ham),  "ham_count",      0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (stat->connections_count), "connections", 0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (stat->control_connections_count),
				"control_connections", 0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (mem_st.pools_allocated), "pools_allocated", 0,
				false);
		ucl_object_insert_key (top,
				ucl_object_fromint (mem_st.pools_freed), "pools_freed", 0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (mem_st.bytes_allocated), "bytes_allocated", 0,
				false);
		ucl_object_insert_key (top,
				ucl_object_fromint (
						mem_st.chunks_allocated), "chunks_allocated", 0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (mem_st.shared_chunks_allocated),
				"shared_chunks_allocated", 0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (mem_st.chunks_freed), "chunks_freed", 0, false);
		ucl_object_insert_key (top,
				ucl_object_fromint (
						mem_st.oversized_chunks), "chunks_oversized", 0, false);

		ucl_object_push_lua (L, top, true);
		ucl_object_unref (top);
	}
	else {
		return luaL_error (L, "invalid arguments");
	}

	return 1;
}