*/
LUA_FUNCTION_DEF (config, disable_symbol);
+/***
+ * @method rspamd_config:get_symbol_parent(symbol)
+ * Returns a parent symbol for specific symbol (or symbol itself if top level)
+ * @param {string} symbol symbol's name
+ */
+LUA_FUNCTION_DEF (config, get_symbol_parent);
+
/***
* @method rspamd_config:__newindex(name, callback)
* This metamethod is called if new indicies are added to the `rspamd_config` object.
LUA_INTERFACE_DEF (config, get_symbol_callback),
LUA_INTERFACE_DEF (config, set_symbol_callback),
LUA_INTERFACE_DEF (config, get_symbol_stat),
+ LUA_INTERFACE_DEF (config, get_symbol_parent),
LUA_INTERFACE_DEF (config, register_finish_script),
LUA_INTERFACE_DEF (config, register_monitored),
LUA_INTERFACE_DEF (config, add_doc),
}
static gint
-rspamd_register_symbol_fromlua (lua_State *L,
- struct rspamd_config *cfg,
- const gchar *name,
- gint ref,
- gdouble weight,
- gint priority,
- enum rspamd_symbol_type type,
- gint parent,
- gboolean optional,
- gboolean no_squeeze)
+rspamd_lua_squeeze_rule (lua_State *L,
+ struct rspamd_config *cfg,
+ const gchar *name,
+ gint cbref,
+ enum rspamd_symbol_type type,
+ gint parent)
{
- struct lua_callback_data *cd;
gint ret = -1, err_idx;
- if (priority == 0 && weight < 0) {
- priority = 1;
- }
+ lua_pushcfunction (L, &rspamd_lua_traceback);
+ err_idx = lua_gettop (L);
- if ((ret = rspamd_symcache_find_symbol (cfg->cache, name)) != -1) {
- if (optional) {
- msg_debug_config ("duplicate symbol: %s, skip registering", name);
+ if (type & SYMBOL_TYPE_VIRTUAL) {
+ if (rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_virtual")) {
+ lua_pushnumber (L, parent);
+ if (name) {
+ lua_pushstring (L, name);
+ }
+ else {
+ lua_pushnil (L);
+ }
- return ret;
+ /* Now call for squeeze function */
+ if (lua_pcall (L, 2, 1, err_idx) != 0) {
+ GString *tb = lua_touserdata (L, -1);
+ msg_err_config ("call to squeeze_virtual failed: %v", tb);
+
+ if (tb) {
+ g_string_free (tb, TRUE);
+ }
+ }
+
+ ret = lua_tonumber (L, -1);
}
else {
- msg_err_config ("duplicate symbol: %s, skip registering", name);
-
- return -1;
+ msg_err_config ("lua_squeeze is absent or bad (missing squeeze_virtual),"
+ " your Rspamd installation"
+ " is likely corrupted!");
}
}
-
- if (ref != -1) {
- if (type & SYMBOL_TYPE_USE_CORO) {
- /* Coroutines are incompatible with squeezing */
- no_squeeze = TRUE;
- }
- /*
- * We call for routine called lua_squeeze_rules.squeeze_rule if it exists
- */
- lua_pushcfunction (L, &rspamd_lua_traceback);
- err_idx = lua_gettop (L);
-
- if (!no_squeeze && (type & (SYMBOL_TYPE_CALLBACK|SYMBOL_TYPE_NORMAL)) &&
- rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_rule")) {
+ else {
+ if (rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_rule")) {
if (name) {
lua_pushstring (L, name);
}
}
/* Push function reference */
- lua_rawgeti (L, LUA_REGISTRYINDEX, ref);
+ lua_rawgeti (L, LUA_REGISTRYINDEX, cbref);
/* Flags */
lua_createtable (L, 0, 0);
}
ret = lua_tonumber (L, -1);
+ }
+ else {
+ msg_err_config ("lua_squeeze is absent or bad (missing squeeze_rule),"
+ " your Rspamd installation"
+ " is likely corrupted!");
+ }
+ }
- if (ret == -1) {
- /* Do direct registration */
- cd = rspamd_mempool_alloc0 (cfg->cfg_pool,
- sizeof (struct lua_callback_data));
- cd->magic = rspamd_lua_callback_magic;
- cd->cb_is_ref = TRUE;
- cd->callback.ref = ref;
- cd->L = L;
+ /* Cleanup lua stack */
+ lua_settop (L, err_idx - 1);
- if (name) {
- cd->symbol = rspamd_mempool_strdup (cfg->cfg_pool, name);
- }
+ return ret;
+}
- if (type & SYMBOL_TYPE_USE_CORO) {
- ret = rspamd_symcache_add_symbol (cfg->cache,
- name,
- priority,
- lua_metric_symbol_callback_coro,
- cd,
- type,
- parent);
- }
- else {
- ret = rspamd_symcache_add_symbol (cfg->cache,
- name,
- priority,
- lua_metric_symbol_callback,
- cd,
- type,
- parent);
- }
+static gint
+rspamd_register_symbol_fromlua (lua_State *L,
+ struct rspamd_config *cfg,
+ const gchar *name,
+ gint ref,
+ gdouble weight,
+ gint priority,
+ enum rspamd_symbol_type type,
+ gint parent,
+ gboolean optional,
+ gboolean no_squeeze)
+{
+ struct lua_callback_data *cd;
+ gint ret = -1;
- rspamd_mempool_add_destructor (cfg->cfg_pool,
- (rspamd_mempool_destruct_t) lua_destroy_cfg_symbol,
- cd);
- }
+ if (priority == 0 && weight < 0) {
+ priority = 1;
+ }
+
+ if ((ret = rspamd_symcache_find_symbol (cfg->cache, name)) != -1) {
+ if (optional) {
+ msg_debug_config ("duplicate symbol: %s, skip registering", name);
+
+ return ret;
}
else {
+ msg_err_config ("duplicate symbol: %s, skip registering", name);
+
+ return -1;
+ }
+ }
+
+ if (ref != -1) {
+ if (type & SYMBOL_TYPE_USE_CORO) {
+ /* Coroutines are incompatible with squeezing */
+ no_squeeze = TRUE;
+ }
+ /*
+ * We call for routine called lua_squeeze_rules.squeeze_rule if it exists
+ */
+ if (no_squeeze || (ret = rspamd_lua_squeeze_rule (L, cfg, name, ref,
+ type, parent)) == -1) {
cd = rspamd_mempool_alloc0 (cfg->cfg_pool,
sizeof (struct lua_callback_data));
cd->magic = rspamd_lua_callback_magic;
(rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
cd);
}
-
- /* Cleanup lua stack */
- lua_settop (L, err_idx - 1);
}
else {
+ if (!no_squeeze) {
+ rspamd_lua_squeeze_rule (L, cfg, name, ref,
+ type, parent);
+ }
+ /* Not a squeezed symbol */
ret = rspamd_symcache_add_symbol (cfg->cache,
name,
priority,
ret = lua_toboolean (L, -1);
}
}
+ else {
+ msg_err_config ("cannot get lua_squeeze_rules.squeeze_dependency function");
+ }
lua_settop (L, err_idx - 1);
return 1;
}
+static gint
+lua_config_get_symbol_parent (lua_State *L)
+{
+ LUA_TRACE_POINT;
+ struct rspamd_config *cfg = lua_check_config (L, 1);
+ const gchar *sym = luaL_checkstring (L, 2), *parent;
+
+ if (cfg != NULL && sym != NULL) {
+ parent = rspamd_symcache_get_parent (cfg->cache, sym);
+
+ if (parent) {
+ lua_pushstring (L, parent);
+ }
+ else {
+ lua_pushnil (L);
+ }
+ }
+ else {
+ return luaL_error (L, "invalid arguments");
+ }
+
+ return 1;
+}
static gint
lua_config_register_finish_script (lua_State *L)