From c9465acd65e197e48da8648eb8d1ef602d6772ed Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 12 Jul 2009 15:26:23 +0000 Subject: Read and saved projects from and into XML files. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@91 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 44 ++++++++- src/Makefile.am | 5 +- src/analysis/binary.c | 158 ++++++++++++------------------- src/analysis/binary.h | 13 ++- src/common/extstr.c | 38 ++++++++ src/common/extstr.h | 6 ++ src/configuration.c | 125 ++++++++++++++++++++++++ src/configuration.h | 59 ++++++++++++ src/editor.c | 210 +++++++++++++---------------------------- src/editor.h | 38 ++++++++ src/main.c | 104 ++++++++++++++++++++ src/params.c | 49 ++++++++++ src/params.h | 74 +++++++++++++++ src/project.c | 190 ++++++++++++++++++++++++------------- src/project.h | 14 ++- src/xml.c | 257 +++++++++++++++++++++++++++++++++++++++++++++++--- src/xml.h | 28 +++++- 17 files changed, 1072 insertions(+), 340 deletions(-) create mode 100644 src/configuration.c create mode 100644 src/configuration.h create mode 100644 src/editor.h create mode 100644 src/main.c create mode 100644 src/params.c create mode 100644 src/params.h diff --git a/ChangeLog b/ChangeLog index bcbc54f..701095d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +09-07-12 Cyrille Bagard + + * src/analysis/binary.c: + * src/analysis/binary.h: + Read and save binaries from and into XML files. Remove the previous code. + + * src/common/extstr.c: + * src/common/extstr.h: + Build a list of words from a string. + + * src/configuration.c: + * src/configuration.h: + Manage basic and generic configurations. + + * src/editor.c: + Clean the code and update calls. Create an 'Open Project' menu item. + + * src/editor.h: + New entry: create a header for editor.c + + * src/main.c: + New entry: move code from editor.c here. Load and save the main + configuration. + + * src/Makefile.am: + Add the configuration.[ch], editor.h, main.c and params.[ch] to + openida_SOURCES. + + * src/params.c: + * src/params.h: + New entries: define the main configuration of the program. + + * src/project.c: + * src/project.h: + Read and save projects from and into XML files. Remove the previous code. + Display the content of a loaded project onto the GUI. + + * src/xml.c: + * src/xml.h: + Reorganize the interactions with the libxml2 : clean the code and + provide new functions to write XML files. These files need to be cleaned. + 09-07-03 Cyrille Bagard * src/graph/layout.c: @@ -350,7 +392,7 @@ Remove the useless AdressMode field. * src/Makefile.am: - Remove the pan_symbols.[ch] from openida_SOURCES. + Remove the pan_symbols.[ch] files from openida_SOURCES. * src/panel/log.c: Fix some compilation warnings. 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 + + /* 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 . + */ + + +#include "configuration.h" + + +#include +#include +#include + + +#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 . + */ + + +#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 /* Fonction main() */ -#include /* idem */ -#include /* ... */ +#include "editor.h" + + -#include /** 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 + + + +/* 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 +#include +#include +#include + + +#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 . + */ + + +#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 . + */ + + +#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 #include +#include #include #include @@ -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 *); diff --git a/src/xml.c b/src/xml.c index baa4eb2..19003eb 100644 --- a/src/xml.c +++ b/src/xml.c @@ -29,6 +29,9 @@ #include +#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; + +} diff --git a/src/xml.h b/src/xml.h index 2d35cc6..82e2578 100644 --- a/src/xml.h +++ b/src/xml.h @@ -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 */ -- cgit v0.11.2-87-g4458