/* OpenIDA - Outil d'analyse de fichiers binaires * shell.c - panneau d'affichage du shell Python * * Copyright (C) 2006-2007 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 "shell.h" #include #include #include #include #include #include #include #include #include static pid_t child = 0; #define _(str) str /* Réagit à la terminaison d'un shell Python lancé. */ static void terminal_child_exited_cb(VteReaper *, GPid, gint, VteTerminal *); /* Lance un nouveau shell Python dans un terminal donné. */ static void run_new_shell_in_terminal(VteTerminal *); /* Réagit aux premières lignes de l'interpréteur Python. */ void python_started_cb(VteTerminal *, gpointer); /* Exécute un shell interprétant du Python. */ static gpointer python_shell_thread(gpointer); int amaster; int aslave; char name[64]; /****************************************************************************** * * * Paramètres : ref = adresse de l'espace de référencements. * * * * Description : Construit le panneau d'affichage des symboles. * * * * Retour : Adresse du panneau mis en place. * * * * Remarques : - * * * ******************************************************************************/ GtkWidget *build_shell_panel(GObject *ref) { GtkWidget *result; /* Panneau à retourner */ GtkWidget *term; /* Terminal proprement dit */ GError *error; /* Bilan de création de thread */ term = vte_terminal_new(); result = gtk_scrolled_window_new(NULL, GTK_ADJUSTMENT(VTE_TERMINAL(term)->adjustment)); gtk_widget_show(result); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(result), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(result), GTK_SHADOW_IN); gtk_widget_show(term); gtk_container_add(GTK_CONTAINER(result), term); vte_terminal_set_cursor_blinks(VTE_TERMINAL(term), TRUE); //return result; openpty(&amaster, &aslave, name, NULL, NULL); fprintf(stderr, "m = %d, s = %d, n = \"%s\"\n", amaster, aslave, name); vte_terminal_set_pty(VTE_TERMINAL(term), amaster); if (!g_thread_create((GThreadFunc)python_shell_thread, term, FALSE, &error)) { printf ("Failed to create the thread: %s\n", error->message); } /* g_signal_connect(vte_reaper_get(), "child-exited", G_CALLBACK(terminal_child_exited_cb), term); run_new_shell_in_terminal(VTE_TERMINAL(term)); */ return result; } /****************************************************************************** * * * Paramètres : reaper = surveillant des processus exécuté dans le terminal. * * pid = identifiant du processus terminé. * * status = informations sur la sortie de l'interpréteur. * * term = terminal affiché à l'écran. * * * * Description : Réagit à la terminaison d'un shell Python lancé. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void terminal_child_exited_cb(VteReaper *reaper, GPid pid, gint status, VteTerminal *term) { vte_terminal_feed(term, _("Exit detected ; lauching an new Python shell...\n\r"), -1); run_new_shell_in_terminal(term); } /****************************************************************************** * * * Paramètres : term = terminal affiché à l'écran. * * * * Description : Lance un nouveau shell Python dans un terminal donné. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void run_new_shell_in_terminal(VteTerminal *term) { gdouble refval; /* Attente active (bouh !) */ size_t len; /* Longueur de chaîne */ char *args[] = { "python", NULL }; #ifdef DEBUG char *env[] = { NULL, NULL }; #else char **env = NULL; #endif refval = gtk_adjustment_get_value(GTK_ADJUSTMENT(term->adjustment)); #ifdef DEBUG len = strlen("PYTHONPATH=") + strlen(PACKAGE_SOURCE_DIR) + strlen("/src/plugins/pyoida"); env[0] = (char *)calloc(len + 1, sizeof(char)); strcpy(env[0], "PYTHONPATH="); strcat(env[0], PACKAGE_SOURCE_DIR); strcat(env[0], "/src/plugins/pyoida"); #endif child = vte_terminal_fork_command(VTE_TERMINAL(term), args[0], args, env, NULL, 0, 0, 0); vte_reaper_add_child(child); printf("ref :: %g\n", refval); //while (refval == gtk_adjustment_get_value(GTK_ADJUSTMENT(term->adjustment))); g_signal_connect(term, "contents-changed", G_CALLBACK(python_started_cb), NULL); } /****************************************************************************** * * * Paramètres : term = terminal affiché à l'écran. * * data = adresse non utilisée ici. * * * * Description : Réagit aux premières lignes de l'interpréteur Python. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void python_started_cb(VteTerminal *term, gpointer data) { static int counter = 0; /* Saut du prologue */ if (counter++ == 0) return; else counter = 0; vte_terminal_feed_child(term, "import pyoida\n", -1); vte_terminal_feed_child(term, "from pyoida import *\n", -1); g_signal_handlers_disconnect_by_func(term, G_CALLBACK(python_started_cb), NULL); } /****************************************************************************** * * * Paramètres : ????????????????????????????????????????????????? * * * * Description : Exécute un shell interprétant du Python. * * * * Retour : ??? * * * * Remarques : - * * * ******************************************************************************/ static gpointer python_shell_thread(gpointer data) { FILE *stream; printf("==== FE :: '%s'\n", ptsname(aslave)); //stream = fopen("/dev/pts/21", "w+"); stream = fdopen(aslave, "w+"); if (stream == NULL) { perror("fdopen"); return NULL; } /* Mise à jour des entrées/sorties */ /* close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); dup(aslave); dup(aslave); dup(aslave); */ Py_Initialize(); amaster = STDIN_FILENO; write(amaster, "import pyoida\n", strlen("import pyoida\n")); write(amaster, "from pyoida import *\n", strlen("from pyoida import *\n")); write(amaster, "logger.log_simple_message(2, 'uhih')\n", strlen("logger.log_simple_message(2, 'uhih')\n")); write(amaster, "for i in pyoida.current_binary().lines():\n", strlen("for i in pyoida.current_binary().lines():\n")); write(amaster, "\tprint i\n", strlen("\tprint i\n")); printf("+++++++++++++++++++++++++++looping\n"); PyRun_AnyFile(stream, NULL); printf("===========================looping\n"); Py_Finalize(); return NULL; }