diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile.am | 5 | ||||
| -rw-r--r-- | src/analysis/binary.c | 158 | ||||
| -rw-r--r-- | src/analysis/binary.h | 13 | ||||
| -rw-r--r-- | src/common/extstr.c | 38 | ||||
| -rw-r--r-- | src/common/extstr.h | 6 | ||||
| -rw-r--r-- | src/configuration.c | 125 | ||||
| -rw-r--r-- | src/configuration.h | 59 | ||||
| -rw-r--r-- | src/editor.c | 210 | ||||
| -rw-r--r-- | src/editor.h | 38 | ||||
| -rw-r--r-- | src/main.c | 104 | ||||
| -rw-r--r-- | src/params.c | 49 | ||||
| -rw-r--r-- | src/params.h | 74 | ||||
| -rw-r--r-- | src/project.c | 190 | ||||
| -rw-r--r-- | src/project.h | 14 | ||||
| -rw-r--r-- | src/xml.c | 257 | ||||
| -rw-r--r-- | src/xml.h | 28 | 
16 files changed, 1029 insertions, 339 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 347980b..fd11575 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -62,9 +62,12 @@ liboidaplugin_la_LIBADD =						\  ############################################################  openida_SOURCES = 						\ +	configuration.h configuration.c		\  	dlg_sections.h dlg_sections.c		\ -	editor.c							\ +	editor.h editor.c					\ +	main.c								\  	pan_strings.h pan_strings.c			\ +	params.h params.c					\  	project.h project.c					\  	shell.h shell.c						\  	xdg.h xdg.c							\ diff --git a/src/analysis/binary.c b/src/analysis/binary.c index d7d050b..c528e96 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -39,6 +39,7 @@  #include "line_comment.h"  #include "line_prologue.h"  #include "prototype.h" +#include "../common/extstr.h"  #include "../panel/log.h"  #include "../plugins/pglist.h" @@ -160,7 +161,8 @@ openida_binary *load_binary_file(const char *filename)  /******************************************************************************  *                                                                             * -*  Paramètres  : xpathObj = point de lecture de tous les éléments.            * +*  Paramètres  : context = contexte pour les recherches XPath.                * +*                path    = chemin d'accès au noeud XML à lire.                *  *                                                                             *  *  Description : Charge en mémoire le contenu d'un fichier à partir d'XML.    *  *                                                                             * @@ -170,20 +172,69 @@ openida_binary *load_binary_file(const char *filename)  *                                                                             *  ******************************************************************************/ -openida_binary *load_binary_file_from_xml(xmlXPathObjectPtr xpathObj) +openida_binary *g_binary_file_new_from_xml(xmlXPathContextPtr context, const char *path)  {      openida_binary *result;                 /* Adresse à retourner         */ +    size_t access_len;                      /* Taille d'un chemin interne  */ +    char *access;                           /* Chemin pour une sous-config.*/ +    char *filename;                         /* Chemin du binaire à charger */ -    int i; +    result = NULL; -    result = (openida_binary *)calloc(1, sizeof(openida_binary)); +    /* Chemin du fichier à retrouver */ + +    access_len = strlen(path) + strlen("/Filename") + 1; + +    access = calloc(access_len, sizeof(char)); +    snprintf(access, access_len, "%s/Filename", path); + +    filename = get_node_text_value(context, access); + +    free(access); + +    /* Chargement */ + +    if (filename != NULL) +    { +        result = load_binary_file(filename); +        free(filename); +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : binary  = élément binaire à traiter.                         * +*                xdoc    = structure XML en cours d'édition.                  * +*                context = contexte à utiliser pour les recherches.           * +*                path    = chemin d'accès réservé au binaire.                 * +*                                                                             * +*  Description : Ecrit une sauvegarde du binaire dans un fichier XML.         * +*                                                                             * +*  Retour      : true si l'opération a bien tourné, false sinon.              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    for (i = 0; i < XPATH_OBJ_NODES_COUNT(xpathObj); i++) -        if (xmlStrEqual(NODE_FROM_PATH_OBJ(xpathObj, i)->name, BAD_CAST "Filename")) -            result->filename = qck_get_node_text_value(NODE_FROM_PATH_OBJ(xpathObj, i)); +bool g_openida_binary_save(const openida_binary *binary, xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +{ +    bool result;                            /* Bilan à faire remonter      */ +    char *access;                           /* Chemin d'accès à un élément */ + +    result = true; + +    /* Nom du fichier associé */ +    access = strdup(path); +    access = stradd(access, "/Filename"); +    result &= add_content_to_node(xdoc, context, access, binary->filename); +    free(access);      return result; @@ -332,99 +383,6 @@ GRenderingLine *get_openida_binary_lines(const openida_binary *binary) -/****************************************************************************** -*                                                                             * -*  Paramètres  : xpathCtx = contexte à utiliser pour mener les parcours.      * -*                base     = première partie de l'expression XPath d'accès.    * -*                index    = indice de la élément dans la liste des voisins.   * -*                                                                             * -*  Description : Lit un élément binaire depuis un fichier XML.                * -*                                                                             * -*  Retour      : Représentation mise en place à libérer de la mémoire.        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -openida_binary *read_openida_binary_from_xml(xmlXPathContextPtr xpathCtx, const char *base, unsigned int index) -{ -    openida_binary *result;                 /* Représentation à retourner  */ -    size_t expr_len;                        /* Taille d'une expression     */ -    char *expr;                             /* Chemin XPath reconstitué    */ -    xmlXPathObjectPtr xpathObj;             /* Cible d'une recherche       */ -    char *value;                            /* Type d'élément rencontré    */ -    size_t sub_expr_len;                    /* Taille d'une expression #2  */ -    char *sub_expr;                         /* Chemin XPath reconstitué #2 */ -    int i;                                  /* Boucle de parcours          */ - -    result = NULL; - -    /* S'occupe en premier lieu du niveau courant */ - -    expr_len = strlen(base) + strlen("/*[position()=") + strlen("4294967295") /* UINT_MAX */ + strlen("]") + 1; - -    expr = (char *)calloc(expr_len, sizeof(char)); -    snprintf(expr, expr_len, "%s/*[position()=%u]", base, index); - -    xpathObj = get_node_xpath_object(xpathCtx, expr); - -    value = qck_get_node_prop_value(NODE_FROM_PATH_OBJ(xpathObj, 0), "type"); - -    xmlXPathFreeObject(xpathObj); - -    if (value == NULL) goto robfx_err1; - -    /* Raffinement au second passage */ - -    sub_expr_len = expr_len + strlen("/*"); -    sub_expr = (char *)calloc(sub_expr_len, sizeof(char)); -    snprintf(sub_expr, sub_expr_len, "%s/*", expr); - -    xpathObj = get_node_xpath_object(xpathCtx, sub_expr); - -    if (strcmp(value, "file") == 0) result = load_binary_file_from_xml(xpathObj); - -    xmlXPathFreeObject(xpathObj); - -    free(sub_expr); - - robfx_err1: - -    free(expr); - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : binary = élément binaire à traiter.                          * -*                writer = rédacteur dédié à l'écriture.                       * -*                                                                             * -*  Description : Ecrit une sauvegarde du binaire dans un fichier XML.         * -*                                                                             * -*  Retour      : true si l'opération a bien tourné, false sinon.              * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool write_openida_binary_to_xml(const openida_binary *binary, xmlTextWriterPtr writer) -{ -    bool result;                            /* Bilan à faire remonter      */ - -    result = open_xml_element(writer, "Binary"); - -    result &= write_xml_attribute(writer, "type", "file"); - -    result &= write_xml_element_with_content(writer, "Filename", "%s", binary->filename); - -    result &= close_xml_element(writer); - -    return result; - -} diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 0c63738..cf47492 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -42,6 +42,12 @@ typedef struct _openida_binary openida_binary;  /* Charge en mémoire le contenu d'un fichier. */  openida_binary *load_binary_file(const char *); +/* Charge en mémoire le contenu d'un fichier à partir d'XML. */ +openida_binary *g_binary_file_new_from_xml(xmlXPathContextPtr, const char *); + +/* Ecrit une sauvegarde du binaire dans un fichier XML. */ +bool g_openida_binary_save(const openida_binary *, xmlDocPtr, xmlXPathContextPtr, const char *); +  /* Décharge de la mémoire le contenu d'un fichier. */  void unload_binary_file(openida_binary *); @@ -65,13 +71,6 @@ GRenderingLine *get_openida_binary_lines(const openida_binary *); -/* Lit un élément binaire depuis un fichier XML. */ -openida_binary *read_openida_binary_from_xml(xmlXPathContextPtr, const char *, unsigned int); - -/* Ecrit une sauvegarde du binaire dans un fichier. */ -bool write_openida_binary_to_xml(const openida_binary *, xmlTextWriterPtr); - - diff --git a/src/common/extstr.c b/src/common/extstr.c index 5b2dfd8..f8e83f2 100644 --- a/src/common/extstr.c +++ b/src/common/extstr.c @@ -184,6 +184,44 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2)  /******************************************************************************  *                                                                             * +*  Paramètres  : str   = chaîne de caractères à traiter.                      * +*                delim = séparateur entre les mots.                           * +*                count = nombre de mots trouvés. [OUT]                        * +*                                                                             * +*  Description : Extrait une liste de mots d'une chaîne.                      * +*                                                                             * +*  Retour      : Tableau construit à libérer de la mémoire.                   * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +char **strtoka(const char *str, const char *delim, size_t *count) +{ +    char **result;                          /* Tableau à retourner         */ +    char *tmp;                              /* Sauvegarde modifiable       */ +    char *word;                             /* Nouveau mot détecté         */ + +    result = NULL; +    *count = 0; + +    tmp = strdup(str); + +    for (word = strtok(tmp, delim); word != NULL; word = strtok(NULL, delim)) +    { +        result = (char **)realloc(result, ++(*count) * sizeof(char *)); +        result[*count - 1] = strdup(word); +    } + +    free(tmp); + +    return result; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : input = chaîne de caractères à traiter.                      *  *                                                                             *  *  Description : S'assure qu'une chaîne de caractères tient sur une ligne.    * diff --git a/src/common/extstr.h b/src/common/extstr.h index 3e27608..80759b5 100644 --- a/src/common/extstr.h +++ b/src/common/extstr.h @@ -25,6 +25,9 @@  #define _COMMON_EXTSTR_H +#include <sys/types.h> + +  /* Complète une chaîne de caractères avec une autre. */  char *stradd(char *str1, const char *str2); @@ -38,6 +41,9 @@ int strrcmp(const char *, const char *);  /* Remplace des éléments d'une chaîne par d'autres. */  char *strrpl(char *, const char *, const char *); +/* Extrait une liste de mots d'une chaîne. */ +char **strtoka(const char *, const char *, size_t *); +  /* S'assure qu'une chaîne de caractères tient sur une ligne. */  char *escape_crlf(char *); diff --git a/src/configuration.c b/src/configuration.c new file mode 100644 index 0000000..f7cdfbe --- /dev/null +++ b/src/configuration.c @@ -0,0 +1,125 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * configuration.c - éléments de configuration du programme + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "configuration.h" + + +#include <malloc.h> +#include <stdlib.h> +#include <string.h> + + +#include "xml.h" +#include "common/extstr.h" + + + + +/* Paramètres de configuration */ +struct _configuration +{ +    config_param *params;                   /* Paramètres à consulter      */ +    unsigned int count;                     /* Quantité de ces paramètres  */ + +    char *filename;                         /* Fichier externe             */ + +    xmlDocPtr xdoc;                         /* Document XML de configurat° */ +    xmlXPathContextPtr context;             /* Contexte de recherche XPath */ + +}; + + + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : name   = désignation de la configuration.                    * +*                params = tableau de paramètres à consulter / mettre à jour.  * +*                count  = taille du tableau en question.                      * +*                                                                             * +*  Description : Charge la configuration principale.                          * +*                                                                             * +*  Retour      : Configuration prête à emploi.                                * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +configuration *load_configuration(const char *name, config_param *params, unsigned int count) +{ +    configuration *result;                  /* Structure à retourner       */ +    char *home;                             /* Répertoire de l'utilisateur */ + +    result = (configuration *)calloc(1, sizeof(configuration)); + +    result->params = params; +    result->count = count; + +    /* FIXME : créer le répertoire, et en XDG */ +    home = strdup(getenv("HOME") != NULL ? getenv("HOME") : ""); +    result->filename = stradd(home, "/.openida/"); +    result->filename = stradd(result->filename, name); +    result->filename = stradd(result->filename, ".xml"); + +    if (!open_xml_file(result->filename, &result->xdoc, &result->context)) +        create_new_xml_file(&result->xdoc, &result->context); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : config = configuration à libérer de la mémoire.              * +*                                                                             * +*  Description : Décharge la configuration principale.                        * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_configuration(configuration *config) +{ +    unsigned int i;                         /* Boucle de parcours          */ + +    printf("Writing '%s'\n", config->filename); + +    for (i = 0; i < config->count; i++) +        switch (1) +        { +            case 1: +                add_content_to_node(config->xdoc, config->context, +                                    config->params[i].path, config->params[i].cur.string); +                break; + +        } + +    save_xml_file(config->xdoc, config->filename); + +    free(config); + +} diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..c86e1e1 --- /dev/null +++ b/src/configuration.h @@ -0,0 +1,59 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * configuration.h - prototypes pour les éléments de configuration du programme + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _CONFIGURATION_H +#define _CONFIGURATION_H + + + +/* Valeurs supportées par les configurations */ +typedef union _config_value +{ +    char *string;                           /* Chaîne de caractère         */ + +} config_value; + +/* Eléments des configurations */ +typedef struct _config_param +{ +    const char *path;                       /* Chemin d'accès XML          */ + +    config_value def;                       /* Valeur par défaut           */ +    config_value cur;                       /* Valeur courante             */ + +} config_param; + + +/* Paramètres de configuration */ +typedef struct _configuration configuration; + + +/* Charge la configuration principale. */ +configuration *load_configuration(const char *, config_param *, unsigned int); + +/* Décharge la configuration principale. */ +void unload_configuration(configuration *); + + + +#endif  /* _CONFIGURATION_H */ diff --git a/src/editor.c b/src/editor.c index ad0373b..2738621 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1,6 +1,6 @@ -/* OpenIDA - Outils de configurations pour le WM Firebox - * editor.c - fichier principal de l'éditeur de configuration +/* OpenIDA - Outil d'analyse de fichiers binaires + * editor.c - fenêtre principale de l'interface graphique   *   * Copyright (C) 2006-2007 Cyrille Bagard   * @@ -22,12 +22,11 @@   */ -#include <locale.h>/* Fonction main() */ -#include <config.h> /* idem */ -#include <stdlib.h> /* ... */ +#include "editor.h" + + -#include <gtk/gtk.h>  /** exemple GTK **/ @@ -47,9 +46,6 @@  #include "gtkext/easygtk.h"  #include "gtkext/gtkbinview.h"  #include "gtkext/gtkdockpanel.h" -#include "format/exe_format.h" -#include "format/mangling/demangler.h" -#include "plugins/pglist.h"  #include "debug/debuggers.h"  #include "panel/panels.h" @@ -74,6 +70,8 @@ GtkWidget *create_editor(void);  void destroy_editor(GtkWidget *, gpointer); +/* Réagit au menu "Fichier -> Ouvrir un projet". */ +void mcb_file_open_project(GtkMenuItem *, gpointer);  /* Réagit au menu "Fichier -> Enregistrer le projet". */  void mcb_file_save_project(GtkMenuItem *, gpointer); @@ -135,72 +133,6 @@ void update_debug_menu_items(GObject *, gboolean); -void open_last_file(GObject *ref); - - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         * -*                argv = arguments de la ligne de commande.                    * -*                                                                             * -*  Description : Point d'entrée du programme.                                 * -*                                                                             * -*  Retour      : EXIT_SUCCESS si le prgm s'est déroulé sans encombres.        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -int main(int argc, char **argv) -{ -    GtkWidget *editor;                      /* Fenêtre graphique           */ - -    setlocale(LC_ALL, ""); -    /* -    bindtextdomain(PACKAGE, LOCALE_DIR); -    textdomain(PACKAGE); -    */ - -    /* init threads */ -    g_thread_init(NULL); -    gdk_threads_init(); - -    /* Initialisation de GTK */ -    gtk_set_locale(); -    gtk_init(&argc, &argv); - -    /* -     * this initialize the library and check potential ABI mismatches -     * between the version it was compiled for and the actual shared -     * library used. -     */ -    /*LIBXML_TEST_VERSION*/ - -    add_pixmap_directory(PACKAGE_DATA_DIR); -    add_pixmap_directory(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "pixmaps"); - -    /* Initialisation du programme */ -    init_all_processors(); -    init_all_demanglers(); -    init_all_exe_formats(); - -    /* Création de l'interface */ -    editor = create_editor(); -    gtk_widget_show(editor); - -    init_all_plugins(G_OBJECT(editor)); - -    open_last_file(G_OBJECT(editor)); - -    gdk_threads_enter(); -    gtk_main(); -    gdk_threads_leave(); - -    return EXIT_SUCCESS; - -} - @@ -301,6 +233,12 @@ GtkWidget *create_editor(void)      menubar = gtk_menu_new();      gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), menubar); +    submenuitem = qck_create_menu_item(NULL, NULL, _("Open project"), G_CALLBACK(mcb_file_open_project), result); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + +    submenuitem = qck_create_menu_separator(); +    gtk_container_add(GTK_CONTAINER(menubar), submenuitem); +      submenuitem = qck_create_menu_item(NULL, NULL, _("Save project"), G_CALLBACK(mcb_file_save_project), result);      gtk_container_add(GTK_CONTAINER(menubar), submenuitem); @@ -422,7 +360,7 @@ GtkWidget *create_editor(void)      load_recent_openida_projects_list(G_OBJECT(result), G_CALLBACK(mcb_open_recent_project)); -    project = /*load_openida_project_from_xml("/tmp/test.oip")*/create_empty_openida_project(); +    project = create_empty_openida_project();      set_current_openida_project(project);      reload_menu_project(G_OBJECT(result)); @@ -615,6 +553,53 @@ void destroy_editor(GtkWidget *widget, gpointer data) + +/****************************************************************************** +*                                                                             * +*  Paramètres  : menuitem = élément de menu sélectionné.                      * +*                data     = adresse de l'espace de référencement global.      * +*                                                                             * +*  Description : Réagit au menu "Fichier -> Ouvrir un projet".                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void mcb_file_open_project(GtkMenuItem *menuitem, gpointer data) +{ +    GtkWidget *dialog;                      /* Boîte à afficher            */ +    gchar *filename;                        /* Nom du fichier à intégrer   */ +    openida_project *project;               /* Projet chargé               */ + +    dialog = gtk_file_chooser_dialog_new (_("Open a project"), GTK_WINDOW(data), +                                          GTK_FILE_CHOOSER_ACTION_OPEN, +                                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, +                                          GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, +                                          NULL); + +    if (gtk_dialog_run(GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) +    { +        filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); + +        project = g_openida_project_new_from_xml(filename); + +        if (project != NULL) +        { +            set_current_openida_project(project); +            display_openida_project(project, G_OBJECT(data)); +        } + +        g_free(filename); + +    } + +    gtk_widget_destroy(dialog); + +} + +  /******************************************************************************  *                                                                             *  *  Paramètres  : menuitem = élément de menu sélectionné.                      * @@ -635,7 +620,7 @@ void mcb_file_save_project(GtkMenuItem *menuitem, gpointer data)      project = get_current_openida_project();      if (has_storing_filename(project)) -        write_openida_project_to_xml(project, NULL); +        g_openida_project_save(project, NULL);      else          mcb_file_save_project_as(menuitem, data); @@ -671,7 +656,7 @@ void mcb_file_save_project_as(GtkMenuItem *menuitem, gpointer data)      {          filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); -        write_openida_project_to_xml(get_current_openida_project(), filename); +        g_openida_project_save(get_current_openida_project(), filename);          g_free(filename); @@ -704,7 +689,7 @@ void mcb_open_recent_project(GtkMenuItem *menuitem, gpointer data)      caption = gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem)))); -    project = load_openida_project_from_xml(caption); +    project = NULL/*load_openida_project_from_xml(caption)*/;      if (project != NULL)      { @@ -1198,70 +1183,3 @@ void update_debug_menu_items(GObject *ref, gboolean stopped)      gtk_widget_set_sensitive(submenuitem, stopped);  } - - - - - - - - - -void open_last_file(GObject *ref) -{ - - -    GtkWidget *scrolledwindow; - - -    GtkWidget *snippet; - - - -    GtkDockPanel *dpanel;                   /* Support de panneaux         */ -    GtkDockItem *ditem;                     /* Panneau avec ses infos.     */ - -    openida_binary *binary; - - -    openida_project *project; - -    GtkWidget *view;                        /* Affichage du code binaire   */ -    GtkBinView *binview;                    /* Afficheur effectif de code  */ - - - -    binary = load_binary_file("/tmp/hello"); - -    if (binary == NULL) -    { -        /* TODO : log ... */ -        return; -    } - - -    project = get_current_openida_project(); - -    attach_binary_to_openida_project(project, binary); - -    view = get_view_for_openida_project_binary(project, binary, BVW_BLOCK, &binview); - -    g_object_set_data(ref, "binview", binview); - - - -    dpanel = GTK_DOCK_PANEL(g_object_get_data(ref, "binpanel")); - -    ditem = gtk_dock_item_new(openida_binary_to_string(binary), view); -    gtk_dock_panel_add_item(dpanel, ditem); - - - - -    g_object_set_data(ref, "current_binary", binary); - - -    reload_symbols_panel_content(get_panel(PNT_SYMBOLS), get_openida_binary_format(binary)); - - -} diff --git a/src/editor.h b/src/editor.h new file mode 100644 index 0000000..1862dbc --- /dev/null +++ b/src/editor.h @@ -0,0 +1,38 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * editor.h - prototypes pour la fenêtre principale de l'interface graphique + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#ifndef _EDITOR_H +#define _EDITOR_H + + +#include <gtk/gtkwidget.h> + + + +/* Construit la fenêtre de l'éditeur. */ +GtkWidget *create_editor(void); + + + +#endif  /* _EDITOR_H */ diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..0d51fa9 --- /dev/null +++ b/src/main.c @@ -0,0 +1,104 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * main.c - fichier d'entrée du programme + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 this program; if not, write to the Free Software + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA + */ + + +#include <config.h> +#include <locale.h> +#include <stdlib.h> +#include <gtk/gtk.h> + + +#include "editor.h" +#include "params.h" +#include "arch/processor.h" +#include "format/exe_format.h" +#include "format/mangling/demangler.h" +#include "gtkext/support.h" +#include "plugins/pglist.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : argc = nombre d'arguments dans la ligne de commande.         * +*                argv = arguments de la ligne de commande.                    * +*                                                                             * +*  Description : Point d'entrée du programme.                                 * +*                                                                             * +*  Retour      : EXIT_SUCCESS si le prgm s'est déroulé sans encombres.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +int main(int argc, char **argv) +{ +    configuration *config;                  /* Configuration principale    */ +    GtkWidget *editor;                      /* Fenêtre graphique           */ + +    config = load_configuration("main", main_params, MPT_COUNT); + +    setlocale(LC_ALL, ""); +    /* +    bindtextdomain(PACKAGE, LOCALE_DIR); +    textdomain(PACKAGE); +    */ + +    /* init threads */ +    g_thread_init(NULL); +    gdk_threads_init(); + +    /* Initialisation de GTK */ +    gtk_set_locale(); +    gtk_init(&argc, &argv); + +    /* +     * this initialize the library and check potential ABI mismatches +     * between the version it was compiled for and the actual shared +     * library used. +     */ +    /*LIBXML_TEST_VERSION*/ + +    add_pixmap_directory(PACKAGE_DATA_DIR); +    add_pixmap_directory(PACKAGE_SOURCE_DIR G_DIR_SEPARATOR_S "pixmaps"); + +    /* Initialisation du programme */ +    init_all_processors(); +    init_all_demanglers(); +    init_all_exe_formats(); + +    /* Création de l'interface */ +    editor = create_editor(); +    gtk_widget_show(editor); + +    init_all_plugins(G_OBJECT(editor)); + +    gdk_threads_enter(); +    gtk_main(); +    gdk_threads_leave(); + +    unload_configuration(config); + +    return EXIT_SUCCESS; + +} diff --git a/src/params.c b/src/params.c new file mode 100644 index 0000000..3b21149 --- /dev/null +++ b/src/params.c @@ -0,0 +1,49 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * params.c - éléments de la configuration principale + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "params.h" + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : config = éventuelle configuration à définir comme principale.* +*                                                                             * +*  Description : Fournit un lien vers la configuration principale.            * +*                                                                             * +*  Retour      : Configuration prête à emploi ou NULL si aucune définie.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +configuration *_get_main_configuration(configuration *config) +{ +    static configuration *result = NULL;    /* Structure à retourner       */ + +    if (config != NULL) +        result = config; + +    return result; + +} diff --git a/src/params.h b/src/params.h new file mode 100644 index 0000000..25e2dcf --- /dev/null +++ b/src/params.h @@ -0,0 +1,74 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * params.h - prototypes pour les éléments de la configuration principale + * + * Copyright (C) 2009 Cyrille Bagard + * + *  This file is part of OpenIDA. + * + *  OpenIDA 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. + * + *  OpenIDA 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 Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _PARAMS_H +#define _PARAMS_H + + +#include "configuration.h" + + +#ifndef NULL +#   define NULL ((void *)0) +#endif + + + +/* Eléments de la configuration principale */ + +typedef enum _MainParamType +{ +    MPT_RECENT_PROJECT_1,                   /* Projet récent numéro 1      */ +    MPT_RECENT_PROJECT_2,                   /* Projet récent numéro 2      */ +    MPT_RECENT_PROJECT_3,                   /* Projet récent numéro 3      */ +    MPT_RECENT_PROJECT_4,                   /* Projet récent numéro 4      */ +    MPT_RECENT_PROJECT_5,                   /* Projet récent numéro 5      */ +    MPT_RECENT_PROJECT_6,                   /* Projet récent numéro 6      */ +    MPT_RECENT_PROJECT_7,                   /* Projet récent numéro 7      */ + +    MPT_COUNT + +} MainParamType; + +static config_param main_params[MPT_COUNT] = { + +    [MPT_RECENT_PROJECT_1] = { "/OpenIDA/Recents/Project1", NULL, NULL }, +    [MPT_RECENT_PROJECT_2] = { "/OpenIDA/Recents/Project2", NULL, NULL }, +    [MPT_RECENT_PROJECT_3] = { "/OpenIDA/Recents/Project3", NULL, NULL }, +    [MPT_RECENT_PROJECT_4] = { "/OpenIDA/Recents/Project4", NULL, NULL }, +    [MPT_RECENT_PROJECT_5] = { "/OpenIDA/Recents/Project5", NULL, NULL }, +    [MPT_RECENT_PROJECT_6] = { "/OpenIDA/Recents/Project6", NULL, NULL }, +    [MPT_RECENT_PROJECT_7] = { "/OpenIDA/Recents/Project7", NULL, NULL }, + +}; + + +#define get_main_configuration() get_main_configuration(NULL) + + +/* Fournit un lien vers la configuration principale. */ +configuration *_get_main_configuration(configuration *); + + + +#endif  /* _PARAMS_H */ diff --git a/src/project.c b/src/project.c index 9f880a2..9273b94 100644 --- a/src/project.c +++ b/src/project.c @@ -26,6 +26,7 @@  #include <dirent.h>  #include <malloc.h> +#include <stdio.h>  #include <string.h>  #include <unistd.h> @@ -34,7 +35,9 @@  #include "xml.h"  #include "gtkext/easygtk.h"  #include "gtkext/gtkblockview.h" +#include "gtkext/gtkdockpanel.h"  #include "gtkext/gtkgraphview.h" +#include "panel/panels.h" @@ -226,50 +229,108 @@ openida_project *create_empty_openida_project(void)  *                                                                             *  ******************************************************************************/ -openida_project *load_openida_project_from_xml(const char *filename) +openida_project *g_openida_project_new_from_xml(const char *filename)  {      openida_project *result;                /* Adresse à retourner         */ -    xmlDoc *xdoc;                           /* Structure XML chargée       */ -    xmlNode *xroot;                         /* Noeud premier de la def.    */ -    xmlXPathContextPtr xpathCtx;            /* Contexte pour les XPath     */ -    xmlXPathObjectPtr xpathObj;             /* Cible d'une recherche       */ +    xmlDocPtr xdoc;                         /* Structure XML chargée       */ +    xmlXPathContextPtr context;             /* Contexte pour les XPath     */ +    xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */      unsigned int i;                         /* Boucle de parcours          */ +    size_t access_len;                      /* Taille d'un chemin interne  */ +    char *access;                           /* Chemin pour une sous-config.*/      openida_binary *binary;                 /* Représentation à intégrer   */ -    if (!open_xml_file(filename, &xdoc, &xroot, &xpathCtx)) return NULL; +    if (!open_xml_file(filename, &xdoc, &context)) return NULL;      result = (openida_project *)calloc(1, sizeof(openida_project)); +    /* Chargement des éléments binaires attachés */ +    xobject = get_node_xpath_object(context, "/OpenIDAProject/Binaries/Binary"); -    xpathObj = get_node_xpath_object(xpathCtx, "/OpenIDAProject/Binaries/*"); +    for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++) +    { +        access_len = strlen("/OpenIDAProject/Binaries/Binary[position()=") +            + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1; -    printf("nodes :: %d\n", XPATH_OBJ_NODES_COUNT(xpathObj)); +        access = calloc(access_len, sizeof(char)); +        snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%u]", i + 1); -    for (i = 0; i < XPATH_OBJ_NODES_COUNT(xpathObj); i++) -    { -        binary = read_openida_binary_from_xml(xpathCtx, "/OpenIDAProject/Binaries", i + 1); +        binary = g_binary_file_new_from_xml(context, access); + +        free(access);          if (binary != NULL)              attach_binary_to_openida_project(result, binary);      } -    if(xpathObj != NULL) -        xmlXPathFreeObject(xpathObj); +    if(xobject != NULL) +        xmlXPathFreeObject(xobject); + +    /* Fin du chargement */ + +    close_xml_file(xdoc, context); + +    return result; + +} + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project  = project à sauvegarder.                            * +*                filename = nom de fichier à utiliser ou NULL pour l'existant.* +*                                                                             * +*  Description : Procède à l'enregistrement d'un projet donné.                * +*                                                                             * +*  Retour      : true si l'enregistrement s'est déroule sans encombre.        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +bool g_openida_project_save(openida_project *project, const char *filename) +{ +    bool result;                            /* Bilan à retourner           */ +    xmlDocPtr xdoc;                         /* Document XML à créer        */ +    xmlXPathContextPtr context;             /* Contexte pour les recherches*/ +    size_t i;                               /* Boucle de parcours          */ +    size_t access_len;                      /* Taille d'un chemin interne  */ +    char *access;                           /* Chemin pour une sous-config.*/ +    result = create_new_xml_file(&xdoc, &context); +    result &= (ensure_node_exist(xdoc, context, "/OpenIDAProject") != NULL); +    /* Enregistrement des éléments binaires attachés */ +    for (i = 0; i < project->binaries_count && result; i++) +    { +        access_len = strlen("/OpenIDAProject/Binaries/Binary[position()=") +            + strlen("4294967295" /* UINT_MAX */) + strlen("]") + 1; +        access = calloc(access_len, sizeof(char)); +        snprintf(access, access_len, "/OpenIDAProject/Binaries/Binary[position()=%u]", i + 1); -    xmlXPathFreeContext(xpathCtx); -    xmlFreeDoc(xdoc); -    xmlCleanupParser(); +        result = g_openida_binary_save(project->binaries[i]->binary, xdoc, context, access); +        free(access); +    } + +    /* Sauvegarde finale */ + +    result &= save_xml_file(xdoc, filename); + +    if (result) +    { +        if (project->filename != NULL) free(project->filename); +        project->filename = strdup(filename); + +    } + +    close_xml_file(xdoc, context);      return result; @@ -318,55 +379,6 @@ bool has_storing_filename(const openida_project *project)  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : project  = project à sauvegarder.                            * -*                filename = nom de fichier à utiliser ou NULL pour l'existant.* -*                                                                             * -*  Description : Procède à l'enregistrement d'un projet donné.                * -*                                                                             * -*  Retour      : true si l'enregistrement s'est déroule sans encombre.        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool write_openida_project_to_xml(openida_project *project, const char *filename) -{ -    bool result;                            /* Bilan à faire remonter      */ -    xmlTextWriterPtr writer;                /* Rédacteur pour la sortie XML*/ -    size_t i;                               /* Boucle de parcours          */ - -    writer = start_writing_xml_file(filename); - -    result = open_xml_element(writer, "OpenIDAProject"); - -    /* Enregistrement des éléments binaires attachés */ - -    result &= open_xml_element(writer, "Binaries"); - -    for (i = 0; i < project->binaries_count && result; i++) -        write_openida_binary_to_xml(project->binaries[i], writer); - -    result &= close_xml_element(writer); - -    result &= close_xml_element(writer); - -    result &= end_writing_xml_file(writer); - -    if (result) -    { -        if (project->filename != NULL) free(project->filename); -        project->filename = strdup(filename); -    } - -    return result; - -} - - - - @@ -568,3 +580,51 @@ void load_recent_openida_projects_list(GObject *ref, GCallback *func)      gtk_widget_set_sensitive(menuitem, one_entry);  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = projet dont le contenu est à afficher.             * +*                func    = fonction à appeler lors d'un clic sur les menus.   * +*                                                                             * +*  Description : Met en place un projet à l'écran.                            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void display_openida_project(const openida_project *project, GObject *ref) +{ +    GtkDockPanel *dpanel;                   /* Support de panneaux         */ +    size_t i;                               /* Boucle de parcours          */ +    openida_binary *binary; +    GtkWidget *view;                        /* Affichage du code binaire   */ +    GtkDockItem *ditem;                     /* Panneau avec ses infos.     */ + +    dpanel = GTK_DOCK_PANEL(g_object_get_data(ref, "binpanel")); + +    for (i = 0; i < project->binaries_count; i++) +    { +        binary = project->binaries[i]->binary; + +        view = get_loaded_binary_view(project->binaries[i], BVW_BLOCK); + +        ditem = gtk_dock_item_new(openida_binary_to_string(binary), view); +        gtk_dock_panel_add_item(dpanel, ditem); + +    } + + +    if (i > 0) +    { +        g_object_set_data(ref, "current_binary", binary); + + +        reload_symbols_panel_content(get_panel(PNT_SYMBOLS), get_openida_binary_format(binary)); + +    } + + +} diff --git a/src/project.h b/src/project.h index d05ab5b..80b9507 100644 --- a/src/project.h +++ b/src/project.h @@ -61,7 +61,10 @@ openida_project *_get_current_openida_project(openida_project *);  openida_project *create_empty_openida_project(void);  /* Crée un projet à partir du contenu XML d'un fichier. */ -openida_project *load_openida_project_from_xml(const char *); +openida_project *g_openida_project_new_from_xml(const char *); + +/* Procède à l'enregistrement d'un projet donné. */ +bool g_openida_project_save(openida_project *, const char *);  /* Ferme un projet et libère la mémoire associée. */  void close_openida_project(openida_project *); @@ -71,10 +74,6 @@ bool has_storing_filename(const openida_project *); -/* Procède à l'enregistrement d'un projet donné. */ -bool write_openida_project_to_xml(openida_project *, const char *); - -  /* Attache un fichier donné à un projet donné. */  void attach_binary_to_openida_project(openida_project *, openida_binary *); @@ -98,9 +97,8 @@ const openida_binary **get_openida_project_binaries(const openida_project *, siz  /* Met en place les menus rechargeant les projets récents. */  void load_recent_openida_projects_list(GObject *, GCallback *); - - - +/* Met en place un projet à l'écran. */ +void display_openida_project(const openida_project *, GObject *); @@ -29,6 +29,9 @@  #include <string.h> +#include "common/extstr.h" + +  #ifdef DEBUG  #   define XML_LOG fprintf  #else @@ -37,6 +40,88 @@ +/****************************************************************************** +*                                                                             * +*  Paramètres  : filename = nom du fichier à ouvrir.                          * +*                xdoc     = structure XML chargée. [OUT]                      * +*                context  = contexte à utiliser pour les recherches. [OUT]    * +*                                                                             * +*  Description : Crée un nouveau fichier XML.                                 * +*                                                                             * +*  Retour      : true si l'opération a pu s'effectuer, false sinon.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool create_new_xml_file(xmlDocPtr *xdoc, xmlXPathContextPtr *context) +{ +    *xdoc = xmlNewDoc(BAD_CAST "1.0"); + +    if (*xdoc == NULL) +        return false; + +    *context = xmlXPathNewContext(*xdoc); + +    if (*context == NULL) +    { +        xmlFreeDoc(*xdoc); +        return false; +    } + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : xdoc     = structure XML chargée.                            * +*                filename = nom du fichier à remplir.                         * +*                                                                             * +*  Description : Sauvegarde une structure XML dans un fichier.                * +*                                                                             * +*  Retour      : true si l'opération a pu s'effectuer, false sinon.           * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool save_xml_file(xmlDocPtr xdoc, const char *filename) +{ +    int ret;                                /* Bilan de l'appel            */ + +    ret = xmlSaveFormatFileEnc(filename, xdoc, "UTF-8", 1); + +    return (ret != -1); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : xdoc     = structure XML chargée à supprimer.                * +*                context  = contexte utilisé pour les recherches.             * +*                                                                             * +*  Description : Ferme une structure XML.                                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void close_xml_file(xmlDocPtr xdoc, xmlXPathContextPtr context) +{ +    xmlXPathFreeContext(context); +    xmlFreeDoc(xdoc); + +    xmlCleanupParser(); + +} + + +  /* ---------------------------------------------------------------------------------- */  /*                       OPERATIONS DE LECTURE D'UN FICHIER XML                       */  /* ---------------------------------------------------------------------------------- */ @@ -46,7 +131,6 @@  *                                                                             *  *  Paramètres  : filename = nom du fichier à ouvrir.                          *  *                xdoc     = structure XML chargée. [OUT]                      * -*                xroot    = noeud premier de l'ensemble des définitions.[OUT] *  *                xpathCtx = contexte à utiliser pour les recherches. [OUT]    *  *                                                                             *  *  Description : Ouvre un fichier XML de façon encadrée.                      * @@ -57,7 +141,7 @@  *                                                                             *  ******************************************************************************/ -gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlNode **xroot, xmlXPathContextPtr *xpathCtx) +gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlXPathContextPtr *xpathCtx)  {      *xdoc = xmlParseFile(filename); @@ -67,15 +151,6 @@ gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlNode **xroot, xml          return FALSE;      } -    *xroot = xmlDocGetRootElement(*xdoc); - -    if (*xroot == NULL) -    { -        XML_LOG(stderr, "Can not access the root node in '%s'\n", filename); -        xmlFreeDoc(*xdoc); -        return FALSE; -    } -      *xpathCtx = xmlXPathNewContext(*xdoc);      if (*xpathCtx == NULL) @@ -572,3 +647,163 @@ bool write_xml_content(xmlTextWriterPtr writer, const char *format, ...)      return (retval >= 0);  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                       OPERATIONS D'ECRITURE D'UN FICHIER XML                       */ +/* ---------------------------------------------------------------------------------- */ + + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : context = contexte à utiliser pour les recherches.           * +*                path    = chemin d'accès au noeud visé.                      * +*                                                                             * +*  Description : Fournit le premier noeud correspondant à un chemin XPath.    * +*                                                                             * +*  Retour      : Adresse du noeud trouvé ou NULL en cas d'échec.              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +xmlNodePtr get_node_from_xpath(xmlXPathContextPtr context, const char *path) +{ +    xmlNodePtr result;                      /* Noeud trouvé à renvoyer     */ +    xmlXPathObjectPtr xobject;              /* Point de départ XML         */ + +    result = NULL; + +    xobject = get_node_xpath_object(context, path); +    if (xobject == NULL) return NULL; + +    if (xobject->nodesetval->nodeNr > 0) +        result = xobject->nodesetval->nodeTab[0]; + +    xmlXPathFreeObject(xobject); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : xdoc    = structure XML chargée.                             * +*                context = contexte à utiliser pour les recherches.           * +*                path    = chemin d'accès au noeud visé.                      * +*                                                                             * +*  Description : S'assure qu'un noeud donné est bien présent dans le document.* +*                                                                             * +*  Retour      : Noeud en question ou NULL en cas d'échec à la création.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +xmlNodePtr ensure_node_exist(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +{ +    xmlNodePtr result;                      /* Noeud à retourner           */ +    char **levels;                          /* Niveaux dans le chemin      */ +    size_t levels_count;                    /* Nombre de ces niveaux       */ +    xmlNodePtr last;                        /* Dernier noeud valide        */ +    size_t i;                               /* Boucle de parcours #1       */ +    char *iter_path;                        /* Chamin d'accès pour le test */ +    size_t j;                               /* Boucle de parcours #2       */ +    xmlNodePtr iter;                        /* Test d'accès à un noeud     */ +    char *cond;                             /* Marque de condition ('[')   */ + +    result = get_node_from_xpath(context, path); + +    if (result == NULL) +    { +        levels = strtoka(path, "/", &levels_count); + +        /* Recherche la racine valide la plus haute */ + +        last = xmlDocGetRootElement(xdoc); + +        for (i = 0; i < levels_count && last != NULL; i++) +        { +            iter_path = strdup(""); + +            for (j = 0; j <= i; j++) +            { +                iter_path = stradd(iter_path, "/"); +                iter_path = stradd(iter_path, levels[j]); +            } + +            iter = get_node_from_xpath(context, iter_path); + +            if (iter == NULL) break; +            else last = iter; + +        } + +        /* Inscription des noeuds restants */ + +        if (last == NULL) +        { +            last = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i++], NULL); +            xmlDocSetRootElement(xdoc, last); + +            if (i == levels_count) +                result = last; + +        } + +        for ( ; i < levels_count && last != NULL; i++) +        { +            cond = strchr(levels[i], '['); +            if (cond != NULL) *cond = '\0'; + +            result = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i], NULL); +            result = xmlAddChild(last, result); +            last = result; +        } + +        /* Libération de la mémoire */ + +        for (i = 0; i < levels_count; i++) +            free(levels[i]); + +        free(levels); + +    } + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : xdoc    = structure XML chargée.                             * +*                context = contexte à utiliser pour les recherches.           * +*                path    = chemin d'accès au noeud visé.                      * +*                content = texte à inscrire en contenu.                       * +*                                                                             * +*  Description : S'assure qu'un noeud donné est bien présent dans le document.* +*                                                                             * +*  Retour      : true en cas de succès, false sinon.                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool add_content_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *content) +{ +    xmlNodePtr node;                        /* Noeud à modifier            */ + +    if (content == NULL) return true; + +    node = ensure_node_exist(xdoc, context, path); +    if (node == NULL) return false; + +    xmlNodeSetContent(node, content); + +    return true; + +} @@ -34,6 +34,18 @@ + +/* Crée un nouveau fichier XML. */ +bool create_new_xml_file(xmlDocPtr *, xmlXPathContextPtr *); + +/* Sauvegarde une structure XML dans un fichier. */ +bool save_xml_file(xmlDocPtr, const char *); + +/* Ferme une structure XML. */ +void close_xml_file(xmlDocPtr, xmlXPathContextPtr); + + +  /* --------------------- OPERATIONS DE LECTURE D'UN FICHIER XML --------------------- */ @@ -42,7 +54,7 @@  /* Ouvre un fichier XML de façon encadrée. */ -gboolean open_xml_file(const char *filename, xmlDoc **, xmlNode **, xmlXPathContextPtr *); +gboolean open_xml_file(const char *filename, xmlDoc **, xmlXPathContextPtr *);  /* Obtient de façon encadrée l'accès à un noeud défini. */  xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr, const char *); @@ -93,4 +105,18 @@ bool write_xml_content(xmlTextWriterPtr, const char *, ...); +/* --------------------- OPERATIONS D'ECRITURE D'UN FICHIER XML --------------------- */ + + +/* Fournit le premier noeud correspondant à un chemin XPath. */ +xmlNodePtr get_node_from_xpath(xmlXPathContextPtr, const char *); + +/* S'assure qu'un noeud donné est bien présent dans le document. */ +xmlNodePtr ensure_node_exist(xmlDocPtr, xmlXPathContextPtr, const char *); + +/* S'assure qu'un noeud donné est bien présent dans le document. */ +bool add_content_to_node(xmlDocPtr, xmlXPathContextPtr, const char *, const char *); + + +  #endif  /* _XML_H */  | 
