aboutsummaryrefslogtreecommitdiffstats
path: root/src/rspamadm
diff options
context:
space:
mode:
Diffstat (limited to 'src/rspamadm')
-rw-r--r--src/rspamadm/configdump.c115
-rw-r--r--src/rspamadm/control.c8
-rw-r--r--src/rspamadm/lua_repl.c33
-rw-r--r--src/rspamadm/signtool.c4
4 files changed, 124 insertions, 36 deletions
diff --git a/src/rspamadm/configdump.c b/src/rspamadm/configdump.c
index 456875cf2..d090b66f0 100644
--- a/src/rspamadm/configdump.c
+++ b/src/rspamadm/configdump.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,8 @@ static gboolean symbol_groups_only = FALSE;
static gboolean symbol_full_details = FALSE;
static gboolean skip_template = FALSE;
static char *config = NULL;
+static gboolean local_conf_only = FALSE;
+static gboolean override_conf_only = FALSE;
extern struct rspamd_main *rspamd_main;
/* Defined in modules.c */
extern module_t *modules[];
@@ -66,6 +68,8 @@ static GOptionEntry entries[] = {
"Show full symbol details only", NULL},
{"skip-template", 'T', 0, G_OPTION_ARG_NONE, &skip_template,
"Do not apply Jinja templates", NULL},
+ {"local", 0, 0, G_OPTION_ARG_NONE, &local_conf_only, "Show only local and override configuration", NULL},
+ {"override", 0, 0, G_OPTION_ARG_NONE, &override_conf_only, "Show only override configuration", NULL},
{NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}};
static const char *
@@ -82,6 +86,8 @@ rspamadm_configdump_help(gboolean full_help, const struct rspamadm_command *cmd)
"-c: config file to test\n"
"-m: show state of modules only\n"
"-h: show help for dumped options\n"
+ "--local: show only local (and override) configuration\n"
+ "--override: show only override configuration\n"
"--help: shows available options and commands";
}
else {
@@ -96,6 +102,84 @@ config_logger(rspamd_mempool_t *pool, gpointer ud)
{
}
+static ucl_object_t *
+filter_non_default(const ucl_object_t *obj, bool override_only)
+{
+ ucl_object_t *result = NULL;
+ ucl_object_iter_t it = NULL;
+ const ucl_object_t *cur;
+
+ if (obj == NULL) {
+ return NULL;
+ }
+
+ int min_prio = override_only ? 1 : 0;
+
+ if (ucl_object_get_priority(obj) > min_prio) {
+
+ switch (ucl_object_type(obj)) {
+ case UCL_OBJECT:
+ result = ucl_object_typed_new(ucl_object_type(obj));
+
+ while ((cur = ucl_object_iterate(obj, &it, true))) {
+ ucl_object_t *filtered = filter_non_default(cur, override_conf_only);
+ if (filtered) {
+ ucl_object_insert_key(result, filtered, ucl_object_key(cur), cur->keylen, true);
+ }
+ }
+ break;
+ case UCL_ARRAY:
+ result = ucl_object_typed_new(ucl_object_type(obj));
+
+ while ((cur = ucl_object_iterate(obj, &it, true))) {
+ ucl_object_t *filtered = filter_non_default(cur, override_conf_only);
+ if (filtered) {
+ ucl_array_append(result, filtered);
+ }
+ }
+ default:
+ result = ucl_object_ref(obj);
+ break;
+ }
+
+ return result;
+ }
+
+ if (ucl_object_type(obj) == UCL_OBJECT || ucl_object_type(obj) == UCL_ARRAY) {
+ bool has_non_default = false;
+
+ result = ucl_object_typed_new(ucl_object_type(obj));
+ while ((cur = ucl_object_iterate(obj, &it, true))) {
+ ucl_object_t *filtered = filter_non_default(cur, override_only);
+ if (filtered) {
+ has_non_default = true;
+
+ if (ucl_object_type(obj) == UCL_OBJECT) {
+ ucl_object_insert_key(result, filtered,
+ ucl_object_key(cur), cur->keylen, true);
+ }
+ else if (ucl_object_type(obj) == UCL_ARRAY) {
+ ucl_array_append(result, filtered);
+ }
+ else {
+ g_assert_not_reached();
+ }
+ }
+ }
+
+ /* Avoid empty objects */
+ if (!has_non_default) {
+ ucl_object_unref(result);
+ result = NULL;
+ }
+
+ return result;
+ }
+
+
+ return NULL;
+}
+
static void
rspamadm_add_doc_elt(const ucl_object_t *obj, const ucl_object_t *doc_obj,
ucl_object_t *comment_obj)
@@ -524,7 +608,20 @@ rspamadm_configdump(int argc, char **argv, const struct rspamadm_command *cmd)
/* Output configuration */
if (argc == 1) {
- rspamadm_dump_section_obj(cfg, cfg->cfg_ucl_obj, cfg->doc_strings);
+ const ucl_object_t *output_obj = cfg->cfg_ucl_obj;
+ if (local_conf_only || override_conf_only) {
+ output_obj = filter_non_default(cfg->cfg_ucl_obj, override_conf_only);
+ if (!output_obj) {
+ rspamd_printf("No non-default configuration found\n");
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ rspamadm_dump_section_obj(cfg, output_obj, cfg->doc_strings);
+
+ if (local_conf_only || override_conf_only) {
+ ucl_object_unref((ucl_object_t *) output_obj);
+ }
}
else {
for (i = 1; i < argc; i++) {
@@ -537,10 +634,18 @@ rspamadm_configdump(int argc, char **argv, const struct rspamadm_command *cmd)
else {
LL_FOREACH(obj, cur)
{
+ const ucl_object_t *output_obj = cur;
+ if (local_conf_only || override_conf_only) {
+ output_obj = filter_non_default(cur, override_conf_only);
+ if (!output_obj) {
+ rspamd_printf("No non-default configuration found for section %s\n", argv[i]);
+ continue;
+ }
+ }
if (!json && !compact) {
rspamd_printf("*** Section %s ***\n", argv[i]);
}
- rspamadm_dump_section_obj(cfg, cur, doc_obj);
+ rspamadm_dump_section_obj(cfg, output_obj, doc_obj);
if (!json && !compact) {
rspamd_printf("\n*** End of section %s ***\n", argv[i]);
@@ -548,6 +653,10 @@ rspamadm_configdump(int argc, char **argv, const struct rspamadm_command *cmd)
else {
rspamd_printf("\n");
}
+
+ if (local_conf_only || override_conf_only) {
+ ucl_object_unref((ucl_object_t *) output_obj);
+ }
}
}
}
diff --git a/src/rspamadm/control.c b/src/rspamadm/control.c
index 381bdaa7a..cd550c04e 100644
--- a/src/rspamadm/control.c
+++ b/src/rspamadm/control.c
@@ -1,11 +1,11 @@
-/*-
- * Copyright 2016 Vsevolod Stakhov
+/*
+ * Copyright 2025 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -112,7 +112,7 @@ rspamd_control_finish_handler(struct rspamd_http_connection *conn,
struct rspamadm_control_cbdata *cbdata = conn->ud;
body = rspamd_http_message_get_body(msg, &body_len);
- parser = ucl_parser_new(0);
+ parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
if (!body || !ucl_parser_add_chunk(parser, body, body_len)) {
rspamd_fprintf(stderr, "cannot parse server's reply: %s\n",
diff --git a/src/rspamadm/lua_repl.c b/src/rspamadm/lua_repl.c
index 1d6da5aa9..f9099d895 100644
--- a/src/rspamadm/lua_repl.c
+++ b/src/rspamadm/lua_repl.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,9 +24,8 @@
#include "lua/lua_thread_pool.h"
#include "message.h"
#include "unix-std.h"
-#ifdef WITH_LUA_REPL
+
#include "replxx.h"
-#endif
#include "worker_util.h"
#ifdef WITH_LUAJIT
#include <luajit.h>
@@ -43,10 +42,7 @@ static int batch = -1;
extern struct rspamd_async_session *rspamadm_session;
static const char *default_history_file = ".rspamd_repl.hist";
-
-#ifdef WITH_LUA_REPL
static Replxx *rx_instance = NULL;
-#endif
#ifdef WITH_LUAJIT
#define MAIN_PROMPT LUAJIT_VERSION "> "
@@ -232,7 +228,6 @@ rspamadm_exec_input(lua_State *L, const char *input)
int i, cbref;
int top = 0;
char outbuf[8192];
- struct lua_logger_trace tr;
struct thread_entry *thread = lua_thread_pool_get_for_config(rspamd_main->cfg);
L = thread->lua_state;
@@ -272,9 +267,8 @@ rspamadm_exec_input(lua_State *L, const char *input)
rspamd_printf("local function: %d\n", cbref);
}
else {
- memset(&tr, 0, sizeof(tr));
- lua_logger_out_type(L, i, outbuf, sizeof(outbuf) - 1, &tr,
- LUA_ESCAPE_UNPRINTABLE);
+ lua_logger_out(L, i, outbuf, sizeof(outbuf),
+ LUA_ESCAPE_UNPRINTABLE);
rspamd_printf("%s\n", outbuf);
}
}
@@ -393,7 +387,6 @@ rspamadm_lua_message_handler(lua_State *L, int argc, char **argv)
gpointer map;
gsize len;
char outbuf[8192];
- struct lua_logger_trace tr;
if (argv[1] == NULL) {
rspamd_printf("no callback is specified\n");
@@ -455,9 +448,8 @@ rspamadm_lua_message_handler(lua_State *L, int argc, char **argv)
rspamd_printf("lua callback for %s returned:\n", argv[i]);
for (j = old_top + 1; j <= lua_gettop(L); j++) {
- memset(&tr, 0, sizeof(tr));
- lua_logger_out_type(L, j, outbuf, sizeof(outbuf), &tr,
- LUA_ESCAPE_UNPRINTABLE);
+ lua_logger_out(L, j, outbuf, sizeof(outbuf),
+ LUA_ESCAPE_UNPRINTABLE);
rspamd_printf("%s\n", outbuf);
}
}
@@ -503,7 +495,6 @@ rspamadm_lua_try_dot_command(lua_State *L, const char *input)
return FALSE;
}
-#ifdef WITH_LUA_REPL
static int lex_ref_idx = -1;
static void
@@ -599,20 +590,14 @@ lua_syntax_highlighter(const char *str, ReplxxColor *colours, int size, void *ud
lua_settop(L, 0);
}
-#endif
static void
rspamadm_lua_run_repl(lua_State *L, bool is_batch)
{
char *input = NULL;
-#ifdef WITH_LUA_REPL
gboolean is_multiline = FALSE;
GString *tb = NULL;
gsize i;
-#else
- /* Always set is_batch */
- is_batch = TRUE;
-#endif
for (;;) {
if (is_batch) {
@@ -644,7 +629,6 @@ rspamadm_lua_run_repl(lua_State *L, bool is_batch)
lua_settop(L, 0);
}
else {
-#ifdef WITH_LUA_REPL
replxx_set_highlighter_callback(rx_instance, lua_syntax_highlighter,
L);
@@ -706,7 +690,6 @@ rspamadm_lua_run_repl(lua_State *L, bool is_batch)
}
}
}
-#endif
}
}
@@ -1009,16 +992,12 @@ rspamadm_lua(int argc, char **argv, const struct rspamadm_command *cmd)
}
if (!batch) {
-#ifdef WITH_LUA_REPL
rx_instance = replxx_init();
replxx_set_max_history_size(rx_instance, max_history);
replxx_history_load(rx_instance, histfile);
-#endif
rspamadm_lua_run_repl(L, false);
-#ifdef WITH_LUA_REPL
replxx_history_save(rx_instance, histfile);
replxx_end(rx_instance);
-#endif
}
else {
rspamadm_lua_run_repl(L, true);
diff --git a/src/rspamadm/signtool.c b/src/rspamadm/signtool.c
index 6d60e6700..538767b19 100644
--- a/src/rspamadm/signtool.c
+++ b/src/rspamadm/signtool.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 Vsevolod Stakhov
+ * Copyright 2025 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -573,7 +573,7 @@ rspamadm_signtool(int argc, char **argv, const struct rspamadm_command *cmd)
else {
g_assert(keypair_file != NULL);
- parser = ucl_parser_new(0);
+ parser = ucl_parser_new(UCL_PARSER_SAFE_FLAGS);
if (!ucl_parser_add_file(parser, keypair_file) ||
(top = ucl_parser_get_object(parser)) == NULL) {