From 2e144129d6884f4f9ec5d3f599ec2820613ed419 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 10 Oct 2023 01:49:08 +0200
Subject: Load Kaitai definitions from $KSPATH when needed.

---
 plugins/kaitai/import.c       | 142 +++++++++++++++++++++++++++++++++++++-----
 plugins/kaitai/rost/space.c   |  18 +++++-
 plugins/kaitai/rost/trigger.c |   6 +-
 plugins/kaitai/rost/trigger.h |   5 +-
 plugins/pychrysalide/core.c   |  12 ++--
 src/analysis/scan/space.c     |   4 +-
 6 files changed, 160 insertions(+), 27 deletions(-)

diff --git a/plugins/kaitai/import.c b/plugins/kaitai/import.c
index 88cd03a..516a091 100644
--- a/plugins/kaitai/import.c
+++ b/plugins/kaitai/import.c
@@ -29,13 +29,23 @@
 #include <string.h>
 
 
+#include <common/environment.h>
+#include <core/logs.h>
+
+
 
 /* Charge un type Kaitai à partir d'une définition voisine. */
 static GKaitaiType *import_relative_kaitai_definition(const char *, const char *);
 
+/* Charge un type Kaitai depuis un emplacement de $KSPATH. */
+static GKaitaiType *import_kaitai_definition_from_env(const char *);
+
 /* Charge un interpréteur pour une définition voisine. */
 static GKaitaiStruct *load_relative_kaitai_definition(const char *, const char *);
 
+/* Charge un interpréteur depuis un emplacement de $KSPATH. */
+static GKaitaiStruct *load_kaitai_definition_from_env(const char *);
+
 
 
 /******************************************************************************
@@ -82,6 +92,63 @@ static GKaitaiType *import_relative_kaitai_definition(const char *target, const
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : target = désignation de la définition à retrouver.           *
+*                                                                             *
+*  Description : Charge un type Kaitai depuis un emplacement de $KSPATH.      *
+*                                                                             *
+*  Retour      : Type valide en place ou NULL en cas d'échec.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GKaitaiType *import_kaitai_definition_from_env(const char *target)
+{
+    GKaitaiType *result;                    /* Structure chargée à renvoyer*/
+    char *paths;                            /* Emplacements de greffons    */
+    char *save;                             /* Sauvegarde pour ré-entrance */
+    char *path;                             /* Chemin à fouiller           */
+    char *filename;                         /* Nom de fichier à tester     */
+    int ret;                                /* Bilan d'une construction    */
+
+    result = NULL;
+
+    paths = get_env_var("KSPATH");
+
+    save = NULL;   /* gcc... */
+
+    for (path = strtok_r(paths, ":", &save);
+         path != NULL;
+         path = strtok_r(NULL, ":", &save))
+    {
+        ret = asprintf(&filename, "%s%c%s.ksy", path, G_DIR_SEPARATOR, target);
+        if (ret == -1)
+        {
+            LOG_ERROR_N("asprintf");
+            continue;
+        }
+
+        result = g_kaitai_type_new_as_import(target, filename);
+
+        free(filename);
+
+        if (result != NULL)
+        {
+            log_variadic_message(LMT_PROCESS, _("Found a required Kaitai definition: %s"), filename);
+            break;
+        }
+
+    }
+
+    free(paths);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : target    = désignation de la définition à retrouver.        *
 *                reference = éventuel fichier pour les positions relatives.   *
 *                                                                             *
@@ -100,15 +167,10 @@ GKaitaiType *import_kaitai_definition(const char *target, const char *reference)
     result = NULL;
 
     if (reference != NULL)
-    {
         result = import_relative_kaitai_definition(target, reference);
 
-        if (result != NULL)
-            goto done;
-
-    }
-
- done:
+    if (result == NULL)
+        result = import_kaitai_definition_from_env(target);
 
     return result;
 
