From 24ff611b744d26d7f95f9dd2f46292d774b0ab16 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 26 Oct 2013 22:08:05 +0100 Subject: [PATCH] Allow xml->ucl config conversion. Now it is possible to read UCL configs directly and convert legacy XML to UCL by --convert-config option. Default config is now rspamd.conf, not rspamd.xml. --- src/cfg_file.h | 2 +- src/cfg_utils.c | 72 ++++++++++++++++++++++++++++++++++++++++--------- src/main.c | 4 ++- src/main.h | 2 +- 4 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/cfg_file.h b/src/cfg_file.h index 875ce3373..659d6981e 100644 --- a/src/cfg_file.h +++ b/src/cfg_file.h @@ -532,7 +532,7 @@ gboolean parse_normalizer (struct config_file *cfg, struct statfile *st, const g /* * Read XML configuration file */ -gboolean read_xml_config (struct config_file *cfg, const gchar *filename); +gboolean read_rspamd_config (struct config_file *cfg, const gchar *filename, const gchar *convert_to); /* * Register symbols of classifiers inside metrics diff --git a/src/cfg_utils.c b/src/cfg_utils.c index d41f364ba..0e698cdcd 100644 --- a/src/cfg_utils.c +++ b/src/cfg_utils.c @@ -955,18 +955,31 @@ static GMarkupParser xml_parser = { .error = rspamd_xml_error, }; +static const char* +get_filename_extension (const char *filename) +{ + const char *dot_pos = strrchr (filename, '.'); + + if (dot_pos != NULL) { + return (dot_pos + 1); + } + + return NULL; +} + gboolean -read_xml_config (struct config_file *cfg, const gchar *filename) +read_rspamd_config (struct config_file *cfg, const gchar *filename, const gchar *convert_to) { struct stat st; gint fd; gchar *data, *rcl; + const gchar *ext; GMarkupParseContext *ctx; GError *err = NULL; struct rspamd_rcl_section *top; - gboolean res; - + gboolean res, is_xml = FALSE; struct rspamd_xml_userdata ud; + struct ucl_parser *parser; if (stat (filename, &st) == -1) { msg_err ("cannot stat %s: %s", filename, strerror (errno)); @@ -985,23 +998,58 @@ read_xml_config (struct config_file *cfg, const gchar *filename) } close (fd); - /* Prepare xml parser */ - memset (&ud, 0, sizeof (ud)); - ud.cfg = cfg; - ud.state = 0; - ctx = g_markup_parse_context_new (&xml_parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &ud, NULL); - res = g_markup_parse_context_parse (ctx, data, st.st_size, &err); + ext = get_filename_extension (filename); + if (ext != NULL && strcmp (ext, "xml") == 0) { + is_xml = TRUE; + } - munmap (data, st.st_size); + if (is_xml) { + /* Prepare xml parser */ + memset (&ud, 0, sizeof (ud)); + ud.cfg = cfg; + ud.state = 0; + ctx = g_markup_parse_context_new (&xml_parser, G_MARKUP_TREAT_CDATA_AS_TEXT, &ud, NULL); + res = g_markup_parse_context_parse (ctx, data, st.st_size, &err); + + munmap (data, st.st_size); + + top = rspamd_rcl_config_init (); + + err = NULL; + } + else { + parser = ucl_parser_new (UCL_PARSER_KEY_LOWERCASE); + if (!ucl_parser_add_chunk (parser, data, st.st_size)) { + msg_err ("ucl parser error: %s", ucl_parser_get_error (parser)); + munmap (data, st.st_size); + return FALSE; + } + munmap (data, st.st_size); + cfg->rcl_obj = ucl_parser_get_object (parser); + } - top = rspamd_rcl_config_init (); - err = NULL; if (!res || !rspamd_read_rcl_config (top, cfg, cfg->rcl_obj, &err)) { msg_err ("rcl parse error: %s", err->message); return FALSE; } + if (is_xml && convert_to != NULL) { + /* Convert XML config to UCL */ + rcl = ucl_object_emit (cfg->rcl_obj, UCL_EMIT_CONFIG); + if (rcl != NULL) { + fd = open (convert_to, O_CREAT|O_TRUNC|O_WRONLY, 00644); + if (fd == -1) { + msg_err ("cannot open %s: %s", convert_to, strerror (errno)); + } + else if (write (fd, rcl, strlen (rcl)) == -1) { + msg_err ("cannot write rcl %s: %s", convert_to, strerror (errno)); + } + close (fd); + free (rcl); + } + } + return TRUE; } diff --git a/src/main.c b/src/main.c index 8f37f5cc9..6c4f0c318 100644 --- a/src/main.c +++ b/src/main.c @@ -75,6 +75,7 @@ static gboolean dump_vars = FALSE; static gboolean dump_cache = FALSE; static gboolean is_debug = FALSE; static gboolean is_insecure = FALSE; +static gchar *convert_config = FALSE; /* List of workers that are pending to start */ static GList *workers_pending = NULL; @@ -103,6 +104,7 @@ static GOptionEntry entries[] = { "test-lua", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &lua_tests, "Specify lua file(s) to test", NULL }, { "sign-config", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &sign_configs, "Specify config file(s) to sign", NULL }, { "private-key", 0, 0, G_OPTION_ARG_FILENAME, &privkey, "Specify private key to sign", NULL }, + { "convert-config", 0, 0, G_OPTION_ARG_FILENAME, &convert_config, "Convert cnfiguration to UCL", NULL}, { NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL } }; @@ -754,7 +756,7 @@ load_rspamd_config (struct config_file *cfg, gboolean init_modules) struct filter *filt; struct module_ctx *cur_module = NULL; - if (! read_xml_config (cfg, cfg->cfg_name)) { + if (! read_rspamd_config (cfg, cfg->cfg_name, convert_config)) { return FALSE; } diff --git a/src/main.h b/src/main.h index e0545408c..f169b4f5d 100644 --- a/src/main.h +++ b/src/main.h @@ -22,7 +22,7 @@ #include "roll_history.h" /* Default values */ -#define FIXED_CONFIG_FILE ETC_PREFIX "/rspamd.xml" +#define FIXED_CONFIG_FILE ETC_PREFIX "/rspamd.conf" /* Time in seconds to exit for old worker */ #define SOFT_SHUTDOWN_TIME 10 /* Default metric name */ -- 2.39.5