/* 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 . */ #include "project.h" #include #include #include #include #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); }