summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog44
-rw-r--r--src/Makefile.am5
-rw-r--r--src/analysis/binary.c158
-rw-r--r--src/analysis/binary.h13
-rw-r--r--src/common/extstr.c38
-rw-r--r--src/common/extstr.h6
-rw-r--r--src/configuration.c125
-rw-r--r--src/configuration.h59
-rw-r--r--src/editor.c210
-rw-r--r--src/editor.h38
-rw-r--r--src/main.c104
-rw-r--r--src/params.c49
-rw-r--r--src/params.h74
-rw-r--r--src/project.c190
-rw-r--r--src/project.h14
-rw-r--r--src/xml.c257
-rw-r--r--src/xml.h28
17 files changed, 1072 insertions, 340 deletions
diff --git a/ChangeLog b/ChangeLog
index bcbc54f..701095d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+09-07-12 Cyrille Bagard <nocbos@gmail.com>
+
+ * 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 <nocbos@gmail.com>
* 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 <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 *);
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 <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;
+
+}
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 */