heraia.c

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /*
00003  *  heraia.c
00004  *  heraia - an hexadecimal file editor and analyser based on ghex
00005  *
00006  *  (C) Copyright 2005 - 2009 Olivier Delhomme
00007  *  e-mail : heraia@delhomme.org
00008  *  URL    : http://heraia.tuxfamily.org
00009  *
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2, or  (at your option)
00013  *  any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY;  without even the implied warranty of
00017  *  MERCHANTABILITY  or  FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023  */
00024 /** @file heraia.c
00025  * This is the main program file.
00026  * Initialization is done here and then hand is passed to gtk's main thread
00027  */
00028 /**
00029  * @author Olivier DELHOMME,
00030  *         Sébastien TRICAUD,
00031  *         Grégory AUDET
00032  * @version 0.0.9
00033  * @date 2005-2009
00034  */
00035 
00036 #include "heraia_types.h"
00037 
00038 static gboolean version(void);
00039 static gboolean usage(int status);
00040 static window_prop_t *init_window_properties(gint x, gint y, guint height, guint width, gboolean displayed);
00041 static heraia_window_t *init_window_property_struct(heraia_window_t *main_window);
00042 static heraia_window_t *heraia_init_main_struct(void);
00043 static HERAIA_ERROR init_heraia_plugin_system(heraia_window_t *main_window);
00044 static GList *init_heraia_location_list(void);
00045 static gboolean manage_command_line_options(Options *opt, int argc, char **argv);
00046 
00047 /**
00048  *  libheraia_main_struct is a global variable that points
00049  *  to the main structure and is intended for the library use ONLY !
00050  *  It should not be used anywhere else or for any other purpose
00051  */
00052 static heraia_window_t *libheraia_main_struct = NULL;
00053 
00054 
00055 /**
00056  *  This is intended to be called by the library or any program that will use
00057  *  the library in order to get the pointer to the main structure heraia_window_t.
00058  *  @return heraia_window_t *, a pointer to the main structure
00059  */
00060 heraia_window_t *get_main_struct(void)
00061 {
00062         return libheraia_main_struct;
00063 }
00064 
00065 /**
00066  *  prints program name, version, author, date and licence
00067  *  to the standard output
00068  */
00069 static gboolean version(void)
00070 {
00071         fprintf (stdout, "heraia, %s - %s - Version %s - License %s\n", HERAIA_AUTHORS, HERAIA_DATE, HERAIA_VERSION, HERAIA_LICENSE);
00072         return TRUE;
00073 }
00074 
00075 
00076 /**
00077  *  Function that informs the user about the command line options
00078  *  available with heraia
00079  *  @param status : integer that indicate wether to display help (!=0) or
00080  *                      an error message (0)
00081  *  @return
00082  *          - TRUE -> help message has been printed
00083  *          - FALSE -> error message has been printed
00084  */
00085 static gboolean usage(int status)
00086 {
00087         if (status == 0)
00088                 {
00089                         fprintf (stderr,
00090                                          "Try `heraia --help' for more information.\n");
00091                         return FALSE;
00092                 }
00093         else
00094                 {
00095                         version();
00096                         fprintf(stdout, "\nheraia is a simple hexadecimal file editor and file analyser");
00097                         fprintf(stdout, "\nUsage :\n  heraia [options] filename\n");
00098                         fprintf(stdout, "\nOptions :\n\
00099   -h, --help\tThis help.\n\
00100   -v, --version\tProgram version information.\n");
00101                         return TRUE;
00102                 }
00103 }
00104 
00105 
00106 /**
00107  *  Inits the properties of a window with defined values
00108  *  @param  x,y are x,y coordinates on the screen
00109  *  @param  height represents the height of the window
00110  *  @param  width represents the width of the window. x+height,y+width is
00111  *          window's right bottom corner
00112  *  @param  displayed says wether the window is displayed or not
00113  *  @return a new allocated window_prop_t * structure.
00114  */
00115 static window_prop_t *init_window_properties(gint x, gint y, guint height, guint width, gboolean displayed)
00116 {
00117         window_prop_t *window_p;
00118 
00119         /* Malloc the window properties struct */
00120         window_p = (window_prop_t *) g_malloc0(sizeof(window_prop_t));
00121 
00122         /* Sets the default values */
00123         window_p->x = x;
00124         window_p->y = y;
00125         window_p->height = height;
00126         window_p->width = width;
00127         window_p->displayed = displayed;
00128 
00129         return window_p;
00130 }
00131 
00132 
00133 /**
00134  *  Inits the window property structure
00135  *  @param main_window : main structure
00136  *  @return main structure with an initiated window property structure
00137  */
00138 static heraia_window_t *init_window_property_struct(heraia_window_t *main_window)
00139 {
00140         all_window_prop_t *win_prop = NULL;
00141         window_prop_t *about_box = NULL;
00142         window_prop_t *data_interpretor = NULL;
00143         window_prop_t *log_box = NULL;
00144         window_prop_t *main_dialog = NULL;
00145         window_prop_t *plugin_list = NULL;
00146         window_prop_t *ldt = NULL;
00147         window_prop_t *main_pref_window = NULL;
00148 
00149         /* Global struct */
00150         win_prop = (all_window_prop_t *) g_malloc0(sizeof(all_window_prop_t));
00151 
00152         /* Initial states for the dialog boxes (default values) */
00153         about_box = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, FALSE);
00154         data_interpretor = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, H_DI_DISPLAYED);
00155         log_box = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, FALSE);
00156     main_dialog = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, TRUE);
00157         plugin_list = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, FALSE);
00158         ldt = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, FALSE);
00159         main_pref_window = init_window_properties(0, 0, WPT_DEFAULT_HEIGHT, WPT_DEFAULT_WIDTH, FALSE);
00160 
00161         /* Attach to the struct */
00162         win_prop->about_box = about_box;
00163         win_prop->data_interpretor = data_interpretor;
00164         win_prop->log_box = log_box;
00165         win_prop->main_dialog = main_dialog;
00166         win_prop->plugin_list = plugin_list;
00167         win_prop->ldt = ldt;
00168         win_prop->main_pref_window = main_pref_window;
00169 
00170         /* attach it to the main struct so that it can be read everywhere */
00171         main_window->win_prop = win_prop;
00172 
00173         return main_window;
00174 }
00175 
00176 
00177 /**
00178  * Initialize the main structure (main_window)
00179  * @return a pointer to a newly initialized main structure
00180  */
00181 static heraia_window_t *heraia_init_main_struct(void)
00182 {
00183         heraia_window_t *herwin = NULL;
00184         xml_t *xmls = NULL;
00185 
00186         herwin = (heraia_window_t *) g_malloc0(sizeof(heraia_window_t));
00187 
00188         if (!herwin)
00189                 {
00190                         fprintf(stderr, "Main structure could not be initialiazed !");
00191                         fprintf(stderr, "Do you have a memory problem ?\n");
00192                         return NULL;
00193                 }
00194 
00195         /* preference file name initialisation */
00196         herwin->prefs = NULL;
00197         init_preference_struct(herwin);
00198         verify_preference_file(herwin->prefs->pathname, herwin->prefs->filename);
00199 
00200         /**
00201          * First, in this early stage of the development we want to toggle debugging
00202          *  mode ON which is enabled by default in the configure.ac file !
00203          */
00204         herwin->debug = ENABLE_DEBUG;
00205         /* herwin->filename = NULL; */
00206 
00207         herwin->current_doc = NULL;
00208         herwin->plugins_list = NULL;
00209         herwin->location_list = init_heraia_location_list(); /* location list initilization */
00210         herwin->data_type_list = NULL;
00211         herwin->current_data_type = NULL;
00212         herwin->available_treatment_list = init_treatments(); /* treatment list initialization */
00213 
00214 
00215         /* xml_t structure initialisation */
00216         xmls = (xml_t *) g_malloc0(sizeof(xml_t));
00217         xmls->main = NULL;
00218         herwin->xmls = xmls;
00219 
00220         /* data interpretor structure initialization */
00221         herwin->current_DW = (data_window_t *) g_malloc0 (sizeof(data_window_t));
00222         herwin->current_DW->current_hexwidget = NULL;
00223         herwin->current_DW->diw = NULL;
00224         /* herwin->current_DW->window_displayed = FALSE; */
00225         herwin->current_DW->tab_displayed = 0;  /* the first tab */
00226 
00227         /* init window property structure */
00228         herwin = init_window_property_struct(herwin);
00229 
00230         /* documents */
00231         herwin->documents = g_ptr_array_new();
00232 
00233         /* init global variable for the library */
00234         libheraia_main_struct = herwin;
00235 
00236         return herwin;
00237 }
00238 
00239 
00240 
00241 /**
00242  *  Function that initializes the plugin system if any :
00243  *   - loads any plugin where expected to be found
00244  *   - inits the plugin window
00245  * @param main_window : main structure (heraia_window_t *)
00246  * @return HERAIA_NO_PLUGINS if no plugins where found or HERAIA_NOERR in
00247  *         case of no errors
00248  */
00249 static HERAIA_ERROR init_heraia_plugin_system(heraia_window_t *main_window)
00250 {
00251 
00252         /* Checking for plugins */
00253         if (plugin_capable() == TRUE)
00254                 {
00255                         log_message(main_window, G_LOG_LEVEL_INFO, "Enabling plugins");
00256                         load_plugins(main_window);
00257 
00258                         /* the plugin_list_window (here the plugins may be loaded !) */
00259                         log_message(main_window, G_LOG_LEVEL_DEBUG, "Inits the plugin list window");
00260                         plugin_list_window_init_interface(main_window);
00261 
00262                         return HERAIA_NOERR;
00263                 }
00264         else
00265                 {
00266                         log_message(main_window, G_LOG_LEVEL_WARNING, "Plugins will be disabled");
00267                         return HERAIA_NO_PLUGINS;
00268                 }
00269 }
00270 
00271 /**
00272  *  Here we want to init the location list where we might look for
00273  *  in the future. These can be viewed as default paths
00274  *  @warning when adding new locations, keep in ming that the list is a
00275              prepended list in reverse order.
00276  *  @return a new allocatde GList containing all locations
00277  */
00278 static GList *init_heraia_location_list(void)
00279 {
00280         gchar *path = NULL;
00281         const gchar* const *system_data_dirs;
00282         guint i = 0;
00283         GList *location_list = NULL;
00284 
00285         /* heraia's binary path */
00286         path = g_strdup_printf("%s", g_get_current_dir());
00287         location_list = g_list_prepend(location_list, path);
00288 
00289         /* System data dirs */
00290         system_data_dirs = g_get_system_data_dirs();
00291         i = 0;
00292         while(system_data_dirs[i] != NULL)
00293                 {
00294                         path = g_strdup_printf("%s%c%s", system_data_dirs[i], G_DIR_SEPARATOR, "heraia");
00295                         location_list = g_list_prepend(location_list, path);
00296                         i++;
00297                 }
00298 
00299         /* System config dirs */
00300         system_data_dirs = g_get_system_config_dirs();
00301         i = 0;
00302         while(system_data_dirs[i] != NULL)
00303                 {
00304                         path = g_strdup_printf("%s%c%s", system_data_dirs[i], G_DIR_SEPARATOR, "heraia");
00305                         location_list = g_list_prepend(location_list, path);
00306                         i++;
00307                 }
00308 
00309         /* the user path */
00310         path =  g_strdup_printf("%s%c.%s", g_get_home_dir(), G_DIR_SEPARATOR, "heraia");
00311         location_list = g_list_prepend(location_list, path);
00312 
00313         /* A global user data path */
00314         path = g_strdup_printf("%s%c%s", g_get_user_data_dir(), G_DIR_SEPARATOR, "heraia");
00315         location_list = g_list_prepend(location_list, path);
00316 
00317         /* A global config data path */
00318         path = g_strdup_printf("%s%c%s", g_get_user_config_dir(), G_DIR_SEPARATOR, "heraia");
00319         location_list = g_list_prepend(location_list, path);
00320 
00321         return location_list;
00322 }
00323 
00324 /**
00325  *  Manages all the command line options and populates the
00326  *  Options *opt structure accordingly
00327  *  @param opt (Options *opt) filled here with the parameters found in **argv
00328  *  @param argc : number of command line arguments
00329  *  @param argv : array of string (char *) that contains arguments
00330  *  @return gboolean that seems to always be TRUE
00331  */
00332 static gboolean manage_command_line_options(Options *opt, int argc, char **argv)
00333 {
00334         int exit_value = TRUE;
00335         int c = 0;
00336         gchar *filename = NULL;
00337 
00338         while ((c = getopt_long (argc, argv, "vh", long_options, NULL)) != -1)
00339                 {
00340                         switch (c)
00341                                 {
00342                                 case 0:                 /* long options handler */
00343                                         break;
00344 
00345                                 case 'v':
00346                                         exit_value = version();
00347                                         opt->usage = TRUE;  /* We do not want to continue after */
00348                                         break;
00349 
00350                                 case 'h':
00351                                         exit_value = usage(1);
00352                                         opt->usage = TRUE;
00353                                         break;
00354 
00355                                 default:
00356                                         exit_value = usage(0);
00357                                         opt->usage = TRUE;
00358                                 }
00359                 }
00360 
00361         while (optind < argc) /** @todo manage a list of filenames instead of one filename */
00362                 {
00363                         filename = (char *) malloc (sizeof(char) * strlen(argv[optind]) + 1);
00364                         strcpy(filename, argv[optind]);
00365                         opt->filenames = g_list_prepend(opt->filenames, filename);
00366                         optind++;
00367                 }
00368 
00369         return exit_value;
00370 }
00371 
00372 /**
00373  * Inits the Options struct that contains all
00374  * stuff needed to managed command line options
00375  * within heraia
00376  * @return returns a newly allocated Options structure
00377  *         initialized to default values
00378  */
00379 static Options *init_options_struct(void)
00380 {
00381         Options *opt = NULL;
00382 
00383         opt = (Options *) g_malloc0(sizeof(Options));
00384 
00385         opt->filenames = NULL;  /* At first we do not have any filename */
00386         opt->usage = FALSE;
00387 
00388         return opt;
00389 }
00390 
00391 /**
00392  *  main program
00393  *  options :
00394  *   - --version
00395  *   - --help
00396  */
00397 int main (int argc, char ** argv)
00398 {
00399         Options *opt; /* A structure to manage the command line options  */
00400         gboolean exit_value = TRUE;
00401         heraia_window_t *main_window = NULL;
00402         GList *list = NULL;
00403 
00404         opt = init_options_struct();
00405 
00406         main_window = heraia_init_main_struct();
00407 
00408         libheraia_initialize();
00409 
00410         if (main_window->debug == TRUE)
00411                 {
00412                         fprintf(stdout, "Main struct initialized !\n");
00413                 }
00414 
00415         /* Command line options evaluation */
00416         exit_value = manage_command_line_options(opt, argc, argv);
00417 
00418         if (opt->usage != TRUE)
00419                 {
00420                         if (main_window->debug == TRUE)
00421                                 {
00422                                         fprintf(stderr, "Beginning things\n");
00423                                         libheraia_test(); /* testing libheraia */
00424                                 }
00425 
00426                         /* init of gtk and new window */
00427                         exit_value = gtk_init_check(&argc, &argv);
00428 
00429                         if (load_heraia_ui(main_window) == TRUE)
00430                                 {
00431 
00432                                         log_message(main_window, G_LOG_LEVEL_INFO, "Main interface loaded (%s)", main_window->xmls->main->filename);
00433                     log_message(main_window, G_LOG_LEVEL_DEBUG, "Preference file is %s", main_window->prefs->filename);
00434                                         log_message(main_window, G_LOG_LEVEL_DEBUG, "data interpretor's tab is %d", main_window->current_DW->tab_displayed);
00435 
00436                                         init_heraia_plugin_system(main_window);
00437 
00438                                         if (opt->filenames != NULL)
00439                                                 {
00440                                                         list = g_list_first(opt->filenames);
00441                                                         while (list != NULL)
00442                                                         {
00443                                                                 load_file_to_analyse(main_window, list->data);
00444                                                                 list = g_list_next(list);
00445                                                         }
00446                                                 }
00447 
00448                                         log_message(main_window, G_LOG_LEVEL_DEBUG, "Main_window : %p", main_window);
00449 
00450                                         init_heraia_interface(main_window);
00451 
00452                                         /* gtk main loop */
00453                                         gtk_main();
00454 
00455                                         exit_value = TRUE;
00456                                 }
00457                         else
00458                                 {
00459                                         fprintf(stderr, "File heraia.glade not found !\n");
00460                                 }
00461                 }
00462 
00463         libheraia_finalize();
00464 
00465         return !exit_value; /* Apparently gtk TRUE and FALSE are inverted compared to bash ! */
00466 }

Generated on Tue May 19 20:01:37 2009 for Heraia by  doxygen 1.5.8