/* Chrysalide - Outil d'analyse de fichiers binaires * main.c - fichier d'entrée du programme * * Copyright (C) 2009-2017 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide 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. * * Chrysalide 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 #include #include #include #include #include #include "analysis/loading.h" #include "analysis/project.h" #include "analysis/contents/file.h" #include "analysis/db/server.h" #include "common/xdg.h" #include "core/core.h" #include "core/global.h" #include "core/params.h" #include "glibext/delayed.h" #include "gui/editor.h" #include "gui/core/core.h" #include "gui/core/global.h" #include "plugins/pglist.h" /* Affiche des indications quant à l'utilisation du programme. */ static void show_chrysalide_help(const char *); /* Affiche des indications sur la version courante du programme. */ static void show_chrysalide_version(void); /* Recharge le dernier projet ouvert s'il existe. */ static gboolean load_last_project(GGenConfig *); /* Ouvre les éventuels fichiers fournis au démarrage. */ static int open_binaries(char **, int); /****************************************************************************** * * * Paramètres : name = nom du programme en question. * * * * Description : Affiche des indications quant à l'utilisation du programme. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void show_chrysalide_help(const char *name) { char *base; /* Version courte du nom */ base = basename(name); printf("\n"); printf("Usage: %s [--help] [--version]\n", base); printf(" %s [--batch] \n", base); printf("\n"); printf("\t--help\t\tShow this help message.\n"); printf("\t--version\tDisplay the program version.\n"); printf("\n"); printf("\t--batch\t\tExit after processing files.\n"); printf("\n"); } /****************************************************************************** * * * Paramètres : - * * * * Description : Affiche des indications sur la version courante du programme.* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void show_chrysalide_version(void) { printf("\n"); printf("-o- Chrysalide r%u -o-\n", REVISION); printf(_("Last compiled on %s at %s\n"), __DATE__, __TIME__); printf("\n"); printf(_("Pictures directory: %s\n"), PIXMAPS_DIR); printf(_("Themes directory: %s\n"), THEMES_DIR); printf(_("Plugins directory: %s\n"), PLUGINS_DIR); printf(_("Locale directory: %s\n"), LOCALE_DIR); printf("\n"); } /****************************************************************************** * * * Paramètres : argc = nombre d'arguments dans la ligne de commande. * * argv = arguments de la ligne de commande. * * * * Description : Point d'entrée du programme. * * * * Retour : EXIT_SUCCESS si le prgm s'est déroulé sans encombres. * * * * Remarques : - * * * ******************************************************************************/ int main(int argc, char **argv) { int result; /* Bilan de l'exécution */ bool show_help; /* Affichage de l'aide ? */ bool show_version; /* Affichage de la version ? */ bool batch_mode; /* Exécution sans GUI ? */ int index; /* Indice d'argument */ int ret; /* Bilan d'un appel */ GtkWidget *editor; /* Fenêtre graphique */ GDbServer *server; /* Enregistrements locaux */ GGenConfig *config; /* Configuration globale */ bool status; /* Bilan d'opérations */ char *author; /* Identification à diffuser */ char *pub; /* Chemin de la clef publique */ bool welcome; /* Affichage de la bienvenue ? */ static struct option long_options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "batch", no_argument, NULL, 'b' }, { NULL, 0, NULL, 0 } }; result = EXIT_FAILURE; /** * Initialisation de la bibliothèque et validation des correspondances * d'ABI entre la version du moment de la compilation et celle présente * sur le système courant. */ LIBXML_TEST_VERSION; /* Décodage des options */ show_help = false; show_version = false; batch_mode = false; while (true) { ret = getopt_long(argc, argv, "hvb", long_options, &index); if (ret == -1) break; switch (ret) { case 'h': show_help = true; break; case 'v': show_version = true; break; case 'b': batch_mode = true; break; } } /* Actions de base */ if (show_help) { show_chrysalide_help(argv[0]); result = EXIT_SUCCESS; goto done; } if (show_version) { show_chrysalide_version(); result = EXIT_SUCCESS; goto done; } /* Lancement des choses sérieuses */ setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALE_DIR); textdomain(PACKAGE); /* Initialisation de GTK */ g_set_prgname("Chrysalide"); setlocale (LC_ALL, ""); gtk_init(&argc, &argv); /* Initialisation du programme */ if (!load_all_basic_components()) return EXIT_FAILURE; /* Création de l'interface */ editor = create_editor(); if (editor == NULL) goto failed_to_load_editor; if (!batch_mode) gtk_widget_show_now(editor); init_all_plugins(true); config = get_main_configuration(); status = complete_loading_of_all_gui_components(config); if (!status) goto exit_complete_gui; /* Utilisateur représenté */ if (!g_generic_config_get_value(config, MPK_AUTHOR_NAME, &author)) /*goto glbcl_exit*/; /* Chemin vers la clef privée */ pub = get_xdg_config_dir("chrysalide" G_DIR_SEPARATOR_S "id_rsa.pub"); server = g_db_server_new_internal(author, pub); g_db_server_start(server); /* Charge le dernier projet ? */ if (batch_mode) welcome = true; else g_generic_config_get_value(config, MPK_WELCOME_STARTUP, &welcome); if (!welcome) g_idle_add((GSourceFunc)load_last_project, config); else set_current_project(g_study_project_new()); /* Exécution du programme */ result = open_binaries(argv + optind, argc - optind); if (batch_mode) g_work_queue_wait_for_completion(get_work_queue(), DEFAULT_WORK_GROUP); else gtk_main(); g_db_server_stop(server); exit_complete_gui: exit_all_plugins(); if (!batch_mode) /* FIXME */ gtk_widget_destroy(editor); failed_to_load_editor: unload_all_basic_components(); done: return result; } /****************************************************************************** * * * Paramètres : cfg = configuration globale sur laquelle s'appuyer. * * ref = espace de référencement global. * * * * Description : Recharge le dernier projet ouvert s'il existe. * * * * Retour : G_SOURCE_REMOVE pour ne pas répéter l'action. * * * * Remarques : - * * * ******************************************************************************/ static gboolean load_last_project(GGenConfig *cfg) { const char *filename; /* Chemin du dernier projet */ GStudyProject *project; /* Nouveau projet courant */ if (!g_generic_config_get_value(cfg, MPK_LAST_PROJECT, &filename)) filename = NULL; if (filename == NULL) project = g_study_project_new(); else project = g_study_project_open(filename); set_current_project(project); return G_SOURCE_REMOVE; } /****************************************************************************** * * * Paramètres : files = noms de fichier fournis en ligne de commande. * * count = nombre d'arguments restant à traiter. * * * * Description : Ouvre les éventuels fichiers fournis au démarrage. * * * * Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ static int open_binaries(char **files, int count) { int result; /* Bilan à retourner */ int i; /* Boucle de parcours */ GBinContent *content; /* Contenu binaire à charger */ result = EXIT_SUCCESS; for (i = 0; i < count && result == EXIT_SUCCESS; i++) { content = g_file_content_new(files[i]); if (content != NULL) { qck_study_new_content(content, PCS_ROOT); g_object_unref(G_OBJECT(content)); } else result = EXIT_FAILURE; } return result; }