From 1af5983f201066eff529e57d2bddd4f398f32cfd Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 8 Feb 2016 19:17:49 +0000 Subject: [PATCH] Start rework of configdump - Add support of paths - Add initial support of help - Fix options --- src/rspamadm/configdump.c | 140 ++++++++++++++++++++++++++++++-------- 1 file changed, 112 insertions(+), 28 deletions(-) diff --git a/src/rspamadm/configdump.c b/src/rspamadm/configdump.c index e4800a26e..2ed4b7eb2 100644 --- a/src/rspamadm/configdump.c +++ b/src/rspamadm/configdump.c @@ -23,8 +23,8 @@ static gboolean json = FALSE; static gboolean compact = FALSE; +static gboolean show_help = FALSE; static gchar *config = NULL; -static gchar **sections = NULL; extern struct rspamd_main *rspamd_main; /* Defined in modules.c */ extern module_t *modules[]; @@ -47,8 +47,8 @@ static GOptionEntry entries[] = { "Compacted json output", NULL}, {"config", 'c', 0, G_OPTION_ARG_STRING, &config, "Config file to test", NULL}, - {"section", 's', 0, G_OPTION_ARG_STRING_ARRAY, §ions, - "Sections to dump", NULL}, + {"show-help", 'h', 0, G_OPTION_ARG_NONE, &show_help, + "Show help as comments for each option", NULL }, {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL} }; @@ -59,12 +59,12 @@ rspamadm_configdump_help (gboolean full_help) if (full_help) { help_str = "Perform configuration file dump\n\n" - "Usage: rspamadm configdump [-c -j --compact [-s
[-s
]]]\n" + "Usage: rspamadm configdump [-c -j --compact [ [ ...]]]\n" "Where options are:\n\n" "-j: output plain json\n" "--compact: output compacted json\n" "-c: config file to test\n" - "-s: specify section to dump (can be multiple)\n" + "-h: show help for dumped options\n" "--help: shows available options and commands"; } else { @@ -91,25 +91,116 @@ config_logger (rspamd_mempool_t *pool, gpointer ud) } static void -rspamadm_dump_section_obj (const ucl_object_t *obj) +rspamadm_add_doc_elt (const ucl_object_t *obj, const ucl_object_t *doc_obj, + ucl_object_t *comment_obj) +{ + rspamd_fstring_t *comment = rspamd_fstring_new (); + const ucl_object_t *elt, *cur; + ucl_object_t *nobj; + + if (doc_obj != NULL) { + /* Create doc comment */ + rspamd_printf_fstring (&comment, "/*\n"); + } + + elt = ucl_object_find_key (doc_obj, "data"); + if (elt) { + rspamd_printf_fstring (&comment, "* %s\n", ucl_object_tostring (elt)); + } + + elt = ucl_object_find_key (doc_obj, "type"); + if (elt) { + rspamd_printf_fstring (&comment, "* Type: %s\n", ucl_object_tostring (elt)); + } + + elt = ucl_object_find_key (doc_obj, "required"); + if (elt) { + rspamd_printf_fstring (&comment, "* Required %b\n", + ucl_object_toboolean (elt)); + } + + rspamd_printf_fstring (&comment, " */\n"); + + nobj = ucl_object_fromlstring (comment->str, comment->len); + rspamd_fstring_free (comment); + + LL_FOREACH (obj, cur) { + ucl_object_insert_key (comment_obj, nobj, (const char *)&cur, + sizeof (void *), true); + } +} + +static void +rspamadm_gen_comments (const ucl_object_t *obj, const ucl_object_t *doc_obj, + ucl_object_t *comments) +{ + const ucl_object_t *cur_obj, *cur_doc; + ucl_object_iter_t it = NULL; + ucl_object_t *cur_elt; + + if (obj == NULL || doc_obj == NULL || obj->keylen == 0) { + return; + } + + cur_doc = ucl_object_find_keyl (doc_obj, obj->key, obj->keylen); + + if (cur_doc != NULL) { + rspamadm_add_doc_elt (obj, cur_doc, comments); + } + + if (ucl_object_type (obj) == UCL_OBJECT) { + while ((cur_obj = ucl_iterate_object (obj, &it, true))) { + cur_doc = ucl_object_find_keyl (doc_obj, cur_obj->key, + cur_obj->keylen); + + if (cur_doc != NULL) { + cur_elt = (ucl_object_t *)ucl_object_find_keyl (comments, + (const char *)&cur_obj, + sizeof (void *)); + if (cur_elt == NULL) { + cur_elt = ucl_object_typed_new (UCL_OBJECT); + } + + ucl_object_insert_key (comments, cur_elt, (const char *)&cur_obj, + sizeof (void *), true); + + rspamadm_gen_comments (cur_obj, cur_doc, cur_elt); + } + } + } +} + +static void +rspamadm_dump_section_obj (const ucl_object_t *obj, const ucl_object_t *doc_obj) { rspamd_fstring_t *output; + ucl_object_t *comments = NULL; output = rspamd_fstring_new (); + if (show_help) { + comments = ucl_object_typed_new (UCL_OBJECT); + rspamadm_gen_comments (obj, doc_obj, comments); + } + if (json) { - rspamd_ucl_emit_fstring (obj, UCL_EMIT_JSON, &output); + rspamd_ucl_emit_fstring_comments (obj, UCL_EMIT_JSON, &output, comments); } else if (compact) { - rspamd_ucl_emit_fstring (obj, UCL_EMIT_JSON_COMPACT, &output); + rspamd_ucl_emit_fstring_comments (obj, UCL_EMIT_JSON_COMPACT, &output, + comments); } else { - rspamd_ucl_emit_fstring (obj, UCL_EMIT_CONFIG, &output); + rspamd_ucl_emit_fstring_comments (obj, UCL_EMIT_CONFIG, &output, + comments); } rspamd_printf ("%V", output); - rspamd_fstring_free (output); + + if (comments != NULL) { + ucl_object_unref (comments); + } } static void @@ -118,11 +209,11 @@ rspamadm_configdump (gint argc, gchar **argv) GOptionContext *context; GError *error = NULL; const gchar *confdir; - const ucl_object_t *obj, *cur; + const ucl_object_t *obj, *cur, *doc_obj; struct rspamd_config *cfg = rspamd_main->cfg; gboolean ret = TRUE; worker_t **pworker; - gchar **sec; + gint i; context = g_option_context_new ( "keypair - create encryption keys"); @@ -178,40 +269,33 @@ rspamadm_configdump (gint argc, gchar **argv) if (ret) { /* Output configuration */ - - - if (!sections) { - rspamadm_dump_section_obj (cfg->rcl_obj); + if (argc == 1) { + rspamadm_dump_section_obj (cfg->rcl_obj, cfg->doc_strings); } else { - sec = sections; - - while (*sec != NULL) { - obj = ucl_object_find_key (cfg->rcl_obj, *sec); + for (i = 1; i < argc; i ++) { + obj = ucl_lookup_path (cfg->rcl_obj, argv[i]); + doc_obj = ucl_lookup_path (cfg->doc_strings, argv[i]); if (!obj) { - rspamd_printf ("Section %s NOT FOUND\n", *sec); + rspamd_printf ("Section %s NOT FOUND\n", argv[i]); } else { LL_FOREACH (obj, cur) { if (!json && !compact) { - rspamd_printf ("*** Section %s ***\n", *sec); + rspamd_printf ("*** Section %s ***\n", argv[i]); } - rspamadm_dump_section_obj (cur); + rspamadm_dump_section_obj (cur, doc_obj); if (!json && !compact) { - rspamd_printf ("*** End of section %s ***\n", *sec); + rspamd_printf ("*** End of section %s ***\n", argv[i]); } else { rspamd_printf ("\n"); } } } - - sec ++; } - - g_strfreev (sections); } } -- 2.39.5