diff options
Diffstat (limited to 'src/project.c')
-rw-r--r-- | src/project.c | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/src/project.c b/src/project.c new file mode 100644 index 0000000..2ec9e09 --- /dev/null +++ b/src/project.c @@ -0,0 +1,431 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * project.c - gestion d'un groupe de fichiers binaires + * + * Copyright (C) 2008 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 <http://www.gnu.org/licenses/>. + */ + + +#include "project.h" + + +#include <dirent.h> +#include <malloc.h> +#include <string.h> +#include <unistd.h> + + +#include "easygtk.h" +#include "xdg.h" +#include "xml.h" + + + + +/* Propriétés d'un ensemble de fichiers ouverts */ +struct openida_project +{ + char *filename; /* Lieu d'enregistrement */ + + openida_binary **binaries; /* Fichiers binaires associés */ + size_t binaries_count; /* Nombre de ces fichiers */ + + + +}; + + + + + + + + +/****************************************************************************** +* * +* Paramètres : project = éventuel adresse à renvoyer désormais. * +* * +* Description : Fournit l'adresse du projet courant. * +* * +* Retour : Adresse du projet ouvert ou NULL si aucun (!). * +* * +* Remarques : - * +* * +******************************************************************************/ + +openida_project *_get_current_openida_project(openida_project *project) +{ + static openida_project *result = NULL; /* Adresse à retourner */ + + if (project != NULL) + { + if (result != NULL) close_openida_project(result); + result = project; + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée un projet vide. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +openida_project *create_empty_openida_project(void) +{ + openida_project *result; /* Adresse à retourner */ + + result = (openida_project *)calloc(1, sizeof(openida_project)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : filename = chemin d'accès au fichier à charger. * +* * +* Description : Crée un projet à partir du contenu XML d'un fichier. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +openida_project *load_openida_project_from_xml(const char *filename) +{ + openida_project *result; /* Adresse à retourner */ + xmlDoc *xdoc; /* Structure XML chargée */ + xmlNode *xroot; /* Noeud premier de la def. */ + xmlXPathContextPtr xpathCtx; /* Contexte pour les XPath */ + xmlXPathObjectPtr xpathObj; /* Cible d'une recherche */ + unsigned int i; /* Boucle de parcours */ + openida_binary *binary; /* Représentation à intégrer */ + + if (!open_xml_file(filename, &xdoc, &xroot, &xpathCtx)) return NULL; + + result = (openida_project *)calloc(1, sizeof(openida_project)); + + + + xpathObj = get_node_xpath_object(xpathCtx, "/OpenIDAProject/Binaries/*"); + + printf("nodes :: %d\n", XPATH_OBJ_NODES_COUNT(xpathObj)); + + for (i = 0; i < XPATH_OBJ_NODES_COUNT(xpathObj); i++) + { + binary = read_openida_binary_from_xml(xpathCtx, "/OpenIDAProject/Binaries", i + 1); + + if (binary != NULL) + attach_binary_to_openida_project(result, binary); + + } + + if(xpathObj != NULL) + xmlXPathFreeObject(xpathObj); + + + + + + + + + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(xdoc); + xmlCleanupParser(); + + + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : project = project à effacer de la mémoire. * +* * +* Description : Ferme un projet et libère la mémoire associée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void close_openida_project(openida_project *project) +{ + + + + + free(project); + +} + + +/****************************************************************************** +* * +* Paramètres : project = project à consulter. * +* * +* Description : Indique si un projet a tous les éléments pour être sauvé. * +* * +* Retour : true si aucun nom de fichier n'a à être fourni. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool has_storing_filename(const openida_project *project) +{ + return (project->filename != NULL); + +} + + +/****************************************************************************** +* * +* Paramètres : project = project à sauvegarder. * +* filename = nom de fichier à utiliser ou NULL pour l'existant.* +* * +* Description : Procède à l'enregistrement d'un projet donné. * +* * +* Retour : true si l'enregistrement s'est déroule sans encombre. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_openida_project_to_xml(openida_project *project, const char *filename) +{ + bool result; /* Bilan à faire remonter */ + xmlTextWriterPtr writer; /* Rédacteur pour la sortie XML*/ + size_t i; /* Boucle de parcours */ + + writer = start_writing_xml_file(filename); + + result = open_xml_element(writer, "OpenIDAProject"); + + /* Enregistrement des éléments binaires attachés */ + + result &= open_xml_element(writer, "Binaries"); + + for (i = 0; i < project->binaries_count && result; i++) + write_openida_binary_to_xml(project->binaries[i], writer); + + result &= close_xml_element(writer); + + result &= close_xml_element(writer); + + result &= end_writing_xml_file(writer); + + if (result) + { + if (project->filename != NULL) free(project->filename); + project->filename = strdup(filename); + } + + return result; + +} + + + + + + + +/****************************************************************************** +* * +* Paramètres : project = project à effacer de la mémoire. * +* binary = fichier binaire à associer au projet actuel. * +* * +* Description : Attache un fichier donné à un projet donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void attach_binary_to_openida_project(openida_project *project, openida_binary *binary) +{ + project->binaries = (openida_binary **)realloc(project->binaries, + ++project->binaries_count * sizeof(openida_binary *)); + + + + + + project->binaries[project->binaries_count - 1] = binary; + + +} + + +/****************************************************************************** +* * +* Paramètres : project = project à effacer de la mémoire. * +* binary = fichier binaire à dissocier au projet actuel. * +* * +* Description : Détache un fichier donné à un projet donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void detach_binary_to_openida_project(openida_project *project, openida_binary *binary) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < project->binaries_count; i++) + if (project->binaries[i] == binary) break; + + if ((i + 1) < project->binaries_count) + memmove(&project->binaries[i], &project->binaries[i + 1], (project->binaries_count - i - 1) * sizeof(openida_binary *)); + + project->binaries = (openida_binary **)realloc(project->binaries, + --project->binaries_count * sizeof(openida_binary *)); + +} + + +/****************************************************************************** +* * +* Paramètres : project = project à effacer de la mémoire. * +* count = nombre de binaires pris en compte. [OUT] * +* * +* Description : Fournit l'ensemble des binaires associés à un projet. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +const openida_binary **get_openida_project_binaries(const openida_project *project, size_t *count) +{ + *count = project->binaries_count; + + return project->binaries; + +} + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* PARTIE GRAPHIQUE DES [DE]CHARGEMENTS */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : ref = espace global de référencement. * +* func = fonction à appeler lors d'un clic sur les menus. * +* * +* Description : Met en place les menus rechargeant les projets récents. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void load_recent_openida_projects_list(GObject *ref, GCallback *func) +{ + gboolean one_entry; /* Au moins en entrée chargée */ + GtkWidget *menuitem; /* Menu principal à compléter */ + GtkWidget *menubar; /* Support pour éléments */ + char *directory; /* Répertoire prévu pour proj. */ + DIR *dir; /* Répertoire avec contenu ? */ + struct dirent *entry; /* Elément de répertoire */ + char *filename; /* Nom de fichier à ouvrir */ + char realfile[PATH_MAX]; /* Nom du fichier pointé */ + ssize_t ret; /* Bilan de la lecture */ + GtkWidget *submenuitem; /* Sous-menu à ajouter */ + + one_entry = false; + + menuitem = GTK_WIDGET(g_object_get_data(ref, "menu_recent_prjs")); + menubar = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem)); + + directory = get_xdg_config_dir("openida/recents"); + + dir = opendir(directory); + /* TODO :: check */ + + if (dir != NULL) + { + for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) + { + if (strcmp(entry->d_name, ".") == 0) continue; + if (strcmp(entry->d_name, "..") == 0) continue; + + if (strlen(entry->d_name) <= 4) continue; + if (strcmp(&entry->d_name[strlen(entry->d_name) - 4], ".xml") != 0) continue; + + filename = (char *)calloc(strlen(directory) + 2 + strlen(entry->d_name) + 1, sizeof(char)); + strcpy(filename, directory); + strcat(filename, "/"); + strcat(filename, entry->d_name); + + ret = readlink(filename, realfile, PATH_MAX); + /* TODO :: check */ + + if (ret == -1) goto process_next_recent; + + submenuitem = qck_create_menu_item(NULL, NULL, realfile, func, ref); + gtk_container_add(GTK_CONTAINER(menubar), submenuitem); + + one_entry = true; + + process_next_recent: + + free(filename); + + } + + closedir(dir); + + } + + free(directory); + + recent_list_end: + + gtk_widget_set_sensitive(menuitem, one_entry); + +} |