1 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 : /*
3 : * heraia.c
4 : * heraia - an hexadecimal file editor and analyser based on ghex
5 : *
6 : * (C) Copyright 2005 - 2008 Olivier Delhomme
7 : * e-mail : heraia@delhomme.org
8 : * URL : http://heraia.tuxfamily.org
9 : *
10 : * This program is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * This program is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU General Public License
21 : * along with this program; if not, write to the Free Software
22 : * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 : */
24 :
25 : #include "heraia_types.h"
26 :
27 : static gboolean version(void);
28 : static gboolean usage(int status);
29 : static window_prop_t *init_window_properties(gint x, gint y, gboolean displayed);
30 : static heraia_window_t *init_window_property_struct(heraia_window_t *main_window);
31 : static heraia_window_t *heraia_init_main_struct(void);
32 : static HERAIA_ERROR init_heraia_plugin_system(heraia_window_t *main_window);
33 : static GList *init_heraia_location_list(void);
34 : static gboolean manage_command_line_options(Options *opt, int argc, char **argv);
35 :
36 : /**
37 : * prints program name, version, author, date and licence
38 : * to the standard output
39 : */
40 : static gboolean version(void)
41 : {
42 1 : fprintf (stdout, "heraia, %s - %s - Version %s - License %s\n", HERAIA_AUTHORS, HERAIA_DATE, HERAIA_VERSION, HERAIA_LICENSE);
43 1 : return TRUE;
44 : }
45 :
46 :
47 : /**
48 : * Function that informs the user aboit the command line options
49 : * available with heraia
50 : */
51 : static gboolean usage(int status)
52 0 : {
53 0 : if (status == 0)
54 : {
55 0 : fprintf (stderr,
56 : "Try `heraia --help' for more information.\n");
57 0 : return FALSE;
58 : }
59 : else
60 : {
61 : version();
62 0 : fprintf(stdout, "\nheraia is a simple hexadecimal file editor and file analyser");
63 0 : fprintf(stdout, "\nUsage :\n heraia [options] filename\n");
64 0 : fprintf(stdout, "\nOptions :\n\
65 : -h, --help\tThis help.\n\
66 : -v, --version\tProgram version information.\n");
67 0 : return TRUE;
68 : }
69 : }
70 :
71 :
72 : /**
73 : * Inits the properties of a window with defined values
74 : */
75 : static window_prop_t *init_window_properties(gint x, gint y, gboolean displayed)
76 : {
77 : window_prop_t *window_p;
78 :
79 : /* Malloc the window properties struct */
80 12 : window_p = (window_prop_t *) g_malloc0(sizeof(window_prop_t));
81 :
82 : /* Sets the default values */
83 12 : window_p->x = x;
84 12 : window_p->y = y;
85 12 : window_p->displayed = displayed;
86 :
87 12 : return window_p;
88 : }
89 :
90 :
91 : /**
92 : * Inits the window property structure
93 : */
94 : static heraia_window_t *init_window_property_struct(heraia_window_t *main_window)
95 2 : {
96 2 : all_window_prop_t *win_prop = NULL;
97 2 : window_prop_t *about_box = NULL;
98 2 : window_prop_t *data_interpretor = NULL;
99 2 : window_prop_t *log_box = NULL;
100 2 : window_prop_t *main_dialog = NULL;
101 2 : window_prop_t *plugin_list = NULL;
102 2 : window_prop_t *ldt = NULL;
103 :
104 : /* Global struct */
105 2 : win_prop = (all_window_prop_t *) g_malloc0(sizeof(all_window_prop_t));
106 :
107 : /* Initial states for the dialog boxes (default values) */
108 2 : about_box = init_window_properties(0, 0, FALSE);
109 2 : data_interpretor = init_window_properties(0, 0, H_DI_DISPLAYED);
110 2 : log_box = init_window_properties(0, 0, FALSE);
111 2 : main_dialog = init_window_properties(0, 0, TRUE);
112 2 : plugin_list = init_window_properties(0, 0, FALSE);
113 2 : ldt = init_window_properties(0, 0, FALSE);
114 :
115 : /* Attach to the struct */
116 2 : win_prop->about_box = about_box;
117 2 : win_prop->data_interpretor = data_interpretor;
118 2 : win_prop->log_box = log_box;
119 2 : win_prop->main_dialog = main_dialog;
120 2 : win_prop->plugin_list = plugin_list;
121 2 : win_prop->ldt = ldt;
122 :
123 : /* attach it to the main struct so that it can be read everywhere */
124 2 : main_window->win_prop = win_prop;
125 :
126 2 : return main_window;
127 : }
128 :
129 :
130 : /**
131 : * Initialize the main structure (main_window)
132 : */
133 : static heraia_window_t *heraia_init_main_struct(void)
134 2 : {
135 2 : heraia_window_t *herwin = NULL;
136 2 : xml_t *xmls = NULL;
137 :
138 2 : herwin = (heraia_window_t *) g_malloc0(sizeof(heraia_window_t));
139 :
140 2 : if (!herwin)
141 : {
142 0 : fprintf(stderr, "Main structure could not be initialiazed !");
143 0 : fprintf(stderr, "Do you have a memory problem ?\n");
144 0 : return NULL;
145 : }
146 :
147 : /**
148 : * First, in this early stage of the development we want to toggle debugging
149 : * mode ON which is enabled by default in the configure.ac file !
150 : */
151 2 : herwin->debug = ENABLE_DEBUG;
152 2 : herwin->filename = NULL;
153 :
154 2 : herwin->current_doc = NULL;
155 2 : herwin->plugins_list = NULL;
156 2 : herwin->location_list = init_heraia_location_list(); /* location list initilization */
157 2 : herwin->data_type_list = NULL;
158 2 : herwin->current_data_type = NULL;
159 2 : herwin->available_treatment_list = init_treatments(); /* treatment list initialization */
160 :
161 : /* xml_t structure initialisation */
162 2 : xmls = (xml_t *) g_malloc0(sizeof(xml_t));
163 2 : xmls->main = NULL;
164 2 : herwin->xmls = xmls;
165 :
166 : /* data interpretor structure initialization */
167 2 : herwin->current_DW = (data_window_t *) g_malloc0 (sizeof(data_window_t));
168 2 : herwin->current_DW->current_hexwidget = NULL;
169 2 : herwin->current_DW->diw = NULL;
170 : /* herwin->current_DW->window_displayed = FALSE; */
171 2 : herwin->current_DW->tab_displayed = 0; /* the first tab */
172 :
173 : /* init window property structure */
174 2 : herwin = init_window_property_struct(herwin);
175 :
176 2 : return herwin;
177 : }
178 :
179 : /**
180 : * Function that initializes the plugin system if any :
181 : * - loads any plugin where expected to be found
182 : * - inits the plugin window
183 : */
184 : static HERAIA_ERROR init_heraia_plugin_system(heraia_window_t *main_window)
185 : {
186 :
187 : /* Checking for plugins */
188 1 : if (plugin_capable() == TRUE)
189 : {
190 1 : log_message(main_window, G_LOG_LEVEL_INFO, "Enabling plugins");
191 1 : load_plugins(main_window);
192 :
193 : /* the plugin_list_window (here the plugins may be loaded !) */
194 1 : log_message(main_window, G_LOG_LEVEL_DEBUG, "Inits the plugin list window");
195 1 : plugin_list_window_init_interface(main_window);
196 :
197 1 : return HERAIA_NOERR;
198 : }
199 : else
200 : {
201 0 : log_message(main_window, G_LOG_LEVEL_WARNING, "Plugins will be disabled");
202 0 : return HERAIA_NO_PLUGINS;
203 : }
204 : }
205 :
206 : /**
207 : * Here we want to init the location list where we might look for
208 : * in the future. These can be viewed as default paths
209 : * Beware : prepended list in reverse order.
210 : */
211 : static GList *init_heraia_location_list(void)
212 2 : {
213 2 : gchar *path = NULL;
214 : const gchar* const *system_data_dirs;
215 2 : guint i = 0;
216 2 : GList *location_list = NULL;
217 :
218 : /* heraia's binary path */
219 2 : path = g_strdup_printf("%s", g_get_current_dir());
220 2 : location_list = g_list_prepend(location_list, path);
221 :
222 : /* System data dirs */
223 2 : system_data_dirs = g_get_system_data_dirs();
224 2 : i = 0;
225 10 : while(system_data_dirs[i] != NULL)
226 : {
227 6 : path = g_strdup_printf("%s%c%s", system_data_dirs[i], G_DIR_SEPARATOR, "heraia");
228 6 : location_list = g_list_prepend(location_list, path);
229 6 : i++;
230 : }
231 :
232 : /* System config dirs */
233 2 : system_data_dirs = g_get_system_config_dirs();
234 2 : i = 0;
235 6 : while(system_data_dirs[i] != NULL)
236 : {
237 2 : path = g_strdup_printf("%s%c%s", system_data_dirs[i], G_DIR_SEPARATOR, "heraia");
238 2 : location_list = g_list_prepend(location_list, path);
239 2 : i++;
240 : }
241 :
242 : /* the user path */
243 2 : path = g_strdup_printf("%s%c.%s", g_get_home_dir(), G_DIR_SEPARATOR, "heraia");
244 2 : location_list = g_list_prepend(location_list, path);
245 :
246 : /* A global user data path */
247 2 : path = g_strdup_printf("%s%c%s", g_get_user_data_dir(), G_DIR_SEPARATOR, "heraia");
248 2 : location_list = g_list_prepend(location_list, path);
249 :
250 : /* A global config data path */
251 2 : path = g_strdup_printf("%s%c%s", g_get_user_config_dir(), G_DIR_SEPARATOR, "heraia");
252 2 : location_list = g_list_prepend(location_list, path);
253 :
254 2 : return location_list;
255 : }
256 :
257 : /**
258 : * Manages all the command line options and populates the
259 : * Options *opt structure accordingly
260 : */
261 : static gboolean manage_command_line_options(Options *opt, int argc, char ** argv)
262 2 : {
263 2 : int exit_value = TRUE;
264 2 : int c = 0;
265 :
266 5 : while ((c = getopt_long (argc, argv, "vh", long_options, NULL)) != -1)
267 : {
268 1 : switch (c)
269 : {
270 : case 0: /* long options handler */
271 : break;
272 :
273 : case 'v':
274 1 : exit_value = version();
275 1 : opt->usage = TRUE; /* We do not want to continue after */
276 1 : break;
277 :
278 : case 'h':
279 0 : exit_value = usage(1);
280 0 : opt->usage = TRUE;
281 0 : break;
282 :
283 : default:
284 0 : exit_value = usage(0);
285 0 : opt->usage = TRUE;
286 : }
287 : }
288 :
289 2 : if (optind < argc) /* filename */
290 : {
291 1 : opt->filename = (char *) malloc (sizeof(char) * strlen(argv[optind]) + 1);
292 1 : strcpy(opt->filename, argv[optind]);
293 : }
294 : /**
295 : * We do not bother anymore if there is no file name to load
296 : * else
297 : * {
298 : * if (opt->usage != TRUE)
299 : * {
300 : * exit_value = usage(0);
301 : * opt->usage = TRUE;
302 : * }
303 : * }
304 : */
305 :
306 2 : return exit_value;
307 : }
308 :
309 :
310 : /**
311 : * main program
312 : * options :
313 : * --version
314 : * --help
315 : */
316 : int main (int argc, char ** argv)
317 2 : {
318 : Options *opt; /* A structure to manage the command line options */
319 2 : gboolean exit_value = TRUE;
320 2 : heraia_window_t *main_window = NULL;
321 :
322 2 : opt = (Options *) g_malloc0(sizeof(Options));
323 :
324 2 : opt->filename = NULL; /* At first we do not have any filename */
325 2 : opt->usage = FALSE;
326 :
327 2 : main_window = heraia_init_main_struct();
328 :
329 2 : if (main_window->debug == TRUE)
330 : {
331 2 : fprintf(stdout, "Main struct initialized !\n");
332 : }
333 :
334 : /* Command line options evaluation */
335 2 : exit_value = manage_command_line_options(opt, argc, argv);
336 :
337 2 : if (opt->usage != TRUE)
338 : {
339 1 : if (main_window->debug == TRUE)
340 : {
341 1 : fprintf(stderr, "Beginning things\n");
342 : }
343 :
344 : /* init of gtk and new window */
345 1 : exit_value = gtk_init_check(&argc, &argv);
346 :
347 1 : if (load_heraia_ui(main_window) == TRUE)
348 : {
349 :
350 1 : log_message(main_window, G_LOG_LEVEL_INFO, "Main interface loaded (%s)", main_window->xmls->main->filename);
351 :
352 : init_heraia_plugin_system(main_window);
353 :
354 1 : if (opt->filename != NULL)
355 : {
356 1 : load_file_to_analyse(main_window, opt->filename);
357 : }
358 :
359 :
360 1 : log_message(main_window, G_LOG_LEVEL_DEBUG, "Main_window : %p", main_window);
361 :
362 1 : init_heraia_interface(main_window);
363 :
364 : /* gtk main loop */
365 1 : gtk_main();
366 :
367 1 : exit_value = TRUE;
368 : }
369 : else
370 : {
371 0 : fprintf(stderr, "File heraia.glade not found !\n");
372 : }
373 : }
374 :
375 2 : return !exit_value; /* Apparently gtk TRUE and FALSE are inverted compared to bash ! */
376 : }
|