From ef58d4479922ad026367c6daa73469f8ac42f001 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 19 Sep 2023 08:32:48 +0200
Subject: Allow ROST rules loading from standard input.

---
 src/rost.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 92 insertions(+), 6 deletions(-)

diff --git a/src/rost.c b/src/rost.c
index 9428dff..928aa12 100644
--- a/src/rost.c
+++ b/src/rost.c
@@ -25,7 +25,9 @@
 #include <getopt.h>
 #include <libgen.h>
 #include <locale.h>
+#include <malloc.h>
 #include <stdlib.h>
+#include <string.h>
 
 
 #include <i18n.h>
@@ -51,6 +53,9 @@ static void show_rost_help(const char *);
 /* Affiche des indications sur la version courante du programme. */
 static void show_rost_version(void);
 
+/* Récupère un contenu à traiter depuis l'entrée standard. */
+static void *get_input_data_from_stdin(void);
+
 
 
 /******************************************************************************
@@ -140,6 +145,60 @@ static void show_rost_version(void)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Récupère un contenu à traiter depuis l'entrée standard.      *
+*                                                                             *
+*  Retour      : Adresse valide ou NULL en cas d'échec.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void *get_input_data_from_stdin(void)
+{
+    char *result;                           /* Espace mémoire à retourner  */
+    size_t length;                          /* Taille de ce contenu        */
+    ssize_t got;                            /* Quantité d'octets lus       */
+
+    result = NULL;
+
+    length = 0;
+
+#define ALLOC_SIZE 2048
+
+    while (true)
+    {
+        result = realloc(result, (length + ALLOC_SIZE) * sizeof(char));
+
+        got = read(STDIN_FILENO, result + length, ALLOC_SIZE);
+
+        if (got == -1)
+        {
+            LOG_ERROR_N("read");
+            goto exit_with_error;
+        }
+
+        length += got;
+
+        if (got < ALLOC_SIZE)
+            break;
+
+    }
+
+    return result;
+
+ exit_with_error:
+
+    free(result);
+
+    return NULL;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         *
 *                argv = arguments de la ligne de commande.                    *
 *                                                                             *
@@ -160,9 +219,10 @@ int main(int argc, char **argv)
     GScanOptions *options;                  /* Options d'analyses          */
     int index;                              /* Indice d'argument           */
     int ret;                                /* Bilan d'un appel            */
+    char *edir;                             /* Répertoire de base effectif */
     char *rules;                            /* Définition de règles        */
     char *target;                           /* Cible communiquée           */
-    char *edir;                             /* Répertoire de base effectif */
+    void *rule_content;                     /* Contenu à traduire          */
     GContentScanner *scanner;               /* Encadrement d'une recherche */
     GBinContent *content;                   /* Contenu à analyser          */
     GScanContext *context;                  /* Contexte des trouvailles    */
@@ -237,16 +297,13 @@ int main(int argc, char **argv)
 
     }
 
-    if ((optind + 2) != argc)
+    if ((optind + 1) != argc && (optind + 2) != argc)
     {
         show_rost_help(argv[0]);
         result = EXIT_FAILURE;
         goto done;
     }
 
-    rules = argv[optind];
-    target = argv[optind + 1];
-
     /* Actions de base */
 
     if (show_help)
@@ -293,7 +350,36 @@ int main(int argc, char **argv)
 
     /* Traitement des recherches */
 
-    scanner = g_content_scanner_new_from_file(rules);
+    if ((optind + 1) == argc)
+    {
+        rules = NULL;
+        target = argv[optind];
+    }
+    else
+    {
+        rules = argv[optind];
+        target = argv[optind + 1];
+
+        if (strcmp(rules, "-") == 0 || strcmp(rules, "/dev/stdin") == 0)
+            rules = NULL;
+
+    }
+
+    if (rules == NULL)
+    {
+        rule_content = get_input_data_from_stdin();
+
+        if (rule_content != NULL)
+        {
+            scanner = g_content_scanner_new_from_text(rule_content);
+            free(rule_content);
+        }
+        else
+            scanner = NULL;
+
+    }
+    else
+        scanner = g_content_scanner_new_from_file(rules);
 
     if (scanner != NULL)
     {
-- 
cgit v0.11.2-87-g4458