diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2015-08-27 00:26:20 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2015-08-27 00:26:20 (GMT) |
commit | e07a541d1dea13a19a587f2b97d12ed3443f235b (patch) | |
tree | 95ef0ba21345c34c7c246ff824ba70317b810717 /plugins/pychrysa/plugin.c | |
parent | 50a657889a32a6df365bf9880a6f56bf3a0e828c (diff) |
Redefined and improved the load process for Python plugins.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@572 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'plugins/pychrysa/plugin.c')
-rw-r--r-- | plugins/pychrysa/plugin.c | 690 |
1 files changed, 394 insertions, 296 deletions
diff --git a/plugins/pychrysa/plugin.c b/plugins/pychrysa/plugin.c index e1db3de..44cb0d8 100644 --- a/plugins/pychrysa/plugin.c +++ b/plugins/pychrysa/plugin.c @@ -26,20 +26,14 @@ #include <pygobject.h> +#include <string.h> #include <common/extstr.h> - -#include "../../src/analysis/binary.h" -#include "../../src/plugins/plugin-int.h" +#include <plugins/plugin-int.h> #include "helpers.h" -#include "analysis/binary.h" -//#include "debug/debugger.h" - - - @@ -71,9 +65,20 @@ static void g_python_plugin_class_init(GPythonPluginClass *); /* Initialise l'instance d'un greffon Python. */ static void g_python_plugin_init(GPythonPlugin *); +/* Reconstruit la déclaration d'interface à partir de lectures. */ +static bool g_python_plugin_read_interface(GPythonPlugin *); + /* Procède à l'initialisation du greffon. */ static bool g_python_plugin_do_init(GPythonPlugin *, GObject *); +/* Procède à l'extinction du greffon. */ +static bool g_python_plugin_do_exit(GPythonPlugin *, GObject *); + + + + + + /* Indique l'utilité pratique du greffon. */ static PluginAction g_python_plugin_get_action(const GPythonPlugin *); @@ -92,49 +97,8 @@ static bool g_python_plugin_execute_on_binary(GPythonPlugin *, GLoadedBinary *, /* ------------------------- MODULE PYTHON POUR LES SCRIPTS ------------------------- */ -/* Classe plugin pour Python */ -typedef struct _pychrysa_plugin -{ - PyObject_HEAD - -} pychrysa_plugin; - - - - - - -/* Crée un nouveau greffon Python abstrait. */ -static PyObject *pychrysa_plugin_new(PyTypeObject *, PyObject *, PyObject *); - -/* Exécute une action valide pour le greffon Python. */ -static PyObject *pychrysa_plugin_run(PyObject *, PyObject *); - - - /* Définit les constantes pour les greffons en Python. */ -static bool pychrysa_plugin_define_constants(PyObject *); - -/* Procède à l'initialisation du greffon. */ -static PyObject *pychrysa_plugin_init(PyObject *, PyObject *); - -/* Définit le comportement par défaut d'un greffon Python. */ -static PyObject *pychrysa_plugin_get_action(PyObject *, PyObject *); - -/* Définit l'issue de la recherche d'un format par défaut. */ -static PyObject *pychrysa_plugin_is_matching(PyObject *, PyObject *); - - -/* Exécute une action relative à un débogueur. */ -//static PyObject *pychrysa_plugin_handle_debugger(PyObject *, PyObject *); - - - - - - - - +static bool py_plugin_module_define_constants(PyTypeObject *); @@ -196,6 +160,7 @@ static void g_python_plugin_init(GPythonPlugin *plugin) * * * Paramètres : modname = nom du module à charger. * * filename = chemin d'accès au code Python à charger. * +* ref = espace de référencement global. * * * * Description : Crée un greffon à partir de code Python. * * * @@ -205,33 +170,62 @@ static void g_python_plugin_init(GPythonPlugin *plugin) * * ******************************************************************************/ -GPluginModule *g_python_plugin_new(const char *modname, const char *filename) +GPluginModule *g_python_plugin_new(const char *modname, const char *filename, GObject *ref) { GPythonPlugin *result; /* Structure à retourner */ PyObject *name; /* Chemin d'accès pour Python */ PyObject *module; /* Script Python chargé */ + PyObject *err_type; /* Type d'erreur Python */ + PyObject *err_value; /* Instance Python d'erreur */ + PyObject *err_traceback; /* Trace Python associée */ + PyObject *err_string; /* Description Python d'erreur */ + const char *err_msg; /* Représentation humaine */ PyObject *dict; /* Dictionnaire associé */ PyObject *class; /* Classe à instancier */ PyObject *instance; /* Instance Python du greffon */ + size_t i; /* Boucle de parcours */ + uint32_t category; /* Catégorie principale */ + uint32_t sub; /* Sous-catégorie visée */ -#if PY_VERSION_HEX >= 0x03000000 - name = PyUnicode_FromString(filename); -#else - name = PyString_FromString(filename); -#endif + name = PyUnicode_FromString(modname); if (name == NULL) goto gppn_bad_exit; module = PyImport_Import(name); Py_DECREF(name); - if (module == NULL) + if (PyErr_Occurred()) { - PyErr_Print(); - goto gppn_bad_exit; + PyErr_Fetch(&err_type, &err_value, &err_traceback); + + if (err_value == NULL) + log_variadic_message(LMT_ERROR, + _("An unknown error occured when importing '%s'..."), modname); + else + { + err_string = PyObject_Str(err_value); + err_msg = PyUnicode_AsUTF8(err_string); + + log_variadic_message(LMT_ERROR, + _("An error occured when importing '%s': \"%s\""), modname, err_msg); + + Py_DECREF(err_string); + Py_DECREF(err_value); + + } + + Py_XDECREF(err_traceback); + Py_XDECREF(err_type); + + Py_XDECREF(module); + + module = NULL; + } + if (module == NULL) goto gppn_bad_exit; + dict = PyModule_GetDict(module); - class = PyDict_GetItemString(dict, modname); + class = PyDict_GetItemString(dict, "AutoLoad"); if (class == NULL) goto gppn_no_class; if (!PyType_Check(class->ob_type)) goto gppn_no_class; @@ -241,28 +235,154 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) result = g_object_new(G_TYPE_PYTHON_PLUGIN, NULL); - //G_PLUGIN_MODULE(result)->name = strdup(modname); - //G_PLUGIN_MODULE(result)->name = stradd(G_PLUGIN_MODULE(result)->name, ".py"); - //G_PLUGIN_MODULE(result)->filename = strdup(G_PLUGIN_MODULE(result)->name); + G_PLUGIN_MODULE(result)->filename = strdup(filename); + + result->module = module; + result->instance = instance; + + if (!g_python_plugin_read_interface(result)) + { + printf("bad interface------------\n"); + goto gppn_interface_error; + } + - G_PLUGIN_MODULE(result)->init = (init_plugin_fc)g_python_plugin_do_init; - G_PLUGIN_MODULE(result)->get_action = (get_plugin_action_fc)g_python_plugin_get_action; + //G_PLUGIN_MODULE(result)->get_action = (get_plugin_action_fc)g_python_plugin_get_action; //G_PLUGIN_MODULE(result)->is_matching = (is_matching_fc)g_python_plugin_is_matching; - result->module = module; - result->instance = instance; + + + + + + + /* Localisation des différents points d'entrée déclarés */ + +#define register_python_binding(inst, sym, binding) \ + ({ \ + bool __result; \ + if (!has_python_method(inst, #sym)) \ + { \ + log_variadic_message(LMT_ERROR, \ + _("No '%s' entry in plugin candidate '%s'"), \ + #sym, G_PLUGIN_MODULE(result)->filename); \ + __result = false; \ + } \ + else \ + { \ + G_PLUGIN_MODULE(result)->sym = binding; \ + __result = true; \ + } \ + __result; \ + }) + + for (i = 0; i < G_PLUGIN_MODULE(result)->interface->actions_count; i++) + { + category = MASK_PLUGIN_CATEGORY(G_PLUGIN_MODULE(result)->interface->actions[i]); + sub = MASK_PLUGIN_SUB_CATEGORY(G_PLUGIN_MODULE(result)->interface->actions[i]); + + switch (category) + { + case DPC_BASIC: + + switch (sub) + { + case DPS_NONE: + break; + + case PGA_PLUGIN_INIT: + if (!register_python_binding(instance, init, (pg_management_fc)g_python_plugin_do_init)) + goto gppn_bad_plugin; + break; + + case PGA_PLUGIN_EXIT: + if (!register_python_binding(instance, exit, (pg_management_fc)g_python_plugin_do_exit)) + goto gppn_bad_plugin; + break; + + default: + log_variadic_message(LMT_WARNING, + _("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename); + break; + + } + + break; +#if 0 + case DPC_BINARY_PROCESSING: + + switch (sub) + { + case DPS_FORMAT: + + switch (result->interface->actions[i]) + { + + case PGA_FORMAT_LOADER_LAST: + if (!load_plugin_symbol(result->module, + "handle_binary_format", &result->handle_format)) + goto bad_plugin; + break; + + default: + log_variadic_message(LMT_WARNING, + _("Unknown action '0x%02x' in plugin '%s'..."), + result->interface->actions[i], filename); + break; + + } + + break; + + case DPS_DISASSEMBLY: + if (!load_plugin_symbol(result->module, + "process_binary_disassembly", &result->proc_disass)) + goto bad_plugin; + break; + + default: + log_variadic_message(LMT_WARNING, + _("Unknown sub-category '0x%02x' in plugin '%s'..."), sub, filename); + break; + + } + + break; +#endif + default: + log_variadic_message(LMT_WARNING, + _("Unknown category '0x%02x' in plugin '%s'..."), category, filename); + break; + + } + + } + + /* Conclusion */ + + if (!g_plugin_module_load(G_PLUGIN_MODULE(result), ref)) + goto gppn_bad_plugin; return G_PLUGIN_MODULE(result); + gppn_bad_plugin: + + gppn_interface_error: + + g_object_unref(G_OBJECT(result)); + + //Py_DECREF(instance); + gppn_no_instance: gppn_no_class: - Py_DECREF(module); + //Py_DECREF(module); gppn_bad_exit: + printf("bad exit :(\n"); return NULL; } @@ -271,6 +391,105 @@ GPluginModule *g_python_plugin_new(const char *modname, const char *filename) /****************************************************************************** * * * Paramètres : plugin = greffon à initialiser. * +* * +* Description : Reconstruit la déclaration d'interface à partir de lectures. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_python_plugin_read_interface(GPythonPlugin *plugin) +{ + bool result; /* Bilan à renvoyer */ + plugin_interface interface; /* Recueil des éléments */ + PyObject *desc; /* Tableau de description */ + PyObject *str; /* Chaîne de caractères */ + PyObject *tuple; /* Liste d'éléments à traiter */ + Py_ssize_t count; /* Nombre d'éléments présents */ + Py_ssize_t i; /* Boucle de parcours */ + PyObject *action; /* Identifiant d'une action */ + plugin_interface *final; /* Interface finale conservée */ + + result = true; + + desc = run_python_method(plugin->instance, "get_interface", NULL); + if (!PyDict_Check(desc)) + { + result = false; + goto pgpri_end; + } + + memset(&interface, 0, sizeof(interface)); + + /* Chargements des premières chaînes */ + +#define READ_STR_FIELD(name) \ + str = PyDict_GetItemString(desc, #name); \ + if ((result = PyUnicode_Check(str))) \ + interface.name = strdup(PyUnicode_DATA(str)); \ + + READ_STR_FIELD(name); + READ_STR_FIELD(desc); + READ_STR_FIELD(version); + + /* Chargement des actions supportées */ + + tuple = PyDict_GetItemString(desc, "actions"); + + if (!PyList_Check(tuple)) + { + result = false; + goto pgpri_failed; + } + + count = PyList_GET_SIZE(tuple); + + interface.actions = (plugin_action_t *)calloc(count, sizeof(plugin_action_t)); + interface.actions_count = count; + + for (i = 0; i < count; i++) + { + action = PyList_GET_ITEM(tuple, i); + + interface.actions[i] = PyLong_AsLong(action); + + } + + pgpri_failed: + + if (result) + { + final = (plugin_interface *)calloc(1, sizeof(plugin_interface)); + + memcpy(final, &interface, sizeof(interface)); + + G_PLUGIN_MODULE(plugin)->interface = final; + + } + else + { + if (interface.name != NULL) free((char *)interface.name); + if (interface.desc != NULL) free((char *)interface.desc); + if (interface.version != NULL) free((char *)interface.version); + + if (interface.actions != NULL) free(interface.actions); + + } + + pgpri_end: + + Py_XDECREF(desc); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à initialiser. * * ref = espace de référencement global. * * * * Description : Procède à l'initialisation du greffon. * @@ -286,17 +505,47 @@ static bool g_python_plugin_do_init(GPythonPlugin *plugin, GObject *ref) bool result; /* Bilan à retourner */ PyObject *args; /* Arguments pour l'appel */ PyObject *value; /* Valeur obtenue */ - int cmp; /* Bilan de la comparaison */ args = PyTuple_New(1); PyTuple_SetItem(args, 0, pygobject_new(ref)); value = run_python_method(plugin->instance, "init", args); - if (PyObject_Cmp(value, Py_True, &cmp) == -1) - result = false; - else - result = (cmp == 0); + result = PyObject_IsTrue(value); + + Py_XDECREF(value); + Py_DECREF(args); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : plugin = greffon à initialiser. * +* ref = espace de référencement global. * +* * +* Description : Procède à l'extinction du greffon. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_python_plugin_do_exit(GPythonPlugin *plugin, GObject *ref) +{ + bool result; /* Bilan à retourner */ + PyObject *args; /* Arguments pour l'appel */ + PyObject *value; /* Valeur obtenue */ + + args = PyTuple_New(1); + PyTuple_SetItem(args, 0, pygobject_new(ref)); + + value = run_python_method(plugin->instance, "exit", args); + + result = PyObject_IsTrue(value); Py_XDECREF(value); Py_DECREF(args); @@ -306,6 +555,12 @@ static bool g_python_plugin_do_init(GPythonPlugin *plugin, GObject *ref) } + + + + + + /****************************************************************************** * * * Paramètres : plugin = greffon de prise en charge à utiliser. * @@ -355,6 +610,9 @@ static PluginAction g_python_plugin_get_action(const GPythonPlugin *plugin) static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *plugin, char **filename, bin_t **data, off_t *length) { + return MFA_NONE; + +#if 0 MatchingFormatAction result; /* Valeur à retourner */ PyObject *args; /* Arguments pour l'appel */ PyObject *value; /* Valeurs obtenues */ @@ -439,7 +697,7 @@ static MatchingFormatAction g_python_plugin_is_matching(const GPythonPlugin *plu Py_DECREF(args); return result; - +#endif } @@ -467,7 +725,7 @@ static bool g_python_plugin_execute_on_binary(GPythonPlugin *plugin, GLoadedBina args = PyTuple_New(2); PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(binary))); - PyTuple_SetItem(args, 1, PyInt_FromLong(action)); + PyTuple_SetItem(args, 1, Py_None);//PyInt_FromLong(action)); value = run_python_method(plugin->instance, "execute_on_binary", args); @@ -508,7 +766,7 @@ static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinary args = PyTuple_New(2); PyTuple_SetItem(args, 0, py_binary_debugger_from_c(debugger)); - PyTuple_SetItem(args, 1, PyInt_FromLong(action)); + PyTuple_SetItem(args, 1, Py_None);//PyInt_FromLong(action)); value = run_python_method(plugin->instance, "handle_debugger", args); @@ -533,29 +791,10 @@ static bool g_python_plugin_handle_debugger(const GPythonPlugin *plugin, GBinary /* ---------------------------------------------------------------------------------- */ -/****************************************************************************** -* * -* Paramètres : type = type de l'objet à instancier. * -* args = arguments fournis à l'appel. * -* kwds = arguments de type key=val fournis. * -* * -* Description : Crée un nouveau greffon Python abstrait. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -static PyObject *pychrysa_plugin_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - pychrysa_plugin *result; /* Instance à retourner */ - result = (pychrysa_plugin *)type->tp_alloc(type, 0); - return (PyObject *)result; -} @@ -567,264 +806,123 @@ static PyObject *pychrysa_plugin_new(PyTypeObject *type, PyObject *args, PyObjec /****************************************************************************** * * -* Paramètres : dict = dictionnaire à compléter. * +* Paramètres : obj_type = type dont le dictionnaire est à compléter. * * * * Description : Définit les constantes pour les greffons en Python. * * * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool pychrysa_plugin_define_constants(PyObject *dict) -{ - int ret; /* Bilan d'un ajout */ - - //ret = PyDict_SetItemString(dict, "PGA_NONE", PyInt_FromLong(PGA_NONE)); - //if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_FORMAT_MATCHER", PyInt_FromLong(PGA_FORMAT_MATCHER)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_DISASSEMBLE", PyInt_FromLong(PGA_DISASSEMBLE)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_BINARY_DISASSEMBLED", PyInt_FromLong(PGA_BINARY_DISASSEMBLED)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_BINARY_LINKED", PyInt_FromLong(PGA_BINARY_LINKED)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_BINARY_BOUNDED", PyInt_FromLong(PGA_BINARY_BOUNDED)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_BINARY_GROUPED", PyInt_FromLong(PGA_BINARY_GROUPED)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_BINARY_PRINTED", PyInt_FromLong(PGA_BINARY_PRINTED)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_DISASS_PROCESS", PyInt_FromLong(PGA_DISASS_PROCESS)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_CODE_PROCESS", PyInt_FromLong(PGA_CODE_PROCESS)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_DEBUGGER_ATTACH", PyInt_FromLong(PGA_DEBUGGER_ATTACH)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "PGA_DEBUGGER_DETACH", PyInt_FromLong(PGA_DEBUGGER_DETACH)); - if (ret == -1) return false; - - /* PGA_FORMAT_MATCHER */ - - ret = PyDict_SetItemString(dict, "MFA_NONE", PyInt_FromLong(MFA_NONE)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "MFA_MATCHED", PyInt_FromLong(MFA_MATCHED)); - if (ret == -1) return false; - - ret = PyDict_SetItemString(dict, "MFA_RELOAD", PyInt_FromLong(MFA_RELOAD)); - 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 : Procède à l'initialisation du greffon. * -* * -* Retour : Rien en équivalent Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *pychrysa_plugin_init(PyObject *self, PyObject *args) -{ - Py_INCREF(Py_True); - return Py_True; - -} - - -/****************************************************************************** -* * -* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * -* args = arguments fournis à l'appel. * -* * -* Description : Définit le comportement par défaut d'un greffon Python. * -* * -* Retour : Rien en équivalent Python. * +* Retour : true en cas de succès de l'opération, false sinon. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *pychrysa_plugin_get_action(PyObject *self, PyObject *args) +static bool py_plugin_module_define_constants(PyTypeObject *obj_type) { - return PyInt_FromLong(0/*PGA_NONE*/); - -} - - -/****************************************************************************** -* * -* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * -* args = arguments fournis à l'appel. * -* * -* Description : Définit l'issue de la recherche d'un format par défaut. * -* * -* Retour : Rien en équivalent Python. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static PyObject *pychrysa_plugin_is_matching(PyObject *self, PyObject *args) -{ - PyObject *result; /* Liste à retourner */ - - result = PyTuple_New(3); + bool result; /* Bilan à retourner */ - PyTuple_SetItem(result, 0, PyInt_FromLong(MFA_NONE)); - //Py_DECREF(Py_None); - PyTuple_SetItem(result, 1, Py_None); - //Py_DECREF(Py_None); - PyTuple_SetItem(result, 2, Py_None); + result = true; + + result &= PyDict_AddIntMacro(obj_type, PGA_BASIC_NONE); + result &= PyDict_AddIntMacro(obj_type, PGA_PLUGIN_INIT); + result &= PyDict_AddIntMacro(obj_type, PGA_PLUGIN_EXIT); + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_MATCHER); + result &= PyDict_AddIntMacro(obj_type, PGA_FORMAT_LOADER_LAST); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_STARTED); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_RAW); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_HOOKED_LINK); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_HOOKED_POST); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_LIMITED); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_LOOPS); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_LINKED); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_GROUPED); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_RANKED); + result &= PyDict_AddIntMacro(obj_type, PGA_DISASSEMBLY_ENDED); return result; } - - /****************************************************************************** * * -* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * -* args = arguments fournis à l'appel. * +* Paramètres : - * * * -* Description : Exécute une action relative à un débogueur. * +* Description : Fournit un accès à une définition de type à diffuser. * * * -* Retour : True en équivalent Python. * +* Retour : Définition d'objet pour Python. * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *pychrysa_plugin_handle_debugger(PyObject *self, PyObject *args) +PyTypeObject *get_python_plugin_module_type(void) { - Py_RETURN_TRUE; - -} - - -/****************************************************************************** -* * -* Paramètres : self = classe assurant le lien avec l'éditeur de messages. * -* args = arguments fournis à l'appel. * -* * -* Description : Exécute une action valide pour le greffon Python. * -* * -* Retour : Rien en équivalent Python. * -* * -* Remarques : - * -* * -******************************************************************************/ + static PyMethodDef py_plugin_module_methods[] = { + { NULL } + }; -static PyObject *pychrysa_plugin_run(PyObject *self, PyObject *args) -{ - Py_RETURN_NONE; + static PyGetSetDef py_plugin_module_getseters[] = { + { NULL } + }; -} + static PyTypeObject py_plugin_module_type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "pychrysalide.PluginModule", + .tp_basicsize = sizeof(PyGObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = "Chrysalide plugin for Python.", + .tp_methods = py_plugin_module_methods, + .tp_getset = py_plugin_module_getseters + }; + return &py_plugin_module_type; +} /****************************************************************************** * * * Paramètres : module = module dont la définition est à compléter. * * * -* Description : Ajoute l'objet 'plugin' au module Python. * +* Description : Prend en charge l'objet 'pychrysalide.PluginModule'. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -bool add_plugin_to_python_module(PyObject *module) +bool register_python_plugin_module(PyObject *module) { + PyTypeObject *py_plugin_module_type; /* Type Python 'PluginModule' */ int ret; /* Bilan d'un appel */ + PyObject *dict; /* Dictionnaire du module */ - static PyMethodDef pychrysa_plugin_methods[] = { - { - "init", (PyCFunction)pychrysa_plugin_init, - METH_VARARGS, - "Initialize the plugin." - }, - { - "get_action", (PyCFunction)pychrysa_plugin_get_action, - METH_NOARGS, - "Register the plugin for given actions." - }, - { - "is_matching", (PyCFunction)pychrysa_plugin_is_matching, - METH_VARARGS, - "Define if the given file can be handled." - }, - { - "handle_debugger", (PyCFunction)pychrysa_plugin_handle_debugger, - METH_VARARGS, - "Be notify about debugger attaching or detaching." - }, - { - "run", (PyCFunction)pychrysa_plugin_run, - METH_VARARGS, - "Run the plugin for a specific action." - }, - { NULL } - }; - - static PyTypeObject pychrysa_plugin_type = { + py_plugin_module_type = get_python_plugin_module_type(); - PyObject_HEAD_INIT(NULL) + py_plugin_module_type->tp_base = &PyGObject_Type; + py_plugin_module_type->tp_basicsize = py_plugin_module_type->tp_base->tp_basicsize; - .tp_name = "plugin.Plugin", - .tp_basicsize = sizeof(pychrysa_plugin), - - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - - .tp_doc = "PyChrysalide plugin objects", - - - .tp_methods = pychrysa_plugin_methods, - .tp_new = (newfunc)pychrysa_plugin_new - - }; - - if (PyType_Ready(&pychrysa_plugin_type) < 0) + if (PyType_Ready(py_plugin_module_type) != 0) return false; - if (!pychrysa_plugin_define_constants(pychrysa_plugin_type.tp_dict)) + if (!py_plugin_module_define_constants(py_plugin_module_type)) return false; - Py_INCREF(&pychrysa_plugin_type); - ret = PyModule_AddObject(module, "Plugin", (PyObject *)&pychrysa_plugin_type); + Py_INCREF(py_plugin_module_type); + ret = PyModule_AddObject(module, "PluginModule", (PyObject *)py_plugin_module_type); + if (ret != 0) return false; + + dict = PyModule_GetDict(module); + pygobject_register_class(dict, "PluginModule", G_TYPE_PLUGIN_MODULE, py_plugin_module_type, + Py_BuildValue("(O)", py_plugin_module_type->tp_base)); - return (ret == 0); + return true; } |