From 859bdb6b51d76058eb1a8bfa619a15978f50b251 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sat, 19 Sep 2009 13:01:04 +0000 Subject: Improved the pyoida module. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@116 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 81 +++- configure.ac | 2 + plugins/Makefile.am | 2 +- plugins/pyoida/Makefile.am | 22 + plugins/pyoida/analysis/Makefile.am | 17 + plugins/pyoida/analysis/py_binary.c | 360 +++++++++++++++ plugins/pyoida/analysis/py_binary.h | 45 ++ plugins/pyoida/analysis/py_line-int.h | 53 +++ plugins/pyoida/analysis/py_line.c | 603 ++++++++++++++++++++++++ plugins/pyoida/analysis/py_line.h | 45 ++ plugins/pyoida/analysis/py_line_code.c | 281 ++++++++++++ plugins/pyoida/analysis/py_line_code.h | 45 ++ plugins/pyoida/linsyscalls/oidapgi.py | 28 ++ plugins/pyoida/py_log.c | 341 ++++++++++++++ plugins/pyoida/py_log.h | 39 ++ plugins/pyoida/pyoida.c | 134 ++++++ plugins/pyoida/pyoida.h | 38 ++ src/Makefile.am | 3 +- src/analysis/binary.c | 4 +- src/analysis/binary.h | 2 +- src/common/Makefile.am | 7 +- src/common/xml.c | 809 +++++++++++++++++++++++++++++++++ src/common/xml.h | 122 +++++ src/configuration.c | 2 +- src/plugins/pglist.c | 2 +- src/plugins/plugin.c | 4 +- src/project.c | 2 +- src/shell.c | 37 +- src/xml.c | 809 --------------------------------- src/xml.h | 122 ----- 30 files changed, 3104 insertions(+), 957 deletions(-) create mode 100644 plugins/pyoida/Makefile.am create mode 100644 plugins/pyoida/analysis/Makefile.am create mode 100644 plugins/pyoida/analysis/py_binary.c create mode 100644 plugins/pyoida/analysis/py_binary.h create mode 100644 plugins/pyoida/analysis/py_line-int.h create mode 100644 plugins/pyoida/analysis/py_line.c create mode 100644 plugins/pyoida/analysis/py_line.h create mode 100644 plugins/pyoida/analysis/py_line_code.c create mode 100644 plugins/pyoida/analysis/py_line_code.h create mode 100755 plugins/pyoida/linsyscalls/oidapgi.py create mode 100644 plugins/pyoida/py_log.c create mode 100644 plugins/pyoida/py_log.h create mode 100644 plugins/pyoida/pyoida.c create mode 100644 plugins/pyoida/pyoida.h create mode 100644 src/common/xml.c create mode 100644 src/common/xml.h delete mode 100644 src/xml.c delete mode 100644 src/xml.h diff --git a/ChangeLog b/ChangeLog index 4711c05..a0e9573 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,82 @@ +09-09-19 Cyrille Bagard + + * configure.ac: + Add the new Makefile from the 'plugins/pyoida/Makefile' and + 'plugins/pyoida/analysis/Makefile' directories to AC_CONFIG_FILES. + + * plugins/Makefile.am: + Add pyoida to SUBDIRS. + + * plugins/pyoida/analysis/Makefile.am: + New entry: compile the analysis part of the pyoida module. + + * plugins/pyoida/analysis/py_binary.c: + * plugins/pyoida/analysis/py_binary.h: + * plugins/pyoida/analysis/py_line.c: + * plugins/pyoida/analysis/py_line.h: + Moved entries: update and clean the code. + + * plugins/pyoida/analysis/py_line_code.c: + * plugins/pyoida/analysis/py_line_code.h: + New entries: create PyCodeLine objects based on PyLine ones. + + * plugins/pyoida/analysis/py_line-int.h: + New entry: define the internals of PyLine. + + * plugins/pyoida/Makefile.am: + Rename the library, abandoning the Automake canonical name for the one + recognized by Python. Remove py_binary.[ch] and py_line.[ch] from + {libpyoida|pyoida}_la_SOURCES. Add analysis/libpyoidaanalysis.la to + pyoida_la_LIBADD and update pyoida_la_LDFLAGS. + + * plugins/pyoida/py_binary.c: + * plugins/pyoida/py_binary.h: + * plugins/pyoida/py_line.c: + * plugins/pyoida/py_line.h: + Moved entries (see plugins/pyoida/analysis/). + + * plugins/pyoida/py_log.c: + Update included headers path. + + * plugins/pyoida/pyoida.c: + Update code (openida_binary -> GOpenidaBinary). Load the PyCodeLine objects. + + * src/analysis/binary.c: + Typo. + + * src/analysis/binary.h: + Update included headers path. + + * src/common/Makefile.am: + Add xml.[ch] to libcommon_a_SOURCES, '$(LIBGTK_LIBS) $(LIBXML_LIBS)' to + libcommon_la_LDFLAGS and '$(LIBGTK_CFLAGS) $(LIBXML_CFLAGS)' to INCLUDES. + + * src/common/xml.c: + * src/common/xml.h: + New entries: moved from the upper directory. Update included headers path. + + * src/configuration.c: + Update included headers path. + + * src/Makefile.am: + Remove the xml.[ch] files from openida_SOURCES. + + * src/plugins/pglist.c: + Enable plugins. + + * src/plugins/plugin.c: + Do not look for the full plugin interface. + + * src/project.c: + Update included headers path. + + * src/shell.c + Try to deal with the terminal. + + * src/xml.c: + * src/xml.h: + Moved entries (see src/common/). + 09-09-15 Cyrille Bagard * src/format/elf/elf.c: @@ -359,7 +438,7 @@ Init all formats. * src/Makefile.am: - Remove the pan_strings.[ch] from openida_SOURCES. + Remove the pan_strings.[ch] files from openida_SOURCES. * src/panel/Makefile.am: Add the strings.[ch] files to libpanel_a_SOURCES. diff --git a/configure.ac b/configure.ac index dc2f498..18be62a 100644 --- a/configure.ac +++ b/configure.ac @@ -232,6 +232,8 @@ AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64,UINT64\nVOID:OBJECT\nVOID:OB AC_CONFIG_FILES([Makefile pixmaps/Makefile plugins/Makefile + plugins/pyoida/Makefile + plugins/pyoida/analysis/Makefile plugins/stackvars/Makefile src/Makefile src/analysis/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index f2c6152..379beaa 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = stackvars +SUBDIRS = pyoida stackvars diff --git a/plugins/pyoida/Makefile.am b/plugins/pyoida/Makefile.am new file mode 100644 index 0000000..1dd0d1f --- /dev/null +++ b/plugins/pyoida/Makefile.am @@ -0,0 +1,22 @@ + +pkglib_LTLIBRARIES = pyoida.la + +pyoida_la_SOURCES = \ + py_log.h py_log.c \ + pyoida.h pyoida.c + +pyoida_la_LIBADD = \ + analysis/libpyoidaanalysis.la + +pyoida_la_LDFLAGS = -module -avoid-version $(LIBGTK_LIBS) $(LIBXML_LIBS) $(LIBPYTHON_LIBS) \ + -L../../src/panels/ -lpanels -L../../src/.libs -loidadisass -loidagtkext \ + -L../../src/plugins/.libs -lplugins + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) + +SUBDIRS = analysis diff --git a/plugins/pyoida/analysis/Makefile.am b/plugins/pyoida/analysis/Makefile.am new file mode 100644 index 0000000..df49499 --- /dev/null +++ b/plugins/pyoida/analysis/Makefile.am @@ -0,0 +1,17 @@ + +noinst_LTLIBRARIES = libpyoidaanalysis.la + +libpyoidaanalysis_la_SOURCES = \ + py_binary.h py_binary.c \ + py_line.h py_line.c \ + py_line_code.h py_line_code.c + + +libpyoidaanalysis_la_LDFLAGS = + + +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) + +AM_CPPFLAGS = + +AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS) diff --git a/plugins/pyoida/analysis/py_binary.c b/plugins/pyoida/analysis/py_binary.c new file mode 100644 index 0000000..c8d7446 --- /dev/null +++ b/plugins/pyoida/analysis/py_binary.c @@ -0,0 +1,360 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_binary.c - intermédiaire des binaires pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "py_binary.h" + +#include + + + +#include "py_line.h" + + + +typedef struct { + PyObject_HEAD + + GOpenidaBinary *binary; /* Instance réelle rattachée */ + +} pybinary; + + +#define _(str) str + + + + + +/* Fournit la description du type 'binary' pour Python. */ +PyTypeObject *pybinary_get_type(void); + + + + +/* Fournit les lignes de rendu associé pour Python. */ +static PyObject *pybinary_get_lines(pybinary *); + + + + + + + +static void +pybinary_dealloc(pybinary* self) +{ +#if 0 + Py_XDECREF(self->first); + Py_XDECREF(self->last); +#endif + + //printf("dealloc\n"); + + self->ob_type->tp_free((PyObject*)self); + //Py_TYPE(self)->tp_free((PyObject*)self); + + //printf("dealloc::end\n"); + +} + +static PyObject * +pybinary_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + pybinary *self; + + + printf("creating a new binary\n"); + + self = (pybinary *)type->tp_alloc(type, 0); + if (self != NULL) { +#if 0 + self->first = PyString_FromString("");//PyUnicode_FromString(""); + if (self->first == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->last = PyString_FromString("");//PyUnicode_FromString(""); + if (self->last == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->number = 0; +#endif + } + + return (PyObject *)self; +} + + +/****************************************************************************** +* * +* Paramètres : binary = modèle à représenter en Python. * +* * +* Description : Initialise le greffon permettant l'usage de Python. * +* * +* Retour : Nouvelle instance d'objet Python ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *pybinary_new_from_existing(GOpenidaBinary *binary) +{ + pybinary *result; /* Nouvelle instance à renvoyer*/ + PyTypeObject *type; /* Type d'objet à créer */ + + printf("EXISTING :: %p\n", binary); + + type = pybinary_get_type(); + + result = (pybinary *)type->tp_alloc(type, 0); + + if (result != NULL) + result->binary = binary; + + return (PyObject *)result; + +} + + + + +static int +pybinary_init(pybinary *self, PyObject *args, PyObject *kwds) +{ +#if 0 + PyObject *first=NULL, *last=NULL, *tmp; + + static char *kwlist[] = {"first", "last", "number", NULL}; + + printf("pybinary_init\n"); + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, + &first, &last, + &self->number)) + return -1; + + if (first) { + tmp = self->first; + Py_INCREF(first); + self->first = first; + Py_DECREF(tmp); + } + + if (last) { + tmp = self->last; + Py_INCREF(last); + self->last = last; + Py_DECREF(tmp); + } +#endif + return 0; +} + + + + + + + +static PyMemberDef pybinary_members[] = { +#if 0 + {"number", T_INT, offsetof(pybinary, number), 0, + "noddy number"}, +#endif + {NULL} /* Sentinel */ +}; + + + + + + + +/****************************************************************************** +* * +* Paramètres : self = instance manipulée à traiter. * +* * +* Description : Fournit les lignes de rendu associé pour Python. * +* * +* Retour : Nouvelle instance d'objet Python ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *pybinary_get_lines(pybinary *self) +{ + PyObject *result; /* Liste à retourner */ + GRenderingLine *lines; /* Liste récupérée à convertir */ + + lines = g_openida_binary_get_lines(self->binary); + + result = pyline_new_from_existing(lines, lines); + + return result; + +} + + + + +#if 0 +static PyObject * +pybinary_name(pybinary* self) +{ + static PyObject *format = NULL; + PyObject *args, *result; + + if (format == NULL) { + format = PyString_FromString("%s %s");//PyUnicode_FromString("%s %s"); + if (format == NULL) + return NULL; + } + + args = Py_BuildValue("OO", self->first, self->last); + if (args == NULL) + return NULL; + + result = PyUnicode_Format(format, args); + Py_DECREF(args); + + return result; +} +#endif + +static PyMethodDef pybinary_methods[] = { +#if 0 + {"name", (PyCFunction)pybinary_name, METH_NOARGS, + "Return the name, combining the first and last name" + }, +#endif + { "lines", (PyCFunction)pybinary_get_lines, METH_NOARGS, + "Provide a list of associated rendering lines." + }, + {NULL} /* Sentinel */ +}; + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit la description du type 'binary' pour Python. * +* * +* Retour : Adresse de la description du type 'binary'. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *pybinary_get_type(void) +{ + static PyTypeObject result = { + + PyObject_HEAD_INIT(NULL) + +#if PY_VERSION_HEX < 0x03000000 + 0, /*ob_size*/ +#endif + + "noddy.pybinary", /* tp_name */ + sizeof(pybinary), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pybinary_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved / tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "pybinary objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pybinary_methods, /* tp_methods */ + pybinary_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pybinary_init, /* tp_init */ + 0, /* tp_alloc */ + pybinary_new, /* tp_new */ + }; + + return &result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute l'objet 'binary' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_binary_to_python_module(PyObject *module) +{ + int ret; /* Bilan d'un appel */ + + if (PyType_Ready(pybinary_get_type()) < 0) + return false; + + printf("Adding binary type\n"); + + + + Py_INCREF(pybinary_get_type()); + PyModule_AddObject(module, "binary", (PyObject *)pybinary_get_type()); + + + return true; /* FIXME */ + + +} diff --git a/plugins/pyoida/analysis/py_binary.h b/plugins/pyoida/analysis/py_binary.h new file mode 100644 index 0000000..f87d2a5 --- /dev/null +++ b/plugins/pyoida/analysis/py_binary.h @@ -0,0 +1,45 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_binary.h - prototypes pour l'intermédiaire des binaires pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYOIDA_PY_BINARY_H +#define _PLUGINS_PYOIDA_PY_BINARY_H + + +#include +#include + + +#include "../../../src/analysis/binary.h" + + + +/* Initialise le greffon permettant l'usage de Python. */ +PyObject *pybinary_new_from_existing(GOpenidaBinary *); + +/* Ajoute l'objet 'binary' au module Python. */ +bool add_binary_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_PY_BINARY_H */ diff --git a/plugins/pyoida/analysis/py_line-int.h b/plugins/pyoida/analysis/py_line-int.h new file mode 100644 index 0000000..408eae8 --- /dev/null +++ b/plugins/pyoida/analysis/py_line-int.h @@ -0,0 +1,53 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_line.h - prototypes internes pour les lignes de représentation en Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYOIDA_PY_LINE_INT_H +#define _PLUGINS_PYOIDA_PY_LINE_INT_H + + +#include "py_line.h" + + + +typedef struct { + PyObject_HEAD + + GRenderingLine *head; + + GRenderingLine *line; /* Instance réelle rattachée */ + + vmpa_t address; /* Adresse mise en cache */ + +} PyLine; + + +/* Fournit la description du type 'PyLine' pour Python. */ +PyTypeObject *pyline_get_type(void); + +/* Initialise le greffon permettant l'usage de Python. */ +void pyline_init_from_existing(PyLine *, GRenderingLine *, GRenderingLine *); + + + +#endif /* _PLUGINS_PYOIDA_PY_LINE_INT_H */ diff --git a/plugins/pyoida/analysis/py_line.c b/plugins/pyoida/analysis/py_line.c new file mode 100644 index 0000000..bce8c1e --- /dev/null +++ b/plugins/pyoida/analysis/py_line.c @@ -0,0 +1,603 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_line.c - intermédiaire des lignes de représentation pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "py_line.h" + +#include + + + +#include "../../../src/analysis/line_code.h" + + +#include "py_line-int.h" +#include "py_line_code.h" + + + + + +#define _(str) str + + + + + + + +/* Prépare un parcours de lignes. */ +static PyObject *pyline_get_iter(PyLine *); + + + + + +/* ---------------------- ITERATEUR POUR LE PARCOURS DE LIGNES ---------------------- */ + + +/* Itérateur pour lignes de rendu */ +typedef struct _PyLineIter +{ + PyObject_HEAD /* A laisser en premier */ + + GRenderingLine *head; /* Liste à parcourir */ + GRenderingLine *cur; /* Point de parcours courant */ + +} PyLineIter; + + +/* Fournit la description de l'itérateur 'PyLine' pour Python. */ +static PyTypeObject *pylineiter_get_type(void); + +/* Prépare l'itérateur pour un parcours de lignes de rendu. */ +static PyObject *pylineiter_new(GRenderingLine *); + +/* Libère la mémoire occupée par un itérateur de 'PyLine'. */ +static void pylineiter_dealloc(PyLineIter *); + +/* Fournit l'élément suivant dans un parcours de lignes. */ +static PyObject *pylineiter_get_next(PyLineIter *); + + + + +/* ---------------------- EQUIVALENT PYTHON DES LIGNES DE CODE ---------------------- */ + + +/* Représentation Python d'une ligne de code */ +typedef struct _PyCodeLine +{ + PyLine base; /* A laisser en premier */ + +} PyCodeLine; + + + + + + + + + + + +static void +pyline_dealloc(PyLine *self) +{ +#if 0 + Py_XDECREF(self->first); + Py_XDECREF(self->last); +#endif + + //printf("dealloc\n"); + + + g_object_set_data(G_OBJECT(self->line), "pyline", NULL); + + + self->ob_type->tp_free((PyObject*)self); + //Py_TYPE(self)->tp_free((PyObject*)self); + + //printf("dealloc::end\n"); + +} + +static PyObject * +pyline_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyLine *self; + + + printf("creating a new line\n"); + + self = (PyLine *)type->tp_alloc(type, 0); + if (self != NULL) { +#if 0 + self->first = PyString_FromString("");//PyUnicode_FromString(""); + if (self->first == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->last = PyString_FromString("");//PyUnicode_FromString(""); + if (self->last == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->number = 0; +#endif + } + + return (PyObject *)self; +} + + +/****************************************************************************** +* * +* Paramètres : head = ???? * +* line = modèle à représenter en Python. * +* * +* Description : Initialise le greffon permettant l'usage de Python. * +* * +* Retour : Nouvelle instance d'objet Python ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *pyline_new_from_existing(GRenderingLine *head, GRenderingLine *line) +{ + PyLine *result; /* Nouvelle instance à renvoyer*/ + PyTypeObject *type; /* Type d'objet à créer */ + + result = (PyLine *)g_object_get_data(G_OBJECT(line), "pyline"); + + if (result == NULL) + { + if (G_IS_CODE_LINE(line)) + result = pycodeline_new_from_existing(head, line); + + else + { + type = pyline_get_type(); + + result = (PyLine *)type->tp_alloc(type, 0); + + if (result != NULL) + { + result->head = head; + result->line = line; + + g_object_set_data(G_OBJECT(line), "pyline", result); + + } + + } + + } + + return (PyObject *)result; + +} + + + + +static int +pyline_init(PyLine *self, PyObject *args, PyObject *kwds) +{ +#if 0 + PyObject *first=NULL, *last=NULL, *tmp; + + static char *kwlist[] = {"first", "last", "number", NULL}; + + printf("pyline_init\n"); + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, + &first, &last, + &self->number)) + return -1; + + if (first) { + tmp = self->first; + Py_INCREF(first); + self->first = first; + Py_DECREF(tmp); + } + + if (last) { + tmp = self->last; + Py_INCREF(last); + self->last = last; + Py_DECREF(tmp); + } +#endif + return 0; +} + + + +/****************************************************************************** +* * +* Paramètres : self = instance à initialiser. * +* head = ???? * +* line = modèle à représenter en Python. * +* * +* Description : Initialise le greffon permettant l'usage de Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void pyline_init_from_existing(PyLine *self, GRenderingLine *head, GRenderingLine *line) +{ + self->head = head; + self->line = line; + + self->address = get_rendering_line_address(self->line); + +} + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : self = instance manipulée à traiter. * +* * +* Description : Prépare un parcours de lignes. * +* * +* Retour : Point de départ d'un parcours. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *pyline_get_iter(PyLine *self) +{ + return (PyObject *)pylineiter_new(self->head); + +} + + + + + + +#if 0 +static PyObject * +pyline_name(pyline* self) +{ + static PyObject *format = NULL; + PyObject *args, *result; + + if (format == NULL) { + format = PyString_FromString("%s %s");//PyUnicode_FromString("%s %s"); + if (format == NULL) + return NULL; + } + + args = Py_BuildValue("OO", self->first, self->last); + if (args == NULL) + return NULL; + + result = PyUnicode_Format(format, args); + Py_DECREF(args); + + return result; +} +#endif + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit la description du type 'PyLine' pour Python. * +* * +* Retour : Adresse de la description du type 'line'. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyTypeObject *pyline_get_type(void) +{ + + static PyMethodDef pyline_methods[] = { +#if 0 + {"name", (PyCFunction)pyline_name, METH_NOARGS, + "Return the name, combining the first and last name" + }, +#endif + { NULL } +}; + + + static PyMemberDef pyline_members[] = { + { "address", T_ULONGLONG, offsetof(PyLine, address), READONLY, + "physical or virtual address relative to the line." }, + { NULL } +}; + + + static PyTypeObject result = { + + PyObject_HEAD_INIT(NULL) + +#if PY_VERSION_HEX < 0x03000000 + 0, /*ob_size*/ +#endif + + "noddy.pyline", /* tp_name */ + sizeof(PyLine), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pyline_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved / tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "PyLine objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + (getiterfunc)pyline_get_iter, /* tp_iter */ + 0, /* tp_iternext */ + pyline_methods, /* tp_methods */ + pyline_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pyline_init, /* tp_init */ + 0, /* tp_alloc */ + pyline_new, /* tp_new */ + }; + + return &result; + +} + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute l'objet 'line' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_line_to_python_module(PyObject *module) +{ + int ret; /* Bilan d'un appel */ + + if (PyType_Ready(pyline_get_type()) < 0) + return false; + + if (PyType_Ready(pylineiter_get_type()) < 0) + return false; + + + + + printf("Adding line type\n"); + + + + Py_INCREF(pyline_get_type()); + PyModule_AddObject(module, "line", (PyObject *)pyline_get_type()); + + Py_INCREF(pylineiter_get_type()); + PyModule_AddObject(module, "lineiter", (PyObject *)pylineiter_get_type()); + + + return true; /* FIXME */ + + +} + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* ITERATEUR POUR LE PARCOURS DE LIGNES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit la description de l'itérateur 'PyLine' pour Python. * +* * +* Retour : Adresse de la description du type 'PyLineIter'. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyTypeObject *pylineiter_get_type(void) +{ + static PyTypeObject result = { + + PyObject_HEAD_INIT(NULL) + +#if PY_VERSION_HEX < 0x03000000 + 0, /* ob_size */ +#endif + + "pyoida.analysis.PyLineIter", /* tp_name */ + sizeof(PyLineIter), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pylineiter_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved / tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + "PyLineIter objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + PyObject_SelfIter, /* tp_iter */ + (iternextfunc)pylineiter_get_next, /* tp_iternext */ + 0, /* tp_methods */ + }; + + return &result; + +} + + +/****************************************************************************** +* * +* Paramètres : head = liste à parcourir. * +* * +* Description : Prépare l'itérateur pour un parcours de lignes de rendu. * +* * +* Retour : Instance d'itérateur prête à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *pylineiter_new(GRenderingLine *head) +{ + PyLineIter *result; /* Nouvelle instance à renvoyer*/ + PyTypeObject *type; /* Type d'objet à créer */ + + type = pylineiter_get_type(); + + result = (PyLineIter *)type->tp_alloc(type, 0); + + if (result != NULL) + { + result->head = head; + result->cur = NULL; + } + + return (PyObject *)result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = instance d'objet à supprimer. * +* * +* Description : Libère la mémoire occupée par un itérateur de 'PyLine'. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void pylineiter_dealloc(PyLineIter *self) +{ +#if PY_VERSION_HEX < 0x03000000 + self->ob_type->tp_free((PyObject *)self); +#else + Py_TYPE(self)->tp_free((PyObject *)self); +#endif + +} + + +/****************************************************************************** +* * +* Paramètres : self = instance manipulée à traiter. * +* * +* Description : Fournit l'élément suivant dans un parcours de lignes. * +* * +* Retour : Point suivant du parcours ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *pylineiter_get_next(PyLineIter *self) +{ + PyObject *result; /* Elément à retourner */ + GRenderingLine *next; /* Elément réel suivant */ + + if (self->cur == NULL) next = self->head; + else next = g_rendering_line_get_next_iter(self->head, self->cur, NULL); + + if (next != NULL) + { + self->cur = next; + result = pyline_new_from_existing(self->head, next); + } + + else result = NULL; + + return (PyObject *)result; + +} diff --git a/plugins/pyoida/analysis/py_line.h b/plugins/pyoida/analysis/py_line.h new file mode 100644 index 0000000..681e13b --- /dev/null +++ b/plugins/pyoida/analysis/py_line.h @@ -0,0 +1,45 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_line.h - prototypes pour l'intermédiaire des lignes de représentation pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYOIDA_PY_LINE_H +#define _PLUGINS_PYOIDA_PY_LINE_H + + +#include +#include + + +#include "../../../src/analysis/line.h" + + + +/* Initialise le greffon permettant l'usage de Python. */ +PyObject *pyline_new_from_existing(GRenderingLine *, GRenderingLine *); + +/* Ajoute l'objet 'line' au module Python. */ +bool add_line_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_PY_LINE_H */ diff --git a/plugins/pyoida/analysis/py_line_code.c b/plugins/pyoida/analysis/py_line_code.c new file mode 100644 index 0000000..26fe513 --- /dev/null +++ b/plugins/pyoida/analysis/py_line_code.c @@ -0,0 +1,281 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_line_code.h - prototypes pour l'intermédiaire des lignes de code pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "py_line_code.h" + + +#include "py_line-int.h" + + + +typedef struct { + + PyLine base; /* Classe dérivée */ + +} PyCodeLine; + + + + +/* Fournit la description du type 'PyCodeLine' pour Python. */ +static PyTypeObject *pycodeline_get_type(void); + + + + +static int +pycodeline_init(PyCodeLine *self, PyObject *args, PyObject *kwds); + +static PyObject * +pycodeline_new(PyTypeObject *type, PyObject *args, PyObject *kwds); + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Fournit la description du type 'PyCodeLine' pour Python. * +* * +* Retour : Adresse de la description du type 'PyCodeLine'. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyTypeObject *pycodeline_get_type(void) +{ + static PyMethodDef pycodeline_methods[] = { +#if 0 + {"name", (PyCFunction)pyline_name, METH_NOARGS, + "Return the name, combining the first and last name" + }, +#endif + { NULL } +}; + + static PyTypeObject result = { + + PyObject_HEAD_INIT(NULL) + +#if PY_VERSION_HEX < 0x03000000 + 0, /*ob_size*/ +#endif + + "pyoida.analysis.PyCodeLine", /* tp_name */ + sizeof(PyCodeLine), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved / tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "pycodeline objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pycodeline_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pycodeline_init, /* tp_init */ + 0, /* tp_alloc */ + pycodeline_new, /* tp_new */ + }; + + return &result; + +} + + + + +static int +pycodeline_init(PyCodeLine *self, PyObject *args, PyObject *kwds) +{ +#if 0 + PyObject *first=NULL, *last=NULL, *tmp; + + static char *kwlist[] = {"first", "last", "number", NULL}; + + printf("pycodeline_init\n"); + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, + &first, &last, + &self->number)) + return -1; + + if (first) { + tmp = self->first; + Py_INCREF(first); + self->first = first; + Py_DECREF(tmp); + } + + if (last) { + tmp = self->last; + Py_INCREF(last); + self->last = last; + Py_DECREF(tmp); + } +#endif + return 0; +} + + + + + +static PyObject * +pycodeline_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyCodeLine *self; + + + printf("creating a new line\n"); + + self = (PyCodeLine *)type->tp_alloc(type, 0); + if (self != NULL) { +#if 0 + self->first = PyString_FromString("");//PyUnicode_FromString(""); + if (self->first == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->last = PyString_FromString("");//PyUnicode_FromString(""); + if (self->last == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->number = 0; +#endif + } + + return (PyObject *)self; +} + + + + + +/****************************************************************************** +* * +* Paramètres : head = ???? * +* line = modèle à représenter en Python. * +* * +* Description : Initialise le greffon permettant l'usage de Python. * +* * +* Retour : Nouvelle instance d'objet Python ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *pycodeline_new_from_existing(GRenderingLine *head, GCodeLine *line) +{ + PyCodeLine *result; /* Nouvelle instance à renvoyer*/ + PyTypeObject *type; /* Type d'objet à créer */ + + result = (PyCodeLine *)g_object_get_data(G_OBJECT(line), "pyobject"); + + if (result == NULL) + { + type = pycodeline_get_type(); + + result = (PyCodeLine *)type->tp_alloc(type, 0); + + if (result != NULL) + { + pyline_init_from_existing((PyLine *)result, head, line); + + g_object_set_data(G_OBJECT(line), "pyobject", result); + + } + + } + + return (PyObject *)result; + +} + + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute l'objet 'line' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_pycodeline_to_python_module(PyObject *module) +{ + + + pycodeline_get_type()->tp_base = pyline_get_type(); + if (PyType_Ready(pycodeline_get_type()) < 0) + return false; + + + Py_INCREF(pycodeline_get_type()); + PyModule_AddObject(module, "codeline", (PyObject *)pycodeline_get_type()); + + + + return true; /* FIXME */ + +} diff --git a/plugins/pyoida/analysis/py_line_code.h b/plugins/pyoida/analysis/py_line_code.h new file mode 100644 index 0000000..8a67b44 --- /dev/null +++ b/plugins/pyoida/analysis/py_line_code.h @@ -0,0 +1,45 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_line_code.h - prototypes pour l'intermédiaire des lignes de code pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYOIDA_PY_LINE_CODE_H +#define _PLUGINS_PYOIDA_PY_LINE_CODE_H + + +#include +#include + + +#include "../../../src/analysis/line_code.h" + + + +/* Initialise le greffon permettant l'usage de Python. */ +PyObject *pycodeline_new_from_existing(GRenderingLine *, GCodeLine *); + +/* Ajoute l'objet 'PyCodeLine' au module Python. */ +bool add_pycodeline_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_PY_LINE_CODE_H */ diff --git a/plugins/pyoida/linsyscalls/oidapgi.py b/plugins/pyoida/linsyscalls/oidapgi.py new file mode 100755 index 0000000..dd4e010 --- /dev/null +++ b/plugins/pyoida/linsyscalls/oidapgi.py @@ -0,0 +1,28 @@ +#!/usr/bin/python + +import pyoida +#import oidaline +from pyoida import Noddy + + +class OpenIDAPlugin: + """A simple example class""" + + + + + +if __name__ == "__main__": + print "OpenIDA PlugIn" + + + print "Hello World\n", + + pyoida.system("ls -lh") + + test = Noddy("first", "last") + + print test.name() + + #oidaline.echo() + diff --git a/plugins/pyoida/py_log.c b/plugins/pyoida/py_log.c new file mode 100644 index 0000000..706d626 --- /dev/null +++ b/plugins/pyoida/py_log.c @@ -0,0 +1,341 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_log.c - intermédiaire du panneau de messages pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "py_log.h" + +#include + + +#include "../../src/panels/log.h" + + +typedef struct { + PyObject_HEAD + PyObject *first; + PyObject *last; + int number; +} pylog; + + +#define _(str) str + + + + +/* Définit les constantes pour les types de message. */ +bool pylog_define_constants(PyObject *); + +/* Affiche un message dans le journal des messages système. */ +PyObject *pylog_simple_message(PyObject *, PyObject *); + + + + +/****************************************************************************** +* * +* Paramètres : dict = dictionnaire à compléter. * +* * +* Description : Définit les constantes pour les types de message. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool pylog_define_constants(PyObject *dict) +{ + int ret; /* Bilan d'un ajout */ + + ret = PyDict_SetItemString(dict, "LMT_INFO", PyInt_FromLong(LMT_INFO)); + if (ret == -1) return false; + + ret = PyDict_SetItemString(dict, "LMT_BAD_BINARY", PyInt_FromLong(LMT_BAD_BINARY)); + if (ret == -1) return false; + + ret = PyDict_SetItemString(dict, "LMT_PROCESS", PyInt_FromLong(LMT_PROCESS)); + if (ret == -1) return false; + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * +* args = arguments fournis à l'appel. * +* * +* Description : Affiche un message dans le journal des messages système. * +* * +* Retour : Rien en équivalent Python. * +* * +* Remarques : - * +* * +******************************************************************************/ + +PyObject *pylog_simple_message(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + LogMessageType type; /* Espèce du message */ + const char *msg; /* Contenu du message */ + + if (!PyArg_ParseTuple(args, "is", &type, &msg)) + return NULL; + + switch (type) + { + case LMT_INFO: + case LMT_BAD_BINARY: + case LMT_PROCESS: + log_simple_message(type, msg); + result = Py_None; + break; + + default: + PyErr_SetString(PyExc_ValueError, + _("Invalid type of message")); + result = NULL; + break; + + } + + return result; + +} + + + + + + + + + + +static void +pylog_dealloc(pylog* self) +{ + Py_XDECREF(self->first); + Py_XDECREF(self->last); + + + //printf("dealloc\n"); + + self->ob_type->tp_free((PyObject*)self); + //Py_TYPE(self)->tp_free((PyObject*)self); + + //printf("dealloc::end\n"); + +} + +static PyObject * +pylog_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + pylog *self; + + self = (pylog *)type->tp_alloc(type, 0); + if (self != NULL) { + self->first = PyString_FromString("");//PyUnicode_FromString(""); + if (self->first == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->last = PyString_FromString("");//PyUnicode_FromString(""); + if (self->last == NULL) + { + Py_DECREF(self); + return NULL; + } + + self->number = 0; + } + + return (PyObject *)self; +} + +static int +pylog_init(pylog *self, PyObject *args, PyObject *kwds) +{ + PyObject *first=NULL, *last=NULL, *tmp; + + static char *kwlist[] = {"first", "last", "number", NULL}; + + printf("pylog_init\n"); + + if (! PyArg_ParseTupleAndKeywords(args, kwds, "|SSi", kwlist, + &first, &last, + &self->number)) + return -1; + + if (first) { + tmp = self->first; + Py_INCREF(first); + self->first = first; + Py_DECREF(tmp); + } + + if (last) { + tmp = self->last; + Py_INCREF(last); + self->last = last; + Py_DECREF(tmp); + } + + return 0; +} + +static PyMemberDef pylog_members[] = { + {"number", T_INT, offsetof(pylog, number), 0, + "noddy number"}, + {NULL} /* Sentinel */ +}; + + + + + + + + + + +static PyObject * +pylog_name(pylog* self) +{ + static PyObject *format = NULL; + PyObject *args, *result; + + if (format == NULL) { + format = PyString_FromString("%s %s");//PyUnicode_FromString("%s %s"); + if (format == NULL) + return NULL; + } + + args = Py_BuildValue("OO", self->first, self->last); + if (args == NULL) + return NULL; + + result = PyUnicode_Format(format, args); + Py_DECREF(args); + + return result; +} + +static PyMethodDef pylog_methods[] = { + {"name", (PyCFunction)pylog_name, METH_NOARGS, + "Return the name, combining the first and last name" + }, + { "log_simple_message", (PyCFunction)pylog_simple_message, METH_VARARGS | METH_STATIC, + "Return the name, combining the first and last name" + }, + {NULL} /* Sentinel */ +}; + + +static PyTypeObject pylog_type = { + + PyObject_HEAD_INIT(NULL) + +#if PY_VERSION_HEX < 0x03000000 + 0, /*ob_size*/ +#endif + + "noddy.pylog", /* tp_name */ + sizeof(pylog), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pylog_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved / tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "pylog objects", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pylog_methods, /* tp_methods */ + pylog_members, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pylog_init, /* tp_init */ + 0, /* tp_alloc */ + pylog_new, /* tp_new */ +}; + + +/****************************************************************************** +* * +* Paramètres : module = module dont la définition est à compléter. * +* * +* Description : Ajoute l'objet 'log' au module Python. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_log_to_python_module(PyObject *module) +{ + int ret; /* Bilan d'un appel */ + + if (PyType_Ready(&pylog_type) < 0) + return; + + printf("Adding log type\n"); + + + pylog_define_constants(pylog_type.tp_dict); + + + + + Py_INCREF(&pylog_type); + PyModule_AddObject(module, "logger", (PyObject *)&pylog_type); + + + return true; /* FIXME */ + + +} diff --git a/plugins/pyoida/py_log.h b/plugins/pyoida/py_log.h new file mode 100644 index 0000000..5274428 --- /dev/null +++ b/plugins/pyoida/py_log.h @@ -0,0 +1,39 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * py_log.h - prototypes pour l'intermédiaire du panneau de messages pour Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _PLUGINS_PYOIDA_PY_LOG_H +#define _PLUGINS_PYOIDA_PY_LOG_H + + +#include +#include + + + +/* Ajoute l'objet 'log' au module Python. */ +bool add_log_to_python_module(PyObject *); + + + +#endif /* _PLUGINS_PYOIDA_PY_LOG_H */ diff --git a/plugins/pyoida/pyoida.c b/plugins/pyoida/pyoida.c new file mode 100644 index 0000000..860da5b --- /dev/null +++ b/plugins/pyoida/pyoida.c @@ -0,0 +1,134 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * pyoida.c - plugin permettant des extensions en Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#include "pyoida.h" + + + +#include + + +#include "analysis/py_binary.h" +#include "analysis/py_line.h" +#include "analysis/py_line_code.h" +#include "py_log.h" + + +static GObject *_ref = NULL; + + + +static PyObject *pyoida_get_current_binary(PyObject *self, PyObject *args) +{ + GOpenidaBinary *binary; /* Structure à copier */ + + binary = (GOpenidaBinary *)g_object_get_data(_ref, "current_binary"); + + return pybinary_new_from_existing(binary); + +} + +static PyMethodDef SpamMethods[] = { + {"current_binary", pyoida_get_current_binary, METH_NOARGS, + "Give the current analyzed binary."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + + + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : ref = espace de référencement global. * +* * +* Description : Initialise le greffon permettant l'usage de Python. * +* * +* Retour : true. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool init_plugin(GObject *ref) +{ + + printf("Init pyoida\n"); + + _ref = ref; + + return true; + +} + + +#if PY_VERSION_HEX >= 0x03000000 + +/* Python 3.x code */ + +static struct PyModuleDef spammodule = { + PyModuleDef_HEAD_INIT, + "pyoida", /* name of module */ + "pyoida_doc", /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the module, + or -1 if the module keeps state in global variables. */ + SpamMethods +}; + +PyMODINIT_FUNC +PyInit_pyoida(void) +{ + printf("Passage 3\n"); + (void) PyModule_Create(&spammodule); +} + +#else + +/* Python 2.x code */ + + +PyMODINIT_FUNC +initpyoida(void) +{ + PyObject *module; + + + printf("Passage 2\n"); + module = Py_InitModule("pyoida", SpamMethods); + + add_binary_to_python_module(module); + add_line_to_python_module(module); + add_pycodeline_to_python_module(module); + add_log_to_python_module(module); + +} + +#endif diff --git a/plugins/pyoida/pyoida.h b/plugins/pyoida/pyoida.h new file mode 100644 index 0000000..736db8e --- /dev/null +++ b/plugins/pyoida/pyoida.h @@ -0,0 +1,38 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * pyoida.h - prototypes pour le plugin permettant des extensions en Python + * + * Copyright (C) 2009 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see . + */ + + +#ifndef _PLUGINS_PYOIDA_H +#define _PLUGINS_PYOIDA_H + + +#include +#include + + + +/* Initialise le greffon permettant l'usage de Python. */ +bool init_plugin(GObject *); + + + +#endif /* _PLUGINS_PYOIDA_H */ diff --git a/src/Makefile.am b/src/Makefile.am index ea03c36..7e819de 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,8 +79,7 @@ openida_SOURCES = \ params.h params.c \ project.h project.c \ shell.h shell.c \ - xdg.h xdg.c \ - xml.h xml.c + xdg.h xdg.c INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/intl $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) `pkg-config --cflags gthread-2.0` $(LIBPYTHON_CFLAGS) $(LIBVTE_CFLAGS) diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 4e63cbe..c991125 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -137,7 +137,7 @@ static void g_openida_binary_class_init(GOpenidaBinaryClass *klass) /****************************************************************************** * * -* Paramètres : line = instance à initialiser. * +* Paramètres : binary = instance à initialiser. * * * * Description : Initialise une description de fichier binaire. * * * @@ -147,7 +147,7 @@ static void g_openida_binary_class_init(GOpenidaBinaryClass *klass) * * ******************************************************************************/ -static void g_openida_binary_init(GOpenidaBinary *line) +static void g_openida_binary_init(GOpenidaBinary *binary) { } diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 0a8d0e9..ac5af77 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -32,7 +32,7 @@ #include "line.h" #include "../arch/processor.h" #include "../format/executable.h" -#include "../xml.h" +#include "../common/xml.h" diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 1bb66d9..c4937dd 100755 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -5,12 +5,13 @@ libcommon_la_SOURCES = \ dllist.h dllist.c \ endianness.h endianness.c \ extstr.h extstr.c \ - macros.h + macros.h \ + xml.h xml.c -libcommon_la_LDFLAGS = +libcommon_la_LDFLAGS = $(LIBGTK_LIBS) $(LIBXML_LIBS) -INCLUDES = +INCLUDES = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) AM_CPPFLAGS = diff --git a/src/common/xml.c b/src/common/xml.c new file mode 100644 index 0000000..b89b4f9 --- /dev/null +++ b/src/common/xml.c @@ -0,0 +1,809 @@ + +/* Firebox Tools - Outils de configurations pour le WM Firebox + * xml.c - lecture ou écriture de documents XML + * + * Copyright (C) 2006-2007 Cyrille Bagard + * + * This file is part of Firebox Tools. + * + * Firebox Tools 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 2 of the License, or + * (at your option) any later version. + * + * Firebox Tools 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 "xml.h" + + +#include +#include + + +#include "extstr.h" + + +#ifdef DEBUG +# define XML_LOG fprintf +#else +# define XML_LOG if (FALSE) fprintf +#endif + + + +/****************************************************************************** +* * +* Paramètres : filename = nom du fichier à ouvrir. * +* xdoc = structure XML chargée. [OUT] * +* context = contexte à utiliser pour les recherches. [OUT] * +* * +* Description : Crée un nouveau fichier XML. * +* * +* Retour : true si l'opération a pu s'effectuer, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool create_new_xml_file(xmlDocPtr *xdoc, xmlXPathContextPtr *context) +{ + *xdoc = xmlNewDoc(BAD_CAST "1.0"); + + if (*xdoc == NULL) + return false; + + *context = xmlXPathNewContext(*xdoc); + + if (*context == NULL) + { + xmlFreeDoc(*xdoc); + return false; + } + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : xdoc = structure XML chargée. * +* filename = nom du fichier à remplir. * +* * +* Description : Sauvegarde une structure XML dans un fichier. * +* * +* Retour : true si l'opération a pu s'effectuer, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool save_xml_file(xmlDocPtr xdoc, const char *filename) +{ + int ret; /* Bilan de l'appel */ + + ret = xmlSaveFormatFileEnc(filename, xdoc, "UTF-8", 1); + + return (ret != -1); + +} + + +/****************************************************************************** +* * +* Paramètres : xdoc = structure XML chargée à supprimer. * +* context = contexte utilisé pour les recherches. * +* * +* Description : Ferme une structure XML. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void close_xml_file(xmlDocPtr xdoc, xmlXPathContextPtr context) +{ + xmlXPathFreeContext(context); + xmlFreeDoc(xdoc); + + xmlCleanupParser(); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERATIONS DE LECTURE D'UN FICHIER XML */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : filename = nom du fichier à ouvrir. * +* xdoc = structure XML chargée. [OUT] * +* xpathCtx = contexte à utiliser pour les recherches. [OUT] * +* * +* Description : Ouvre un fichier XML de façon encadrée. * +* * +* Retour : true si l'opération a pu s'effectuer, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlXPathContextPtr *xpathCtx) +{ + *xdoc = xmlParseFile(filename); + + if (*xdoc == NULL) + { + XML_LOG(stderr, "Can not parse the XML file '%s'\n", filename); + return FALSE; + } + + *xpathCtx = xmlXPathNewContext(*xdoc); + + if (*xpathCtx == NULL) + { + XML_LOG(stderr, "Unable to create new XPath context\n"); + xmlFreeDoc(*xdoc); + return FALSE; + } + + return TRUE; + +} + + +/****************************************************************************** +* * +* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud visé. * +* * +* Description : Obtient de façon encadrée l'accès à un noeud défini. * +* * +* Retour : Adresse de l'accès trouvé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr xpathCtx, const char *path) +{ + xmlXPathObjectPtr result; /* Noeud XML à renvoyer */ + + result = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); + + if (result == NULL) + { + XML_LOG(stderr, "Unable to evaluate xpath expression '%s'\n", path); + return NULL; + } + + if (result->nodesetval == NULL) + { + XML_LOG(stderr, "Node '%s' not found\n", path); + xmlXPathFreeObject(result); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud dont une propriété est à lire. * +* * +* Description : Obtient une valeur placée entre <...> et . * +* * +* Retour : Valeur sous forme de chaîne de caractères ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *qck_get_node_text_value(xmlNodePtr node) +{ + char *result; /* Valeur en question renvoyée */ + + 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); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud visé. * +* * +* Description : Obtient une valeur placée entre <...> et . * +* * +* Retour : Valeur sous forme de chaîne de caractères ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *get_node_text_value(xmlXPathContextPtr xpathCtx, const char *path) +{ + char *result; /* Valeur en question renvoyée */ + xmlXPathObjectPtr xpathObj; /* Point de départ XML */ + + result = NULL; + + xpathObj = get_node_xpath_object(xpathCtx, path); + if (xpathObj == NULL) return NULL; + + if (xpathObj->nodesetval->nodeNr > 0) + result = qck_get_node_text_value(xpathObj->nodesetval->nodeTab[0]); + + xmlXPathFreeObject(xpathObj); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud dont une propriété est à lire. * +* name = nom de la propriété à lire. * +* * +* Description : Obtient la valeur d'une propriété d'un élément. * +* * +* Retour : Valeur sous forme de chaîne de caractères ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *qck_get_node_prop_value(xmlNodePtr node, const char *name) +{ + char *result; /* Valeur en question renvoyée */ + xmlAttrPtr attrib; /* Liste d'attributs présents */ + + result = NULL; + + if (node == NULL) return NULL; + + /* Lecture de la valeur */ + + for (attrib = node->properties; attrib != NULL && result == NULL; attrib = attrib->next) + if (xmlStrEqual(attrib->name, BAD_CAST name)) result = strdup((char *)attrib->children->content); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud à traiter. * +* name = nom de la propriété à lire. * +* * +* Description : Obtient la valeur d'une propriété d'un élément. * +* * +* Retour : Valeur sous forme de chaîne de caractères ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *get_node_prop_value(xmlXPathContextPtr xpathCtx, const char *path, const char *name) +{ + char *result; /* Valeur en question renvoyée */ + xmlXPathObjectPtr xpathObj; /* Point de départ XML */ + + result = NULL; + + xpathObj = get_node_xpath_object(xpathCtx, path); + if (xpathObj == NULL) return NULL; + + if (xpathObj->nodesetval->nodeNr > 0) + result = qck_get_node_prop_value(xpathObj->nodesetval->nodeTab[0], name); + + xmlXPathFreeObject(xpathObj); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : node = noeud de texte avec un lien avec le document XML. * +* * +* Description : Construit un chemin d'accès complet selon le fichier XML. * +* * +* Retour : Valeur à libérer de la mémoire après usage ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *qck_build_filename_with_doc_url(xmlNodePtr node) +{ + char *result; /* Construction à retourner */ + char *text; /* Valeur du texte lu */ + char *last; /* Point de remplacement */ + + result = NULL; + + text = qck_get_node_text_value(node); + + if (text != NULL) + { + result = (char *)calloc(xmlStrlen(node->doc->URL) + strlen(text) + 1, sizeof(char)); + + strcpy(result, (const char *)node->doc->URL); + + last = strrchr(result, '/'); + last++; + + strcpy(last, text); + free(text); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud à traiter. * +* * +* Description : Construit un chemin d'accès complet selon le fichier XML. * +* * +* Retour : Valeur sous forme de chaîne de caractères ou NULL. * +* * +* Remarques : - * +* * +******************************************************************************/ + +char *build_filename_with_doc_url(xmlXPathContextPtr xpathCtx, const char *path) +{ + char *result; /* Valeur en question renvoyée */ + xmlXPathObjectPtr xpathObj; /* Point de départ XML */ + + result = NULL; + + xpathObj = get_node_xpath_object(xpathCtx, path); + if (xpathObj == NULL) return NULL; + + if (xpathObj->nodesetval->nodeNr > 0) + result = qck_build_filename_with_doc_url(xpathObj->nodesetval->nodeTab[0]); + + xmlXPathFreeObject(xpathObj); + + return result; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERATIONS D'ECRITURE D'UN FICHIER XML */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : filename = nom du fichier à ouvrir. * +* * +* Description : Amorce l'écriture d'un nouveau fichier XML. * +* * +* Retour : Rédacteur mis en place ou NULL en cas d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +xmlTextWriterPtr start_writing_xml_file(const char *filename) +{ + xmlTextWriterPtr result; /* Moyen à retourner */ + int retval; /* Bilan d'une opération */ + + result = xmlNewTextWriterFilename(filename, 0); + + if (result == NULL) + { + XML_LOG(stderr, "Error creating the xml writer\n"); + return NULL; + } + + retval = xmlTextWriterStartDocument(result, NULL, "UTF-8", "yes"); + if (retval < 0) + { + XML_LOG(stderr, "Error at xmlTextWriterStartDocument\n"); + xmlFreeTextWriter(result); + return NULL; + } + + retval = xmlTextWriterSetIndent(result, 1); + if (retval < 0) + { + XML_LOG(stderr, "Error setting indentation\n"); + xmlFreeTextWriter(result); + return NULL; + } + + retval = xmlTextWriterSetIndentString(result, BAD_CAST "\t"); + if (retval < 0) + { + XML_LOG(stderr, "Error setting indentation string\n"); + xmlFreeTextWriter(result); + return NULL; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : writer = rédacteur dédié à l'écriture. * +* * +* Description : Met fin à l'écriture d'un nouveau fichier XML. * +* * +* Retour : Bilan de l'opération : true ou false. * +* * +* Remarques : Ferme au besoin toutes les balises encore ouvertes. * +* * +******************************************************************************/ + +bool end_writing_xml_file(xmlTextWriterPtr writer) +{ + int retval; /* Bilan de l'opération */ + + retval = xmlTextWriterEndDocument(writer); + if (retval < 0) + { + XML_LOG(stderr, "Error at xmlTextWriterEndDocument\n"); + return false; + } + + xmlFreeTextWriter(writer); + + return true; + +} + + +/****************************************************************************** +* * +* Paramètres : writer = rédacteur dédié à l'écriture. * +* name = nom de la balise à écrire. * +* * +* Description : Ecrit une balise et ne la referme pas. * +* * +* Retour : Bilan de l'opération : true ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool open_xml_element(xmlTextWriterPtr writer, const char *name) +{ + int retval; /* Bilan de l'opération */ + + retval = xmlTextWriterStartElement(writer, BAD_CAST name); + + if (retval < 0) + XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); + + return (retval >= 0); + +} + + +/****************************************************************************** +* * +* Paramètres : writer = rédacteur dédié à l'écriture. * +* * +* Description : Ferme la dernière balise laissée ouverte. * +* * +* Retour : Bilan de l'opération : true ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool close_xml_element(xmlTextWriterPtr writer) +{ + int retval; /* Bilan de l'opération */ + + retval = xmlTextWriterEndElement(writer); + + if (retval < 0) + XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); + + return (retval >= 0); + +} + + +/****************************************************************************** +* * +* Paramètres : writer = rédacteur dédié à l'écriture. * +* name = nom de la balise à écrire. * +* format = format de la chaîne à traiter. * +* ... = informations à inscrire. * +* * +* Description : Ecrit une balise avec un contenu textuel. * +* * +* Retour : Bilan de l'opération : true ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_xml_element_with_content(xmlTextWriterPtr writer, const char *name, const char *format, ...) +{ + va_list ap; /* Liste d'arguments variable */ + int retval; /* Bilan de l'opération */ + + va_start(ap, format); + + retval = xmlTextWriterWriteVFormatElement(writer, BAD_CAST name, format, ap); + + if (retval < 0) + XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); + + va_end(ap); + + return (retval >= 0); + +} + + +/****************************************************************************** +* * +* Paramètres : writer = rédacteur dédié à l'écriture. * +* name = nom de l'attribut à écrire. * +* format = format de la chaîne à traiter. * +* ... = informations à inscrire. * +* * +* Description : Ecrit un attribut avec un contenu textuel. * +* * +* Retour : Bilan de l'opération : true ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_xml_attribute(xmlTextWriterPtr writer, const char *name, const char *format, ...) +{ + va_list ap; /* Liste d'arguments variable */ + int retval; /* Bilan de l'opération */ + + va_start(ap, format); + + retval = xmlTextWriterWriteVFormatAttribute(writer, BAD_CAST name, format, ap); + + if (retval < 0) + XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); + + va_end(ap); + + return (retval >= 0); + +} + + +/****************************************************************************** +* * +* Paramètres : writer = rédacteur dédié à l'écriture. * +* format = format de la chaîne à traiter. * +* ... = informations à inscrire. * +* * +* Description : Ecrit un contenu textuel. * +* * +* Retour : Bilan de l'opération : true ou false. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_xml_content(xmlTextWriterPtr writer, const char *format, ...) +{ + va_list ap; /* Liste d'arguments variable */ + int retval; /* Bilan de l'opération */ + + va_start(ap, format); + + retval = xmlTextWriterWriteVFormatString(writer, format, ap); + + if (retval < 0) + XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); + + va_end(ap); + + return (retval >= 0); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OPERATIONS D'ECRITURE D'UN FICHIER XML */ +/* ---------------------------------------------------------------------------------- */ + + + +/****************************************************************************** +* * +* Paramètres : context = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud visé. * +* * +* Description : Fournit le premier noeud correspondant à un chemin XPath. * +* * +* Retour : Adresse du noeud trouvé ou NULL en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +xmlNodePtr get_node_from_xpath(xmlXPathContextPtr context, const char *path) +{ + xmlNodePtr result; /* Noeud trouvé à renvoyer */ + xmlXPathObjectPtr xobject; /* Point de départ XML */ + + result = NULL; + + xobject = get_node_xpath_object(context, path); + if (xobject == NULL) return NULL; + + if (xobject->nodesetval->nodeNr > 0) + result = xobject->nodesetval->nodeTab[0]; + + xmlXPathFreeObject(xobject); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : xdoc = structure XML chargée. * +* context = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud visé. * +* * +* Description : S'assure qu'un noeud donné est bien présent dans le document.* +* * +* Retour : Noeud en question ou NULL en cas d'échec à la création. * +* * +* Remarques : - * +* * +******************************************************************************/ + +xmlNodePtr ensure_node_exist(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) +{ + xmlNodePtr result; /* Noeud à retourner */ + char **levels; /* Niveaux dans le chemin */ + size_t levels_count; /* Nombre de ces niveaux */ + xmlNodePtr last; /* Dernier noeud valide */ + size_t i; /* Boucle de parcours #1 */ + char *iter_path; /* Chamin d'accès pour le test */ + size_t j; /* Boucle de parcours #2 */ + xmlNodePtr iter; /* Test d'accès à un noeud */ + char *cond; /* Marque de condition ('[') */ + + result = get_node_from_xpath(context, path); + + if (result == NULL) + { + levels = strtoka(path, "/", &levels_count); + + /* Recherche la racine valide la plus haute */ + + last = xmlDocGetRootElement(xdoc); + + for (i = 0; i < levels_count && last != NULL; i++) + { + iter_path = strdup(""); + + for (j = 0; j <= i; j++) + { + iter_path = stradd(iter_path, "/"); + iter_path = stradd(iter_path, levels[j]); + } + + iter = get_node_from_xpath(context, iter_path); + + if (iter == NULL) break; + else last = iter; + + } + + /* Inscription des noeuds restants */ + + if (last == NULL) + { + last = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i++], NULL); + xmlDocSetRootElement(xdoc, last); + + if (i == levels_count) + result = last; + + } + + for ( ; i < levels_count && last != NULL; i++) + { + cond = strchr(levels[i], '['); + if (cond != NULL) *cond = '\0'; + + result = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i], NULL); + result = xmlAddChild(last, result); + last = result; + } + + /* Libération de la mémoire */ + + for (i = 0; i < levels_count; i++) + free(levels[i]); + + free(levels); + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : xdoc = structure XML chargée. * +* context = contexte à utiliser pour les recherches. * +* path = chemin d'accès au noeud visé. * +* content = texte à inscrire en contenu. * +* * +* Description : S'assure qu'un noeud donné est bien présent dans le document.* +* * +* Retour : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool add_content_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *content) +{ + xmlNodePtr node; /* Noeud à modifier */ + + if (content == NULL) return true; + + node = ensure_node_exist(xdoc, context, path); + if (node == NULL) return false; + + xmlNodeSetContent(node, content); + + return true; + +} diff --git a/src/common/xml.h b/src/common/xml.h new file mode 100644 index 0000000..82e2578 --- /dev/null +++ b/src/common/xml.h @@ -0,0 +1,122 @@ + +/* Firebox Tools - Outils de configurations pour le WM Firebox + * xml.h - prototypes pour la lecture ou l'écriture de documents XML + * + * Copyright (C) 2006-2007 Cyrille Bagard + * + * This file is part of Firebox Tools. + * + * Firebox Tools 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 2 of the License, or + * (at your option) any later version. + * + * Firebox Tools 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 _XML_H +#define _XML_H + + +#include +#include +#include +#include +#include + + + + +/* Crée un nouveau fichier XML. */ +bool create_new_xml_file(xmlDocPtr *, xmlXPathContextPtr *); + +/* Sauvegarde une structure XML dans un fichier. */ +bool save_xml_file(xmlDocPtr, const char *); + +/* Ferme une structure XML. */ +void close_xml_file(xmlDocPtr, xmlXPathContextPtr); + + + +/* --------------------- OPERATIONS DE LECTURE D'UN FICHIER XML --------------------- */ + + +#define XPATH_OBJ_NODES_COUNT(obj) (obj != NULL ? obj->nodesetval->nodeNr : 0) +#define NODE_FROM_PATH_OBJ(obj, i) obj->nodesetval->nodeTab[i] + + +/* Ouvre un fichier XML de façon encadrée. */ +gboolean open_xml_file(const char *filename, xmlDoc **, xmlXPathContextPtr *); + +/* Obtient de façon encadrée l'accès à un noeud défini. */ +xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr, const char *); + +/* Obtient une valeur placée entre <...> et . */ +char *qck_get_node_text_value(xmlNodePtr); + +/* Obtient une valeur placée entre <...> et . */ +char *get_node_text_value(xmlXPathContextPtr, const char *); + +/* Obtient la valeur d'une propriété d'un élément. */ +char *qck_get_node_prop_value(xmlNodePtr, const char *); + +/* Obtient la valeur d'une propriété d'un élément. */ +char *get_node_prop_value(xmlXPathContextPtr, const char *, const char *); + +/* Construit un chemin d'accès complet selon le fichier XML. */ +char *qck_build_filename_with_doc_url(xmlNodePtr); + +/* Construit un chemin d'accès complet selon le fichier XML. */ +char *build_filename_with_doc_url(xmlXPathContextPtr xpathCtx, const char *path); + + + +/* --------------------- OPERATIONS D'ECRITURE D'UN FICHIER XML --------------------- */ + + +/* Amorce l'écriture d'un nouveau fichier XML. */ +xmlTextWriterPtr start_writing_xml_file(const char *); + +/* Met fin à l'écriture d'un nouveau fichier XML. */ +bool end_writing_xml_file(xmlTextWriterPtr); + +/* Ecrit une balise et ne la referme pas. */ +bool open_xml_element(xmlTextWriterPtr, const char *); + +/* Ferme la dernière balise laissée ouverte. */ +bool close_xml_element(xmlTextWriterPtr); + +/* Ecrit une balise avec un contenu textuel. */ +bool write_xml_element_with_content(xmlTextWriterPtr, const char *, const char *, ...); + +/* Ecrit un attribut avec un contenu textuel. */ +bool write_xml_attribute(xmlTextWriterPtr, const char *, const char *, ...); + +/* Ecrit un contenu textuel. */ +bool write_xml_content(xmlTextWriterPtr, const char *, ...); + + + +/* --------------------- OPERATIONS D'ECRITURE D'UN FICHIER XML --------------------- */ + + +/* Fournit le premier noeud correspondant à un chemin XPath. */ +xmlNodePtr get_node_from_xpath(xmlXPathContextPtr, const char *); + +/* S'assure qu'un noeud donné est bien présent dans le document. */ +xmlNodePtr ensure_node_exist(xmlDocPtr, xmlXPathContextPtr, const char *); + +/* S'assure qu'un noeud donné est bien présent dans le document. */ +bool add_content_to_node(xmlDocPtr, xmlXPathContextPtr, const char *, const char *); + + + +#endif /* _XML_H */ diff --git a/src/configuration.c b/src/configuration.c index de4f2f1..8823271 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -30,8 +30,8 @@ #include "xdg.h" -#include "xml.h" #include "common/extstr.h" +#include "common/xml.h" diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c index 6725fd8..6d47f57 100644 --- a/src/plugins/pglist.c +++ b/src/plugins/pglist.c @@ -77,7 +77,7 @@ bool init_all_plugins(GObject *ref) { _list.ref = ref; - browse_directory_for_plugins(&_list, PACKAGE_SOURCE_DIR "/plugins.disabled"); + browse_directory_for_plugins(&_list, PACKAGE_SOURCE_DIR "/plugins"); return true; diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c index cde1ab5..7c62146 100644 --- a/src/plugins/plugin.c +++ b/src/plugins/plugin.c @@ -135,7 +135,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref) result->module = g_module_open(filename, G_MODULE_BIND_LAZY); - +#if 0 if (!g_module_symbol(result->module, "get_plugin_action", (gpointer *)&__get_action)) { printf("Err plugin get_action sym\n"); @@ -156,7 +156,7 @@ GPluginModule *g_plugin_module_new(const gchar *filename, GObject *ref) } - +#endif if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init)) diff --git a/src/project.c b/src/project.c index 06059ed..cf76a33 100644 --- a/src/project.c +++ b/src/project.c @@ -29,7 +29,7 @@ #include "params.h" -#include "xml.h" +#include "common/xml.h" #include "gtkext/easygtk.h" #include "gtkext/gtkblockview.h" #include "gtkext/gtkdockpanel.h" diff --git a/src/shell.c b/src/shell.c index 1f8d28d..2d3420f 100644 --- a/src/shell.c +++ b/src/shell.c @@ -105,7 +105,11 @@ GtkWidget *build_shell_panel(GObject *ref) vte_terminal_set_cursor_blinks(VTE_TERMINAL(term), TRUE); - //return result; +#if 0 + vte_terminal_fork_command (term, "/bin/sh", NULL, NULL, "/", 0, 0, 0); + return result; +#endif + openpty(&amaster, &aslave, name, NULL, NULL); @@ -264,6 +268,10 @@ static gpointer python_shell_thread(gpointer data) { FILE *stream; + int stdout2; + FILE *out2; + + printf("==== FE :: '%s'\n", ptsname(amaster)); printf("==== FE :: '%s'\n", ptsname(aslave)); @@ -279,38 +287,45 @@ static gpointer python_shell_thread(gpointer data) /* Mise à jour des entrées/sorties */ - /* + + stdout2 = dup(STDOUT_FILENO); + out2 = fdopen(stdout2, "w"); + + fprintf(out2, ">>> stdout2 :: %d\n", stdout2); + + +#if 1 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); dup(aslave); dup(aslave); dup(aslave); - */ - +#endif Py_Initialize(); - amaster = STDIN_FILENO; - + //amaster = STDIN_FILENO; + /* write(amaster, "import pyoida\n", strlen("import pyoida\n")); write(amaster, "from pyoida import *\n", strlen("from pyoida import *\n")); + write(amaster, "logger.log_simple_message(2, 'uhih')\n", strlen("logger.log_simple_message(2, 'uhih')\n")); + write(amaster, "for i in pyoida.current_binary().lines():\n", strlen("for i in pyoida.current_binary().lines():\n")); + write(amaster, "\tprint i\n", strlen("\tprint i\n")); + */ - - write(amaster, "logger.log_simple_message(2, 'uhih')\n", strlen("logger.log_simple_message(2, 'uhih')\n")); - + write(amaster, "execfile('test.py')", strlen("execfile('test.py')")); - write(amaster, "for i in pyoida.current_binary().lines():\n", strlen("for i in pyoida.current_binary().lines():\n")); - write(amaster, "\tprint i\n", strlen("\tprint i\n")); + fprintf(out2, ">>> stdout2 :: %d (inside)\n", stdout2); diff --git a/src/xml.c b/src/xml.c deleted file mode 100644 index 19003eb..0000000 --- a/src/xml.c +++ /dev/null @@ -1,809 +0,0 @@ - -/* Firebox Tools - Outils de configurations pour le WM Firebox - * xml.c - lecture ou écriture de documents XML - * - * Copyright (C) 2006-2007 Cyrille Bagard - * - * This file is part of Firebox Tools. - * - * Firebox Tools 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 2 of the License, or - * (at your option) any later version. - * - * Firebox Tools 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 "xml.h" - - -#include -#include - - -#include "common/extstr.h" - - -#ifdef DEBUG -# define XML_LOG fprintf -#else -# define XML_LOG if (FALSE) fprintf -#endif - - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à ouvrir. * -* xdoc = structure XML chargée. [OUT] * -* context = contexte à utiliser pour les recherches. [OUT] * -* * -* Description : Crée un nouveau fichier XML. * -* * -* Retour : true si l'opération a pu s'effectuer, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool create_new_xml_file(xmlDocPtr *xdoc, xmlXPathContextPtr *context) -{ - *xdoc = xmlNewDoc(BAD_CAST "1.0"); - - if (*xdoc == NULL) - return false; - - *context = xmlXPathNewContext(*xdoc); - - if (*context == NULL) - { - xmlFreeDoc(*xdoc); - return false; - } - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : xdoc = structure XML chargée. * -* filename = nom du fichier à remplir. * -* * -* Description : Sauvegarde une structure XML dans un fichier. * -* * -* Retour : true si l'opération a pu s'effectuer, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool save_xml_file(xmlDocPtr xdoc, const char *filename) -{ - int ret; /* Bilan de l'appel */ - - ret = xmlSaveFormatFileEnc(filename, xdoc, "UTF-8", 1); - - return (ret != -1); - -} - - -/****************************************************************************** -* * -* Paramètres : xdoc = structure XML chargée à supprimer. * -* context = contexte utilisé pour les recherches. * -* * -* Description : Ferme une structure XML. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void close_xml_file(xmlDocPtr xdoc, xmlXPathContextPtr context) -{ - xmlXPathFreeContext(context); - xmlFreeDoc(xdoc); - - xmlCleanupParser(); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* OPERATIONS DE LECTURE D'UN FICHIER XML */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à ouvrir. * -* xdoc = structure XML chargée. [OUT] * -* xpathCtx = contexte à utiliser pour les recherches. [OUT] * -* * -* Description : Ouvre un fichier XML de façon encadrée. * -* * -* Retour : true si l'opération a pu s'effectuer, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlXPathContextPtr *xpathCtx) -{ - *xdoc = xmlParseFile(filename); - - if (*xdoc == NULL) - { - XML_LOG(stderr, "Can not parse the XML file '%s'\n", filename); - return FALSE; - } - - *xpathCtx = xmlXPathNewContext(*xdoc); - - if (*xpathCtx == NULL) - { - XML_LOG(stderr, "Unable to create new XPath context\n"); - xmlFreeDoc(*xdoc); - return FALSE; - } - - return TRUE; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* * -* Description : Obtient de façon encadrée l'accès à un noeud défini. * -* * -* Retour : Adresse de l'accès trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr xpathCtx, const char *path) -{ - xmlXPathObjectPtr result; /* Noeud XML à renvoyer */ - - result = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); - - if (result == NULL) - { - XML_LOG(stderr, "Unable to evaluate xpath expression '%s'\n", path); - return NULL; - } - - if (result->nodesetval == NULL) - { - XML_LOG(stderr, "Node '%s' not found\n", path); - xmlXPathFreeObject(result); - return NULL; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud dont une propriété est à lire. * -* * -* Description : Obtient une valeur placée entre <...> et . * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *qck_get_node_text_value(xmlNodePtr node) -{ - char *result; /* Valeur en question renvoyée */ - - 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); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* * -* Description : Obtient une valeur placée entre <...> et . * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *get_node_text_value(xmlXPathContextPtr xpathCtx, const char *path) -{ - char *result; /* Valeur en question renvoyée */ - xmlXPathObjectPtr xpathObj; /* Point de départ XML */ - - result = NULL; - - xpathObj = get_node_xpath_object(xpathCtx, path); - if (xpathObj == NULL) return NULL; - - if (xpathObj->nodesetval->nodeNr > 0) - result = qck_get_node_text_value(xpathObj->nodesetval->nodeTab[0]); - - xmlXPathFreeObject(xpathObj); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud dont une propriété est à lire. * -* name = nom de la propriété à lire. * -* * -* Description : Obtient la valeur d'une propriété d'un élément. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *qck_get_node_prop_value(xmlNodePtr node, const char *name) -{ - char *result; /* Valeur en question renvoyée */ - xmlAttrPtr attrib; /* Liste d'attributs présents */ - - result = NULL; - - if (node == NULL) return NULL; - - /* Lecture de la valeur */ - - for (attrib = node->properties; attrib != NULL && result == NULL; attrib = attrib->next) - if (xmlStrEqual(attrib->name, BAD_CAST name)) result = strdup((char *)attrib->children->content); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud à traiter. * -* name = nom de la propriété à lire. * -* * -* Description : Obtient la valeur d'une propriété d'un élément. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *get_node_prop_value(xmlXPathContextPtr xpathCtx, const char *path, const char *name) -{ - char *result; /* Valeur en question renvoyée */ - xmlXPathObjectPtr xpathObj; /* Point de départ XML */ - - result = NULL; - - xpathObj = get_node_xpath_object(xpathCtx, path); - if (xpathObj == NULL) return NULL; - - if (xpathObj->nodesetval->nodeNr > 0) - result = qck_get_node_prop_value(xpathObj->nodesetval->nodeTab[0], name); - - xmlXPathFreeObject(xpathObj); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud de texte avec un lien avec le document XML. * -* * -* Description : Construit un chemin d'accès complet selon le fichier XML. * -* * -* Retour : Valeur à libérer de la mémoire après usage ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *qck_build_filename_with_doc_url(xmlNodePtr node) -{ - char *result; /* Construction à retourner */ - char *text; /* Valeur du texte lu */ - char *last; /* Point de remplacement */ - - result = NULL; - - text = qck_get_node_text_value(node); - - if (text != NULL) - { - result = (char *)calloc(xmlStrlen(node->doc->URL) + strlen(text) + 1, sizeof(char)); - - strcpy(result, (const char *)node->doc->URL); - - last = strrchr(result, '/'); - last++; - - strcpy(last, text); - free(text); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud à traiter. * -* * -* Description : Construit un chemin d'accès complet selon le fichier XML. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *build_filename_with_doc_url(xmlXPathContextPtr xpathCtx, const char *path) -{ - char *result; /* Valeur en question renvoyée */ - xmlXPathObjectPtr xpathObj; /* Point de départ XML */ - - result = NULL; - - xpathObj = get_node_xpath_object(xpathCtx, path); - if (xpathObj == NULL) return NULL; - - if (xpathObj->nodesetval->nodeNr > 0) - result = qck_build_filename_with_doc_url(xpathObj->nodesetval->nodeTab[0]); - - xmlXPathFreeObject(xpathObj); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* OPERATIONS D'ECRITURE D'UN FICHIER XML */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à ouvrir. * -* * -* Description : Amorce l'écriture d'un nouveau fichier XML. * -* * -* Retour : Rédacteur mis en place ou NULL en cas d'erreur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -xmlTextWriterPtr start_writing_xml_file(const char *filename) -{ - xmlTextWriterPtr result; /* Moyen à retourner */ - int retval; /* Bilan d'une opération */ - - result = xmlNewTextWriterFilename(filename, 0); - - if (result == NULL) - { - XML_LOG(stderr, "Error creating the xml writer\n"); - return NULL; - } - - retval = xmlTextWriterStartDocument(result, NULL, "UTF-8", "yes"); - if (retval < 0) - { - XML_LOG(stderr, "Error at xmlTextWriterStartDocument\n"); - xmlFreeTextWriter(result); - return NULL; - } - - retval = xmlTextWriterSetIndent(result, 1); - if (retval < 0) - { - XML_LOG(stderr, "Error setting indentation\n"); - xmlFreeTextWriter(result); - return NULL; - } - - retval = xmlTextWriterSetIndentString(result, BAD_CAST "\t"); - if (retval < 0) - { - XML_LOG(stderr, "Error setting indentation string\n"); - xmlFreeTextWriter(result); - return NULL; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* * -* Description : Met fin à l'écriture d'un nouveau fichier XML. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : Ferme au besoin toutes les balises encore ouvertes. * -* * -******************************************************************************/ - -bool end_writing_xml_file(xmlTextWriterPtr writer) -{ - int retval; /* Bilan de l'opération */ - - retval = xmlTextWriterEndDocument(writer); - if (retval < 0) - { - XML_LOG(stderr, "Error at xmlTextWriterEndDocument\n"); - return false; - } - - xmlFreeTextWriter(writer); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* name = nom de la balise à écrire. * -* * -* Description : Ecrit une balise et ne la referme pas. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool open_xml_element(xmlTextWriterPtr writer, const char *name) -{ - int retval; /* Bilan de l'opération */ - - retval = xmlTextWriterStartElement(writer, BAD_CAST name); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* * -* Description : Ferme la dernière balise laissée ouverte. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool close_xml_element(xmlTextWriterPtr writer) -{ - int retval; /* Bilan de l'opération */ - - retval = xmlTextWriterEndElement(writer); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* name = nom de la balise à écrire. * -* format = format de la chaîne à traiter. * -* ... = informations à inscrire. * -* * -* Description : Ecrit une balise avec un contenu textuel. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_xml_element_with_content(xmlTextWriterPtr writer, const char *name, const char *format, ...) -{ - va_list ap; /* Liste d'arguments variable */ - int retval; /* Bilan de l'opération */ - - va_start(ap, format); - - retval = xmlTextWriterWriteVFormatElement(writer, BAD_CAST name, format, ap); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - va_end(ap); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* name = nom de l'attribut à écrire. * -* format = format de la chaîne à traiter. * -* ... = informations à inscrire. * -* * -* Description : Ecrit un attribut avec un contenu textuel. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_xml_attribute(xmlTextWriterPtr writer, const char *name, const char *format, ...) -{ - va_list ap; /* Liste d'arguments variable */ - int retval; /* Bilan de l'opération */ - - va_start(ap, format); - - retval = xmlTextWriterWriteVFormatAttribute(writer, BAD_CAST name, format, ap); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - va_end(ap); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* format = format de la chaîne à traiter. * -* ... = informations à inscrire. * -* * -* Description : Ecrit un contenu textuel. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_xml_content(xmlTextWriterPtr writer, const char *format, ...) -{ - va_list ap; /* Liste d'arguments variable */ - int retval; /* Bilan de l'opération */ - - va_start(ap, format); - - retval = xmlTextWriterWriteVFormatString(writer, format, ap); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - va_end(ap); - - return (retval >= 0); - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* OPERATIONS D'ECRITURE D'UN FICHIER XML */ -/* ---------------------------------------------------------------------------------- */ - - - -/****************************************************************************** -* * -* Paramètres : context = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* * -* Description : Fournit le premier noeud correspondant à un chemin XPath. * -* * -* Retour : Adresse du noeud trouvé ou NULL en cas d'échec. * -* * -* Remarques : - * -* * -******************************************************************************/ - -xmlNodePtr get_node_from_xpath(xmlXPathContextPtr context, const char *path) -{ - xmlNodePtr result; /* Noeud trouvé à renvoyer */ - xmlXPathObjectPtr xobject; /* Point de départ XML */ - - result = NULL; - - xobject = get_node_xpath_object(context, path); - if (xobject == NULL) return NULL; - - if (xobject->nodesetval->nodeNr > 0) - result = xobject->nodesetval->nodeTab[0]; - - xmlXPathFreeObject(xobject); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xdoc = structure XML chargée. * -* context = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* * -* Description : S'assure qu'un noeud donné est bien présent dans le document.* -* * -* Retour : Noeud en question ou NULL en cas d'échec à la création. * -* * -* Remarques : - * -* * -******************************************************************************/ - -xmlNodePtr ensure_node_exist(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path) -{ - xmlNodePtr result; /* Noeud à retourner */ - char **levels; /* Niveaux dans le chemin */ - size_t levels_count; /* Nombre de ces niveaux */ - xmlNodePtr last; /* Dernier noeud valide */ - size_t i; /* Boucle de parcours #1 */ - char *iter_path; /* Chamin d'accès pour le test */ - size_t j; /* Boucle de parcours #2 */ - xmlNodePtr iter; /* Test d'accès à un noeud */ - char *cond; /* Marque de condition ('[') */ - - result = get_node_from_xpath(context, path); - - if (result == NULL) - { - levels = strtoka(path, "/", &levels_count); - - /* Recherche la racine valide la plus haute */ - - last = xmlDocGetRootElement(xdoc); - - for (i = 0; i < levels_count && last != NULL; i++) - { - iter_path = strdup(""); - - for (j = 0; j <= i; j++) - { - iter_path = stradd(iter_path, "/"); - iter_path = stradd(iter_path, levels[j]); - } - - iter = get_node_from_xpath(context, iter_path); - - if (iter == NULL) break; - else last = iter; - - } - - /* Inscription des noeuds restants */ - - if (last == NULL) - { - last = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i++], NULL); - xmlDocSetRootElement(xdoc, last); - - if (i == levels_count) - result = last; - - } - - for ( ; i < levels_count && last != NULL; i++) - { - cond = strchr(levels[i], '['); - if (cond != NULL) *cond = '\0'; - - result = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i], NULL); - result = xmlAddChild(last, result); - last = result; - } - - /* Libération de la mémoire */ - - for (i = 0; i < levels_count; i++) - free(levels[i]); - - free(levels); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xdoc = structure XML chargée. * -* context = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* content = texte à inscrire en contenu. * -* * -* Description : S'assure qu'un noeud donné est bien présent dans le document.* -* * -* Retour : true en cas de succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool add_content_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *content) -{ - xmlNodePtr node; /* Noeud à modifier */ - - if (content == NULL) return true; - - node = ensure_node_exist(xdoc, context, path); - if (node == NULL) return false; - - xmlNodeSetContent(node, content); - - return true; - -} diff --git a/src/xml.h b/src/xml.h deleted file mode 100644 index 82e2578..0000000 --- a/src/xml.h +++ /dev/null @@ -1,122 +0,0 @@ - -/* Firebox Tools - Outils de configurations pour le WM Firebox - * xml.h - prototypes pour la lecture ou l'écriture de documents XML - * - * Copyright (C) 2006-2007 Cyrille Bagard - * - * This file is part of Firebox Tools. - * - * Firebox Tools 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 2 of the License, or - * (at your option) any later version. - * - * Firebox Tools 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 _XML_H -#define _XML_H - - -#include -#include -#include -#include -#include - - - - -/* Crée un nouveau fichier XML. */ -bool create_new_xml_file(xmlDocPtr *, xmlXPathContextPtr *); - -/* Sauvegarde une structure XML dans un fichier. */ -bool save_xml_file(xmlDocPtr, const char *); - -/* Ferme une structure XML. */ -void close_xml_file(xmlDocPtr, xmlXPathContextPtr); - - - -/* --------------------- OPERATIONS DE LECTURE D'UN FICHIER XML --------------------- */ - - -#define XPATH_OBJ_NODES_COUNT(obj) (obj != NULL ? obj->nodesetval->nodeNr : 0) -#define NODE_FROM_PATH_OBJ(obj, i) obj->nodesetval->nodeTab[i] - - -/* Ouvre un fichier XML de façon encadrée. */ -gboolean open_xml_file(const char *filename, xmlDoc **, xmlXPathContextPtr *); - -/* Obtient de façon encadrée l'accès à un noeud défini. */ -xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr, const char *); - -/* Obtient une valeur placée entre <...> et . */ -char *qck_get_node_text_value(xmlNodePtr); - -/* Obtient une valeur placée entre <...> et . */ -char *get_node_text_value(xmlXPathContextPtr, const char *); - -/* Obtient la valeur d'une propriété d'un élément. */ -char *qck_get_node_prop_value(xmlNodePtr, const char *); - -/* Obtient la valeur d'une propriété d'un élément. */ -char *get_node_prop_value(xmlXPathContextPtr, const char *, const char *); - -/* Construit un chemin d'accès complet selon le fichier XML. */ -char *qck_build_filename_with_doc_url(xmlNodePtr); - -/* Construit un chemin d'accès complet selon le fichier XML. */ -char *build_filename_with_doc_url(xmlXPathContextPtr xpathCtx, const char *path); - - - -/* --------------------- OPERATIONS D'ECRITURE D'UN FICHIER XML --------------------- */ - - -/* Amorce l'écriture d'un nouveau fichier XML. */ -xmlTextWriterPtr start_writing_xml_file(const char *); - -/* Met fin à l'écriture d'un nouveau fichier XML. */ -bool end_writing_xml_file(xmlTextWriterPtr); - -/* Ecrit une balise et ne la referme pas. */ -bool open_xml_element(xmlTextWriterPtr, const char *); - -/* Ferme la dernière balise laissée ouverte. */ -bool close_xml_element(xmlTextWriterPtr); - -/* Ecrit une balise avec un contenu textuel. */ -bool write_xml_element_with_content(xmlTextWriterPtr, const char *, const char *, ...); - -/* Ecrit un attribut avec un contenu textuel. */ -bool write_xml_attribute(xmlTextWriterPtr, const char *, const char *, ...); - -/* Ecrit un contenu textuel. */ -bool write_xml_content(xmlTextWriterPtr, const char *, ...); - - - -/* --------------------- OPERATIONS D'ECRITURE D'UN FICHIER XML --------------------- */ - - -/* Fournit le premier noeud correspondant à un chemin XPath. */ -xmlNodePtr get_node_from_xpath(xmlXPathContextPtr, const char *); - -/* S'assure qu'un noeud donné est bien présent dans le document. */ -xmlNodePtr ensure_node_exist(xmlDocPtr, xmlXPathContextPtr, const char *); - -/* S'assure qu'un noeud donné est bien présent dans le document. */ -bool add_content_to_node(xmlDocPtr, xmlXPathContextPtr, const char *, const char *); - - - -#endif /* _XML_H */ -- cgit v0.11.2-87-g4458