diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-07-10 14:47:37 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-07-10 14:47:37 (GMT) |
commit | db863244b804cbf4c06399f7c6f8241d91c9ee9b (patch) | |
tree | da7cc911b0f10c5122536271235ab68f2202804a /plugins/pychrysa/glibext | |
parent | e8aa314462196cc9e8461ae23eb13f8bffcc983f (diff) |
Fully rewritten the core configuration system.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@381 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/pychrysa/glibext')
-rw-r--r-- | plugins/pychrysa/glibext/Makefile.am | 8 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/configuration.c | 1214 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/configuration.h | 66 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/module.c | 49 | ||||
-rw-r--r-- | plugins/pychrysa/glibext/module.h | 6 |
5 files changed, 1326 insertions, 17 deletions
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 <pygobject.h> + + +#include <glibext/configuration.h> + + + +/* ---------------------------- 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 <Python.h> +#include <stdbool.h> + + + +/* ---------------------------- 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 <Python.h> |