/* Chrysalide - Outil d'analyse de fichiers binaires * import.c - localisation de fichiers de définitions externes * * Copyright (C) 2023 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Chrysalide. If not, see . */ #include "import.h" #include #include #include #include #include /* 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 *); /****************************************************************************** * * * Paramètres : target = désignation de la définition à retrouver. * * reference = éventuel fichier pour les positions relatives. * * * * Description : Charge un type Kaitai à partir d'une définition voisine. * * * * Retour : Type valide en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ static GKaitaiType *import_relative_kaitai_definition(const char *target, const char *reference) { GKaitaiType *result; /* Structure chargée à renvoyer*/ char *tmp; /* Zone de travail temporaire */ char *base; /* Base de recherche */ char *filename; /* Nom de fichier à tester */ int ret; /* Bilan d'une construction */ result = NULL; tmp = strdup(reference); base = dirname(tmp); ret = asprintf(&filename, "%s%c%s.ksy", base, G_DIR_SEPARATOR, target); if (ret == -1) goto build_error; result = g_kaitai_type_new_as_import(target, filename); free(filename); build_error: free(tmp); return result; } /****************************************************************************** * * * 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); if (result != NULL) log_variadic_message(LMT_PROCESS, _("Found a required Kaitai definition to import: %s"), filename); free(filename); } free(paths); return result; } /****************************************************************************** * * * Paramètres : target = désignation de la définition à retrouver. * * reference = éventuel fichier pour les positions relatives. * * * * Description : Met en place un type Kaitai pour une définition désignée. * * * * Retour : Type valide en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GKaitaiType *import_kaitai_definition(const char *target, const char *reference) { GKaitaiType *result; /* Structure chargée à renvoyer*/ result = NULL; if (reference != NULL) result = import_relative_kaitai_definition(target, reference); if (result == NULL) result = import_kaitai_definition_from_env(target); return result; } /****************************************************************************** * * * Paramètres : target = désignation de la définition à retrouver. * * reference = éventuel fichier pour les positions relatives. * * * * Description : Charge un interpréteur pour une définition voisine. * * * * Retour : Interprétateur valide en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ static GKaitaiStruct *load_relative_kaitai_definition(const char *target, const char *reference) { GKaitaiStruct *result; /* Structure chargée à renvoyer*/ char *tmp; /* Zone de travail temporaire */ char *base; /* Base de recherche */ char *filename; /* Nom de fichier à tester */ int ret; /* Bilan d'une construction */ result = NULL; tmp = strdup(reference); base = dirname(tmp); ret = asprintf(&filename, "%s%c%s.ksy", base, G_DIR_SEPARATOR, target); if (ret == -1) goto build_error; result = g_kaitai_structure_new_from_file(filename); free(filename); build_error: free(tmp); return result; } /****************************************************************************** * * * 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); if (result != NULL) log_variadic_message(LMT_PROCESS, _("Found a required Kaitai definition: %s"), filename); free(filename); } free(paths); return result; } /****************************************************************************** * * * Paramètres : target = désignation de la définition à retrouver. * * reference = éventuel fichier pour les positions relatives. * * * * Description : Met en place un interpréteur pour une définition désignée. * * * * Retour : Interprétateur valide en place ou NULL en cas d'échec. * * * * Remarques : - * * * ******************************************************************************/ GKaitaiStruct *load_kaitai_definition(const char *target, const char *reference) { GKaitaiStruct *result; /* Structure chargée à renvoyer*/ result = NULL; if (reference != NULL) result = load_relative_kaitai_definition(target, reference); if (result == NULL) result = load_kaitai_definition_from_env(target); return result; }