From db863244b804cbf4c06399f7c6f8241d91c9ee9b Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 10 Jul 2014 14:47:37 +0000 Subject: Fully rewritten the core configuration system. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@381 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 128 ++- configure.ac | 2 + plugins/pychrysa/Makefile.am | 8 +- plugins/pychrysa/analysis/binaries/file.c | 4 +- plugins/pychrysa/core/Makefile.am | 15 + plugins/pychrysa/core/module.c | 91 +++ plugins/pychrysa/core/module.h | 39 + plugins/pychrysa/core/params.c | 178 +++++ plugins/pychrysa/core/params.h | 42 + plugins/pychrysa/glibext/Makefile.am | 8 +- plugins/pychrysa/glibext/configuration.c | 1214 ++++++++++++++++++++++++++++ plugins/pychrysa/glibext/configuration.h | 66 ++ plugins/pychrysa/glibext/module.c | 49 +- plugins/pychrysa/glibext/module.h | 6 +- plugins/pychrysa/pychrysa.c | 16 +- src/Makefile.am | 19 +- src/common/extstr.c | 24 +- src/common/fnv1a.c | 12 +- src/common/fnv1a.h | 2 +- src/common/io.c | 44 ++ src/common/io.h | 6 + src/common/xml.c | 15 +- src/configuration.c | 427 ---------- src/configuration.h | 96 --- src/core/Makefile.am | 15 + src/core/core.c | 76 ++ src/core/core.h | 40 + src/core/params.c | 112 +++ src/core/params.h | 58 ++ src/editor.c | 8 +- src/format/mangling/itanium/context.c | 2 +- src/glibext/Makefile.am | 1 + src/glibext/configuration.c | 1232 +++++++++++++++++++++++++++++ src/glibext/configuration.h | 199 +++++ src/glibext/gbuffersegment.c | 2 +- src/gtkext/gtkdockstation.c | 10 +- src/gui/panels/Makefile.am | 1 + src/gui/panels/panel.c | 4 + src/gui/panels/regedit.c | 1071 +++++++++++++++++++++++++ src/gui/panels/regedit.h | 65 ++ src/gui/panels/symbols.c | 4 +- src/main.c | 25 +- src/params.c | 61 -- src/params.h | 61 -- src/project.c | 10 +- 45 files changed, 4834 insertions(+), 734 deletions(-) create mode 100644 plugins/pychrysa/core/Makefile.am create mode 100644 plugins/pychrysa/core/module.c create mode 100644 plugins/pychrysa/core/module.h create mode 100644 plugins/pychrysa/core/params.c create mode 100644 plugins/pychrysa/core/params.h create mode 100644 plugins/pychrysa/glibext/configuration.c create mode 100644 plugins/pychrysa/glibext/configuration.h delete mode 100644 src/configuration.c delete mode 100644 src/configuration.h create mode 100755 src/core/Makefile.am create mode 100644 src/core/core.c create mode 100644 src/core/core.h create mode 100644 src/core/params.c create mode 100644 src/core/params.h create mode 100644 src/glibext/configuration.c create mode 100644 src/glibext/configuration.h create mode 100644 src/gui/panels/regedit.c create mode 100644 src/gui/panels/regedit.h delete mode 100644 src/params.c delete mode 100644 src/params.h diff --git a/ChangeLog b/ChangeLog index 470aef1..68d7c81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,109 @@ +14-07-10 Cyrille Bagard + + * configure.ac: + Add the new Makefiles from the 'plugins/pychrysa/core' and 'src/core' + directories to AC_CONFIG_FILES. + + * plugins/pychrysa/analysis/binaries/file.c: + Typo. Clean the code. + + * plugins/pychrysa/core/Makefile.am: + * plugins/pychrysa/core/module.c: + * plugins/pychrysa/core/module.h: + * plugins/pychrysa/core/params.c: + * plugins/pychrysa/core/params.h: + New entries: add support for items found in 'src/core/'. + + * plugins/pychrysa/glibext/configuration.c: + * plugins/pychrysa/glibext/configuration.h: + New entries: implement configuration in Python. + + * plugins/pychrysa/glibext/Makefile.am: + Define a new libpychrysaglibext.la. + + * plugins/pychrysa/glibext/module.c: + * plugins/pychrysa/glibext/module.h: + Update code. + + * plugins/pychrysa/Makefile.am: + Add 'libpychrysacore.la' and 'libpychrysaglibext.la' to + pychrysalide_la_LIBADD, '-lchrysacore' to pychrysalide_la_LDFLAGS + and 'core' to SUBDIRS. + + * plugins/pychrysa/pychrysa.c: + Update code. Load all basic components. + + * src/common/extstr.c: + Do not rely on regex for replacements anymore. Thus, searching for a + simple dot works. + + * src/common/fnv1a.c: + * src/common/fnv1a.h: + Extend the comparisons by return an integer instead of a boolean. + + * src/common/io.c: + * src/common/io.h: + Provide a way to create the directories needed for an access path. + + * src/common/xml.c: + Fix a kind of bug: make a difference between "no node" and "no value". + + * src/configuration.c: + * src/configuration.h: + Moved entries: see the 'src/glibext/configuration.[ch]' files. + + * src/core/core.c: + * src/core/core.h: + * src/core/Makefile.am: + * src/core/params.c: + * src/core/params.h: + New entries: centralize all core features for isolated plugins (for instance, Python). + + * src/editor.c: + Fix bugs: check if there is a defined project or not when exiting. + + * src/format/mangling/itanium/context.c: + Update code when calling cmp_fnv_64a(). + + * src/glibext/configuration.c: + * src/glibext/configuration.h: + New entries: fully rewrite the core configuration system. + + * src/glibext/gbuffersegment.c: + Update code when calling cmp_fnv_64a(). + + * src/glibext/Makefile.am: + Add the 'configuration.[ch]' files to libglibext_la_SOURCES. + + * src/gtkext/gtkdockstation.c: + Restore the old behavior with the main configuration. + + * src/gui/panels/Makefile.am: + Add the 'regedit.[ch]' to libguipanels_la_SOURCES. + + * src/gui/panels/panel.c: + Load and show the configuration panel ; this has to be updated. + + * src/gui/panels/regedit.c: + * src/gui/panels/regedit.h: + New entries: provide a graphical panel to edit the main configuration. + + * src/gui/panels/symbols.c: + Typo. + + * src/main.c: + Update code. + + * src/Makefile.am: + Inclue the core shared object. + + * src/params.c + * src/params.h: + Move entries: see the 'src/core/params.[ch]' files. + + * src/project.c: + Update code.< + 14-06-25 Cyrille Bagard * plugins/pychrysa/analysis/binaries/file.c: @@ -982,7 +1088,7 @@ 14-03-20 Cyrille Bagard * configure.ac: - Include the libarchive and SQLite to the project. Add the new Makfile + Include the libarchive and SQLite to the project. Add the new Makefile from the 'src/analysis/db' directory to AC_CONFIG_FILES. * src/analysis/binary.c: @@ -1305,7 +1411,7 @@ 13-06-14 Cyrille Bagard * configure.ac: - Add the new Makfile from the 'plugins/pychrysa/format/elf' directory + Add the new Makefile from the 'plugins/pychrysa/format/elf' directory to AC_CONFIG_FILES. * plugins/pychrysa/format/elf/elf.c: @@ -1452,7 +1558,7 @@ 13-03-19 Cyrille Bagard * configure.ac: - Add the new Makfiles from the 'src/gtkext/graph/nodes' directories + Add the new Makefiles from the 'src/gtkext/graph/nodes' directories to AC_CONFIG_FILES. * plugins/pychrysa/analysis/blocks/flow.c: @@ -1807,7 +1913,7 @@ 13-01-26 Cyrille Bagard * configure.ac: - Add the new Makfiles from the 'plugins/pychrysa/analysis/blocks' and + Add the new Makefiles from the 'plugins/pychrysa/analysis/blocks' and 'plugins/python/samples' directories to AC_CONFIG_FILES. * plugins/pychrysa/analysis/block.c: @@ -2272,7 +2378,7 @@ 12-12-22 Cyrille Bagard * configure.ac: - Add the new Makfile from the 'plugins/pychrysa/analysis/binaries' + Add the new Makefile from the 'plugins/pychrysa/analysis/binaries' directory to AC_CONFIG_FILES. * plugins/pychrysa/analysis/binaries/file.c: @@ -2397,7 +2503,7 @@ 12-12-18 Cyrille Bagard * configure.ac: - Add the new Makfile from the 'plugins/pychrysa/gtkext directory to + Add the new Makefile from the 'plugins/pychrysa/gtkext directory to AC_CONFIG_FILES. * plugins/pychrysa/glibext/module.c: @@ -2625,7 +2731,7 @@ 12-12-08 Cyrille Bagard * configure.ac: - Add the new Makfile from the 'src/analysis/blocks' directory to + Add the new Makefile from the 'src/analysis/blocks' directory to AC_CONFIG_FILES. * plugins/androhelpers/androhelpers.c: @@ -2884,7 +2990,7 @@ 12-11-19 Cyrille Bagard * configure.ac: - Add the new Makfiles from the 'plugins/androhelpers' and + Add the new Makefiles from the 'plugins/androhelpers' and 'plugins/pychrysa/format/dex' directories to AC_CONFIG_FILES. Remove the old 'plugins/dexresolver' one. @@ -3277,7 +3383,7 @@ 12-10-18 Cyrille Bagard * configure.ac: - Add the new Makfiles from the src/arch/x86/opcodes and + Add the new Makefiles from the src/arch/x86/opcodes and src/arch/x86/operands directories to AC_CONFIG_FILES. * src/arch/dalvik/operands/register.c: @@ -3530,7 +3636,7 @@ 12-10-12 Cyrille Bagard * configure.ac: - Add the new Makfiles from the src/analysis/types directory to + Add the new Makefiles from the src/analysis/types directory to AC_CONFIG_FILES. * plugins/dexresolver/operand.c: @@ -3642,7 +3748,7 @@ 12-09-15 Cyrille Bagard * configure.ac: - Add the new Makfiles from the plugins/pychrysa/gui and + Add the new Makefiles from the plugins/pychrysa/gui and plugins/pychrysa/gui/panels directories to AC_CONFIG_FILES. * plugins/pychrysa/arch/instruction.c: diff --git a/configure.ac b/configure.ac index e318ba4..846cc82 100644 --- a/configure.ac +++ b/configure.ac @@ -276,6 +276,7 @@ AC_CONFIG_FILES([Makefile plugins/pychrysa/analysis/binaries/Makefile plugins/pychrysa/analysis/blocks/Makefile plugins/pychrysa/arch/Makefile + plugins/pychrysa/core/Makefile plugins/pychrysa/debug/Makefile plugins/pychrysa/format/Makefile plugins/pychrysa/format/dex/Makefile @@ -313,6 +314,7 @@ AC_CONFIG_FILES([Makefile src/arch/x86/opcodes/Makefile src/arch/x86/operands/Makefile src/common/Makefile + src/core/Makefile src/debug/Makefile src/debug/jdwp/Makefile src/debug/jdwp/misc/Makefile diff --git a/plugins/pychrysa/Makefile.am b/plugins/pychrysa/Makefile.am index 8664193..8c59c10 100644 --- a/plugins/pychrysa/Makefile.am +++ b/plugins/pychrysa/Makefile.am @@ -27,11 +27,13 @@ pychrysalide_la_SOURCES = \ pychrysalide_la_LIBADD = \ analysis/libpychrysaanalysis.la \ - arch/libpychrysaarch.la + arch/libpychrysaarch.la \ + core/libpychrysacore.la \ + glibext/libpychrysaglibext.la pychrysalide_la_LDFLAGS = -module -avoid-version \ $(LIBPYTHON_LIBS) $(LIBSQLITE_LIBS) $(LIBARCHIVE_LIBS) \ - -L../../src/.libs -lchrysadisass -lchrysagtkext \ + -L../../src/.libs -lchrysadisass -lchrysagtkext -lchrysacore \ -L../../src/plugins/.libs -lplugins @@ -41,4 +43,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) -SUBDIRS = analysis arch debug format glibext gtkext gui +SUBDIRS = analysis arch core debug format glibext gtkext gui diff --git a/plugins/pychrysa/analysis/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c index e5cc2f1..6bf553b 100644 --- a/plugins/pychrysa/analysis/binaries/file.c +++ b/plugins/pychrysa/analysis/binaries/file.c @@ -155,7 +155,7 @@ PyTypeObject *get_python_binary_file_type(void) * * * Paramètres : module = module dont la définition est à compléter. * * * -* Description : Prend en charge l'objet 'pychrysalide.analysis.LoadedBinary'.* +* Description : Prend en charge l'objet 'pychrysalide.analysis.BinaryFile'. * * * * Retour : Bilan de l'opération. * * * @@ -174,7 +174,7 @@ bool register_python_binary_file(PyObject *module) py_binary_file_type->tp_base = get_python_loaded_binary_type(); py_binary_file_type->tp_basicsize = py_binary_file_type->tp_base->tp_basicsize; - if (PyType_Ready(py_binary_file_type) < 0) + if (PyType_Ready(py_binary_file_type) != 0) return false; Py_INCREF(py_binary_file_type); diff --git a/plugins/pychrysa/core/Makefile.am b/plugins/pychrysa/core/Makefile.am new file mode 100644 index 0000000..1ffacf4 --- /dev/null +++ b/plugins/pychrysa/core/Makefile.am @@ -0,0 +1,15 @@ + +noinst_LTLIBRARIES = libpychrysacore.la + +libpychrysacore_la_SOURCES = \ + module.h module.c \ + params.h params.c + + +libpychrysacore_la_LDFLAGS = + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \ + -I../../../src + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pychrysa/core/module.c b/plugins/pychrysa/core/module.c new file mode 100644 index 0000000..489f173 --- /dev/null +++ b/plugins/pychrysa/core/module.c @@ -0,0 +1,91 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.c - intégration du répertoire core en tant que module + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "module.h" + + +#include "params.h" + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute le module 'core' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_core_module_to_python_module(PyObject *super) +{ + bool result; /* Bilan à retourner */ + PyObject *module; /* Sous-module mis en place */ + int ret; /* Bilan d'un appel */ + + static PyModuleDef py_chrysalide_core_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.core", + .m_doc = "Python module for Chrysalide.core", + + .m_size = -1, + + }; + + result = false; + + module = PyModule_Create(&py_chrysalide_core_module); + if (module == NULL) return false; + + ret = PyState_AddModule(super, &py_chrysalide_core_module); + if (ret != 0) goto acmtpm_exit; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.core"); + if (ret != 0) goto acmtpm_exit; + + Py_INCREF(module); + ret = PyModule_AddObject(super, "core", module); + if (ret != 0) goto acmtpm_exit; + + result = true; + + result &= register_python_params(module); + + acmtpm_exit: + + if (!result) + { + printf("something went wrong in %s...\n", __FUNCTION__); + /* ... */ + + } + + return result; + +} diff --git a/plugins/pychrysa/core/module.h b/plugins/pychrysa/core/module.h new file mode 100644 index 0000000..1da57a1 --- /dev/null +++ b/plugins/pychrysa/core/module.h @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * module.h - prototypes pour l'intégration du répertoire core en tant que module + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _PLUGINS_PYCHRYSALIDE_CORE_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_CORE_MODULE_H + + +#include +#include + + + +/* Ajoute le module 'core' au module Python. */ +bool add_core_module_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_CORE_MODULE_H */ diff --git a/plugins/pychrysa/core/params.c b/plugins/pychrysa/core/params.c new file mode 100644 index 0000000..987bca6 --- /dev/null +++ b/plugins/pychrysa/core/params.c @@ -0,0 +1,178 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * params.c - équivalent Python du fichier "core/params.c" + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "params.h" + + +#include + + +#include + + + +/* Fournit la version du programme global. */ +static PyObject *py_params_get_main_configuration(PyObject *, PyObject *); + +/* Définit les constantes pour les paramètres. */ +static bool py_params_define_constants(PyObject *); + + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* args = non utilisé ici. * +* * +* Description : Fournit la version du programme global. * +* * +* Retour : Numéro de révision. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_params_get_main_configuration(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance GLib à retourner */ + GGenConfig *config; /* Configuration à convertir */ + + config = get_main_configuration(); + + result = pygobject_new(G_OBJECT(config)); + Py_XINCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_params_type(void) +{ + static PyMethodDef py_params_methods[] = { + + { "get_main_configuration", py_params_get_main_configuration, + METH_NOARGS | METH_STATIC, + "Give access to the main configuration of Chrysalide." + }, + { NULL } + + }; + + static PyTypeObject py_params_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.core.params", + .tp_basicsize = sizeof(PyObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "Python object for parameters", + + .tp_methods = py_params_methods + + }; + + return &py_params_type; + +} + + +/****************************************************************************** +* * +* Paramètres : dict = dictionnaire à compléter. * +* * +* Description : Définit les constantes pour les paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_params_define_constants(PyObject *dict) +{ + int ret; /* Bilan d'un ajout */ + +#define DEF_STR_CONST(name) \ + ret = PyDict_SetItemString(dict, #name, PyUnicode_FromString(name)); \ + if (ret == -1) return false; + + DEF_STR_CONST(MPK_LAST_PROJECT); + DEF_STR_CONST(MPK_ELLIPSIS_HEADER); + DEF_STR_CONST(MPK_ELLIPSIS_TAB); + DEF_STR_CONST(MPK_KEYBINDINGS_EDIT); + DEF_STR_CONST(MPK_AUTO_SAVE); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.core.params'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_params(PyObject *module) +{ + PyTypeObject *py_params_type; /* Type Python pour 'params' */ + int ret; /* Bilan d'un appel */ + + py_params_type = get_python_params_type(); + + py_params_type->tp_new = PyType_GenericNew; + + if (PyType_Ready(py_params_type) != 0) + return false; + + if (!py_params_define_constants(py_params_type->tp_dict)) + return false; + + Py_INCREF(py_params_type); + ret = PyModule_AddObject(module, "params", (PyObject *)py_params_type); + + return (ret == 0); + +} diff --git a/plugins/pychrysa/core/params.h b/plugins/pychrysa/core/params.h new file mode 100644 index 0000000..23d1db5 --- /dev/null +++ b/plugins/pychrysa/core/params.h @@ -0,0 +1,42 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * params.h - prototypes pour l'équivalent Python du fichier "core/params.h" + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _PLUGINS_PYCHRYSALIDE_CORE_PARAMS_H +#define _PLUGINS_PYCHRYSALIDE_CORE_PARAMS_H + + +#include +#include + + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_params_type(void); + +/* Prend en charge l'objet 'pychrysalide.core.params'. */ +bool register_python_params(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSALIDE_CORE_PARAMS_H */ diff --git a/plugins/pychrysa/glibext/Makefile.am b/plugins/pychrysa/glibext/Makefile.am index 14ab026..8383434 100644 --- a/plugins/pychrysa/glibext/Makefile.am +++ b/plugins/pychrysa/glibext/Makefile.am @@ -1,9 +1,13 @@ noinst_LTLIBRARIES = libpychrysaglibext.la +# libpychrysaglibext_la_SOURCES = \ +# bufferline.h bufferline.c \ +# codebuffer.h codebuffer.c \ +# module.h module.c + libpychrysaglibext_la_SOURCES = \ - bufferline.h bufferline.c \ - codebuffer.h codebuffer.c \ + configuration.h configuration.c \ module.h module.c diff --git a/plugins/pychrysa/glibext/configuration.c b/plugins/pychrysa/glibext/configuration.c new file mode 100644 index 0000000..9820af3 --- /dev/null +++ b/plugins/pychrysa/glibext/configuration.c @@ -0,0 +1,1214 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.c - prototypes pour l'équivalent Python du fichier "glibext/configuration.c" + * + * Copyright (C) 2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "configuration.h" + + +#include + + +#include + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Crée un nouvel objet Python de type 'ConfigParam'. */ +static PyObject *py_config_param_new(PyTypeObject *, PyObject *, PyObject *); + +/* Efface toute valeur courante d'un paramètre de configuration. */ +static PyObject *py_config_param_make_empty(PyObject *, PyObject *); + +/* Réinitialise la valeur d'un paramètre de configuration. */ +static PyObject *py_config_param_reset(PyObject *, PyObject *); + +/* Indique le chemin d'accès utilisé pour un paramètre. */ +static PyObject *py_config_param_get_path(PyObject *, void *); + +/* Indique le type de valeur utilisée par un paramètre. */ +static PyObject *py_config_param_get_type(PyObject *, void *); + +/* Indique le statut d'une valeur utilisée par un paramètre. */ +static PyObject *py_config_param_get_state(PyObject *, void *); + +/* Indique la valeur courante d'un paramètre de configuration. */ +static PyObject *py_config_param_get_value(PyObject *, void *); + +/* Modifie la valeur courante d'un paramètre de configuration. */ +static int py_config_param_set_value(PyObject *, PyObject *, void *); + +/* Définit les constantes pour les paramètres. */ +static bool py_config_param_define_constants(PyObject *); + + + +/* ----------------------------- PARCOURS DE PARAMETRES ----------------------------- */ + + + +typedef struct _pyConfigParamIterator +{ + + PyObject_HEAD + long int m; + long int i; + + + + GGenConfig *config; /* Configuration à parcourir */ + GList *params; /* Liste de paramètres */ + + GList *last; /* Dernier élément retourné */ + +} pyConfigParamIterator; + + + + +/* Prend acte d'un compteur de référence à 0. */ +static void py_config_param_iterator_dealloc(PyObject *); + +/* Fournit un itérateur pour paramètres de configuration. */ +static PyObject *py_config_param_iterator_iter(PyObject *); + +/* Fournit un itérateur pour paramètres de configuration. */ +static PyObject *py_config_param_iterator_next(PyObject *); + +/* Initialise un objet Python de type 'ConfigParamIterator'. */ +static int py_config_param_iterator_init(PyObject *, PyObject *, PyObject *); + + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +/* Crée un nouvel objet Python de type 'GenConfig'. */ +static PyObject *py_generic_config_new(PyTypeObject *, PyObject *, PyObject *); + +/* Lit la configuration depuis un fichier. */ +static PyObject *py_generic_config_read(PyObject *, PyObject *); + +/* Ecrit la configuration dans un fichier. */ +static PyObject *py_generic_config_write(PyObject *, PyObject *); + +/* Retrouve un élément de configuration par son chemin. */ +static PyObject *py_generic_config_search(PyObject *, PyObject *); + +/* Ajoute un paramètre à une configuration. */ +static PyObject *py_generic_config_add(PyObject *, PyObject *); + +/* Retire un paramètre d'une configuration. */ +static PyObject *py_generic_config_delete(PyObject *, PyObject *); + +/* Fournit le chemin d'accès au binaire représenté. */ +static PyObject *py_generic_config_get_filename(PyObject *, void *); + + + +/* ---------------------------------------------------------------------------------- */ +/* ELEMENT DE CONFIGURATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'ConfigParam'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + char *path; /* Accès au paramètre */ + unsigned int ptype; /* Type de paramètre */ + PyObject *value; /* Valeur par défaut éventuelle*/ + int ret; /* Bilan de lecture des args. */ + GCfgParam *param; /* Paramètre mis en place */ + + value = NULL; + + ret = PyArg_ParseTuple(args, "sI|O", &path, &ptype, &value); + if (!ret) Py_RETURN_NONE; + + if (value == NULL || value == Py_None) + param = g_config_param_new_empty(path, ptype); + + else + switch (ptype) + { + case CPT_BOOLEAN: + if (PyBool_Check(value)) + param = g_config_param_new(path, CPT_BOOLEAN, (bool)(value == Py_True)); + else + param = NULL; + break; + + case CPT_INTEGER: + if (PyLong_Check(value)) + param = g_config_param_new(path, CPT_INTEGER, (int)PyLong_AsLong(value)); + else + param = NULL; + break; + + case CPT_STRING: + if (PyUnicode_Check(value)) + param = g_config_param_new(path, CPT_STRING, PyUnicode_DATA(value)); + else + param = NULL; + break; + + default: + param = NULL; + break; + + } + + if (param != NULL) + { + result = pygobject_new(G_OBJECT(param)); + g_object_unref(param); + } + else result = NULL; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* args = non utilisé ici. * +* * +* Description : Efface toute valeur courante d'un paramètre de configuration.* +* * +* Retour : None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_make_empty(PyObject *self, PyObject *args) +{ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + + param = G_CFG_PARAM(pygobject_get(self)); + + g_config_param_make_empty(param); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* args = non utilisé ici. * +* * +* Description : Réinitialise la valeur d'un paramètre de configuration. * +* * +* Retour : None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_reset(PyObject *self, PyObject *args) +{ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + + param = G_CFG_PARAM(pygobject_get(self)); + + g_config_param_reset(param); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* closure = non utilisé ici. * +* * +* Description : Indique le chemin d'accès utilisé pour un paramètre. * +* * +* Retour : Chemin d'accès en Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_get_path(PyObject *self, void *closure) +{ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + const char *path; /* Chemin d'accès à diffuser */ + + param = G_CFG_PARAM(pygobject_get(self)); + path = g_config_param_get_path(param); + + return PyUnicode_FromString(path); + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* closure = non utilisé ici. * +* * +* Description : Indique le type de valeur utilisée par un paramètre. * +* * +* Retour : Type en Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_get_type(PyObject *self, void *closure) +{ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + ConfigParamType type; /* Type de paramètre */ + + param = G_CFG_PARAM(pygobject_get(self)); + type = g_config_param_get_ptype(param); + + return PyLong_FromLong(type); + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* closure = non utilisé ici. * +* * +* Description : Indique le statut d'une valeur utilisée par un paramètre. * +* * +* Retour : Etat en Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_get_state(PyObject *self, void *closure) +{ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + ConfigParamState state; /* Statut de paramètre */ + + param = G_CFG_PARAM(pygobject_get(self)); + state = g_config_param_get_state(param); + + return PyLong_FromLong(state); + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* closure = non utilisé ici. * +* * +* Description : Indique la valeur courante d'un paramètre de configuration. * +* * +* Retour : Etat en Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_get_value(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + ConfigParamType type; /* Type de paramètre manipulé */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char *string; /* Chaîne de caractères */ + + param = G_CFG_PARAM(pygobject_get(self)); + type = g_config_param_get_ptype(param); + + switch (type) + { + case CPT_BOOLEAN: + g_config_param_get_value(param, &boolean); + result = (boolean ? Py_True : Py_False); + Py_INCREF(result); + break; + + case CPT_INTEGER: + g_config_param_get_value(param, &integer); + result = PyLong_FromLong(integer); + break; + + case CPT_STRING: + g_config_param_get_value(param, &string); + if (string != NULL) + result = PyUnicode_FromString(string); + else + { + result = Py_None; + Py_INCREF(result); + } + break; + + default: + result = NULL; + break; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = paramètre de configuration à manipuler. * +* value = nouvelle valeur à convertir et définir. * +* closure = non utilisé ici. * +* * +* Description : Modifie la valeur courante d'un paramètre de configuration. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_config_param_set_value(PyObject *self, PyObject *value, void *closure) +{ + int result; /* Conclusion à remonter */ + GCfgParam *param; /* Paramètre visé par l'opérat°*/ + ConfigParamType type; /* Type de paramètre manipulé */ + + result = -1; + + param = G_CFG_PARAM(pygobject_get(self)); + + if (value == Py_None) + { + g_config_param_make_empty(param); + result = 0; + } + + else + { + type = g_config_param_get_ptype(param); + + switch (type) + { + case CPT_BOOLEAN: + if (PyBool_Check(value)) + { + g_config_param_set_value(param, (bool)(value == Py_True)); + result = 0; + } + break; + + case CPT_INTEGER: + if (PyLong_Check(value)) + { + g_config_param_set_value(param, (int)PyLong_AsLong(value)); + result = 0; + } + break; + + case CPT_STRING: + if (PyUnicode_Check(value)) + { + g_config_param_set_value(param, PyUnicode_DATA(value)); + result = 0; + } + break; + + default: + break; + + } + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_config_param_type(void) +{ + static PyMethodDef py_config_param_methods[] = { + { "make_empty", py_config_param_make_empty, + METH_NOARGS, + "Unset the value of the current parameter." + }, + { "reset", py_config_param_reset, + METH_NOARGS, + "Reset the content of the current parameter." + }, + { NULL } + }; + + static PyGetSetDef py_config_param_getseters[] = { + { + "path", py_config_param_get_path, NULL, + "Show the path used as key for a configuration parameter.", NULL + }, + { + "type", py_config_param_get_type, NULL, + "Show the type of value provided by a configuration parameter.", NULL + }, + { + "state", py_config_param_get_state, NULL, + "Show the state of a configuration parameter.", NULL + }, + { + "value", py_config_param_get_value, py_config_param_set_value, + "Handle the value of a configuration parameter.", NULL + }, + { NULL } + }; + + static PyTypeObject py_config_param_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.glibext.ConfigParam", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide generic configuration", + + .tp_methods = py_config_param_methods, + .tp_getset = py_config_param_getseters, + .tp_new = (newfunc)py_config_param_new + + }; + + return &py_config_param_type; + +} + + +/****************************************************************************** +* * +* Paramètres : dict = dictionnaire à compléter. * +* * +* Description : Définit les constantes pour les paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool py_config_param_define_constants(PyObject *dict) +{ + int ret; /* Bilan d'un ajout */ + +#define DEF_ULONG_CONST(name) \ + ret = PyDict_SetItemString(dict, #name, PyLong_FromUnsignedLong(name)); \ + if (ret == -1) return false; + + DEF_ULONG_CONST(CPT_BOOLEAN); + DEF_ULONG_CONST(CPT_INTEGER); + DEF_ULONG_CONST(CPT_STRING); + DEF_ULONG_CONST(CPT_COUNT); + + DEF_ULONG_CONST(CPS_UNDEFINED); + DEF_ULONG_CONST(CPS_CHANGED); + DEF_ULONG_CONST(CPS_DEFAULT); + DEF_ULONG_CONST(CPS_EMPTY); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.ConfigParam'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_config_param(PyObject *module) +{ + PyTypeObject *py_config_param_type; /* Type Python 'ConfigParam' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_config_param_type = get_python_config_param_type(); + + py_config_param_type->tp_base = &PyGObject_Type; + py_config_param_type->tp_basicsize = py_config_param_type->tp_base->tp_basicsize; + + if (PyType_Ready(py_config_param_type) != 0) + return false; + + if (!py_config_param_define_constants(py_config_param_type->tp_dict)) + return false; + + Py_INCREF(py_config_param_type); + ret = PyModule_AddObject(module, "ConfigParam", (PyObject *)py_config_param_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "ConfigParam", G_TYPE_CFG_PARAM, py_config_param_type, + Py_BuildValue("(O)", py_config_param_type->tp_base)); + + return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* PARCOURS DE PARAMETRES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : self = instance Python à libérer de la mémoire. * +* * +* Description : Prend acte d'un compteur de référence à 0. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void py_config_param_iterator_dealloc(PyObject *self) +{ + pyConfigParamIterator *iterator; /* Références pour le parcours */ + + /** + * Il aurait été sans doute mieux de reposer ici sur .tp_finalize, + * mais cela semble impliquer de mettre en place tous les mécanismes de GC... + * + * cf. https://docs.python.org/3/extending/newtypes.html#finalization-and-de-allocation + */ + + iterator = (pyConfigParamIterator *)self; + + g_generic_config_runlock(iterator->config); + g_object_unref(G_OBJECT(iterator->config)); + + Py_TYPE(self)->tp_free((PyObject*)self); + +} + + +/****************************************************************************** +* * +* Paramètres : self = itérateur à manipuler. * +* * +* Description : Fournit un itérateur pour paramètres de configuration. * +* * +* Retour : Instance Python prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_iterator_iter(PyObject *self) +{ + Py_INCREF(self); + + return self; + +} + + +/****************************************************************************** +* * +* Paramètres : self = itérateur à manipuler. * +* * +* Description : Fournit un itérateur pour paramètres de configuration. * +* * +* Retour : Instance Python prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_config_param_iterator_next(PyObject *self) +{ + PyObject *result; /* Instance à retourner */ + pyConfigParamIterator *iterator; /* Références pour le parcours */ + GList *item; /* Nouvel élément courant */ + + iterator = (pyConfigParamIterator *)self; + + if (iterator->last == NULL) item = iterator->params; + else item = g_list_next(iterator->last); + + iterator->last = item; + + if (item != NULL) + { + result = pygobject_new(G_OBJECT(item->data)); + Py_XINCREF(result); + } + else + { + PyErr_SetNone(PyExc_StopIteration); + result = NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet instancié à initialiser. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Initialise un objet Python de type 'ConfigParamIterator'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int py_config_param_iterator_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + pyConfigParamIterator *iterator; /* Références pour le parcours */ + PyObject *config; /* Configuration format Python */ + int ret; /* Bilan de lecture des args. */ + + ret = PyArg_ParseTuple(args, "O", &config); + if (!ret) return -1; + + ret = PyObject_IsInstance(config, (PyObject *)get_python_generic_config_type()); + if (!ret) return -1; + + iterator = (pyConfigParamIterator *)self; + + iterator->config = G_GEN_CONFIG(pygobject_get(config)); + g_object_ref(G_OBJECT(iterator->config)); + + g_generic_config_rlock(iterator->config); + + iterator->params = g_generic_config_list_params(iterator->config); + + iterator->last = NULL; + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_config_param_iterator_type(void) +{ + static PyTypeObject py_config_param_iterator_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.glibext.ConfigParamIterator", + .tp_basicsize = sizeof(pyConfigParamIterator), + + .tp_dealloc = py_config_param_iterator_dealloc, + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "Iterator for configuration parameters", + + .tp_iter = py_config_param_iterator_iter, + .tp_iternext = py_config_param_iterator_next, + + .tp_init = py_config_param_iterator_init, + + .tp_new = PyType_GenericNew, + + }; + + return &py_config_param_iterator_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide...ConfigParamIterator'.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_config_param_iterator(PyObject *module) +{ + PyTypeObject *py_config_param_iterator_type; /* Type Python 'ConfigParamIterator' */ + int ret; /* Bilan d'un appel */ + + py_config_param_iterator_type = get_python_config_param_iterator_type(); + + py_config_param_iterator_type->tp_base = &PyBaseObject_Type; + py_config_param_iterator_type->tp_basicsize = py_config_param_iterator_type->tp_base->tp_basicsize; + + if (PyType_Ready(py_config_param_iterator_type) != 0) + return false; + + Py_INCREF(py_config_param_iterator_type); + ret = PyModule_AddObject(module, "ConfigParamIterator", (PyObject *)py_config_param_iterator_type); + if (ret != 0) return false; + + return true; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION GENERIQUE DE CONFIGURATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : type = type de l'objet à instancier. * +* args = arguments fournis à l'appel. * +* kwds = arguments de type key=val fournis. * +* * +* Description : Crée un nouvel objet Python de type 'GenConfig'. * +* * +* Retour : Instance Python mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *result; /* Instance à retourner */ + char *name; /* Nom du fichier à charger */ + int ret; /* Bilan de lecture des args. */ + GGenConfig *config; /* Version GLib du format */ + + ret = PyArg_ParseTuple(args, "s", &name); + if (!ret) Py_RETURN_NONE; + + config = g_generic_config_new(name); + + result = pygobject_new(G_OBJECT(config)); + g_object_unref(config); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = configuration à manipuler. * +* args = non utilisé ici. * +* * +* Description : Lit la configuration depuis un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_read(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GGenConfig *config; /* Version GLib du format */ + bool status; /* Bilan de l'opération */ + + config = G_GEN_CONFIG(pygobject_get(self)); + + status = g_generic_config_read(config); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = configuration à manipuler. * +* args = non utilisé ici. * +* * +* Description : Ecrit la configuration dans un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_write(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GGenConfig *config; /* Version GLib du format */ + bool status; /* Bilan de l'opération */ + + config = G_GEN_CONFIG(pygobject_get(self)); + + status = g_generic_config_write(config); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = configuration à manipuler. * +* args = indication sur l'élément à retrouver. * +* * +* Description : Retrouve un élément de configuration par son chemin. * +* * +* Retour : Elément trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_search(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GGenConfig *config; /* Version GLib du format */ + char *path; /* Chemin d'accès du paramètre */ + int ret; /* Bilan de lecture des args. */ + GCfgParam *param; /* Paramètre trouvé ou NULL */ + + config = G_GEN_CONFIG(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "s", &path); + if (!ret) Py_RETURN_NONE; + + param = g_generic_config_search(config, path); + + result = pygobject_new(G_OBJECT(param)); + Py_XINCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = configuration à manipuler. * +* args = indication sur l'élément à retrouver. * +* * +* Description : Ajoute un paramètre à une configuration. * +* * +* Retour : Elément ajouté ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_add(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + GGenConfig *config; /* Version GLib du format */ + PyObject *param; /* Paramètre transmis */ + int ret; /* Bilan de lecture des args. */ + GCfgParam *added; /* Elément ajouté ou NULL */ + + config = G_GEN_CONFIG(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "O", ¶m); + if (!ret) Py_RETURN_NONE; + + ret = PyObject_IsInstance(param, (PyObject *)get_python_config_param_type()); + if (!ret) Py_RETURN_NONE; + + added = g_generic_config_add_param(config, G_CFG_PARAM(pygobject_get(param))); + + if (added != NULL) + { + result = pygobject_new(G_OBJECT(added)); + Py_XINCREF(result); + } + else + result = NULL; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = configuration à manipuler. * +* args = indication sur l'élément à retrouver. * +* * +* Description : Retire un paramètre d'une configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_delete(PyObject *self, PyObject *args) +{ + GGenConfig *config; /* Version GLib du format */ + char *path; /* Chemin d'accès du paramètre */ + int ret; /* Bilan de lecture des args. */ + + config = G_GEN_CONFIG(pygobject_get(self)); + + ret = PyArg_ParseTuple(args, "s", &path); + if (!ret) Py_RETURN_NONE; + + g_generic_config_delete_param(config, path); + + Py_RETURN_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : self = configuration à manipuler. * +* args = non utilisé ici. * +* * +* Description : Renvoie la liste des paramètres de configuration. * +* * +* Retour : Itérateur pour la liste des paramètres. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_list_params(PyObject *self, PyObject *args) +{ + PyObject *result; /* Instance à retourner */ + PyTypeObject *iterator_type; /* Type Python de l'itérateur */ + PyObject *args_list; /* Arguments de mise en place */ + + iterator_type = get_python_config_param_iterator_type(); + + Py_INCREF(self); + + args_list = Py_BuildValue("(O)", self); + result = PyObject_CallObject((PyObject *)iterator_type, args_list); + + Py_DECREF(args_list); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = NULL car méthode statique. * +* closure = non utilisé ici. * +* * +* Description : Fournit le chemin d'accès au binaire représenté. * +* * +* Retour : Chemin d'accès en Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_generic_config_get_filename(PyObject *self, void *closure) +{ + GGenConfig *config; /* Version GLib du format */ + const char *filename; /* Chemin d'accès au fichier */ + + config = G_GEN_CONFIG(pygobject_get(self)); + + filename = g_generic_config_get_filename(config); + + return PyUnicode_FromString(filename); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit un accès à une définition de type à diffuser. * +* * +* Retour : Définition d'objet pour Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *get_python_generic_config_type(void) +{ + static PyMethodDef py_generic_config_methods[] = { + { "read", py_generic_config_read, + METH_NOARGS, + "Read the configuration from its relative XML file." + }, + { "write", py_generic_config_write, + METH_NOARGS, + "Write the configuration to its relative XML file." + }, + { "search", py_generic_config_search, + METH_VARARGS, + "Look for a given configuration parameter." + }, + { "add", py_generic_config_add, + METH_VARARGS, + "Add an existing parameter to a configuration." + }, + { "delete", py_generic_config_delete, + METH_VARARGS, + "Delete an existing parameter from a configuration." + }, + { "params", py_generic_config_list_params, + METH_NOARGS, + "List all registered configuration parameters." + }, + { NULL } + }; + + static PyGetSetDef py_generic_config_getseters[] = { + { + "filename", py_generic_config_get_filename, NULL, + "Show the filename of the loaded binary file.", NULL + }, + { NULL } + }; + + static PyTypeObject py_generic_config_type = { + + PyVarObject_HEAD_INIT(NULL, 0) + + .tp_name = "pychrysalide.glibext.GenConfig", + .tp_basicsize = sizeof(PyGObject), + + .tp_flags = Py_TPFLAGS_DEFAULT, + + .tp_doc = "PyChrysalide generic configuration", + + .tp_methods = py_generic_config_methods, + .tp_getset = py_generic_config_getseters, + .tp_new = (newfunc)py_generic_config_new + + }; + + return &py_generic_config_type; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Prend en charge l'objet 'pychrysalide.glibext.GenConfig'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool register_python_generic_config(PyObject *module) +{ + PyTypeObject *py_generic_config_type; /* Type Python 'GenConfig' */ + int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ + + py_generic_config_type = get_python_generic_config_type(); + + py_generic_config_type->tp_base = &PyGObject_Type; + py_generic_config_type->tp_basicsize = py_generic_config_type->tp_base->tp_basicsize; + + if (PyType_Ready(py_generic_config_type) != 0) + return false; + + Py_INCREF(py_generic_config_type); + ret = PyModule_AddObject(module, "GenConfig", (PyObject *)py_generic_config_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "GenConfig", G_TYPE_GEN_CONFIG, py_generic_config_type, + Py_BuildValue("(O)", py_generic_config_type->tp_base)); + + return true; + +} diff --git a/plugins/pychrysa/glibext/configuration.h b/plugins/pychrysa/glibext/configuration.h new file mode 100644 index 0000000..e55b3e1 --- /dev/null +++ b/plugins/pychrysa/glibext/configuration.h @@ -0,0 +1,66 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.h - prototypes pour l'équivalent Python du fichier "glibext/configuration.h" + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H +#define _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H + + +#include +#include + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_config_param_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.ConfigParam'. */ +bool register_python_config_param(PyObject *); + + + +/* ----------------------------- PARCOURS DE PARAMETRES ----------------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_config_param_iterator_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.ConfigParamIterator'. */ +bool register_python_config_param_iterator(PyObject *); + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +/* Fournit un accès à une définition de type à diffuser. */ +PyTypeObject *get_python_generic_config_type(void); + +/* Prend en charge l'objet 'pychrysalide.glibext.GenConfig'. */ +bool register_python_generic_config(PyObject *); + + + +#endif /* _PLUGINS_PYCHRYSA_GLIBEXT_CONFIGURATION_H */ diff --git a/plugins/pychrysa/glibext/module.c b/plugins/pychrysa/glibext/module.c index b62ae7b..9f3d3a8 100644 --- a/plugins/pychrysa/glibext/module.c +++ b/plugins/pychrysa/glibext/module.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * module.c - intégration du répertoire glibext en tant que module * - * Copyright (C) 2012 Cyrille Bagard + * Copyright (C) 2012-2014 Cyrille Bagard * * This file is part of Chrysalide. * @@ -25,8 +25,7 @@ #include "module.h" -#include "bufferline.h" -#include "codebuffer.h" +#include "configuration.h" @@ -44,24 +43,50 @@ bool add_glibext_module_to_python_module(PyObject *super) { - bool result; - PyObject *module; + bool result; /* Bilan à retourner */ + PyObject *module; /* Sous-module mis en place */ int ret; /* Bilan d'un appel */ - static PyMethodDef py_glibext_methods[] = { - { NULL } + static PyModuleDef py_chrysalide_glibext_module = { + + .m_base = PyModuleDef_HEAD_INIT, + + .m_name = "pychrysalide.glibext", + .m_doc = "Python module for Chrysalide.glibext", + + .m_size = -1, + }; - module = Py_InitModule("pychrysalide.glibext", py_glibext_methods); + result = false; + + module = PyModule_Create(&py_chrysalide_glibext_module); if (module == NULL) return false; + ret = PyState_AddModule(super, &py_chrysalide_glibext_module); + if (ret != 0) goto agmtpm_exit; + + ret = _PyImport_FixupBuiltin(module, "pychrysalide.glibext"); + if (ret != 0) goto agmtpm_exit; + Py_INCREF(module); - ret = PyModule_AddObject(super, "pychrysalide.glibext", module); + ret = PyModule_AddObject(super, "glibext", module); + if (ret != 0) goto agmtpm_exit; + + result = true; + + result &= register_python_config_param(module); + result &= register_python_config_param_iterator(module); + result &= register_python_generic_config(module); + + agmtpm_exit: - result = (ret == 0); + if (!result) + { + printf("something went wrong in %s...\n", __FUNCTION__); + /* ... */ - result &= register_python_buffer_line(module); - result &= register_python_code_buffer(module); + } return result; diff --git a/plugins/pychrysa/glibext/module.h b/plugins/pychrysa/glibext/module.h index fe13d4c..ddcab15 100644 --- a/plugins/pychrysa/glibext/module.h +++ b/plugins/pychrysa/glibext/module.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * module.h - prototypes pour l'intégration du répertoire glibext en tant que module * - * Copyright (C) 2012 Cyrille Bagard + * Copyright (C) 2012-2014 Cyrille Bagard * * This file is part of Chrysalide. * @@ -22,8 +22,8 @@ */ -#ifndef _PLUGINS_PYOIDA_GLIBEXT_MODULE_H -#define _PLUGINS_PYOIDA_GLIBEXT_MODULE_H +#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_H +#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_H #include diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c index 865c0fc..1835b18 100644 --- a/plugins/pychrysa/pychrysa.c +++ b/plugins/pychrysa/pychrysa.c @@ -57,7 +57,6 @@ - static PyMethodDef SpamMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; @@ -351,8 +350,15 @@ PyMODINIT_FUNC initpychrysa(void) #include "../../revision.h" + +#include + + + #include "analysis/module.h" #include "arch/module.h" +#include "core/module.h" +#include "glibext/module.h" @@ -458,6 +464,12 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) if (pygobject_init(-1, -1, -1) == NULL) return NULL; + if (!load_all_basic_components()) + return NULL; + + + + /** * Pour une raison non identifiée, si le module n'est pas préchargé, * le flot d'exécution plante dans la fonction insertdict() de Objects/dictobject.c:818. @@ -472,6 +484,8 @@ PyMODINIT_FUNC PyInit_pychrysalide(void) status &= add_analysis_module_to_python_module(result); status &= add_arch_module_to_python_module(result); + status &= add_core_module_to_python_module(result); + status &= add_glibext_module_to_python_module(result); printf("status :: %d\n", status); diff --git a/src/Makefile.am b/src/Makefile.am index 75d16d6..7a0ef4d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ -lib_LTLIBRARIES = libchrysaglibext.la libchrysadisass.la libchrysagtkext.la libchrysagui.la libchrysaplugin.la +lib_LTLIBRARIES = libchrysacore.la libchrysaglibext.la libchrysadisass.la libchrysagtkext.la libchrysagui.la libchrysaplugin.la bin_PROGRAMS = chrysalide @@ -13,6 +13,17 @@ bin_PROGRAMS = chrysalide #--- libchrysadisas +libchrysacore_la_SOURCES = + +libchrysacore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) \ + -Lcommon/.libs -lcommon + +libchrysacore_la_LIBADD = \ + core/libcore.la + + +#--- libchrysadisas + libchrysadisass_la_SOURCES = libchrysadisass_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) \ @@ -76,10 +87,8 @@ libchrysaplugin_la_LIBADD = \ ############################################################ chrysalide_SOURCES = \ - configuration.h configuration.c \ editor.h editor.c \ main.c \ - params.h params.c \ project.h project.c @@ -89,7 +98,7 @@ AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) chrysalide_LDFLAGS = $(LIBGTK_LIBS) -L/usr/X11R6/lib -ldl -lm $(LIBXML_LIBS) `pkg-config --libs gthread-2.0` $(LIBPYTHON_LIBS) $(LIBARCHIVE_LIBS) $(LIBSQLITE_LIBS) \ - -L.libs -lchrysaglibext -lchrysadisass -lchrysagtkext -lchrysagui \ + -L.libs -lchrysaglibext -lchrysadisass -lchrysagtkext -lchrysagui -lchrysacore \ -Lcommon/.libs -lcommon \ -Lplugins/.libs -lplugins @@ -105,6 +114,6 @@ chrysalide_LDADD = $(LIBINTL) \ # glibext doit être traité en premier, à cause des marshals GLib -SUBDIRS = glibext gtkext analysis arch format common debug decomp dialogs gui plugins +SUBDIRS = core glibext gtkext analysis arch format common debug decomp dialogs gui plugins # TODO: rm -rf panels diff --git a/src/common/extstr.c b/src/common/extstr.c index caffbcd..851401c 100644 --- a/src/common/extstr.c +++ b/src/common/extstr.c @@ -174,18 +174,15 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2) size_t inlen; /* Taille en entrée */ size_t len1; /* Taille de l'aiguille n°1 */ size_t len2; /* Taille de l'aiguille n°2 */ - regex_t preg; /* Expression régulière */ - size_t curpos; /* Point de recherche */ - regmatch_t pmatch; /* Résultats remontés */ + char *found; /* Position d'une trouvaille */ inlen = strlen(haystack) + 1; len1 = strlen(needle1); len2 = strlen(needle2); - /* On considère que la compilation est toujours bonne... */ - regcomp(&preg, needle1, REG_EXTENDED | REG_ICASE); - - for (curpos = 0; regexec(&preg, &haystack[curpos], 1, &pmatch, 0) != REG_NOMATCH; ) + for (found = strstr(haystack, needle1); + found != NULL; + found = strstr(haystack, needle1)) { if (len1 != len2) { @@ -198,23 +195,16 @@ char *strrpl(char *haystack, const char *needle1, const char *needle2) haystack = (char *)realloc(haystack, inlen * sizeof(char *)); if (len2 > len1) - memmove(&haystack[curpos + pmatch.rm_eo + len2 - len1], &haystack[curpos + pmatch.rm_eo], - inlen - (len2 - len1) - curpos - pmatch.rm_eo); - + memmove(found + len2, found + len1, inlen - len1 - (found - haystack)); else - memmove(&haystack[curpos + pmatch.rm_eo + len1 - len2], &haystack[curpos + pmatch.rm_eo], - inlen - (len1 - len2) - curpos - pmatch.rm_eo); + memmove(found + len1, found + len2, inlen - len1 - (found - haystack)); } - memcpy(&haystack[curpos + pmatch.rm_so], needle2, len2); - - curpos += pmatch.rm_eo + len2; + memcpy(found, needle2, len2); } - regfree(&preg); - return haystack; } diff --git a/src/common/fnv1a.c b/src/common/fnv1a.c index c21a5e1..d017d70 100644 --- a/src/common/fnv1a.c +++ b/src/common/fnv1a.c @@ -40,15 +40,21 @@ * * * Description : Détermine si deux empreintes FNV1a sont indentiques ou non. * * * -* Retour : Bilan de la comparaison. * +* Retour : Bilan de la comparaison : -1, 0 ou 1. * * * * Remarques : - * * * ******************************************************************************/ -bool cmp_fnv_64a(fnv64_t a, fnv64_t b) +int cmp_fnv_64a(fnv64_t a, fnv64_t b) { - return (a == b); + int result; /* Bilan à retourner */ + + if (a < b) result = -1; + else if (a == b) result = 0; + else result = 1; + + return result; } diff --git a/src/common/fnv1a.h b/src/common/fnv1a.h index 294ce12..973781b 100644 --- a/src/common/fnv1a.h +++ b/src/common/fnv1a.h @@ -41,7 +41,7 @@ typedef uint64_t fnv64_t; /* Détermine si deux empreintes FNV1a sont indentiques ou non. */ -bool cmp_fnv_64a(fnv64_t, fnv64_t); +int cmp_fnv_64a(fnv64_t, fnv64_t); /* Détermine l'empreinte FNV1a d'une chaîne de caractères. */ fnv64_t fnv_64a_hash(const char *); diff --git a/src/common/io.c b/src/common/io.c index c3d3231..2275cb4 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -24,4 +24,48 @@ #include "io.h" +#include +#include +#include +#include +#include + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à valider. * +* * +* Description : S'assure qu'un chemin donné existe dans le système. * +* * +* Retour : 0 si le chemin est actuellement présent, -1 sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int ensure_path_exists(const char *path) +{ + int result; /* Bilan de l'assurance */ + char *copy; /* Chemin libérable */ + char *tmp; /* Chemin altérable */ + + copy = strdup(path); + tmp = dirname(copy); + + result = access(tmp, W_OK | X_OK); + + if (result != 0) + { + result = ensure_path_exists(tmp); + + if (result == 0) + result = mkdir(tmp, 0700); + + } + + free(copy); + + return result; + +} diff --git a/src/common/io.h b/src/common/io.h index 9145736..491d8d0 100644 --- a/src/common/io.h +++ b/src/common/io.h @@ -40,4 +40,10 @@ #define safe_write write + +/* S'assure qu'un chemin donné existe dans le système. */ +int ensure_path_exists(const char *); + + + #endif /* _COMMON_IO_H */ diff --git a/src/common/xml.c b/src/common/xml.c index 8c4cc81..36171b3 100644 --- a/src/common/xml.c +++ b/src/common/xml.c @@ -223,11 +223,24 @@ char *qck_get_node_text_value(xmlNodePtr node) result = NULL; if (node != NULL) + { if (node->children != NULL) if (node->children->content != NULL) result = strdup((char *)node->children->content); - if (result == NULL) XML_LOG(stderr, "No text value for node '%s'\n", node->name); + /** + * Si le noeud existe mais qu'il n'y pas de contenu, + * il faut marquer la différence entre deux retours NULL. + * + * On choisit donc : + * - NULL : pas de valeur trouvée car noeud non existant. + * - "" : pas de valeur trouvée, mais noeud bien présent. + */ + + if (result == NULL) + result = strdup(""); + + } return result; diff --git a/src/configuration.c b/src/configuration.c deleted file mode 100644 index 12feeb6..0000000 --- a/src/configuration.c +++ /dev/null @@ -1,427 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * configuration.c - éléments de configuration du programme - * - * Copyright (C) 2009-2014 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * 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 -#include -#include - - -#include "common/extstr.h" -#include "common/xdg.h" -#include "common/xml.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 */ - -}; - - -/* S'assure qu'un chemin donné existe dans le système. */ -static int ensure_path_exists(const char *); - - - -/****************************************************************************** -* * -* 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 *suffix; /* Fin du nom de fichier */ - unsigned int i; /* Boucle de parcours */ - char *strval; /* Valeur en chaîne de carac. */ - - result = (configuration *)calloc(1, sizeof(configuration)); - - for (i = 0; i < count; i++) - params[i].cur = params[i].def; - - result->params = params; - result->count = count; - - suffix = strdup("openida/"); - suffix = stradd(suffix, name); - suffix = stradd(suffix, ".xml"); - - result->filename = get_xdg_config_dir(suffix); - - free(suffix); - - if (!open_xml_file(result->filename, &result->xdoc, &result->context)) - create_new_xml_file(&result->xdoc, &result->context); - - else - for (i = 0; i < count; i++) - switch (params[i].type) - { - case CVT_BOOLEAN: - strval = get_node_text_value(result->context, params[i].path); - if (strval != NULL) - { - set_boolean_config_value(result, i, strcmp(strval, "true") == 0); - free(strval); - } - break; - - case CVT_INTEGER: - strval = get_node_text_value(result->context, params[i].path); - if (strval != NULL) - { - set_integer_config_value(result, i, atoi(strval)); - free(strval); - } - break; - - case CVT_STRING: - strval = get_node_text_value(result->context, params[i].path); - set_string_config_value(result, i, strval); - if (strval != NULL) free(strval); - break; - - default: - break; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : path = chemin d'accès à valider. * -* * -* Description : S'assure qu'un chemin donné existe dans le système. * -* * -* Retour : 0 si le chemin est actuellement présent, -1 sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int ensure_path_exists(const char *path) -{ - int result; /* Bilan de l'assurance */ - char *tmp; /* Chemin altérable */ - - tmp = strdup(path); - tmp = dirname(tmp); - - result = access(tmp, W_OK | X_OK); - - if (result != 0) - { - result = ensure_path_exists(tmp); - - if (result == 0) - result = mkdir(tmp, 0700); - - } - - free(tmp); - - 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) -{ - int ret; /* Bilan de l'assurance */ - unsigned int i; /* Boucle de parcours */ - config_param *params; /* Confort d'utilisation */ - char tmp[12 /* -INT_MIN */]; /* Reconstruction en chaîne */ - - close_xml_file(config->xdoc, config->context); - - ret = ensure_path_exists(config->filename); - if (ret != 0) goto uc_exit; - - create_new_xml_file(&config->xdoc, &config->context); - - for (i = 0; i < config->count; i++) - { - params = &config->params[i]; - - switch (params->type) - { - case CVT_BOOLEAN: - if (params->cur.boolean == params->def.boolean) - continue; - - add_content_to_node(config->xdoc, config->context, - params->path, - params->cur.boolean ? "true" : "false"); - - break; - - case CVT_INTEGER: - if (params->cur.integer == params->def.integer) - continue; - - snprintf(tmp, 12, "%d", params->cur.integer); - add_content_to_node(config->xdoc, config->context, - params->path, tmp); - - break; - - case CVT_STRING: - - if (params->cur.string == NULL && params->def.string == NULL) - continue; - - if (params->def.string != NULL && params->def.string != NULL - && strcmp(params->cur.string, params->def.string) == 0) - continue; - - add_content_to_node(config->xdoc, config->context, - params->path, - params->cur.string != NULL ? params->cur.string : ""); - - break; - - default: - break; - - } - - } - - save_xml_file(config->xdoc, config->filename); - - uc_exit: - - free(config); - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* value = valeur à considérer comme valeur courante. * -* * -* Description : Définit une valeur booléenne dans la configuration. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool set_boolean_config_value(configuration *config, unsigned int index, bool value) -{ - if (index >= config->count) return false; - if (config->params[index].type != CVT_BOOLEAN) return false; - - config->params[index].defined = true; - - config->params[index].cur.boolean = value; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* * -* Description : Fournit une valeur booléenne issue de la configuration. * -* * -* Retour : Valeur courante ou par défaut de la configuration. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_boolean_config_value(configuration *config, unsigned int index) -{ - bool result; /* Valeur à retourner */ - - if (index >= config->count) return false; - if (config->params[index].type != CVT_BOOLEAN) return false; - - if (config->params[index].defined) result = config->params[index].cur.boolean; - else result = config->params[index].def.boolean; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* value = valeur à considérer comme valeur courante. * -* * -* Description : Définit une valeur entière dans la configuration. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool set_integer_config_value(configuration *config, unsigned int index, int value) -{ - if (index >= config->count) return false; - if (config->params[index].type != CVT_INTEGER) return false; - - config->params[index].defined = true; - - config->params[index].cur.integer = value; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* * -* Description : Fournit une valeur entière issue de la configuration. * -* * -* Retour : Valeur courante ou par défaut de la configuration. * -* * -* Remarques : - * -* * -******************************************************************************/ - -int get_integer_config_value(configuration *config, unsigned int index) -{ - int result; /* Valeur à retourner */ - - if (index >= config->count) return 0; - if (config->params[index].type != CVT_INTEGER) return 0; - - if (config->params[index].defined) result = config->params[index].cur.integer; - else result = config->params[index].def.integer; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* value = valeur à considérer comme valeur courante. * -* * -* Description : Définit une chaîne de caractères dans la configuration. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool set_string_config_value(configuration *config, unsigned int index, const char *value) -{ - if (index >= config->count) return false; - if (config->params[index].type != CVT_STRING) return false; - - config->params[index].defined = true; - - if (config->params[index].cur.string != NULL) - free(config->params[index].cur.string); - - config->params[index].cur.string = (value != NULL ? strdup(value) : NULL); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : config = configuration à venir consulter. * -* index = indice de l'élément à traiter. * -* * -* Description : Fournit une chaîne de caractères issue de la configuration. * -* * -* Retour : Valeur courante ou par défaut de la configuration. * -* * -* Remarques : - * -* * -******************************************************************************/ - -const char *get_string_config_value(configuration *config, unsigned int index) -{ - const char *result; /* Valeur à retourner */ - - if (index >= config->count) return NULL; - if (config->params[index].type != CVT_STRING) return NULL; - - if (config->params[index].defined) result = config->params[index].cur.string; - else result = config->params[index].def.string; - - return result; - -} diff --git a/src/configuration.h b/src/configuration.h deleted file mode 100644 index b77c52f..0000000 --- a/src/configuration.h +++ /dev/null @@ -1,96 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * configuration.h - prototypes pour les éléments de configuration du programme - * - * Copyright (C) 2009-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * 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 - - -#include - - -/* Tyoes de valeur pour élement de configuration */ -typedef enum _ConfigValueType -{ - CVT_BOOLEAN, /* Valeur booléenne */ - CVT_INTEGER, /* Valeur entière */ - CVT_STRING, /* Chaîne de caractère */ - - CVT_COUNT - -} ConfigValueType; - -/* Valeurs supportées par les configurations */ -typedef union _config_value -{ - bool boolean; /* Valeur booléenne */ - int integer; /* Valeur entière */ - 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 */ - - ConfigValueType type; /* Type de valeur */ - - bool defined; /* Présence de valeur courante */ - - 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 *); - -/* Définit une valeur booléenne dans la configuration. */ -bool set_boolean_config_value(configuration *, unsigned int, bool); - -/* Fournit une valeur booléenne issue de la configuration. */ -bool get_boolean_config_value(configuration *, unsigned int); - -/* Définit une valeur entière dans la configuration. */ -bool set_integer_config_value(configuration *, unsigned int, int); - -/* Fournit une valeur entière issue de la configuration. */ -int get_integer_config_value(configuration *, unsigned int); - -/* Définit une chaîne de caractères dans la configuration. */ -bool set_string_config_value(configuration *, unsigned int, const char *); - -/* Fournit une chaîne de caractères issue de la configuration. */ -const char *get_string_config_value(configuration *, unsigned int); - - - -#endif /* _CONFIGURATION_H */ diff --git a/src/core/Makefile.am b/src/core/Makefile.am new file mode 100755 index 0000000..0724a3f --- /dev/null +++ b/src/core/Makefile.am @@ -0,0 +1,15 @@ + +noinst_LTLIBRARIES = libcore.la + +libcore_la_SOURCES = \ + core.h core.c \ + params.h params.c + +libcore_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) + + +AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = diff --git a/src/core/core.c b/src/core/core.c new file mode 100644 index 0000000..d90dd5c --- /dev/null +++ b/src/core/core.c @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.c - chargement et le déchargement du tronc commun + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "core.h" + + +#include "params.h" + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Charge les éléments de base du programme. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_all_basic_components(void) +{ + bool result; /* Bilan à retourner */ + + result = true; + + result &= load_main_config_parameters(); + + result &= g_generic_config_read(get_main_configuration()); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Décharge les éléments de base du programme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_all_basic_components(void) +{ + g_generic_config_write(get_main_configuration()); + + unload_main_config_parameters(); + +} diff --git a/src/core/core.h b/src/core/core.h new file mode 100644 index 0000000..2b0ef76 --- /dev/null +++ b/src/core/core.h @@ -0,0 +1,40 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * core.h - prototypes pour le chargement et le déchargement du tronc commun + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _CORE_CORE_H +#define _CORE_CORE_H + + +#include + + + +/* Charge les éléments de base du programme. */ +bool load_all_basic_components(void); + +/* Décharge les éléments de base du programme. */ +void unload_all_basic_components(void); + + + +#endif /* _CORE_CORE_H */ diff --git a/src/core/params.c b/src/core/params.c new file mode 100644 index 0000000..c8263f0 --- /dev/null +++ b/src/core/params.c @@ -0,0 +1,112 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * params.c - éléments de la configuration principale + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 : - * +* * +* Description : Procède au chargement de la configuration principale. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool load_main_config_parameters(void) +{ + GGenConfig *config; /* Configuration à charger */ + GCfgParam *param; /* Paramètre chargé */ + + config = g_generic_config_new("main"); + set_main_configuration(config); + + param = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_ELLIPSIS_HEADER, CPT_INTEGER, 54); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_ELLIPSIS_TAB, CPT_INTEGER, 35); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_KEYBINDINGS_EDIT, CPT_STRING, "F2"); + if (param == NULL) return false; + + param = g_generic_config_create_param(config, MPK_AUTO_SAVE, CPT_BOOLEAN, true); + if (param == NULL) return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Procède au déchargement de la configuration principale. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void unload_main_config_parameters(void) +{ + GGenConfig *config; /* Configuration à décharger */ + + config = get_main_configuration(); + + g_object_unref(G_OBJECT(config)); + +} + + +/****************************************************************************** +* * +* 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 : - * +* * +******************************************************************************/ + +GGenConfig *_get_main_configuration(GGenConfig *config) +{ + static GGenConfig *result = NULL; /* Structure à retourner */ + + if (config != NULL) + result = config; + + return result; + +} diff --git a/src/core/params.h b/src/core/params.h new file mode 100644 index 0000000..b79cc3a --- /dev/null +++ b/src/core/params.h @@ -0,0 +1,58 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * params.h - prototypes pour les éléments de la configuration principale + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _CORE_PARAMS_H +#define _CORE_PARAMS_H + + +#include "../glibext/configuration.h" + + + +/** + * Clefs de paramètres de configuration principale. + */ + +#define MPK_LAST_PROJECT "gui.editor.last_project" +#define MPK_ELLIPSIS_HEADER "gui.editor.panels.ellipsis_header" +#define MPK_ELLIPSIS_TAB "gui.editor.panels.ellipsis_tab" +#define MPK_KEYBINDINGS_EDIT "gui.key_bindings.global.edit" +#define MPK_AUTO_SAVE "project.autosave" + + + +/* Procède au chargement de la configuration principale. */ +bool load_main_config_parameters(void); + +/* Procède au déchargement de la configuration principale. */ +void unload_main_config_parameters(void); + +#define set_main_configuration(cfg) _get_main_configuration(cfg) +#define get_main_configuration() _get_main_configuration(NULL) + +/* Fournit un lien vers la configuration principale. */ +GGenConfig *_get_main_configuration(GGenConfig *); + + + +#endif /* _CORE_PARAMS_H */ diff --git a/src/editor.c b/src/editor.c index d333cf5..d67c4d0 100644 --- a/src/editor.c +++ b/src/editor.c @@ -250,6 +250,7 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da result = FALSE; project = get_current_project(); + if (project == NULL) goto ode_no_project; if (g_study_project_get_filename(project) == NULL) { @@ -282,6 +283,8 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da } + ode_no_project: + return result; } @@ -303,7 +306,10 @@ static gboolean on_delete_editor(GtkWidget *widget, GdkEvent *event, gpointer da static void on_destroy_editor(GtkWidget *widget, gpointer data) { - g_object_unref(G_OBJECT(get_current_project())); + GStudyProject *project; /* Projet courant */ + + project = get_current_project(); + if (project != NULL) g_object_unref(G_OBJECT(project)); /* Fermeture propre */ diff --git a/src/format/mangling/itanium/context.c b/src/format/mangling/itanium/context.c index 87cb9ed..d4be54c 100644 --- a/src/format/mangling/itanium/context.c +++ b/src/format/mangling/itanium/context.c @@ -480,7 +480,7 @@ void g_itanium_dcontext_add_substitution(GItaniumDContext *context, itanium_comp hash = itd_hash_comp(comp); for (i = 0; i < context->subst_count; i++) - if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash)) + if (cmp_fnv_64a(itd_hash_comp(context->substitutions[i]), hash) == 0) break; if (i == context->subst_count) diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 19ff59a..50b9902 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -5,6 +5,7 @@ noinst_LTLIBRARIES = libglibext.la libglibext_la_SOURCES = \ chrysamarshal.h chrysamarshal.c \ + configuration.h configuration.c \ delayed-int.h \ delayed.h delayed.c \ gbinportion.h gbinportion.c \ diff --git a/src/glibext/configuration.c b/src/glibext/configuration.c new file mode 100644 index 0000000..30cbcaf --- /dev/null +++ b/src/glibext/configuration.c @@ -0,0 +1,1232 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.c - éléments de configuration du programme + * + * Copyright (C) 2009-2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 +#include +#include +#include + + +#include "../common/cpp.h" +#include "../common/extstr.h" +#include "../common/fnv1a.h" +#include "../common/io.h" +#include "../common/xdg.h" +#include "../common/xml.h" + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Valeurs supportées par les paramètres */ +typedef union _param_value +{ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char *string; /* Chaîne de caractères */ + +} param_value; + +/* Configuration générique quelconque (instance) */ +struct _GCfgParam +{ + GObject parent; /* A laisser en premier */ + + char *path; /* Chemin d'accès XML */ + fnv64_t hash; /* Empreinte pour accès rapide */ + + ConfigParamType type; /* Type de valeur */ + + ConfigParamState cached_state; /* Etat du paramétrage */ + + param_value def; /* Valeur par défaut */ + bool def_empty; /* Non défini par défaut ? */ + param_value cur; /* Valeur courante */ + bool cur_empty; /* Actuellement non défini ? */ + +}; + +/* Configuration générique quelconque (classe) */ +struct _GCfgParamClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (*modified) (GCfgParam *); + +}; + + +/* Initialise la classe des blocs de données binaires. */ +static void g_config_param_class_init(GCfgParamClass *); + +/* Initialise une instance de bloc de données binaires. */ +static void g_config_param_init(GCfgParam *); + +/* Supprime toutes les références externes. */ +static void g_config_param_dispose(GCfgParam *); + +/* Procède à la libération totale de la mémoire. */ +static void g_config_param_finalize(GCfgParam *); + +/* Lit un paramètre de configuration depuis un fichier. */ +static bool g_config_param_read(GCfgParam *, xmlXPathContextPtr); + +/* Ecrit un paramètre de configuration dans un fichier. */ +static bool g_config_param_write(GCfgParam *, xmlDocPtr, xmlXPathContextPtr); + + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +/* Configuration générique quelconque (instance) */ +struct _GGenConfig +{ + GObject parent; /* A laisser en premier */ + + char *filename; /* CHemin d'accès complet */ + + GList *params; /* Eléments de configuration */ + GRWLock params_access; /* Verrou de protection */ + +}; + +/* Configuration générique quelconque (classe) */ +struct _GGenConfigClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Initialise la classe des blocs de données binaires. */ +static void g_generic_config_class_init(GGenConfigClass *); + +/* Initialise une instance de bloc de données binaires. */ +static void g_generic_config_init(GGenConfig *); + +/* Supprime toutes les références externes. */ +static void g_generic_config_dispose(GGenConfig *); + +/* Procède à la libération totale de la mémoire. */ +static void g_generic_config_finalize(GGenConfig *); + + + +/* ---------------------------------------------------------------------------------- */ +/* ELEMENT DE CONFIGURATION */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour les configurations géénriques. */ +G_DEFINE_TYPE(GCfgParam, g_config_param, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des blocs de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_class_init(GCfgParamClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_config_param_dispose; + object->finalize = (GObjectFinalizeFunc)g_config_param_finalize; + + g_signal_new("modified", + G_TYPE_CFG_PARAM, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GCfgParamClass, modified), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance à initialiser. * +* * +* Description : Initialise une instance de bloc de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_init(GCfgParam *param) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_dispose(GCfgParam *param) +{ + G_OBJECT_CLASS(g_config_param_parent_class)->dispose(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_config_param_finalize(GCfgParam *param) +{ + free(param->path); + + switch (param->type) + { + case CPT_STRING: + if (param->def.string != NULL) + free(param->def.string); + if (param->cur.string != NULL) + free(param->cur.string); + break; + + default: + break; + + } + + G_OBJECT_CLASS(g_config_param_parent_class)->finalize(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à un paramètre en guise de clef. * +* type = type de paramètre à installer. * +* ... = valeur par défaut du paramètre. * +* * +* Description : Crée un paramètre de configuration. * +* * +* Retour : Elément mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *g_config_param_new(const char *path, ConfigParamType type, ...) +{ + GCfgParam *result; /* Structure à retourner */ + va_list ap; /* Liste d'arguments */ + + result = g_object_new(G_TYPE_CFG_PARAM, NULL); + + result->path = strdup(path); + result->hash = fnv_64a_hash(path); + + result->type = type; + + va_start(ap, type); + + switch (result->type) + { + case CPT_BOOLEAN: + result->def.boolean = va_arg(ap, /*bool*/int); + break; + + case CPT_INTEGER: + result->def.integer = va_arg(ap, int); + break; + + case CPT_STRING: + result->def.string = va_arg(ap, char *); + if (result->def.string != NULL) + result->def.string = strdup(result->def.string); + break; + + default: + g_object_unref(G_OBJECT(result)); + result = NULL; + assert(false); + break; + + } + + va_end(ap); + + g_config_param_reset(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : path = chemin d'accès à un paramètre en guise de clef. * +* type = type de paramètre à installer. * +* * +* Description : Crée un paramètre de configuration sans valeur. * +* * +* Retour : Elément mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *g_config_param_new_empty(const char *path, ConfigParamType type) +{ + GCfgParam *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_CFG_PARAM, NULL); + + result->path = strdup(path); + result->hash = fnv_64a_hash(path); + + result->type = type; + + g_config_param_make_empty(result); + + result->def = result->cur; + result->def_empty = true; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : config = paramètre de configuration à charger. * +* context = contexte de lecture d'un fichier XML. * +* * +* Description : Lit un paramètre de configuration depuis un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_config_param_read(GCfgParam *param, xmlXPathContextPtr context) +{ + char *access; /* Chemin d'accès XML */ + char *value; /* Valeur en chaîne de carac. */ + + access = strdup(param->path); + access = strrpl(access, ".", "/"); + access = strprep(access, "/ChrysalideConfig/"); + + value = get_node_text_value(context, access); + if (value == NULL) goto gcpr_no_value; + + if (strlen(value) == 0) + g_config_param_make_empty(param); + + else + switch (param->type) + { + case CPT_BOOLEAN: + g_config_param_set_value(param, strcmp(value, "true") == 0); + break; + + case CPT_INTEGER: + g_config_param_set_value(param, atoi(value)); + break; + + case CPT_STRING: + g_config_param_set_value(param, value); + break; + + default: + assert(false); + break; + + } + + free(value); + + gcpr_no_value: + + free(access); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : config = paramètre de configuration à charger. * +* xdoc = document XML à mettre en place. * +* context = contexte de lecture d'un fichier XML. * +* * +* Description : Ecrit un paramètre de configuration dans un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_config_param_write(GCfgParam *param, xmlDocPtr xdoc, xmlXPathContextPtr context) +{ + bool result; /* Bilan à retourner */ + ConfigParamState state; /* Etat du paramètre */ + char *access; /* Chemin d'accès XML */ + char int_val[sizeof(XSTR(INT_MIN)) + 1];/* Valeur en chaîne de carac. */ + + state = g_config_param_get_state(param); + + if (state & CPS_DEFAULT) + return true; + + result = true; + + access = strdup(param->path); + access = strrpl(access, ".", "/"); + access = strprep(access, "/ChrysalideConfig/"); + + if (state & CPS_EMPTY) + result = add_content_to_node(xdoc, context, access, ""); + + else + switch (param->type) + { + case CPT_BOOLEAN: + result = add_content_to_node(xdoc, context, access, + param->cur.boolean ? "true" : "false"); + break; + + case CPT_INTEGER: + snprintf(int_val, sizeof(int_val), "%d", param->cur.integer); + result = add_content_to_node(xdoc, context, access, int_val); + break; + + case CPT_STRING: + + if (param->def.string != NULL && param->def.string != NULL + && strcmp(param->cur.string, param->def.string) == 0) + break; + + result = add_content_to_node(xdoc, context, access, + param->cur.string != NULL ? param->cur.string : ""); + break; + + default: + assert(false); + break; + + } + + free(access); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à analyser. * +* path = chemin d'accès à retrouver. * +* * +* Description : Etablit une comparaison selon un chemin d'accès. * +* * +* Retour : -1, 0 ou 1 selon les conclusions de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint g_config_param_compare(const GCfgParam *param, const GCfgParam *path) +{ + gint result; /* Bilan à renvoyer */ + + result = cmp_fnv_64a(param->hash, path->hash); + + if (result == 0) + result = strcmp(param->path, path->path); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à consulter. * +* * +* Description : Indique le chemin d'accès utilisé pour un paramètre. * +* * +* Retour : Clef servant de chemin d'accès. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_config_param_get_path(const GCfgParam *param) +{ + return param->path; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à consulter. * +* * +* Description : Indique le type de valeur utilisée par un paramètre. * +* * +* Retour : Type de paramètre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ConfigParamType g_config_param_get_ptype(const GCfgParam *param) +{ + return param->type; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre de configuration à consulter. * +* * +* Description : Indique le statut d'une valeur utilisée par un paramètre. * +* * +* Retour : Etat de paramètre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +ConfigParamState g_config_param_get_state(GCfgParam *param) +{ + if (param->cached_state == CPS_UNDEFINED) + { + if (param->def_empty || param->cur_empty) + { + param->cached_state = (param->def_empty && param->cur_empty ? CPS_DEFAULT : CPS_CHANGED); + param->cached_state |= CPS_EMPTY; + + goto gcpgs_recached; + + } + + switch (param->type) + { + case CPT_BOOLEAN: + param->cached_state = (param->def.boolean && param->cur.boolean ? CPS_DEFAULT : CPS_CHANGED); + break; + + case CPT_INTEGER: + param->cached_state = (param->def.integer == param->cur.integer ? CPS_DEFAULT : CPS_CHANGED); + break; + + case CPT_STRING: + if (param->def.string == NULL && param->cur.string == NULL) + param->cached_state = CPS_DEFAULT; + else if (param->def.string != NULL && param->cur.string != NULL) + param->cached_state = strcmp(param->def.string, param->cur.string) == 0 ? CPS_DEFAULT : CPS_CHANGED; + else + param->cached_state = CPS_CHANGED; + break; + + default: + break; + + } + + gcpgs_recached:; + + } + + return param->cached_state; + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à mettre à jour. * +* * +* Description : Efface toute valeur courante d'un paramètre de configuration.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_make_empty(GCfgParam *param) +{ + switch (param->type) + { + case CPT_BOOLEAN: + param->cur.boolean = false; + break; + + case CPT_INTEGER: + param->cur.integer = INT_MIN; + break; + + case CPT_STRING: + if (param->cur.string != NULL) + { + free(param->cur.string); + param->cur.string = NULL; + } + break; + + default: + break; + + } + + if (!param->cur_empty) + { + param->cur_empty = true; + + /* Réinitialisation du cache d'état... */ + param->cached_state = CPS_UNDEFINED; + + g_signal_emit_by_name(param, "modified"); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à mettre à jour. * +* * +* Description : Réinitialise la valeur d'un paramètre de configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_reset(GCfgParam *param) +{ + bool modified; /* Détermine une modification */ + + modified = !(g_config_param_get_state(param) & CPS_DEFAULT); + + switch (param->type) + { + case CPT_BOOLEAN: + param->cur.boolean = param->def.boolean; + break; + + case CPT_INTEGER: + param->cur.integer = param->def.integer; + break; + + case CPT_STRING: + if (param->def.string != NULL) + param->cur.string = strdup(param->def.string); + else + param->cur.string = NULL; + break; + + default: + assert(false); + break; + + } + + if (modified) + { + param->cur_empty = param->def_empty; + + /* Réinitialisation du cache d'état... */ + param->cached_state = CPS_UNDEFINED; + + g_signal_emit_by_name(param, "modified"); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à mettre à jour. * +* ... = nouvelle valeur du paramètre. * +* * +* Description : Modifie la valeur courante d'un paramètre de configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_set_value(GCfgParam *param, ...) +{ + va_list ap; /* Liste d'arguments */ + bool old_boolean; /* Valeur booléenne */ + int old_integer; /* Valeur entière */ + char *old_string; /* Chaîne de caractères */ + bool modified; /* Détermine une modification */ + + va_start(ap, param); + + switch (param->type) + { + case CPT_BOOLEAN: + old_boolean = param->cur.boolean; + param->cur.boolean = va_arg(ap, /*bool*/int); + modified = (old_boolean != param->cur.boolean); + break; + + case CPT_INTEGER: + old_integer = param->cur.integer; + param->cur.integer = va_arg(ap, int); + modified = (old_integer != param->cur.integer); + break; + + case CPT_STRING: + old_string = param->cur.string; + param->cur.string = va_arg(ap, char *); + if (param->cur.string != NULL) + param->cur.string = strdup(param->cur.string); + + if (old_string == NULL && param->cur.string == NULL) + modified = false; + else if (old_string != NULL && param->cur.string != NULL) + modified = (strcmp(old_string, param->cur.string) != 0); + else + modified = true; + + if (old_string != NULL) + free(old_string); + + break; + + default: + assert(false); + modified = false; + break; + + } + + va_end(ap); + + if (modified) + { + param->cur_empty = false; + + /* Réinitialisation du cache d'état... */ + param->cached_state = CPS_UNDEFINED; + + g_signal_emit_by_name(param, "modified"); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : param = paramètre à consulter. * +* ... = zone d'enregistrement de la valeur du paramètre. * +* * +* Description : Indique la valeur courante d'un paramètre de configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_config_param_get_value(GCfgParam *param, ...) +{ + va_list ap; /* Liste d'arguments */ + + va_start(ap, param); + + switch (param->type) + { + case CPT_BOOLEAN: + *(va_arg(ap, bool *)) = param->cur.boolean; + break; + + case CPT_INTEGER: + *(va_arg(ap, int *)) = param->cur.integer; + break; + + case CPT_STRING: + *(va_arg(ap, char **)) = param->cur.string; + break; + + default: + assert(false); + break; + + } + + va_end(ap); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* GESTION GENERIQUE DE CONFIGURATION */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini par la GLib pour les configurations génériques. */ +G_DEFINE_TYPE(GGenConfig, g_generic_config, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des blocs de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_class_init(GGenConfigClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_generic_config_dispose; + object->finalize = (GObjectFinalizeFunc)g_generic_config_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : config = instance à initialiser. * +* * +* Description : Initialise une instance de bloc de données binaires. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_init(GGenConfig *config) +{ + g_rw_lock_init(&config->params_access); + +} + + +/****************************************************************************** +* * +* Paramètres : config = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_dispose(GGenConfig *config) +{ + GList *iter; /* Boucle de parcours */ + + for (iter = g_list_first(config->params); + iter != NULL; + iter = g_list_next(iter)) + { + g_object_unref(G_OBJECT(iter->data)); + } + + G_OBJECT_CLASS(g_generic_config_parent_class)->dispose(G_OBJECT(config)); + +} + + +/****************************************************************************** +* * +* Paramètres : config = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_generic_config_finalize(GGenConfig *config) +{ + free(config->filename); + + g_rw_lock_clear(&config->params_access); + + G_OBJECT_CLASS(g_generic_config_parent_class)->finalize(G_OBJECT(config)); + +} + + +/****************************************************************************** +* * +* Paramètres : name = désignation de la configuration. * +* * +* Description : Crée une description de partie de code vierge. * +* * +* Retour : Elément mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GGenConfig *g_generic_config_new(const char *name) +{ + GGenConfig *result; /* Structure à retourner */ + char *suffix; /* Fin du nom de fichier */ + + result = g_object_new(G_TYPE_GEN_CONFIG, NULL); + + suffix = strdup("chrysalide/"); + suffix = stradd(suffix, name); + suffix = stradd(suffix, ".xml"); + + result->filename = get_xdg_config_dir(suffix); + + free(suffix); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration à consulter.* +* * +* Description : Indique le fichier utilisé pour l'enregistrement XML. * +* * +* Retour : Chemin d'accès, potentiellement non existant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +const char *g_generic_config_get_filename(const GGenConfig *config) +{ + return config->filename; + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à mettre à jour. * +* write = précise le type d'accès prévu (lecture/écriture). * +* lock = indique le sens du verrouillage à mener. * +* * +* Description : Met à disposition un encadrement des accès aux paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_generic_config_lock_unlock(GGenConfig *config, bool write, bool lock) +{ + if (write) + { + if (lock) g_rw_lock_writer_lock(&config->params_access); + else g_rw_lock_writer_unlock(&config->params_access); + } + else + { + if (lock) g_rw_lock_reader_lock(&config->params_access); + else g_rw_lock_reader_unlock(&config->params_access); + } + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration à charger. * +* * +* Description : Lit la configuration depuis un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_generic_config_read(GGenConfig *config) +{ + bool result; /* Bilan à retourner */ + int ret; /* Test de présence de fichier */ + xmlDocPtr xdoc; /* Document XML de configurat° */ + xmlXPathContextPtr context; /* Contexte de recherche XPath */ + GList *iter; /* Boucle de parcours */ + + ret = access(config->filename, F_OK); + if (ret != 0) return true; + + if (!open_xml_file(config->filename, &xdoc, &context)) + return false; + + g_generic_config_rlock(config); + + for (result = true, iter = g_list_first(config->params); + result && iter != NULL; + iter = g_list_next(iter)) + { + result = g_config_param_read(G_CFG_PARAM(iter->data), context); + } + + g_generic_config_runlock(config); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration à décharger.* +* * +* Description : Ecrit la configuration dans un fichier. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_generic_config_write(GGenConfig *config) +{ + bool result; /* Bilan à retourner */ + int ret; /* Bilan de l'assurance */ + xmlDocPtr xdoc; /* Document XML de configurat° */ + xmlXPathContextPtr context; /* Contexte de recherche XPath */ + GList *iter; /* Boucle de parcours */ + + ret = ensure_path_exists(config->filename); + if (ret != 0) return false; + + if (!create_new_xml_file(&xdoc, &context)) + return false; + + g_generic_config_rlock(config); + + for (result = true, iter = g_list_first(config->params); + result && iter != NULL; + iter = g_list_next(iter)) + { + result = g_config_param_write(G_CFG_PARAM(iter->data), xdoc, context); + } + + g_generic_config_runlock(config); + + save_xml_file(xdoc, config->filename); + + close_xml_file(xdoc, context); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : config = ensemble de paramètres de configuration. * +* path = chemin d'accès au paramètre visé. * +* lock = pose un verrou si ce n'est déjà fait. * +* * +* Description : Retrouve un élément de configuration par son chemin. * +* * +* Retour : Elément trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *_g_generic_config_search(GGenConfig *config, const char *path, bool lock) +{ + GList *item; /* Elément générique de liste */ + GCfgParam fake; /* Faux élément partiel */ + + fake.path = (char *)path; + fake.hash = fnv_64a_hash(path); + + if (lock) + g_generic_config_rlock(config); + + item = g_list_find_custom(config->params, &fake, (GCompareFunc)g_config_param_compare); + + if (lock) + g_generic_config_runlock(config); + + return item ? item->data : NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à mettre à jour. * +* param = paramètre à intégrer dans la configuration. * +* * +* Description : Ajoute un paramètre à une configuration. * +* * +* Retour : Elément mis en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GCfgParam *g_generic_config_add_param(GGenConfig *config, GCfgParam *param) +{ + const char *path; /* Chemin d'accès unique */ + GCfgParam *old; /* Test de présence */ + + path = g_config_param_get_path(param); + + g_generic_config_wlock(config); + + old = _g_generic_config_search(config, path, false); + if (old != NULL) + { + g_object_unref(G_OBJECT(param)); + return NULL; + } + + config->params = g_list_append(config->params, param); + + g_generic_config_wunlock(config); + + return param; + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à mettre à jour. * +* path = chemin d'accès au paramètre visé. * +* * +* Description : Retire un paramètre d'une configuration. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_generic_config_delete_param(GGenConfig *config, const char *path) +{ + GCfgParam *old; /* Test de présence */ + + g_generic_config_wlock(config); + + old = _g_generic_config_search(config, path, false); + + if (old != NULL) + config->params = g_list_remove(config->params, old); + + g_generic_config_wunlock(config); + +} + + +/****************************************************************************** +* * +* Paramètres : config = configuration à consulter. * +* * +* Description : Renvoie la liste des paramètres de configuration. * +* * +* Retour : Liste d'éléments à parcourir. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GList *g_generic_config_list_params(const GGenConfig *config) +{ + /** + * Un verrou doit être posé ! + * Il n'y a pas d'assert() possible pour le vérifier... + */ + + return config->params; + +} diff --git a/src/glibext/configuration.h b/src/glibext/configuration.h new file mode 100644 index 0000000..84d494f --- /dev/null +++ b/src/glibext/configuration.h @@ -0,0 +1,199 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * configuration.h - prototypes pour les éléments de configuration du programme + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _GLIBEXT_CONFIGURATION_H +#define _GLIBEXT_CONFIGURATION_H + + +#include +#include + + + +/* ---------------------------- ELEMENT DE CONFIGURATION ---------------------------- */ + + +/* Types de valeur pour élement de configuration */ +typedef enum _ConfigParamType +{ + CPT_BOOLEAN, /* Valeur booléenne */ + CPT_INTEGER, /* Valeur entière */ + CPT_STRING, /* Chaîne de caractère */ + + CPT_COUNT + +} ConfigParamType; + + +/* Liste dess états d'un paramètre de configuration */ +typedef enum _ConfigParamState +{ + CPS_UNDEFINED = (0 << 0), /* Etat non déterminé */ + CPS_CHANGED = (0 << 1), /* Modification utilisateur */ + CPS_DEFAULT = (1 << 1), /* Valeur par défaut */ + CPS_EMPTY = (1 << 2) /* Valeur vide */ + +} ConfigParamState; + + +#define G_TYPE_CFG_PARAM (g_config_param_get_type()) +#define G_CFG_PARAM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_CFG_PARAM, GCfgParam)) +#define G_IS_CFG_PARAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_CFG_PARAM)) +#define G_CFG_PARAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_CFG_PARAM, GCfgParamClass)) +#define G_IS_CFG_PARAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_CFG_PARAM)) +#define G_CFG_PARAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_CFG_PARAM, GCfgParamClass)) + + +/* Configuration générique quelconque (instance) */ +typedef struct _GCfgParam GCfgParam; + +/* Configuration générique quelconque (classe) */ +typedef struct _GCfgParamClass GCfgParamClass; + + +/* Indique le type défini par la GLib pour les configurations géénriques. */ +GType g_config_param_get_type(void); + +/* Crée un paramètre de configuration. */ +GCfgParam *g_config_param_new(const char *, ConfigParamType, ...); + +/* Crée un paramètre de configuration sans valeur. */ +GCfgParam *g_config_param_new_empty(const char *, ConfigParamType); + +/* Etablit une comparaison selon un chemin d'accès. */ +gint g_config_param_compare(const GCfgParam *, const GCfgParam *); + +/* Indique le chemin d'accès utilisé pour un paramètre. */ +const char *g_config_param_get_path(const GCfgParam *); + +/* Indique le type de valeur utilisée par un paramètre. */ +ConfigParamType g_config_param_get_ptype(const GCfgParam *); + +/* Indique le statut d'une valeur utilisée par un paramètre. */ +ConfigParamState g_config_param_get_state(GCfgParam *); + +/* Efface toute valeur courante d'un paramètre de configuration. */ +void g_config_param_make_empty(GCfgParam *); + +/* Réinitialise la valeur d'un paramètre de configuration. */ +void g_config_param_reset(GCfgParam *); + +/* Modifie la valeur courante d'un paramètre de configuration. */ +void g_config_param_set_value(GCfgParam *, ...); + +/* Indique la valeur courante d'un paramètre de configuration. */ +void g_config_param_get_value(GCfgParam *, ...); + + + +/* ----------------------- GESTION GENERIQUE DE CONFIGURATION ----------------------- */ + + +#define G_TYPE_GEN_CONFIG (g_generic_config_get_type()) +#define G_GEN_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_GEN_CONFIG, GGenConfig)) +#define G_IS_GEN_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_GEN_CONFIG)) +#define G_GEN_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_GEN_CONFIG, GGenConfigClass)) +#define G_IS_GEN_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_GEN_CONFIG)) +#define G_GEN_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_GEN_CONFIG, GGenConfigClass)) + + +/* Configuration générique quelconque (instance) */ +typedef struct _GGenConfig GGenConfig; + +/* Configuration générique quelconque (classe) */ +typedef struct _GGenConfigClass GGenConfigClass; + + +/* Indique le type défini par la GLib pour les configurations génériques. */ +GType g_generic_config_get_type(void); + +/* Crée une description de partie de code vierge. */ +GGenConfig *g_generic_config_new(const char *); + +/* Indique le fichier utilisé pour l'enregistrement XML. */ +const char *g_generic_config_get_filename(const GGenConfig *); + +/* Met à disposition un encadrement des accès aux paramètres. */ +void g_generic_config_lock_unlock(GGenConfig *, bool, bool); + + +#define g_generic_config_wlock(cfg) g_generic_config_lock_unlock(cfg, true, true); +#define g_generic_config_wunlock(cfg) g_generic_config_lock_unlock(cfg, true, false); + +#define g_generic_config_rlock(cfg) g_generic_config_lock_unlock(cfg, false, true); +#define g_generic_config_runlock(cfg) g_generic_config_lock_unlock(cfg, false, false); + + +/* Lit la configuration depuis un fichier. */ +bool g_generic_config_read(GGenConfig *); + +/* Ecrit la configuration dans un fichier. */ +bool g_generic_config_write(GGenConfig *); + +/* Retrouve un élément de configuration par son chemin. */ +GCfgParam *_g_generic_config_search(GGenConfig *, const char *, bool); + + +#define g_generic_config_search(cfg, p) _g_generic_config_search(cfg, p, true) + +#define g_generic_config_set_value(c, p, ...) \ + ({ \ + GCfgParam *__param; \ + __param = g_generic_config_search(c, p); \ + if (__param != NULL) \ + g_config_param_set_value(__param, __VA_ARGS__); \ + __param != NULL ? true : false; \ + }) + +#define g_generic_config_get_value(c, p, ...) \ + ({ \ + GCfgParam *__param; \ + __param = g_generic_config_search(c, p); \ + if (__param != NULL) \ + g_config_param_get_value(__param, __VA_ARGS__); \ + __param != NULL ? true : false; \ + }) + + +/* Ajoute un paramètre à une configuration. */ +GCfgParam *g_generic_config_add_param(GGenConfig *, GCfgParam *); + + +#define g_generic_config_create_param(c, p, t, ...) \ + ({ \ + GCfgParam *__result; \ + __result = g_config_param_new(p, t, __VA_ARGS__); \ + __result = g_generic_config_add_param(c, __result); \ + __result; \ + }) + + +/* Retire un paramètre d'une configuration. */ +void g_generic_config_delete_param(GGenConfig *, const char *); + +/* Renvoie la liste des paramètres de configuration. */ +GList *g_generic_config_list_params(const GGenConfig *); + + + +#endif /* _GLIBEXT_CONFIGURATION_H */ diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c index a289cd0..e610a51 100644 --- a/src/glibext/gbuffersegment.c +++ b/src/glibext/gbuffersegment.c @@ -312,7 +312,7 @@ bool g_buffer_segment_compare(const GBufferSegment *segment, const GBufferSegmen { bool result; /* Bilan à retourner */ - result = cmp_fnv_64a(segment->hash, ref->hash); + result = (cmp_fnv_64a(segment->hash, ref->hash) == 0); result &= (strcmp(segment->text, ref->text) == 0); diff --git a/src/gtkext/gtkdockstation.c b/src/gtkext/gtkdockstation.c index 157b286..b14e299 100644 --- a/src/gtkext/gtkdockstation.c +++ b/src/gtkext/gtkdockstation.c @@ -29,7 +29,7 @@ #include "easygtk.h" -#include "../params.h" +#include "../core/params.h" #include "../common/extstr.h" #include "../glibext/chrysamarshal.h" @@ -231,7 +231,8 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const char *str; /* Titre des prochaines fois */ GtkWidget *label; /* Etiquette d'onglet */ - max = 35; // TODO : config dans un .so pour Python // get_integer_config_value(get_main_configuration(), MPT_ELLIPSIS_TAB); + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_TAB, &max)) + max = -1; str = ellipsis(strdup(caption), max); label = qck_create_label(NULL, NULL, str); @@ -250,7 +251,10 @@ void gtk_dock_panel_add_widget(GtkDockStation *station, GtkWidget *widget, const str = g_object_get_data(G_OBJECT(widget), "title"); if (str != NULL) free(str); - max = 54; // TODO : config dans un .so pour Python // get_integer_config_value(get_main_configuration(), MPT_ELLIPSIS_HEADER); + + if (!g_generic_config_get_value(get_main_configuration(), MPK_ELLIPSIS_HEADER, &max)) + max = -1; + g_object_set_data(G_OBJECT(widget), "title", ellipsis(strdup(desc), max)); gtk_dock_panel_update_title(station, widget, desc); diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am index 12b51cb..0f7768c 100644 --- a/src/gui/panels/Makefile.am +++ b/src/gui/panels/Makefile.am @@ -5,6 +5,7 @@ libguipanels_la_SOURCES = \ glance.h glance.c \ log.h log.c \ panel.h panel.c \ + regedit.h regedit.c \ strings.h strings.c \ symbols.h symbols.c \ welcome.h welcome.c diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c index 9a1e1c2..5a7fc53 100644 --- a/src/gui/panels/panel.c +++ b/src/gui/panels/panel.c @@ -33,6 +33,7 @@ #include "glance.h" #include "log.h" #include "panel-int.h" +#include "regedit.h" #include "strings.h" #include "symbols.h" #include "welcome.h" @@ -372,6 +373,9 @@ void load_main_panels(GObject *ref) g_signal_connect(_nodes->station, "dock-widget", G_CALLBACK(on_docking_to_main_panel), NULL); + item = create_regedit_panel(ref); + g_panel_item_dock(item); + item = create_log_panel(ref); g_panel_item_dock(item); diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c new file mode 100644 index 0000000..77fea39 --- /dev/null +++ b/src/gui/panels/regedit.c @@ -0,0 +1,1071 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * regedit.c - panneau d'affichage des paramètres de configuration + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 "regedit.h" + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "panel-int.h" +#include "../../core/params.h" +#include "../../common/cpp.h" +#include "../../common/extstr.h" +#include "../../gtkext/easygtk.h" + + + +/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ + + +/* Panneau d'affichage des paramètres de configuration (instance) */ +struct _GRegeditPanel +{ + GPanelItem parent; /* A laisser en premier */ + + GtkTreeView *treeview; /* Composant d'affichage */ + regex_t *filter; /* Filtre appliqué ou NULL */ + + GtkMenu *menu; /* Menu contextuel pour param. */ + +}; + +/* Panneau d'affichage des paramètres de configuration (classe) */ +struct _GRegeditPanelClass +{ + GPanelItemClass parent; /* A laisser en premier */ + +}; + + +/* Colonnes de la liste des messages */ +typedef enum _CfgParamColumn +{ + CPC_PARAM, /* Paramètre présenté */ + CPC_BOLD, /* Visuel des changements */ + + CPC_PATH, /* Chemin d'accès à une valeur */ + CPC_STATUS, /* Etat de la définition */ + CPC_TYPE, /* Type de paramètre */ + CPC_VALUE, /* Valeur courante */ + + LGC_COUNT /* Nombre de colonnes */ + +} CfgParamColumn; + + + + +/* Initialise la classe des panneaux des paramètres de config. */ +static void g_regedit_panel_class_init(GRegeditPanelClass *); + +/* Initialise une instance de panneau de paramètres de config. */ +static void g_regedit_panel_init(GRegeditPanel *); + +/* Supprime toutes les références externes. */ +static void g_regedit_panel_dispose(GRegeditPanel *); + +/* Procède à la libération totale de la mémoire. */ +static void g_regedit_panel_finalize(GRegeditPanel *); + + + +/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */ + + +/* Recharge une configuration donnée à l'affichage. */ +static void reload_config_into_treeview(GRegeditPanel *, GGenConfig *); + +/* Actualise l'affichage des données d'un paramètre modifié. */ +static void on_config_param_modified(GCfgParam *, GRegeditPanel *); + +/* Actualise la valeur affichée d'un paramètre de configuration. */ +static void update_config_param_value(GtkTreeStore *, GtkTreeIter *); + +/* Etablit une comparaison entre deux lignes de paramètres. */ +static gint compare_config_list_columns(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer); + +/* Réagit à une pression sur et simule l'édition. */ +static gboolean on_key_pressed_over_params(GtkTreeView *, GdkEventKey *, GRegeditPanel *); + +/* Réagit à une édition de la valeur d'un paramètre. */ +static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTreeStore *); + + + +/* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */ + + +/* Démarre l'actualisation du filtrage des paramètres. */ +static void on_param_search_changed(GtkSearchEntry *, GRegeditPanel *); + +/*Détermine si un paramètre doit être filtré ou non. */ +static bool is_param_filtered(GRegeditPanel *, const char *); + + + +/* ------------------------ ATTRIBUTION D'UN MENU CONTEXTUEL ------------------------ */ + + +/* Assure la gestion des clics de souris sur les paramètres. */ +static gboolean on_button_press_over_params(GtkWidget *, GdkEventButton *, GRegeditPanel *); + +/* Construit le menu contextuel pour les paramètres. */ +GtkMenu *build_param_panel_menu(GRegeditPanel *); + +/* Fournit le paramètre sélectionné dans la liste. */ +static GCfgParam *get_selected_panel_param(GtkTreeView *, GtkTreeIter *); + +/* Réagit avec le menu "Copier le nom". */ +static void mcb_param_panel_copy(GtkMenuItem *, GRegeditPanel *); + +/* Réagit avec le menu "Valeur néant". */ +static void mcb_param_panel_empty(GtkMenuItem *, GRegeditPanel *); + +/* Réagit avec le menu "Réinitialiser la valeur". */ +static void mcb_param_panel_reset(GtkMenuItem *, GRegeditPanel *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE PRINCIPALE DU PANNEAU */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type définit pour un panneau d'aperçu de graphiques. */ +G_DEFINE_TYPE(GRegeditPanel, g_regedit_panel, G_TYPE_PANEL_ITEM); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des panneaux des paramètres de config. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_class_init(GRegeditPanelClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_regedit_panel_dispose; + object->finalize = (GObjectFinalizeFunc)g_regedit_panel_finalize; + + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance à initialiser. * +* * +* Description : Initialise une instance de panneau de paramètres de config. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_init(GRegeditPanel *panel) +{ + GEditorItem *base; /* Version basique d'instance */ + GObject *ref; /* Espace de référencement */ + GtkWidget *label; /* Etiquette à utiliser */ + GtkWidget *search; /* Zone de recherche */ + GtkWidget *scrolled; /* Fenêtre défilante */ + GtkTreeStore *store; /* Modèle de gestion */ + GtkWidget *treeview; /* Affichage de la liste */ + GtkCellRenderer *renderer; /* Moteur de rendu de colonne */ + GtkTreeViewColumn *column; /* Colonne de la liste */ + GtkTreeSortable *sortable; /* Autre vision de la liste */ + + base = G_EDITOR_ITEM(panel); + + base->widget = gtk_grid_new(); + gtk_widget_show(base->widget); + + gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8); + + ref = G_OBJECT(base->widget); + g_object_set_data(ref, "panel", panel); + + /* Partie recherche */ + + label = qck_create_label(NULL, NULL, _("Look for:")); + g_object_set(label, "margin", 8, NULL); + gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1); + + search = gtk_search_entry_new(); + g_signal_connect(search, "search-changed", G_CALLBACK(on_param_search_changed), panel); + gtk_widget_show(search); + gtk_widget_set_hexpand(search, TRUE); + gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1); + + /* Partie paramètres */ + + scrolled = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolled); + gtk_widget_set_vexpand(scrolled, TRUE); + gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1); + + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); + + store = gtk_tree_store_new(LGC_COUNT, G_TYPE_OBJECT, G_TYPE_INT, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); + + treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); + panel->treeview = GTK_TREE_VIEW(treeview); + + g_signal_connect(G_OBJECT(treeview), "button-press-event", + G_CALLBACK(on_button_press_over_params), panel); + g_signal_connect(G_OBJECT(treeview), "key-press-event", + G_CALLBACK(on_key_pressed_over_params), panel); + + gtk_widget_show(treeview); + gtk_container_add(GTK_CONTAINER(scrolled), treeview); + + g_object_unref(G_OBJECT(store)); + + /* Cellule d'affichage */ + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Access path"), renderer, + "text", CPC_PATH, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_PATH); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Status"), renderer, + "text", CPC_STATUS, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_STATUS); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, + "text", CPC_TYPE, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_TYPE); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + renderer = gtk_cell_renderer_text_new(); + g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL); + g_signal_connect(renderer, "edited", G_CALLBACK(on_param_value_edited), store); + column = gtk_tree_view_column_new_with_attributes(_("Value"), renderer, + "text", CPC_VALUE, + "weight", CPC_BOLD, + NULL); + gtk_tree_view_column_set_sort_column_id(column, CPC_VALUE); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); + + /* Tri de la liste */ + + sortable = GTK_TREE_SORTABLE(store); + + gtk_tree_sortable_set_sort_func(sortable, CPC_PATH, compare_config_list_columns, + GINT_TO_POINTER(CPC_PATH), NULL); + + gtk_tree_sortable_set_sort_func(sortable, CPC_STATUS, compare_config_list_columns, + GINT_TO_POINTER(CPC_STATUS), NULL); + + gtk_tree_sortable_set_sort_func(sortable, CPC_TYPE, compare_config_list_columns, + GINT_TO_POINTER(CPC_TYPE), NULL); + + gtk_tree_sortable_set_sort_func(sortable, CPC_VALUE, compare_config_list_columns, + GINT_TO_POINTER(CPC_VALUE), NULL); + + gtk_tree_sortable_set_sort_column_id(sortable, CPC_PATH, GTK_SORT_ASCENDING); + + /* Préparation du menu contextuel */ + + panel->menu = build_param_panel_menu(panel); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_dispose(GRegeditPanel *panel) +{ + G_OBJECT_CLASS(g_regedit_panel_parent_class)->dispose(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_regedit_panel_finalize(GRegeditPanel *panel) +{ + if (panel->filter != NULL) + regfree(panel->filter); + + G_OBJECT_CLASS(g_regedit_panel_parent_class)->finalize(G_OBJECT(panel)); + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Crée un panneau d'affichage des paramètres de configuration. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GEditorItem *g_regedit_panel_new(GObject *ref) +{ + GEditorItem *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_REGEDIT_PANEL, NULL); + + g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_REGEDIT_ID, + _("Configuration parameters"), G_EDITOR_ITEM(result)->widget, "M"); + + reload_config_into_treeview(G_REGEDIT_PANEL(result), get_main_configuration()); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Construit le panneau d'affichage des messages système. * +* * +* Retour : Adresse du panneau mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GPanelItem *create_regedit_panel(GObject *ref) +{ + GEditorItem *result; /* Elément réactif à renvoyer */ + + result = g_regedit_panel_new(ref); + + /* Enregistre correctement le tout */ + register_editor_item(result); + + return G_PANEL_ITEM(result); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* AFFICHAGE A L'AIDE D'UNE LISTE */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : panel = panneau d'affichage de paramètres de configuration. * +* config = configuration à présenter à l'écran. * +* * +* Description : Recharge une configuration donnée à l'affichage. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void reload_config_into_treeview(GRegeditPanel *panel, GGenConfig *config) +{ + GtkTreeStore *store; /* Modèle de gestion */ + GList *params; /* Paramètres de configuration */ + GCfgParam *param; /* Paramètre en cours d'étude */ + GList *p; /* Boucle de parcours */ + char *type_desc; /* Type de paramètre */ + GtkTreeIter iter; /* Point d'insertion */ + + store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview)); + gtk_tree_store_clear(store); + + g_generic_config_rlock(config); + + params = g_generic_config_list_params(config); + + for (p = g_list_first(params); p != NULL; p = g_list_next(p)) + { + param = G_CFG_PARAM(p->data); + + if (is_param_filtered(panel, g_config_param_get_path(param))) + continue; + + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + type_desc = _("Boolean"); + break; + + case CPT_INTEGER: + type_desc = _("Integer"); + break; + + case CPT_STRING: + type_desc = _("String"); + break; + + default: + type_desc = _(""); + break; + + } + + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, + CPC_PARAM, param, + CPC_PATH, g_config_param_get_path(param), + CPC_TYPE, type_desc, + -1); + + update_config_param_value(store, &iter); + + g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), panel); + + } + + g_generic_config_runlock(config); + +} + + +/****************************************************************************** +* * +* Paramètres : param = instance dont le contenu a évolué. * +* panel = panneau d'affichage de paramètres à mettre à jour. * +* * +* Description : Actualise l'affichage des données d'un paramètre modifié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_config_param_modified(GCfgParam *param, GRegeditPanel *panel) +{ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreeIter iter; /* Point de recherche */ + gboolean looping; /* Autorisation de bouclage */ + GCfgParam *item; /* Elément de la liste */ + + model = gtk_tree_view_get_model(panel->treeview); + + for (looping = gtk_tree_model_get_iter_first (model, &iter); + looping; + looping = gtk_tree_model_iter_next(model, &iter)) + { + gtk_tree_model_get(model, &iter, CPC_PARAM, &item, -1); + + if (item == param) + { + update_config_param_value(GTK_TREE_STORE(model), &iter); + break; + } + + } + +} + + +/****************************************************************************** +* * +* Paramètres : store = gestionnaire du tableau de données. * +* iter = point de modification dans les lignes. * +* param = paramètre dont la valeur est à afficher. * +* * +* Description : Actualise la valeur affichée d'un paramètre de configuration.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void update_config_param_value(GtkTreeStore *store, GtkTreeIter *iter) +{ + GCfgParam *param; /* Paramètre à consulter */ + ConfigParamState state; /* Etat du paramètre */ + char *state_desc; /* Version chaînée de l'état */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char int_val[sizeof(XSTR(INT_MIN)) + 1];/* Valeur en chaîne de carac. */ + char *string; /* Chaîne de caractères */ + char *desc; /* Description à afficher */ + + gtk_tree_model_get(GTK_TREE_MODEL(store), iter, CPC_PARAM, ¶m, -1); + + state = g_config_param_get_state(param); + + if (state & CPS_DEFAULT) + state_desc = strdup(_("By default")); + else + state_desc = strdup(_("Changed")); + + if (state & CPS_EMPTY) + state_desc = stradd(state_desc, _(" + empty")); + + if (state & CPS_EMPTY) + desc = ""; + + else + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + g_config_param_get_value(param, &boolean); + desc = (boolean ? _("true") : _("false")); + break; + + case CPT_INTEGER: + g_config_param_get_value(param, &integer); + snprintf(int_val, sizeof(int_val), "%d", integer); + desc = int_val; + break; + + case CPT_STRING: + g_config_param_get_value(param, &string); + desc = (string != NULL ? string : ""); + break; + + default: + assert(false); + desc = "???"; + break; + + } + + gtk_tree_store_set(store, iter, + CPC_BOLD, state & CPS_DEFAULT ? 400 : 800, + CPC_STATUS, state_desc, + CPC_VALUE, desc, -1); + + free(state_desc); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : model = gestionnaire du tableau de données. * +* a = première ligne de données à traiter. * +* b = seconde ligne de données à traiter. * +* column = indice de la colonne à considérer, encodée. * +* * +* Description : Etablit une comparaison entre deux lignes de paramètres. * +* * +* Retour : Indication de tri entre les deux lignes fournies. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gint compare_config_list_columns(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer column) +{ + gint result; /* Valeur calculée à retourner */ + gchar *value_a; /* Cellule de la ligne 'a' */ + gchar *value_b; /* Cellule de la ligne 'b' */ + + gtk_tree_model_get(model, a, GPOINTER_TO_INT(column), &value_a, -1); + gtk_tree_model_get(model, b, GPOINTER_TO_INT(column), &value_b, -1); + + if (value_a == NULL || value_b == NULL) + { + if (value_a == NULL && value_b == NULL) + result = 0; + else + result = (value_a == NULL ? -1 : 1); + } + else + result = g_utf8_collate(value_a,value_b); + + g_free(value_a); + g_free(value_b); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : treeview = composant graphique présentant les paramètres. * +* event = informations liées à l'événement. * +* panel = panneau d'affichage sur lequel s'appuyer. * +* * +* Description : Réagit à une pression sur et simule l'édition. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean on_key_pressed_over_params(GtkTreeView *treeview, GdkEventKey *event, GRegeditPanel *panel) +{ + const gchar *accelerator; /* Combinaison de raccourci */ + guint accel_key; /* Touche de raccourci */ + GdkModifierType accel_mod; /* Modifiateurs attendus aussi */ + GtkTreeIter iter; /* Point de la sélection */ + GtkTreeModel *model; /* Gestionnaire de données */ + GtkTreePath *path; /* Chemin d'accès à ce point */ + + if (!g_generic_config_get_value(get_main_configuration(), MPK_KEYBINDINGS_EDIT, &accelerator)) + return FALSE; + + if (accelerator == NULL) + return FALSE; + + gtk_accelerator_parse(accelerator, &accel_key, &accel_mod); + + if (event->keyval == accel_key && event->state == accel_mod) + { + if (get_selected_panel_param(treeview, &iter) != NULL) + { + model = gtk_tree_view_get_model(treeview); + path = gtk_tree_model_get_path(model, &iter); + + gtk_tree_view_set_cursor(treeview, path, + gtk_tree_view_get_column(treeview, CPC_VALUE - CPC_PATH), + TRUE); + + gtk_tree_path_free(path); + + } + + } + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : renderer = moteur de rendu pour la cellule. * +* path = chemin d'accès vers la cellule éditée. * +* new = nouvelle valeur sous forme de texte à valider. * +* store = gestionnaire des données de la liste affichée. * +* * +* Description : Réagit à une édition de la valeur d'un paramètre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeStore *store) +{ + GtkTreePath *tree_path; /* Chemin d'accès natif */ + GtkTreeIter iter; /* Point de la modification */ + GCfgParam *param; /* Paramètre à actualiser */ + bool boolean; /* Valeur booléenne */ + int integer; /* Valeur entière */ + char *end; /* Pointeur vers '\0' final ? */ + + tree_path = gtk_tree_path_new_from_string(path); + if (tree_path == NULL) return; + + if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tree_path)) + goto opve_bad_iter; + + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, CPC_PARAM, ¶m, -1); + + switch (g_config_param_get_ptype(param)) + { + case CPT_BOOLEAN: + + if (strcmp(new, "true") != 0 && strcmp(new, "false") != 0) + goto opve_bad_value; + + boolean = (strcmp(new, "true") == 0); + g_config_param_set_value(param, boolean); + + break; + + case CPT_INTEGER: + + integer = strtol(new, &end, 10); + if (*end != '\0') goto opve_bad_value; + + g_config_param_set_value(param, integer); + + break; + + case CPT_STRING: + g_config_param_set_value(param, new); + break; + + default: + assert(false); + goto opve_bad_value; + break; + + } + + opve_bad_value: + + g_object_unref(G_OBJECT(param)); + + opve_bad_iter: + + gtk_tree_path_free(tree_path); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* FILTRAGE DES SYMBOLES PRESENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : entry = entrée de texte contenant le filtre brut. * +* panel = panneau assurant l'affichage des paramètres. * +* * +* Description : Démarre l'actualisation du filtrage des paramètres. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_param_search_changed(GtkSearchEntry *entry, GRegeditPanel *panel) +{ + const gchar *text; /* Texte de l'utilisateur */ + int ret; /* Bilan de mise en place */ + GdkRGBA error; /* Couleur d'erreur */ + + if (panel->filter != NULL) + { + regfree(panel->filter); + free(panel->filter); + panel->filter = NULL; + } + + text = gtk_entry_get_text(GTK_ENTRY(entry)); + + if (strlen(text) > 0) + { + panel->filter = (regex_t *)calloc(1, sizeof(regex_t)); + ret = regcomp(panel->filter, text, REG_EXTENDED); + + if (ret != 0) + { + free(panel->filter); + panel->filter = NULL; + + error.red = 1.0; + error.green = 0.0; + error.blue = 0.0; + error.alpha = 1.0; + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error); + + return; + + } + + } + + gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL); + + reload_config_into_treeview(panel, get_main_configuration()); + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau assurant l'affichage des paramètres. * +* name = chemin d'accès au paramètre à traiter. * +* * +* Description : Détermine si un paramètre doit être filtré ou non. * +* * +* Retour : true si le paramètre ne doit pas être affiché, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool is_param_filtered(GRegeditPanel *panel, const char *name) +{ + regmatch_t match; /* Récupération des trouvailles*/ + int ret; /* Bilan du filtrage */ + + if (panel->filter == NULL) + return false; + + ret = regexec(panel->filter, name, 1, &match, 0); + if (ret == REG_NOMATCH) + return true; + + return false; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* ATTRIBUTION D'UN MENU CONTEXTUEL */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : widget = composant GTK visé par l'opération. * +* event = informations liées à l'événement. * +* panel = informations liées au panneau associé. * +* * +* Description : Assure la gestion des clics de souris sur les paramètres. * +* * +* Retour : FALSE pour poursuivre la propagation de l'événement. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static gboolean on_button_press_over_params(GtkWidget *widget, GdkEventButton *event, GRegeditPanel *panel) +{ + if (event->button == 3) + gtk_menu_popup(panel->menu, NULL, NULL, NULL, NULL, event->button, event->time); + + return FALSE; + +} + + +/****************************************************************************** +* * +* Paramètres : panel = panneau d'affichage des paramètres de configuration. * +* * +* Description : Construit le menu contextuel pour les paramètres. * +* * +* Retour : Panneau de menus mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkMenu *build_param_panel_menu(GRegeditPanel *panel) +{ + GtkWidget *result; /* Support à retourner */ + GtkWidget *submenuitem; /* Sous-élément de menu */ + + result = gtk_menu_new(); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Copy the name"), G_CALLBACK(mcb_param_panel_copy), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_separator(); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Make empty"), G_CALLBACK(mcb_param_panel_empty), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + submenuitem = qck_create_menu_item(NULL, NULL, _("Reset"), G_CALLBACK(mcb_param_panel_reset), panel); + gtk_container_add(GTK_CONTAINER(result), submenuitem); + + return GTK_MENU(result); + +} + + +/****************************************************************************** +* * +* Paramètres : treeview = liste d'affichage à consulter. * +* save = zone de conservation du point de trouvaille. [OUT]* +* * +* Description : Fournit le paramètre sélectionné dans la liste. * +* * +* Retour : Paramètre en cours d'édition ou NULL en cas de soucis. * +* * +* Remarques : Le résultat non nul est à déréférencer après usage. * +* * +******************************************************************************/ + +static GCfgParam *get_selected_panel_param(GtkTreeView *treeview, GtkTreeIter *save) +{ + GCfgParam *result; /* Paramètre à renvoyer */ + GtkTreeSelection *selection; /* Représentation de sélection */ + GtkTreeModel *model; /* Gestionnaire des données */ + GtkTreeIter iter; /* Point de la sélection */ + + result = NULL; + + selection = gtk_tree_view_get_selection(treeview); + + if (gtk_tree_selection_get_selected(selection, &model, &iter)) + gtk_tree_model_get(model, &iter, CPC_PARAM, &result, -1); + + if (save != NULL) + *save = iter; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des paramètres de config. * +* * +* Description : Réagit avec le menu "Copier le nom". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_param_panel_copy(GtkMenuItem *menuitem, GRegeditPanel *panel) +{ + GCfgParam *param; /* Paramètre sélectionné */ + const char *content; /* Prochain contenu à diffuser */ + gint clen; /* Taille de ce contenu */ + GtkClipboard *clipboard; /* Presse-papiers à remplir */ + + param = get_selected_panel_param(panel->treeview, NULL); + if (param == NULL) return; + + content = g_config_param_get_path(param); + clen = g_utf8_strlen(content, -1); + + clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text(clipboard, content, clen); + + clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clipboard, content, clen); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des paramètres de config. * +* * +* Description : Réagit avec le menu "Valeur néant". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_param_panel_empty(GtkMenuItem *menuitem, GRegeditPanel *panel) +{ + GCfgParam *param; /* Paramètre sélectionné */ + + param = get_selected_panel_param(panel->treeview, NULL); + if (param == NULL) return; + + g_config_param_make_empty(param); + + g_object_unref(G_OBJECT(param)); + +} + + +/****************************************************************************** +* * +* Paramètres : menuitem = élément de menu sélectionné. * +* panel = panneau d'affichage des paramètres de config. * +* * +* Description : Réagit avec le menu "Réinitialiser". * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void mcb_param_panel_reset(GtkMenuItem *menuitem, GRegeditPanel *panel) +{ + GCfgParam *param; /* Paramètre sélectionné */ + + param = get_selected_panel_param(panel->treeview, NULL); + if (param == NULL) return; + + g_config_param_reset(param); + + g_object_unref(G_OBJECT(param)); + +} diff --git a/src/gui/panels/regedit.h b/src/gui/panels/regedit.h new file mode 100644 index 0000000..7166168 --- /dev/null +++ b/src/gui/panels/regedit.h @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * regedit.h - prototypes pour le panneau d'affichage des paramètres de configuration + * + * Copyright (C) 2014 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * 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 _GUI_PANELS_REGEDIT_H +#define _GUI_PANELS_REGEDIT_H + + +#include + + +#include "panel.h" + + + +#define PANEL_REGEDIT_ID _("Configuration") + + +#define G_TYPE_REGEDIT_PANEL g_regedit_panel_get_type() +#define G_REGEDIT_PANEL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_regedit_panel_get_type(), GRegeditPanel)) +#define G_IS_REGEDIT_PANEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_regedit_panel_get_type())) +#define G_REGEDIT_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_REGEDIT_PANEL, GRegeditPanelClass)) +#define G_IS_REGEDIT_PANEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_REGEDIT_PANEL)) +#define G_REGEDIT_PANEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_REGEDIT_PANEL, GRegeditPanelClass)) + + +/* Panneau d'affichage des paramètres de configuration (instance) */ +typedef struct _GRegeditPanel GRegeditPanel; + +/* Panneau d'affichage des paramètres de configuration (classe) */ +typedef struct _GRegeditPanelClass GRegeditPanelClass; + + +/* Indique le type définit pour un panneau d'affichage des paramètres de configuration. */ +GType g_regedit_panel_get_type(void); + +/* Crée un panneau d'affichage des paramètres de configuration. */ +GEditorItem *g_regedit_panel_new(GObject *); + +/* Construit le panneau d'affichage des messages système. */ +GPanelItem *create_regedit_panel(GObject *); + + + +#endif /* _GUI_PANELS_REGEDIT_H */ diff --git a/src/gui/panels/symbols.c b/src/gui/panels/symbols.c index e9cc637..064c31d 100644 --- a/src/gui/panels/symbols.c +++ b/src/gui/panels/symbols.c @@ -44,7 +44,7 @@ /* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */ -/* Panneau d'aperçu de graphiques (instance) */ +/* Panneau d'affichage des symboles (instance) */ struct _GSymbolsPanel { GPanelItem parent; /* A laisser en premier */ @@ -58,7 +58,7 @@ struct _GSymbolsPanel }; -/* Panneau d'aperçu de graphiques (classe) */ +/* Panneau d'affichage des symboles (classe) */ struct _GSymbolsPanelClass { GPanelItemClass parent; /* A laisser en premier */ diff --git a/src/main.c b/src/main.c index b9764ca..0fdfe31 100644 --- a/src/main.c +++ b/src/main.c @@ -30,10 +30,11 @@ #include #include "editor.h" -#include "params.h" #include "project.h" #include "analysis/db/server.h" #include "arch/processor.h" +#include "core/core.h" +#include "core/params.h" #include "format/format.h" #include "glibext/delayed.h" #include "glibext/gbinportion.h" @@ -42,11 +43,9 @@ #include "../revision.h" +// TODO : remme! #include "format/mangling/itanium/abi.h" - - -/* params.c : configuration générale */ -extern config_param main_params[MPT_COUNT]; +#include "analysis/db/cdb.h" @@ -66,7 +65,7 @@ static void show_version(void) { printf("\n"); - printf("-o- OpenIDA r%u -o-\n", REVISION); + printf("-o- Chrysalide r%u -o-\n", REVISION); printf(_("Last compiled on %s at %s\n"), __DATE__, __TIME__); printf("\n"); @@ -78,7 +77,7 @@ static void show_version(void) printf("\n"); } -#include "analysis/db/cdb.h" + /****************************************************************************** * * @@ -95,7 +94,6 @@ static void show_version(void) int main(int argc, char **argv) { - configuration *config; /* Configuration principale */ GtkWidget *editor; /* Fenêtre graphique */ GDbServer *server; /* Enregistrements locaux */ const char *filename; /* Chemin du dernier projet */ @@ -107,9 +105,6 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } - config = load_configuration("main", main_params, MPT_COUNT); - set_main_configuration(config); - setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALE_DIR); textdomain(PACKAGE); @@ -119,6 +114,9 @@ int main(int argc, char **argv) setlocale (LC_ALL, ""); gtk_init(&argc, &argv); + if (!load_all_basic_components()) + return EXIT_FAILURE; + /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared @@ -176,7 +174,8 @@ int main(int argc, char **argv) /* Charge le dernier projet */ - filename = get_string_config_value(config, MPT_LAST_PROJECT); + if (!g_generic_config_get_value(get_main_configuration(), MPK_LAST_PROJECT, &filename)) + filename = NULL; if (filename == NULL) project = g_study_project_new(G_OBJECT(editor)); else project = g_study_project_open(G_OBJECT(editor), filename); @@ -193,7 +192,7 @@ int main(int argc, char **argv) exit_binary_portion_colors(); - unload_configuration(config); + unload_all_basic_components(); return EXIT_SUCCESS; diff --git a/src/params.c b/src/params.c deleted file mode 100644 index db57951..0000000 --- a/src/params.c +++ /dev/null @@ -1,61 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * params.c - éléments de la configuration principale - * - * Copyright (C) 2009-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * 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" - - - -config_param main_params[MPT_COUNT] = { - - [MPT_LAST_PROJECT] = { "/OpenIDA/Editor/LastProject", CVT_STRING, false, { .string = NULL } }, - [MPT_ELLIPSIS_HEADER] = { "/OpenIDA/Editor/Panels/ellipsis_header", CVT_INTEGER, false, { .integer = 54 } }, - [MPT_ELLIPSIS_TAB] = { "/OpenIDA/Editor/Panels/ellipsis_tab", CVT_INTEGER, false, { .integer = 35 } }, - - [MPT_AUTO_SAVE] = { "/OpenIDA/Project/Autosave", CVT_BOOLEAN, false, { .boolean = true } }, - -}; - - - -/****************************************************************************** -* * -* 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 deleted file mode 100644 index 47c822d..0000000 --- a/src/params.h +++ /dev/null @@ -1,61 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * params.h - prototypes pour les éléments de la configuration principale - * - * Copyright (C) 2009-2012 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * 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_LAST_PROJECT, /* Dernier projet ouvert */ - MPT_ELLIPSIS_HEADER, /* Titre supérieur des panneaux*/ - MPT_ELLIPSIS_TAB, /* Titre inférieur des panneaux*/ - - MPT_AUTO_SAVE, /* Sauvegarde automatique ? */ - - MPT_COUNT - -} MainParamType; - - -#define set_main_configuration(cfg) _get_main_configuration(cfg) -#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 bc3ec66..a555f2d 100644 --- a/src/project.c +++ b/src/project.c @@ -29,9 +29,9 @@ #include -#include "params.h" -#include "common/xml.h" #include "analysis/binaries/file.h" +#include "common/xml.h" +#include "core/params.h" #include "gtkext/easygtk.h" #include "gtkext/gtkblockview.h" #include "gtkext/gtkgraphview.h" @@ -685,10 +685,6 @@ void push_project_into_recent_list(const GStudyProject *project) /* Pour la prochaine ouverture du programme... */ - set_string_config_value(get_main_configuration(), MPT_LAST_PROJECT, project->filename); - - /* Pour la prochaine ouverture du programme... */ - - set_string_config_value(get_main_configuration(), MPT_LAST_PROJECT, project->filename); + g_generic_config_set_value(get_main_configuration(), MPK_LAST_PROJECT, project->filename); } -- cgit v0.11.2-87-g4458