From e279139b7dcae080723412ea475787123c2389d4 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 12 Nov 2023 23:19:44 +0100
Subject: Dump some ROST keywords on request.

---
 src/analysis/scan/core.c  | 29 ++++++++++++++
 src/analysis/scan/core.h  |  3 ++
 src/analysis/scan/space.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/analysis/scan/space.h |  5 ++-
 src/rost.c                | 85 ++++++++++++++++++++++++++++++++++++----
 5 files changed, 212 insertions(+), 9 deletions(-)

diff --git a/src/analysis/scan/core.c b/src/analysis/scan/core.c
index 7e1e462..2b4fd92 100644
--- a/src/analysis/scan/core.c
+++ b/src/analysis/scan/core.c
@@ -159,6 +159,35 @@ bool load_all_known_scan_token_modifiers(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : count = nombre de motificateurs exportés. [OUT]              *
+*                                                                             *
+*  Description : Fournit la désignation de l'ensemble des modificateurs.      *
+*                                                                             *
+*  Retour      : Liste de modificateurs enregistrés.                          *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char **list_all_scan_token_modifiers(size_t *count)
+{
+    char **result;                          /* Liste à retourner           */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = malloc(__modifiers_count * sizeof(char *));
+
+    *count = __modifiers_count;
+
+    for (i = 0; i < __modifiers_count; i++)
+        result[i] = strndup(__modifiers[i].name.data, __modifiers[i].name.len);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : -                                                            *
 *                                                                             *
 *  Description : Décharge tous les modificateurs inscrits.                    *
diff --git a/src/analysis/scan/core.h b/src/analysis/scan/core.h
index 8a18a75..a56ce16 100644
--- a/src/analysis/scan/core.h
+++ b/src/analysis/scan/core.h
@@ -36,6 +36,9 @@ bool register_scan_token_modifier(GScanTokenModifier *);
 /* Charge tous les modificateurs de base. */
 bool load_all_known_scan_token_modifiers(void);
 
+/* Fournit la désignation de l'ensemble des modificateurs. */
+char **list_all_scan_token_modifiers(size_t *);
+
 /* Décharge tous les modificateurs inscrits. */
 void unload_all_scan_token_modifiers(void);
 
diff --git a/src/analysis/scan/space.c b/src/analysis/scan/space.c
index 1aaf8b8..38556a3 100644
--- a/src/analysis/scan/space.c
+++ b/src/analysis/scan/space.c
@@ -24,10 +24,12 @@
 #include "space.h"
 
 
+#include <stdio.h>
 #include <string.h>
 
 
 #include "space-int.h"
+#include "../../core/logs.h"
 
 
 
@@ -236,7 +238,7 @@ bool g_scan_namespace_create(GScanNamespace *space, const char *name)
 *  Paramètres  : space = espace de noms à compléter.                          *
 *                child = élément d'évaluation à intégrer.                     *
 *                                                                             *
-*  Description : Intègre un nouvel élément dans l'esapce de noms.             *
+*  Description : Intègre un nouvel élément dans l'espace de noms.             *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -283,6 +285,101 @@ bool g_scan_namespace_register_item(GScanNamespace *space, GScanRegisteredItem *
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : space = espace de noms à compléter.                          *
+*                count = nombre d'éléments exportés. [OUT]                    *
+*                                                                             *
+*  Description : Réalise l'inventaire d'un espace de noms.                    *
+*                                                                             *
+*  Retour      : Liste d'éléments enregistrés.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+char **g_scan_namespace_explore(const GScanNamespace *space, size_t *count)
+{
+    char **result;                          /* Liste à retourner           */
+    size_t i;                               /* Boucle de parcours #1       */
+    GScanRegisteredItem *child;             /* Elément à considérer        */
+    char **sub_result;                      /* Sous-éléments obtenus       */
+    size_t sub_count;                       /* Quantité de ces éléments    */
+    size_t k;                               /* Boucle de parcours #2       */
+    int ret;                                /* Bilan d'une construction    */
+
+    result = NULL;
+    *count = 0;
+
+    for (i = 0; i < space->count; i++)
+    {
+        child = space->children[i];
+
+        if (G_IS_SCAN_NAMESPACE(child))
+        {
+            sub_result = g_scan_namespace_explore(G_SCAN_NAMESPACE(child), &sub_count);
+
+            result = realloc(result, (*count + sub_count) * sizeof(char *));
+
+            for (k = 0; k < sub_count; k++)
+            {
+                if (space->name == NULL)
+                    result[(*count)++] = sub_result[k];
+
+                else
+                {
+                    ret = asprintf(&result[*count], "%s.%s", space->name, sub_result[k]);
+
+                    if (ret == -1)
+                    {
+                        LOG_ERROR_N("asprintf");
+                        result[*count] = sub_result[k];
+                    }
+
+                    else
+                        free(sub_result[k]);
+
+                    (*count)++;
+
+                }
+
+            }
+
+            if (sub_result != NULL)
+                free(sub_result);
+
+        }
+
+        else
+        {
+            result = realloc(result, (*count + 1) * sizeof(char *));
+
+            if (space->name == NULL)
+                result[(*count)++] = strdup(space->names[i]);
+
+            else
+            {
+                ret = asprintf(&result[*count], "%s.%s", space->name, space->names[i]);
+
+                if (ret == -1)
+                {
+                    LOG_ERROR_N("asprintf");
+                    result[*count] = strdup(space->names[i]);
+                }
+
+                (*count)++;
+
+            }
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
 
 /* ---------------------------------------------------------------------------------- */
 /*                       IMPLEMENTATION DES FONCTIONS DE CLASSE                       */
diff --git a/src/analysis/scan/space.h b/src/analysis/scan/space.h
index 619b960..1b998d8 100644
--- a/src/analysis/scan/space.h
+++ b/src/analysis/scan/space.h
@@ -54,9 +54,12 @@ GType g_scan_namespace_get_type(void);
 /* Construit un nouvel espace de noms pour scan. */
 GScanNamespace *g_scan_namespace_new(const char *);
 
-/* Intègre un nouvel élément dans l'esapce de noms. */
+/* Intègre un nouvel élément dans l'espace de noms. */
 bool g_scan_namespace_register_item(GScanNamespace *, GScanRegisteredItem *);
 
+/* Réalise l'inventaire d'un espace de noms. */
+char **g_scan_namespace_explore(const GScanNamespace *, size_t *);
+
 
 
 #endif  /* _ANALYSIS_SCAN_SPACE_H */
diff --git a/src/rost.c b/src/rost.c
index 96fc8e1..ba19b4f 100644
--- a/src/rost.c
+++ b/src/rost.c
@@ -36,6 +36,7 @@
 
 #include "gleak.h"
 #include "analysis/contents/file.h"
+#include "analysis/scan/core.h"
 #include "analysis/scan/options.h"
 #include "analysis/scan/scanner.h"
 #include "analysis/scan/patterns/backends/bitap.h"
@@ -102,6 +103,11 @@ static void show_rost_help(const char *name)
 
     printf("\n");
 
+    printf("\t--dump-modifiers\tList all registered modifiers for string patterns.\n");
+    printf("\t--dump-namespaces\tExplore the root namespace with all its functions and sub-namespaces.\n");
+
+    printf("\n");
+
     free(tmp);
 
 }
@@ -220,10 +226,18 @@ int main(int argc, char **argv)
     bool show_version;                      /* Affichage de la version ?   */
     bool check_only;                        /* Validation uniquement       */
     LogMessageType verbosity;               /* Niveau de filtre de message */
+    bool dump_modifiers;                    /* Affichage des modificateurs */
+    bool dump_namespaces;                   /* Affichage des fonctions     */
     GScanOptions *options;                  /* Options d'analyses          */
     int index;                              /* Indice d'argument           */
     int ret;                                /* Bilan d'un appel            */
     char *edir;                             /* Répertoire de base effectif */
+    size_t mod_count;                       /* Quantité de modificateurs   */
+    char **modifiers;                       /* Liste de modificateurs      */
+    size_t i;                               /* Boucle de parcours          */
+    GScanNamespace *root_ns;                /* Espace de noms ROST racine  */
+    size_t items_count;                     /* Quantité de modificateurs   */
+    char **items;                           /* Liste de modificateurs      */
     char *rules;                            /* Définition de règles        */
     char *target;                           /* Cible communiquée           */
     size_t rule_length;                     /* Taille d'un contenu         */
@@ -234,6 +248,8 @@ int main(int argc, char **argv)
     sized_string_t padding;                 /* Bourrage pour le JSON       */
     bool full;                              /* Détailler l'affichage ?     */
 
+#define LONG_ID(n) (0x40570000 | n)
+
     static struct option long_options[] = {
         { "help",           no_argument,        NULL,   'h' },
         { "version",        no_argument,        NULL,   'v' },
@@ -245,6 +261,8 @@ int main(int argc, char **argv)
         { "print-tags",     no_argument,        NULL,   'g' },
         { "tag",            required_argument,  NULL,   't' },
         { "verbosity",      required_argument,  NULL,   'V' },
+        { "dump-modifiers", no_argument,        NULL,   LONG_ID(1) },
+        { "dump-namespaces",no_argument,        NULL,   LONG_ID(2) },
         { NULL,             0,                  NULL,   0 }
     };
 
@@ -257,6 +275,8 @@ int main(int argc, char **argv)
 
     check_only = false;
     verbosity = LMT_COUNT;
+    dump_modifiers = false;
+    dump_namespaces = false;
 
     options = g_scan_options_new();
 
@@ -315,15 +335,16 @@ int main(int argc, char **argv)
                 verbosity = strtoul(optarg, NULL, 10);
                 break;
 
-        }
+            case LONG_ID(1):
+                dump_modifiers = true;
+                break;
 
-    }
+            case LONG_ID(2):
+                dump_namespaces = true;
+                break;
+
+        }
 
-    if ((check_only && (optind + 0) != argc && (optind + 1) != argc)
-        || (!check_only && (optind + 1) != argc && (optind + 2) != argc))
-    {
-        show_rost_help(argv[0]);
-        goto done;
     }
 
     /* Actions de base */
@@ -371,6 +392,56 @@ int main(int argc, char **argv)
 
     init_all_plugins(true);
 
+    if (dump_modifiers)
+    {
+        modifiers = list_all_scan_token_modifiers(&mod_count);
+
+        for (i = 0; i < mod_count; i++)
+        {
+            printf("%s\n", modifiers[i]);
+            free(modifiers[i]);
+        }
+
+        if (modifiers != NULL)
+            free(modifiers);
+
+        result = EXIT_SUCCESS;
+
+    }
+
+    if (dump_namespaces)
+    {
+        root_ns = get_rost_root_namespace();
+
+        items = g_scan_namespace_explore(root_ns, &items_count);
+
+        for (i = 0; i < items_count; i++)
+        {
+            printf("%s\n", items[i]);
+            free(items[i]);
+        }
+
+        if (items != NULL)
+            free(items);
+
+        result = EXIT_SUCCESS;
+
+        g_object_unref(G_OBJECT(root_ns));
+
+    }
+
+    if ((check_only && (optind + 0) != argc && (optind + 1) != argc)
+        || (!check_only && (optind + 1) != argc && (optind + 2) != argc))
+    {
+        if (result == EXIT_FAILURE)
+            show_rost_help(argv[0]);
+        goto done;
+    }
+
+    /* Réinitialisation en cas de dump... */
+    else
+        result = EXIT_FAILURE;
+
     /* Traitement des recherches */
 
     if ((optind + 0) == argc)
-- 
cgit v0.11.2-87-g4458