/* OpenIDA - Outil d'analyse de fichiers binaires * pglist.c - gestion de l'ensemble des greffons * * Copyright (C) 2009-2012 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 "pglist.h" #include #include #include #include #include "plugin-int.h" #include "../common/extstr.h" /* Propriétés de l'ensemble des greffons */ typedef struct _plugins_list { GObject *ref; /* Référencement global */ GPluginModule **plugins; /* Liste de greffons */ size_t plugins_count; /* Taille de cette liste */ } plugins_list; /* Liste de l'ensemble des greffons */ static plugins_list _list; /* Filtre les répertoire et les modules de greffons pootentels. */ int filter_dirs_or_mods(const struct dirent *); /* Part à la recherche de greffons sous forme de modules. */ void browse_directory_for_plugins(plugins_list *, const char *); /****************************************************************************** * * * Paramètres : ref = espace de référencement global. * * * * Description : Procède au chargement des différents greffons trouvés. * * * * Retour : Toujours true (même s'il y a des erreurs de chargement). * * * * Remarques : - * * * ******************************************************************************/ bool init_all_plugins(GObject *ref) { _list.ref = ref; g_object_ref(ref); browse_directory_for_plugins(&_list, PACKAGE_SOURCE_DIR "/plugins"); return true; } /****************************************************************************** * * * Paramètres : - * * * * Description : Procède au déchargement des différents greffons présents. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void exit_all_plugins(void) { size_t i; /* Boucle de parcours */ for (i = 0; i < _list.plugins_count; i++) g_object_unref(_list.plugins[i]); if (_list.plugins != NULL) free(_list.plugins); g_object_unref(_list.ref); } /****************************************************************************** * * * Paramètres : entry = entrée de répertoire à analyser. * * * * Description : Filtre les répertoire et les modules de greffons pootentels. * * * * Retour : Valeur non nulle pour garder l'élément. * * * * Remarques : - * * * ******************************************************************************/ int filter_dirs_or_mods(const struct dirent *entry) { int result; /* Conclusion à remonter */ if (entry->d_type == DT_DIR) result = strcmp(entry->d_name, ".") * strcmp(entry->d_name, ".."); else result = (strrcmp(entry->d_name, "." G_MODULE_SUFFIX) == 0 ? 1 : 0); return result; } /****************************************************************************** * * * Paramètres : list = liste de greffons à compléter si possible. * * dir = répertoire à parcourir en quête de greffons (sans /). * * * * Description : Part à la recherche de greffons sous forme de modules. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void browse_directory_for_plugins(plugins_list *list, const char *dir) { struct dirent **namelist; /* Eléments trouvés */ int ret; /* Bilan du parcours */ char *filename; /* Elément à ausculter */ GPluginModule *plugin; /* Greffon à intégrer ou pas */ ret = scandir(dir, &namelist, filter_dirs_or_mods, alphasort); if (ret < 0) { perror("scandir"); return; } while (ret--) { filename = (char *)calloc(strlen(dir) + 1 + strlen(namelist[ret]->d_name) + 1, sizeof(char)); strcpy(filename, dir); strcat(filename, "/"); /* FIXME : Win */ strcat(filename, namelist[ret]->d_name); if (namelist[ret]->d_type == DT_DIR) browse_directory_for_plugins(list, filename); else { plugin = g_plugin_module_new(filename); if (plugin != NULL) add_plugin_to_main_list(plugin); } free(filename); free(namelist[ret]); } free(namelist); } /****************************************************************************** * * * Paramètres : action = fonctionnalité recherchée. * * * * Description : Founit un greffon offrant le service demandé. * * * * Retour : Greffon satisfaisant ou NULL si aucun. * * * * Remarques : - * * * ******************************************************************************/ GPluginModule *get_one_plugin_for_action(PluginAction action) { GPluginModule *result; /* Greffon à retourner */ size_t i; /* Boucle de parcours */ result = NULL; for (i = 0; i < _list.plugins_count; i++) if (g_plugin_module_get_action(_list.plugins[i]) & action) { result = _list.plugins[i]; break; } return result; } /****************************************************************************** * * * Paramètres : action = fonctionnalité recherchée. * * count = nombre de greffons trouvés. [OUT] * * * * Description : Founit les greffons offrant le service demandé. * * * * Retour : Liste de greffons correspondants à libérer de la mémoire. * * * * Remarques : - * * * ******************************************************************************/ GPluginModule **get_all_plugins_for_action(PluginAction action, size_t *count) { GPluginModule **result; /* Greffon à retourner */ size_t i; /* Boucle de parcours */ result = NULL; *count = 0; for (i = 0; i < _list.plugins_count; i++) if (g_plugin_module_get_action(_list.plugins[i]) & action) { result = (GPluginModule **)realloc(result, ++(*count) * sizeof(GPluginModule *)); result[*count - 1] = _list.plugins[i]; } return result; } /****************************************************************************** * * * Paramètres : plugin = greffon à ajouter aux autres disponibles. * * * * Description : Ajoute un greffon à la liste principale de greffons. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void add_plugin_to_main_list(GPluginModule *plugin) { plugins_list *list; /* Liste à modifier */ list = &_list; if (plugin->init != NULL && !plugin->init(plugin, list->ref)) { log_variadic_message(LMT_ERROR, _("Initialization of plugin '%s' failed !"), plugin->filename); g_object_unref(G_OBJECT(plugin)); return; } list->plugins = (GPluginModule **)realloc(list->plugins, ++list->plugins_count * sizeof(GPluginModule *)); list->plugins[list->plugins_count - 1] = plugin; } /****************************************************************************** * * * Paramètres : binary = binaire chargé en mémoire à traiter. * * action = fonctionnalité recherchée. * * lock = indique si l'exécution n'est pas celle principale. * * * * Description : Opère une action donnée sur un binaire défini. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void run_plugins_on_binary(GLoadedBinary *binary, PluginAction action, bool lock) { size_t i; /* Boucle de parcours */ if (lock) gdk_threads_enter(); for (i = 0; i < _list.plugins_count; i++) if (g_plugin_module_get_action(_list.plugins[i]) & action) g_plugin_module_execute_action_on_binary(_list.plugins[i], binary, action); if (lock) { gdk_flush(); gdk_threads_leave(); } }