]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Start rework of configdump
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 8 Feb 2016 19:17:49 +0000 (19:17 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 8 Feb 2016 19:17:49 +0000 (19:17 +0000)
- Add support of paths
- Add initial support of help
- Fix options

src/rspamadm/configdump.c

index e4800a26edc8f4a97a21fb0c4b8f40789e9aa061..2ed4b7eb2986cedb72955ca39a288a754cbbd846 100644 (file)
@@ -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, &sections,
-                               "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 <config_name> -j --compact [-s <section> [-s <section>]]]\n"
+                               "Usage: rspamadm configdump [-c <config_name> -j --compact [<path1> [<path2> ...]]]\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);
                }
        }