@@ -159,6 +221,63 @@ static GKaitaiStruct *load_relative_kaitai_definition(const char *target, const
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : target = désignation de la définition à retrouver.           *
+*                                                                             *
+*  Description : Charge un interpréteur depuis un emplacement de $KSPATH.     *
+*                                                                             *
+*  Retour      : Interprétateur valide en place ou NULL en cas d'échec.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static GKaitaiStruct *load_kaitai_definition_from_env(const char *target)
+{
+    GKaitaiStruct *result;                  /* Structure chargée à renvoyer*/
+    char *paths;                            /* Emplacements de greffons    */
+    char *save;                             /* Sauvegarde pour ré-entrance */
+    char *path;                             /* Chemin à fouiller           */
+    char *filename;                         /* Nom de fichier à tester     */
+    int ret;                                /* Bilan d'une construction    */
+
+    result = NULL;
+
+    paths = get_env_var("KSPATH");
+
+    save = NULL;   /* gcc... */
+
+    for (path = strtok_r(paths, ":", &save);
+         path != NULL;
+         path = strtok_r(NULL, ":", &save))
+    {
+        ret = asprintf(&filename, "%s%c%s.ksy", path, G_DIR_SEPARATOR, target);
+        if (ret == -1)
+        {
+            LOG_ERROR_N("asprintf");
+            continue;
+        }
+
+        result = g_kaitai_structure_new_from_file(filename);
+
+        free(filename);
+
+        if (result != NULL)
+        {
+            log_variadic_message(LMT_PROCESS, _("Found a required Kaitai definition: %s"), filename);
+            break;
+        }
+
+    }
+
+    free(paths);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : target    = désignation de la définition à retrouver.        *
 *                reference = éventuel fichier pour les positions relatives.   *
 *                                                                             *
@@ -177,15 +296,10 @@ GKaitaiStruct *load_kaitai_definition(const char *target, const char *reference)
     result = NULL;
 
     if (reference != NULL)
-    {
         result = load_relative_kaitai_definition(target, reference);
 
-        if (result != NULL)
-            goto done;
-
-    }
-
- done:
+    if (result == NULL)
+        result = load_kaitai_definition_from_env(target);
 
     return result;
 
diff --git a/plugins/kaitai/rost/space.c b/plugins/kaitai/rost/space.c
index ed24562..ee922d2 100644
--- a/plugins/kaitai/rost/space.c
+++ b/plugins/kaitai/rost/space.c
@@ -27,7 +27,9 @@
 #include <string.h>
 
 
+#include "trigger.h"
 #include "space-int.h"
+#include "../import.h"
 
 
 
@@ -226,14 +228,26 @@ static bool g_kaitai_namespace_resolve(GKaitaiNamespace *item, const char *targe
 {
     bool result;                            /* Bilan à retourner           */
     GScanRegisteredItemClass *parent;       /* Version de classe parente   */
+    GKaitaiStruct *kstruct;                 /* Lecteur de définition       */
 
     parent = G_SCAN_REGISTERED_ITEM_CLASS(g_kaitai_namespace_parent_class);
 
     result = parent->resolve(G_SCAN_REGISTERED_ITEM(item), target, ctx, scope, out);
 
-
     if (!result)
-        printf("NEED external def!!!!\n");
+    {
+        kstruct = load_kaitai_definition(target, NULL);
+
+        if (kstruct != NULL)
+        {
+            *out = g_kaitai_trigger_new(kstruct);
+            result = true;
+
+            g_object_unref(G_OBJECT(kstruct));
+
+        }
+
+    }
 
     return result;
 
diff --git a/plugins/kaitai/rost/trigger.c b/plugins/kaitai/rost/trigger.c
index 64e6fe4..6bb6e5d 100644
--- a/plugins/kaitai/rost/trigger.c
+++ b/plugins/kaitai/rost/trigger.c
@@ -175,13 +175,13 @@ static void g_kaitai_trigger_finalize(GKaitaiTrigger *trigger)
 *                                                                             *
 ******************************************************************************/
 
-GKaitaiTrigger *g_kaitai_trigger_new(GKaitaiStruct *kstruct)
+GScanRegisteredItem *g_kaitai_trigger_new(GKaitaiStruct *kstruct)
 {
-    GKaitaiTrigger *result;                 /* Structure à retourner       */
+    GScanRegisteredItem *result;            /* Structure à retourner       */
 
     result = g_object_new(G_TYPE_KAITAI_TRIGGER, NULL);
 
-    if (!g_kaitai_trigger_create(result, kstruct))
+    if (!g_kaitai_trigger_create(G_KAITAI_TRIGGER(result), kstruct))
         g_clear_object(&result);
 
     return result;
diff --git a/plugins/kaitai/rost/trigger.h b/plugins/kaitai/rost/trigger.h
index 3de2e8d..f55e998 100644
--- a/plugins/kaitai/rost/trigger.h
+++ b/plugins/kaitai/rost/trigger.h
@@ -28,6 +28,9 @@
 #include <glib-object.h>
 
 
+#include <analysis/scan/item.h>
+
+
 #include "../parsers/struct.h"
 
 
@@ -51,7 +54,7 @@ typedef struct _GKaitaiTriggerClass GKaitaiTriggerClass;
 GType g_kaitai_trigger_get_type(void);
 
 /* Crée un nouvel accès à une définition Kaitai à instancier. */
-GKaitaiTrigger *g_kaitai_trigger_new(GKaitaiStruct *);
+GScanRegisteredItem *g_kaitai_trigger_new(GKaitaiStruct *);
 
 
 
diff --git a/plugins/pychrysalide/core.c b/plugins/pychrysalide/core.c
index 771d129..597ad81 100644
--- a/plugins/pychrysalide/core.c
+++ b/plugins/pychrysalide/core.c
@@ -800,11 +800,11 @@ static void load_python_plugins(GPluginModule *plugin)
 
     if (dir != NULL)
     {
-         closedir(dir);
+        closedir(dir);
 
-         edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
-         extend_python_path(edir);
-         free(edir);
+        edir = get_effective_directory(PLUGINS_DATA_DIR G_DIR_SEPARATOR_S "python");
+        extend_python_path(edir);
+        free(edir);
 
     }
 
@@ -821,7 +821,7 @@ static void load_python_plugins(GPluginModule *plugin)
     save = NULL;   /* gcc... */
 
     for (path = strtok_r(paths, ":", &save);
-         path != NULL; 
+         path != NULL;
          path = strtok_r(NULL, ":", &save))
     {
         dir = opendir(path);
@@ -900,7 +900,7 @@ static void load_python_plugins(GPluginModule *plugin)
 
         }
 
-         closedir(dir);
+        closedir(dir);
 
     }
 
diff --git a/src/analysis/scan/space.c b/src/analysis/scan/space.c
index 909b96d..7dd9082 100644
--- a/src/analysis/scan/space.c
+++ b/src/analysis/scan/space.c
@@ -337,13 +337,15 @@ static bool g_scan_namespace_resolve(GScanNamespace *item, const char *target, G
     bool result;                            /* Bilan à retourner           */
     size_t i;                               /* Boucle de parcours          */
 
-    result = true;
+    result = false;
 
     for (i = 0; i < item->count; i++)
         if (strcmp(target, item->names[i]) == 0)
         {
             *out = item->children[i];
             g_object_ref(G_OBJECT(*out));
+
+            result = true;
             break;
         }
 
-- 
cgit v0.11.2-87-g4458