Some work on multi file dissection
[metze/wireshark/wip.git] / ui / gtk / main.c
1 /* main.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10  *                              needed by dissect routines
11  * Jeff Foster,    2001/03/12,  added support tabbed hex display windowss
12  *
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27  */
28
29 #include "config.h"
30
31 #include <gtk/gtk.h>
32 #include <gdk/gdkkeysyms.h>
33 #if GTK_CHECK_VERSION(3,0,0)
34 # include <gdk/gdkkeysyms-compat.h>
35 #endif
36
37 #include <stdio.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <locale.h>
41
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45
46 #ifndef HAVE_GETOPT
47 #include "wsutil/wsgetopt.h"
48 #endif
49
50 #ifdef _WIN32 /* Needed for console I/O */
51 #if _MSC_VER < 1500
52 /* AttachConsole() needs this #define! */
53 /* But we're not calling it from here any more; do we need this? */
54 #define _WIN32_WINNT 0x0501
55 #endif
56
57 #include <fcntl.h>
58 #include <conio.h>
59 #include <ui/win32/console_win32.h>
60 #endif
61
62 #ifdef HAVE_LIBPORTAUDIO
63 #include <portaudio.h>
64 #endif /* HAVE_LIBPORTAUDIO */
65
66 #include <wsutil/crash_info.h>
67 #include <wsutil/u3.h>
68 #include <wsutil/privileges.h>
69 #include <wsutil/file_util.h>
70
71 #include <wiretap/merge.h>
72
73 #include <epan/epan.h>
74 #include <epan/filesystem.h>
75 #include <epan/epan_dissect.h>
76 #include <epan/timestamp.h>
77 #include <epan/plugins.h>
78 #include <epan/dfilter/dfilter.h>
79 #include <epan/strutil.h>
80 #include <epan/addr_resolv.h>
81 #include <epan/emem.h>
82 #include <epan/ex-opt.h>
83 #include <epan/funnel.h>
84 #include <epan/expert.h>
85 #include <epan/frequency-utils.h>
86 #include <epan/prefs.h>
87 #include <epan/prefs-int.h>
88 #include <epan/tap.h>
89 #include <epan/stat_cmd_args.h>
90 #include <epan/uat.h>
91 #include <epan/column.h>
92 #include <epan/disabled_protos.h>
93 #include <epan/print.h>
94
95 /* general (not GTK specific) */
96 #include "../file.h"
97 #include "../frame_tvbuff.h"
98 #include "../summary.h"
99 #include "../filters.h"
100 #include "../color.h"
101 #include "../color_filters.h"
102 #include "../register.h"
103 #include "../ringbuffer.h"
104 #include "ui/util.h"
105 #include "../clopts_common.h"
106 #include "../cmdarg_err.h"
107 #include "../version_info.h"
108 #include "../log.h"
109
110 #include "gtk_iface_monitor.h"
111
112 #include "ui/alert_box.h"
113 #include "ui/main_statusbar.h"
114 #include "ui/preference_utils.h"
115 #include "ui/recent.h"
116 #include "ui/recent_utils.h"
117 #include "ui/software_update.h"
118 #include "ui/simple_dialog.h"
119 #include "ui/ui_util.h"
120
121 #ifdef HAVE_LIBPCAP
122 #include "ui/capture_globals.h"
123 #include "ui/iface_lists.h"
124 #endif
125
126 #ifdef HAVE_LIBPCAP
127 #include "capture_ui_utils.h"
128 #include "capture-pcap-util.h"
129 #include "capture_ifinfo.h"
130 #include "capture.h"
131 #include "capture_sync.h"
132 #endif
133
134 #ifdef _WIN32
135 #include "capture-wpcap.h"
136 #include "capture_wpcap_packet.h"
137 #include <tchar.h> /* Needed for Unicode */
138 #include <wsutil/unicode-utils.h>
139 #include <commctrl.h>
140 #include <shellapi.h>
141 #endif /* _WIN32 */
142
143 /* GTK related */
144 #include "ui/gtk/file_dlg.h"
145 #include "ui/gtk/gtkglobals.h"
146 #include "ui/gtk/color_utils.h"
147 #include "ui/gtk/gui_utils.h"
148 #include "ui/gtk/color_dlg.h"
149 #include "ui/gtk/filter_dlg.h"
150 #include "ui/gtk/fileset_dlg.h"
151 #include "ui/gtk/uat_gui.h"
152 #include "ui/gtk/main.h"
153 #include "ui/gtk/main_80211_toolbar.h"
154 #include "ui/gtk/main_airpcap_toolbar.h"
155 #include "ui/gtk/main_filter_toolbar.h"
156 #include "ui/gtk/main_titlebar.h"
157 #include "ui/gtk/menus.h"
158 #include "ui/gtk/main_menubar_private.h"
159 #include "ui/gtk/macros_dlg.h"
160 #include "ui/gtk/main_statusbar_private.h"
161 #include "ui/gtk/main_toolbar.h"
162 #include "ui/gtk/main_toolbar_private.h"
163 #include "ui/gtk/main_welcome.h"
164 #include "ui/gtk/drag_and_drop.h"
165 #include "ui/gtk/capture_file_dlg.h"
166 #include "ui/gtk/packet_panes.h"
167 #include "ui/gtk/keys.h"
168 #include "ui/gtk/packet_win.h"
169 #include "ui/gtk/stock_icons.h"
170 #include "ui/gtk/find_dlg.h"
171 #include "ui/gtk/follow_tcp.h"
172 #include "ui/gtk/font_utils.h"
173 #include "ui/gtk/about_dlg.h"
174 #include "ui/gtk/help_dlg.h"
175 #include "ui/gtk/decode_as_dlg.h"
176 #include "ui/gtk/webbrowser.h"
177 #include "ui/gtk/capture_dlg.h"
178 #include "ui/gtk/capture_if_dlg.h"
179 #include "ui/gtk/tap_param_dlg.h"
180 #include "ui/gtk/prefs_column.h"
181 #include "ui/gtk/prefs_dlg.h"
182 #include "ui/gtk/proto_help.h"
183 #include "ui/gtk/packet_list.h"
184 #include "ui/gtk/filter_expression_save_dlg.h"
185
186 #include "ui/gtk/old-gtk-compat.h"
187
188 #ifdef HAVE_LIBPCAP
189 #include "wsicon.h"
190 #include "wsiconcap.h"
191 #endif
192
193 #ifdef HAVE_AIRPCAP
194 #include <airpcap.h>
195 #include "airpcap_loader.h"
196 #include "airpcap_dlg.h"
197 #include "airpcap_gui_utils.h"
198 #endif
199
200 #include <epan/crypt/airpdcap_ws.h>
201
202
203 #ifdef HAVE_GTKOSXAPPLICATION
204 #include <gtkmacintegration/gtkosxapplication.h>
205 #endif
206
207 /*
208  * Files under personal and global preferences directories in which
209  * GTK settings for Wireshark are stored.
210  */
211 #define RC_FILE "gtkrc"
212
213 #ifdef HAVE_LIBPCAP
214 capture_options global_capture_opts;
215 capture_session global_capture_session;
216 #endif
217
218 capture_file cfile;
219
220 static gboolean capture_stopping;
221
222 /* "exported" main widgets */
223 GtkWidget   *top_level = NULL, *pkt_scrollw, *tree_view_gbl, *byte_nb_ptr_gbl;
224
225 /* placement widgets (can be a bit confusing, because of the many layout possibilities */
226 static GtkWidget   *main_vbox, *main_pane_v1, *main_pane_v2, *main_pane_h1, *main_pane_h2;
227 static GtkWidget   *main_first_pane, *main_second_pane;
228
229 /* internally used widgets */
230 static GtkWidget   *menubar, *main_tb, *filter_tb, *tv_scrollw, *statusbar, *welcome_pane;
231
232 GtkWidget *wireless_tb;
233 #ifdef HAVE_AIRPCAP
234 int    airpcap_dll_ret_val = -1;
235 #endif
236
237 GString *comp_info_str, *runtime_info_str;
238
239 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
240
241 static guint  tap_update_timer_id;
242
243 static void console_log_handler(const char *log_domain,
244     GLogLevelFlags log_level, const char *message, gpointer user_data);
245
246 static void create_main_window(gint, gint, gint, e_prefs*);
247 static void show_main_window(gboolean);
248 static void main_save_window_geometry(GtkWidget *widget);
249
250
251 /* Match selected byte pattern */
252 static void
253 match_selected_cb_do(GtkWidget *filter_te, int action, gchar *text)
254 {
255     char       *cur_filter, *new_filter;
256
257     if ((!text) || (0 == strlen(text))) {
258         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to build a filter!\nTry expanding or choosing another item.");
259         return;
260     }
261
262     g_assert(filter_te);
263
264     cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
265
266     switch (action&MATCH_SELECTED_MASK) {
267
268     case MATCH_SELECTED_REPLACE:
269         new_filter = g_strdup(text);
270         break;
271
272     case MATCH_SELECTED_AND:
273         if ((!cur_filter) || (0 == strlen(cur_filter)))
274             new_filter = g_strdup(text);
275         else
276             new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
277         break;
278
279     case MATCH_SELECTED_OR:
280         if ((!cur_filter) || (0 == strlen(cur_filter)))
281             new_filter = g_strdup(text);
282         else
283             new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
284         break;
285
286     case MATCH_SELECTED_NOT:
287         new_filter = g_strconcat("!(", text, ")", NULL);
288         break;
289
290     case MATCH_SELECTED_AND_NOT:
291         if ((!cur_filter) || (0 == strlen(cur_filter)))
292             new_filter = g_strconcat("!(", text, ")", NULL);
293         else
294             new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
295         break;
296
297     case MATCH_SELECTED_OR_NOT:
298         if ((!cur_filter) || (0 == strlen(cur_filter)))
299             new_filter = g_strconcat("!(", text, ")", NULL);
300         else
301             new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
302         break;
303
304     default:
305         g_assert_not_reached();
306         new_filter = NULL;
307         break;
308     }
309
310     /* Free up the copy we got of the old filter text. */
311     g_free(cur_filter);
312
313     /* Don't change the current display filter if we only want to copy the filter */
314     if (action&MATCH_SELECTED_COPY_ONLY) {
315         GString *gtk_text_str = g_string_new("");
316         g_string_append(gtk_text_str, new_filter);
317         copy_to_clipboard(gtk_text_str);
318         g_string_free(gtk_text_str, TRUE);
319     } else {
320         /* create a new one and set the display filter entry accordingly */
321         gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
322
323         /* Run the display filter so it goes in effect. */
324         if (action&MATCH_SELECTED_APPLY_NOW)
325             main_filter_packets(&cfile, new_filter, FALSE);
326     }
327
328     /* Free up the new filter text. */
329     g_free(new_filter);
330 }
331
332 void
333 match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
334 {
335     char *filter = NULL;
336
337     if (cfile.finfo_selected) {
338         filter = proto_construct_match_selected_string(cfile.finfo_selected,
339                                                        cfile.edt);
340         match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
341     }
342 }
343
344 void
345 colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
346 {
347     char *filter = NULL;
348
349     if (cfile.finfo_selected) {
350         filter = proto_construct_match_selected_string(cfile.finfo_selected,
351                                                        cfile.edt);
352         if ((!filter) || (0 == strlen(filter))) {
353             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
354                 "Could not acquire information to build a filter!\n"
355                 "Try expanding or choosing another item.");
356             return;
357         }
358
359         if (filt_nr==0) {
360             color_display_with_filter(filter);
361         } else {
362             if (filt_nr==255) {
363                 color_filters_reset_tmp();
364             } else {
365                 color_filters_set_tmp(filt_nr,filter, FALSE);
366             }
367             packet_list_colorize_packets();
368         }
369     }
370 }
371
372
373 static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
374 {
375     gchar *selected_proto_url;
376     gchar *proto_abbrev = (gchar *)data;
377
378
379     switch(btn) {
380     case(ESD_BTN_OK):
381         if (cfile.finfo_selected) {
382             /* open wiki page using the protocol abbreviation */
383             selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
384             browser_open_url(selected_proto_url);
385             g_free(selected_proto_url);
386         }
387         break;
388     case(ESD_BTN_CANCEL):
389         break;
390     default:
391         g_assert_not_reached();
392     }
393 }
394
395
396 void
397 selected_ptree_info_cb(GtkWidget *widget _U_, gpointer data _U_)
398 {
399     int field_id;
400     const gchar *proto_abbrev;
401     gpointer  dialog;
402
403
404     if (cfile.finfo_selected) {
405         /* convert selected field to protocol abbreviation */
406         /* XXX - could this conversion be simplified? */
407         field_id = cfile.finfo_selected->hfinfo->id;
408         /* if the selected field isn't a protocol, get its parent */
409         if(!proto_registrar_is_protocol(field_id)) {
410             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
411         }
412
413         proto_abbrev = proto_registrar_get_abbrev(field_id);
414
415         if (!proto_is_private(field_id)) {
416             /* ask the user if the wiki page really should be opened */
417             dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
418                     "%sOpen Wireshark Wiki page of protocol \"%s\"?%s\n"
419                     "\n"
420                     "This will open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
421                     "\n"
422                     "The Wireshark Wiki is a collaborative approach to provide information "
423                     "about Wireshark in several ways (not limited to protocol specifics).\n"
424                     "\n"
425                     "This Wiki is new, so the page of the selected protocol "
426                     "may not exist and/or may not contain valuable information.\n"
427                     "\n"
428                     "As everyone can edit the Wiki and add new content (or extend existing), "
429                     "you are encouraged to add information if you can.\n"
430                     "\n"
431                     "Hint 1: If you are new to wiki editing, try out editing the Sandbox first!\n"
432                     "\n"
433                     "Hint 2: If you want to add a new protocol page, you should use the ProtocolTemplate, "
434                     "which will save you a lot of editing and will give a consistent look over the pages.",
435                     simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
436             simple_dialog_set_cb(dialog, selected_ptree_info_answered_cb, (gpointer)proto_abbrev);
437         } else {
438             /* appologize to the user that the wiki page cannot be opened */
439             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
440                     "%sCan't open Wireshark Wiki page of protocol \"%s\"%s\n"
441                     "\n"
442                     "This would open the \"%s\" related Wireshark Wiki page in your Web browser.\n"
443                     "\n"
444                     "Since this is a private protocol, such information is not available in "
445                     "a public wiki. Therefore this wiki entry is blocked.\n"
446                     "\n"
447                     "Sorry for the inconvenience.\n",
448                     simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
449         }
450     }
451 }
452
453 static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
454 {
455     gchar *selected_proto_url;
456     gchar *proto_abbrev = (gchar *)data;
457
458     switch(btn) {
459     case(ESD_BTN_OK):
460         if (cfile.finfo_selected) {
461             /* open reference page using the protocol abbreviation */
462             selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
463             browser_open_url(selected_proto_url);
464             g_free(selected_proto_url);
465         }
466         break;
467     case(ESD_BTN_CANCEL):
468         break;
469     default:
470         g_assert_not_reached();
471     }
472 }
473
474 void
475 selected_ptree_ref_cb(GtkWidget *widget _U_, gpointer data _U_)
476 {
477     int field_id;
478     const gchar *proto_abbrev;
479     gpointer  dialog;
480
481
482     if (cfile.finfo_selected) {
483         /* convert selected field to protocol abbreviation */
484         /* XXX - could this conversion be simplified? */
485         field_id = cfile.finfo_selected->hfinfo->id;
486         /* if the selected field isn't a protocol, get its parent */
487         if(!proto_registrar_is_protocol(field_id)) {
488             field_id = proto_registrar_get_parent(cfile.finfo_selected->hfinfo->id);
489         }
490
491         proto_abbrev = proto_registrar_get_abbrev(field_id);
492
493         if (!proto_is_private(field_id)) {
494             /* ask the user if the wiki page really should be opened */
495             dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_OK_CANCEL,
496                     "%sOpen Wireshark filter reference page of protocol \"%s\"?%s\n"
497                     "\n"
498                     "This will open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
499                     "\n",
500                     simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
501             simple_dialog_set_cb(dialog, selected_ptree_ref_answered_cb, (gpointer)proto_abbrev);
502         } else {
503             /* appologize to the user that the wiki page cannot be opened */
504             simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
505                     "%sCan't open Wireshark filter reference page of protocol \"%s\"%s\n"
506                     "\n"
507                     "This would open the \"%s\" related Wireshark filter reference page in your Web browser.\n"
508                     "\n"
509                     "Since this is a private protocol, such information is not available on "
510                     "a public website. Therefore this filter entry is blocked.\n"
511                     "\n"
512                     "Sorry for the inconvenience.\n",
513                     simple_dialog_primary_start(), proto_abbrev, simple_dialog_primary_end(), proto_abbrev);
514         }
515     }
516 }
517
518 static gboolean
519 is_address_column (gint column)
520 {
521     if (((cfile.cinfo.col_fmt[column] == COL_DEF_SRC) ||
522          (cfile.cinfo.col_fmt[column] == COL_RES_SRC) ||
523          (cfile.cinfo.col_fmt[column] == COL_DEF_DST) ||
524          (cfile.cinfo.col_fmt[column] == COL_RES_DST)) &&
525         strlen(cfile.cinfo.col_expr.col_expr_val[column]))
526     {
527         return TRUE;
528     }
529
530     return FALSE;
531 }
532
533 GList *
534 get_ip_address_list_from_packet_list_row(gpointer data)
535 {
536     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
537     gint    column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
538     gint    col;
539     frame_data *fdata;
540     GList      *addr_list = NULL;
541
542     fdata = (frame_data *) packet_list_get_row_data(row);
543
544     if (fdata != NULL) {
545         epan_dissect_t edt;
546
547         if (!cf_read_frame (&cfile, fdata))
548             return NULL; /* error reading the frame */
549
550         epan_dissect_init(&edt, cfile.epan, FALSE, FALSE);
551         col_custom_prime_edt(&edt, &cfile.cinfo);
552
553         epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
554             fdata, &cfile.cinfo);
555         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
556
557         /* First check selected column */
558         if (is_address_column (column)) {
559             addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[column]));
560         }
561
562         for (col = 0; col < cfile.cinfo.num_cols; col++) {
563             /* Then check all columns except the selected */
564             if ((col != column) && (is_address_column (col))) {
565                 addr_list = g_list_append (addr_list, se_strdup_printf("%s", cfile.cinfo.col_expr.col_expr_val[col]));
566             }
567         }
568
569         epan_dissect_cleanup(&edt);
570     }
571
572     return addr_list;
573 }
574
575 static gchar *
576 get_filter_from_packet_list_row_and_column(gpointer data)
577 {
578     gint    row = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_ROW_KEY));
579     gint    column = packet_list_get_column_id (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(data), E_MPACKET_LIST_COL_KEY)));
580     frame_data *fdata;
581     gchar      *buf=NULL;
582
583     fdata = (frame_data *) packet_list_get_row_data(row);
584
585     if (fdata != NULL) {
586         epan_dissect_t edt;
587
588         if (!cf_read_frame(&cfile, fdata))
589             return NULL; /* error reading the frame */
590         /* proto tree, visible. We need a proto tree if there's custom columns */
591         epan_dissect_init(&edt, cfile.epan, have_custom_cols(&cfile.cinfo), FALSE);
592         col_custom_prime_edt(&edt, &cfile.cinfo);
593
594         epan_dissect_run(&edt, &cfile.phdr, frame_tvbuff_new_buffer(fdata, &cfile.buf),
595                          fdata, &cfile.cinfo);
596         epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
597
598         if ((cfile.cinfo.col_custom_occurrence[column]) ||
599             (strchr (cfile.cinfo.col_expr.col_expr_val[column], ',') == NULL))
600         {
601             /* Only construct the filter when a single occurrence is displayed
602              * otherwise we might end up with a filter like "ip.proto==1,6".
603              *
604              * Or do we want to be able to filter on multiple occurrences so that
605              * the filter might be calculated as "ip.proto==1 && ip.proto==6"
606              * instead?
607              */
608             if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
609                 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
610                 /* leak a little but safer than ep_ here */
611                 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
612                     header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
613                     if (hfi && hfi->parent == -1) {
614                         /* Protocol only */
615                         buf = se_strdup(cfile.cinfo.col_expr.col_expr[column]);
616                     } else if (hfi && hfi->type == FT_STRING) {
617                         /* Custom string, add quotes */
618                         buf = se_strdup_printf("%s == \"%s\"", cfile.cinfo.col_expr.col_expr[column],
619                                                cfile.cinfo.col_expr.col_expr_val[column]);
620                     }
621                 }
622                 if (buf == NULL) {
623                     buf = se_strdup_printf("%s == %s", cfile.cinfo.col_expr.col_expr[column],
624                                            cfile.cinfo.col_expr.col_expr_val[column]);
625                 }
626             }
627         }
628
629         epan_dissect_cleanup(&edt);
630     }
631
632     return buf;
633 }
634
635 void
636 match_selected_plist_cb(gpointer data, MATCH_SELECTED_E action)
637 {
638     match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY),
639         action,
640         get_filter_from_packet_list_row_and_column((GtkWidget *)data));
641 }
642
643 /* This function allows users to right click in the details window and copy the text
644  * information to the operating systems clipboard.
645  *
646  * We first check to see if a string representation is setup in the tree and then
647  * read the string. If not available then we try to grab the value. If all else
648  * fails we display a message to the user to indicate the copy could not be completed.
649  */
650 void
651 copy_selected_plist_cb(GtkWidget *w _U_, gpointer data _U_, COPY_SELECTED_E action)
652 {
653     GString *gtk_text_str = g_string_new("");
654     char labelstring[ITEM_LABEL_LENGTH];
655     char *stringpointer = labelstring;
656
657     switch(action)
658     {
659     case COPY_SELECTED_DESCRIPTION:
660         if (cfile.finfo_selected->rep &&
661             strlen (cfile.finfo_selected->rep->representation) > 0) {
662             g_string_append(gtk_text_str, cfile.finfo_selected->rep->representation);
663         }
664         break;
665     case COPY_SELECTED_FIELDNAME:
666         if (cfile.finfo_selected->hfinfo->abbrev != 0) {
667             g_string_append(gtk_text_str, cfile.finfo_selected->hfinfo->abbrev);
668         }
669         break;
670     case COPY_SELECTED_VALUE:
671         if (cfile.edt !=0 ) {
672             g_string_append(gtk_text_str,
673                     get_node_field_value(cfile.finfo_selected, cfile.edt));
674         }
675         break;
676     default:
677         break;
678     }
679
680     if (gtk_text_str->len == 0) {
681         /* If no representation then... Try to read the value */
682         proto_item_fill_label(cfile.finfo_selected, stringpointer);
683         g_string_append(gtk_text_str, stringpointer);
684     }
685
686     if (gtk_text_str->len == 0) {
687         /* Could not get item so display error msg */
688         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not acquire information to copy, try expanding or choosing another item");
689     } else {
690         /* Copy string to clipboard */
691         copy_to_clipboard(gtk_text_str);
692     }
693     g_string_free(gtk_text_str, TRUE);                       /* Free the memory */
694 }
695
696
697 /* mark as reference time frame */
698 void
699 set_frame_reftime(gboolean set, frame_data *frame, gint row) {
700     if (row == -1)
701         return;
702     if (set) {
703         frame->flags.ref_time=1;
704         cfile.ref_time_count++;
705     } else {
706         frame->flags.ref_time=0;
707         cfile.ref_time_count--;
708     }
709     cf_reftime_packets(&cfile);
710     if (!frame->flags.ref_time && !frame->flags.passed_dfilter) {
711         packet_list_freeze();
712         cfile.displayed_count--;
713         packet_list_recreate_visible_rows();
714         packet_list_thaw();
715     }
716     packet_list_queue_draw();
717 }
718
719
720 static void reftime_answered_cb(gpointer dialog _U_, gint btn, gpointer data _U_)
721 {
722     switch(btn) {
723     case(ESD_BTN_YES):
724         timestamp_set_type(TS_RELATIVE);
725         recent.gui_time_format  = TS_RELATIVE;
726         cf_timestamp_auto_precision(&cfile);
727         packet_list_queue_draw();
728         break;
729     case(ESD_BTN_NO):
730         break;
731     default:
732         g_assert_not_reached();
733     }
734
735     if (cfile.current_frame) {
736       set_frame_reftime(!cfile.current_frame->flags.ref_time,
737       cfile.current_frame, cfile.current_row);
738     }
739 }
740
741
742 void
743 reftime_frame_cb(GtkWidget *w _U_, gpointer data _U_, REFTIME_ACTION_E action)
744 {
745     static GtkWidget *reftime_dialog = NULL;
746
747     switch(action){
748     case REFTIME_TOGGLE:
749         if (cfile.current_frame) {
750             if(recent.gui_time_format != TS_RELATIVE && cfile.current_frame->flags.ref_time==0) {
751                 reftime_dialog = (GtkWidget *)simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO,
752                     "%sSwitch to the appropriate Time Display Format?%s\n\n"
753                     "Time References don't work well with the currently selected Time Display Format.\n\n"
754                     "Do you want to switch to \"Seconds Since Beginning of Capture\" now?",
755                     simple_dialog_primary_start(), simple_dialog_primary_end());
756                 simple_dialog_set_cb(reftime_dialog, reftime_answered_cb, NULL);
757             } else {
758                 set_frame_reftime(!cfile.current_frame->flags.ref_time,
759                                   cfile.current_frame, cfile.current_row);
760             }
761         }
762         break;
763     case REFTIME_FIND_NEXT:
764         cf_find_packet_time_reference(&cfile, SD_FORWARD);
765         break;
766     case REFTIME_FIND_PREV:
767         cf_find_packet_time_reference(&cfile, SD_BACKWARD);
768         break;
769     }
770 }
771
772 void
773 find_next_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
774 {
775     cf_find_packet_marked(&cfile, SD_FORWARD);
776 }
777
778 void
779 find_prev_mark_cb(GtkWidget *w _U_, gpointer data _U_, int action _U_)
780 {
781     cf_find_packet_marked(&cfile, SD_BACKWARD);
782 }
783
784 static void
785 tree_view_selection_changed_cb(GtkTreeSelection *sel, gpointer user_data _U_)
786 {
787     field_info   *finfo;
788     gchar         len_str[2+10+1+5+1]; /* ", {N} bytes\0",
789                                           N < 4294967296 */
790     gboolean      has_blurb = FALSE;
791     guint         length = 0, byte_len;
792     GtkWidget    *byte_view;
793     const guint8 *byte_data;
794     gint          finfo_length;
795     GtkTreeModel *model;
796     GtkTreeIter   iter;
797
798     /* if nothing is selected */
799     if (!gtk_tree_selection_get_selected(sel, &model, &iter))
800     {
801         /*
802          * Which byte view is displaying the current protocol tree
803          * row's data?
804          */
805         byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
806         if (byte_view == NULL)
807             return;     /* none */
808
809         byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
810         if (byte_data == NULL)
811             return;     /* none */
812
813         cf_unselect_field(&cfile);
814         packet_hex_print(byte_view, byte_data,
815                          cfile.current_frame, NULL, byte_len);
816         proto_help_menu_modify(sel, &cfile);
817         return;
818     }
819     gtk_tree_model_get(model, &iter, 1, &finfo, -1);
820     if (!finfo) return;
821
822     set_notebook_page(byte_nb_ptr_gbl, finfo->ds_tvb);
823
824     byte_view = get_notebook_bv_ptr(byte_nb_ptr_gbl);
825     byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
826     g_assert(byte_data != NULL);
827
828     cfile.finfo_selected = finfo;
829     set_menus_for_selected_tree_row(&cfile);
830
831     if (finfo->hfinfo) {
832         if (finfo->hfinfo->blurb != NULL &&
833             finfo->hfinfo->blurb[0] != '\0') {
834             has_blurb = TRUE;
835             length = (guint) strlen(finfo->hfinfo->blurb);
836         } else {
837             length = (guint) strlen(finfo->hfinfo->name);
838         }
839         finfo_length = finfo->length + finfo->appendix_length;
840
841         if (finfo_length == 0) {
842             len_str[0] = '\0';
843         } else if (finfo_length == 1) {
844             g_strlcpy (len_str, ", 1 byte", sizeof len_str);
845         } else {
846             g_snprintf (len_str, sizeof len_str, ", %d bytes", finfo_length);
847         }
848         statusbar_pop_field_msg();      /* get rid of current help msg */
849         if (length) {
850             statusbar_push_field_msg(" %s (%s)%s",
851                     (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
852                     finfo->hfinfo->abbrev, len_str);
853         } else {
854             /*
855              * Don't show anything if the field name is zero-length;
856              * the pseudo-field for "proto_tree_add_text()" is such
857              * a field, and we don't want "Text (text)" showing up
858              * on the status line if you've selected such a field.
859              *
860              * XXX - there are zero-length fields for which we *do*
861              * want to show the field name.
862              *
863              * XXX - perhaps the name and abbrev field should be null
864              * pointers rather than null strings for that pseudo-field,
865              * but we'd have to add checks for null pointers in some
866              * places if we did that.
867              *
868              * Or perhaps protocol tree items added with
869              * "proto_tree_add_text()" should have -1 as the field index,
870              * with no pseudo-field being used, but that might also
871              * require special checks for -1 to be added.
872              */
873             statusbar_push_field_msg("%s", "");
874         }
875     }
876     packet_hex_print(byte_view, byte_data, cfile.current_frame, finfo,
877                      byte_len);
878     proto_help_menu_modify(sel, &cfile);
879 }
880
881 void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
882     if (cfile.edt->tree)
883         collapse_all_tree(cfile.edt->tree, tree_view_gbl);
884 }
885
886 void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
887     if (cfile.edt->tree)
888         expand_all_tree(cfile.edt->tree, tree_view_gbl);
889 }
890
891 void apply_as_custom_column_cb (GtkWidget *widget _U_, gpointer data _U_)
892 {
893     if (cfile.finfo_selected) {
894         column_prefs_add_custom(COL_CUSTOM, cfile.finfo_selected->hfinfo->name,
895                                 cfile.finfo_selected->hfinfo->abbrev,0);
896         /* Recreate the packet list according to new preferences */
897         packet_list_recreate ();
898         if (!prefs.gui_use_pref_save) {
899             prefs_main_write();
900         }
901         cfile.columns_changed = FALSE; /* Reset value */
902     }
903 }
904
905 void expand_tree_cb(GtkWidget *widget _U_, gpointer data _U_) {
906     GtkTreePath  *path;
907
908     path = tree_find_by_field_info(GTK_TREE_VIEW(tree_view_gbl), cfile.finfo_selected);
909     if(path) {
910         /* the mouse position is at an entry, expand that one */
911         gtk_tree_view_expand_row(GTK_TREE_VIEW(tree_view_gbl), path, TRUE);
912         gtk_tree_path_free(path);
913     }
914 }
915
916 void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
917     static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
918
919     if (cfile.edt->tree) {
920         proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
921     }
922 }
923
924 /* Update main window items based on whether there's a capture in progress. */
925 static void
926 main_set_for_capture_in_progress(gboolean capture_in_progress)
927 {
928     set_menus_for_capture_in_progress(capture_in_progress);
929
930 #ifdef HAVE_LIBPCAP
931     set_toolbar_for_capture_in_progress(capture_in_progress);
932
933     set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
934 #endif
935 }
936
937 /* Update main window items based on whether we have a capture file. */
938 static void
939 main_set_for_capture_file(gboolean have_capture_file_in)
940 {
941     have_capture_file = have_capture_file_in;
942
943     main_widgets_show_or_hide();
944 }
945
946 /* Update main window items based on whether we have captured packets. */
947 static void
948 main_set_for_captured_packets(gboolean have_captured_packets)
949 {
950     set_menus_for_captured_packets(have_captured_packets);
951     set_toolbar_for_captured_packets(have_captured_packets);
952 }
953
954 /* Update main window items based on whether we have a packet history. */
955 void
956 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
957 {
958     set_menus_for_packet_history(back_history, forward_history);
959     set_toolbar_for_packet_history(back_history, forward_history);
960 }
961
962 gboolean
963 main_do_quit(void)
964 {
965     /* get the current geometry, before writing it to disk */
966     main_save_window_geometry(top_level);
967
968     /* write user's recent file to disk
969      * It is no problem to write this file, even if we do not quit */
970     write_profile_recent();
971     write_recent();
972
973     /* XXX - should we check whether the capture file is an
974        unsaved temporary file for a live capture and, if so,
975        pop up a "do you want to exit without saving the capture
976        file?" dialog, and then just return, leaving said dialog
977        box to forcibly quit if the user clicks "OK"?
978
979        If so, note that this should be done in a subroutine that
980        returns TRUE if we do so, and FALSE otherwise, and if it
981        returns TRUE we should return TRUE without nuking anything.
982
983        Note that, if we do that, we might also want to check if
984        an "Update list of packets in real time" capture is in
985        progress and, if so, ask whether they want to terminate
986        the capture and discard it, and return TRUE, before nuking
987        any child capture, if they say they don't want to do so. */
988
989 #ifdef HAVE_LIBPCAP
990     /* Nuke any child capture in progress. */
991     capture_kill_child(&global_capture_session);
992 #endif
993
994     /* Are we in the middle of reading a capture? */
995     if (cfile.state == FILE_READ_IN_PROGRESS) {
996         /* Yes, so we can't just close the file and quit, as
997            that may yank the rug out from under the read in
998            progress; instead, just set the state to
999            "FILE_READ_ABORTED" and return - the code doing the read
1000            will check for that and, if it sees that, will clean
1001            up and quit. */
1002         cfile.state = FILE_READ_ABORTED;
1003
1004         /* Say that the window should *not* be deleted;
1005            that'll be done by the code that cleans up. */
1006         return TRUE;
1007     } else {
1008         /* Close any capture file we have open; on some OSes, you
1009            can't unlink a temporary capture file if you have it
1010            open.
1011            "cf_close()" will unlink it after closing it if
1012            it's a temporary file.
1013
1014            We do this here, rather than after the main loop returns,
1015            as, after the main loop returns, the main window may have
1016            been destroyed (if this is called due to a "destroy"
1017            even on the main window rather than due to the user
1018            selecting a menu item), and there may be a crash
1019            or other problem when "cf_close()" tries to
1020            clean up stuff in the main window.
1021
1022            XXX - is there a better place to put this?
1023            Or should we have a routine that *just* closes the
1024            capture file, and doesn't do anything with the UI,
1025            which we'd call here, and another routine that
1026            calls that routine and also cleans up the UI, which
1027            we'd call elsewhere? */
1028         cf_close(&cfile);
1029
1030         /* Exit by leaving the main loop, so that any quit functions
1031            we registered get called. */
1032         gtk_main_quit();
1033
1034         /* Say that the window should be deleted. */
1035         return FALSE;
1036     }
1037 }
1038
1039 static gboolean
1040 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1041 {
1042     /* If we're in the middle of stopping a capture, don't do anything;
1043        the user can try deleting the window after the capture stops. */
1044     if (capture_stopping)
1045         return TRUE;
1046
1047     /* If there's unsaved data, let the user save it first.
1048        If they cancel out of it, don't quit. */
1049     if (do_file_close(&cfile, TRUE, " before quitting"))
1050         return main_do_quit();
1051     else
1052         return TRUE; /* will this keep the window from being deleted? */
1053 }
1054
1055
1056 static void
1057 main_pane_load_window_geometry(void)
1058 {
1059     if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1060         gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1061     if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1062         gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1063     }
1064 }
1065
1066
1067 static void
1068 main_load_window_geometry(GtkWidget *widget)
1069 {
1070     window_geometry_t geom;
1071
1072     geom.set_pos        = prefs.gui_geometry_save_position;
1073     geom.x              = recent.gui_geometry_main_x;
1074     geom.y              = recent.gui_geometry_main_y;
1075     geom.set_size       = prefs.gui_geometry_save_size;
1076     if (recent.gui_geometry_main_width > 0 &&
1077         recent.gui_geometry_main_height > 0) {
1078         geom.width          = recent.gui_geometry_main_width;
1079         geom.height         = recent.gui_geometry_main_height;
1080         geom.set_maximized  = prefs.gui_geometry_save_maximized;
1081     } else {
1082         /* We assume this means the width and height weren't set in
1083            the "recent" file (or that there is no "recent" file),
1084            and weren't set to a default value, so we don't set the
1085            size.  (The "recent" file code rejects non-positive width
1086            and height values.) */
1087        geom.set_size = FALSE;
1088     }
1089     geom.maximized      = recent.gui_geometry_main_maximized;
1090
1091     window_set_geometry(widget, &geom);
1092
1093     main_pane_load_window_geometry();
1094     statusbar_load_window_geometry();
1095 }
1096
1097
1098 static void
1099 main_save_window_geometry(GtkWidget *widget)
1100 {
1101     window_geometry_t geom;
1102
1103     window_get_geometry(widget, &geom);
1104
1105     if (prefs.gui_geometry_save_position) {
1106         recent.gui_geometry_main_x = geom.x;
1107         recent.gui_geometry_main_y = geom.y;
1108     }
1109
1110     if (prefs.gui_geometry_save_size) {
1111         recent.gui_geometry_main_width  = geom.width;
1112         recent.gui_geometry_main_height = geom.height;
1113     }
1114
1115     if(prefs.gui_geometry_save_maximized) {
1116         recent.gui_geometry_main_maximized = geom.maximized;
1117     }
1118
1119     recent.gui_geometry_main_upper_pane     = gtk_paned_get_position(GTK_PANED(main_first_pane));
1120     recent.gui_geometry_main_lower_pane     = gtk_paned_get_position(GTK_PANED(main_second_pane));
1121     statusbar_save_window_geometry();
1122 }
1123
1124 void
1125 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1126 {
1127     /* If there's unsaved data, let the user save it first. */
1128     if (do_file_close(&cfile, TRUE, " before quitting"))
1129         main_do_quit();
1130 }
1131
1132 static void
1133 print_usage(gboolean print_ver) {
1134
1135   FILE *output;
1136
1137 #ifdef _WIN32
1138   create_console();
1139 #endif
1140
1141   if (print_ver) {
1142     output = stdout;
1143     fprintf(output, "Wireshark " VERSION "%s\n"
1144         "Interactively dump and analyze network traffic.\n"
1145         "See http://www.wireshark.org for more information.\n"
1146         "\n"
1147         "%s",
1148         wireshark_svnversion, get_copyright_info());
1149   } else {
1150     output = stderr;
1151   }
1152   fprintf(output, "\n");
1153   fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1154   fprintf(output, "\n");
1155
1156 #ifdef HAVE_LIBPCAP
1157   fprintf(output, "Capture interface:\n");
1158   fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
1159   fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
1160   fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
1161   fprintf(output, "  -p                       don't capture in promiscuous mode\n");
1162   fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
1163   fprintf(output, "  -S                       update packet display when new packets are captured\n");
1164   fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
1165 #ifdef HAVE_PCAP_CREATE
1166   fprintf(output, "  -I                       capture in monitor mode, if available\n");
1167 #endif
1168 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1169   fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
1170 #endif
1171   fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
1172   fprintf(output, "  -D                       print list of interfaces and exit\n");
1173   fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
1174   fprintf(output, "\n");
1175   fprintf(output, "Capture stop conditions:\n");
1176   fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
1177   fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
1178   fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
1179   fprintf(output, "                              files:NUM - stop after NUM files\n");
1180   /*fprintf(output, "\n");*/
1181   fprintf(output, "Capture output:\n");
1182   fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1183   fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
1184   fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
1185 #endif  /* HAVE_LIBPCAP */
1186 #ifdef HAVE_PCAP_REMOTE
1187   fprintf(output, "RPCAP options:\n");
1188   fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
1189 #endif
1190   /*fprintf(output, "\n");*/
1191   fprintf(output, "Input file:\n");
1192   fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
1193
1194   fprintf(output, "\n");
1195   fprintf(output, "Processing:\n");
1196   fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
1197   fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
1198   fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
1199
1200   fprintf(output, "\n");
1201   fprintf(output, "User interface:\n");
1202   fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
1203   fprintf(output, "  -Y <display filter>      start with the given display filter\n");
1204   fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
1205   fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
1206   fprintf(output, "                           filter\n");
1207   fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
1208   fprintf(output, "  -m <font>                set the font name used for most text\n");
1209   fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
1210   fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
1211   fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
1212   fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
1213
1214   fprintf(output, "\n");
1215   fprintf(output, "Output:\n");
1216   fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
1217
1218   fprintf(output, "\n");
1219   fprintf(output, "Miscellaneous:\n");
1220   fprintf(output, "  -h                       display this help and exit\n");
1221   fprintf(output, "  -v                       display version info and exit\n");
1222   fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
1223   fprintf(output, "                           persdata:path - personal data files\n");
1224   fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
1225   fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
1226 #ifndef _WIN32
1227   fprintf(output, "  --display=DISPLAY        X display to use\n");
1228 #endif
1229
1230 #ifdef _WIN32
1231   destroy_console();
1232 #endif
1233 }
1234
1235 static void
1236 show_version(void)
1237 {
1238   printf(PACKAGE " " VERSION "%s\n"
1239          "\n"
1240          "%s"
1241          "\n"
1242          "%s"
1243          "\n"
1244          "%s",
1245       wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1246       runtime_info_str->str);
1247 }
1248
1249 /*
1250  * Report an error in command-line arguments.
1251  * Creates a console on Windows.
1252  */
1253 void
1254 cmdarg_err(const char *fmt, ...)
1255 {
1256   va_list ap;
1257
1258 #ifdef _WIN32
1259   create_console();
1260 #endif
1261   fprintf(stderr, "wireshark: ");
1262   va_start(ap, fmt);
1263   vfprintf(stderr, fmt, ap);
1264   va_end(ap);
1265   fprintf(stderr, "\n");
1266 }
1267
1268 /*
1269  * Report additional information for an error in command-line arguments.
1270  * Creates a console on Windows.
1271  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1272  * terminal isn't the standard error?
1273  */
1274 void
1275 cmdarg_err_cont(const char *fmt, ...)
1276 {
1277   va_list ap;
1278
1279 #ifdef _WIN32
1280   create_console();
1281 #endif
1282   va_start(ap, fmt);
1283   vfprintf(stderr, fmt, ap);
1284   fprintf(stderr, "\n");
1285   va_end(ap);
1286 }
1287
1288 /*
1289    Once every 3 seconds we get a callback here which we use to update
1290    the tap extensions.
1291  */
1292 static gboolean
1293 tap_update_cb(gpointer data _U_)
1294 {
1295     draw_tap_listeners(FALSE);
1296     return TRUE;
1297 }
1298
1299 /*
1300  * Periodically process outstanding hostname lookups. If we have new items,
1301  * redraw the packet list and tree view.
1302  */
1303
1304 static gboolean
1305 resolv_update_cb(gpointer data _U_)
1306 {
1307   /* Anything new show up? */
1308   if (host_name_lookup_process()) {
1309     if (gtk_widget_get_window(pkt_scrollw))
1310       gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1311     if (gtk_widget_get_window(tv_scrollw))
1312       gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1313   }
1314
1315   /* Always check. Even if we don't do async lookups we could still get
1316      passive updates, e.g. from DNS packets. */
1317   return TRUE;
1318 }
1319
1320
1321 /* Update various parts of the main window for a capture file "unsaved
1322    changes" change - update the title to reflect whether there are
1323    unsaved changes or not, and update the menus and toolbar to
1324    enable or disable the "Save" operation. */
1325 void
1326 main_update_for_unsaved_changes(capture_file *cf)
1327 {
1328   set_titlebar_for_capture_file(cf);
1329   set_menus_for_capture_file(cf);
1330   set_toolbar_for_capture_file(cf);
1331 }
1332
1333 #ifdef HAVE_LIBPCAP
1334 void
1335 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1336 {
1337   /* Update menubar and toolbar */
1338   menu_auto_scroll_live_changed(auto_scroll_live_in);
1339   toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1340
1341   /* change auto scroll state */
1342   auto_scroll_live  = auto_scroll_live_in;
1343 }
1344 #endif
1345
1346 void
1347 main_colorize_changed(gboolean packet_list_colorize)
1348 {
1349   /* Update menubar and toolbar */
1350   menu_colorize_changed(packet_list_colorize);
1351   toolbar_colorize_changed(packet_list_colorize);
1352
1353   /* change colorization */
1354   if(packet_list_colorize != recent.packet_list_colorize) {
1355       recent.packet_list_colorize = packet_list_colorize;
1356       color_filters_enable(packet_list_colorize);
1357       packet_list_colorize_packets();
1358   }
1359 }
1360
1361 static GtkWidget           *close_dlg = NULL;
1362
1363 static void
1364 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1365 {
1366     recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1367 }
1368
1369 #ifdef _WIN32
1370 static void
1371 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1372 {
1373     recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1374 }
1375 #endif
1376
1377 static void
1378 main_cf_cb_file_closing(capture_file *cf)
1379 {
1380     /* if we have more than 10000 packets, show a splash screen while closing */
1381     /* XXX - don't know a better way to decide whether to show or not,
1382      * as most of the time is spend in various calls that destroy various
1383      * data structures, so it wouldn't be easy to use a progress bar,
1384      * rather than, say, a progress spinner, here! */
1385     if(cf->count > 10000) {
1386         close_dlg = (GtkWidget *)simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1387                                   "%sClosing file!%s\n\nPlease wait ...",
1388                                   simple_dialog_primary_start(),
1389                                   simple_dialog_primary_end());
1390         gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1391     }
1392
1393     /* Destroy all windows that refer to the
1394        capture file we're closing. */
1395     destroy_packet_wins();
1396
1397     /* Update the titlebar to reflect the lack of a capture file. */
1398     set_titlebar_for_capture_file(NULL);
1399
1400     /* Disable all menu and toolbar items that make sense only if
1401        you have a capture. */
1402     set_menus_for_capture_file(NULL);
1403     set_toolbar_for_capture_file(NULL);
1404     main_set_for_captured_packets(FALSE);
1405     set_menus_for_selected_packet(cf);
1406     main_set_for_capture_in_progress(FALSE);
1407     set_capture_if_dialog_for_capture_in_progress(FALSE);
1408     set_menus_for_selected_tree_row(cf);
1409
1410     /* Set up main window for no capture file. */
1411     main_set_for_capture_file(FALSE);
1412
1413     main_window_update();
1414 }
1415
1416 static void
1417 main_cf_cb_file_closed(capture_file *cf _U_)
1418 {
1419   if(close_dlg != NULL) {
1420     splash_destroy(close_dlg);
1421     close_dlg = NULL;
1422   }
1423 }
1424
1425
1426 static void
1427 main_cf_cb_file_read_started(capture_file *cf _U_)
1428 {
1429   tap_param_dlg_update();
1430
1431   /* Set up main window for a capture file. */
1432   main_set_for_capture_file(TRUE);
1433 }
1434
1435 static void
1436 main_cf_cb_file_read_finished(capture_file *cf)
1437 {
1438     gchar *dir_path;
1439
1440     if (!cf->is_tempfile && cf->filename) {
1441         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1442         add_menu_recent_capture_file(cf->filename);
1443
1444         /* Remember folder for next Open dialog and save it in recent */
1445         dir_path = get_dirname(g_strdup(cf->filename));
1446         set_last_open_dir(dir_path);
1447         g_free(dir_path);
1448     }
1449
1450     /* Update the appropriate parts of the main window. */
1451     main_update_for_unsaved_changes(cf);
1452
1453     /* Enable menu items that make sense if you have some captured packets. */
1454     main_set_for_captured_packets(TRUE);
1455 }
1456
1457 static void
1458 main_cf_cb_file_rescan_finished(capture_file *cf)
1459 {
1460     gchar *dir_path;
1461
1462     if (!cf->is_tempfile && cf->filename) {
1463         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1464         add_menu_recent_capture_file(cf->filename);
1465
1466         /* Remember folder for next Open dialog and save it in recent */
1467         dir_path = get_dirname(g_strdup(cf->filename));
1468         set_last_open_dir(dir_path);
1469         g_free(dir_path);
1470     }
1471
1472     /* Update the appropriate parts of the main window. */
1473     main_update_for_unsaved_changes(cf);
1474 }
1475
1476 #ifdef HAVE_LIBPCAP
1477 static GList *icon_list_create(
1478     const guint8 *icon16_pb,
1479     const guint8 *icon32_pb,
1480     const guint8 *icon48_pb,
1481     const guint8 *icon64_pb)
1482 {
1483   GList *icon_list = NULL;
1484   GdkPixbuf * pixbuf16;
1485   GdkPixbuf * pixbuf32;
1486   GdkPixbuf * pixbuf48;
1487   GdkPixbuf * pixbuf64;
1488
1489
1490   if(icon16_pb != NULL) {
1491       pixbuf16 = gdk_pixbuf_new_from_inline(-1, icon16_pb, FALSE, NULL);
1492       g_assert(pixbuf16);
1493       icon_list = g_list_append(icon_list, pixbuf16);
1494   }
1495
1496   if(icon32_pb != NULL) {
1497       pixbuf32 = gdk_pixbuf_new_from_inline(-1, icon32_pb, FALSE, NULL);
1498       g_assert(pixbuf32);
1499       icon_list = g_list_append(icon_list, pixbuf32);
1500   }
1501
1502   if(icon48_pb != NULL) {
1503       pixbuf48 = gdk_pixbuf_new_from_inline(-1, icon48_pb, FALSE, NULL);
1504       g_assert(pixbuf48);
1505       icon_list = g_list_append(icon_list, pixbuf48);
1506   }
1507
1508   if(icon64_pb != NULL) {
1509       pixbuf64 = gdk_pixbuf_new_from_inline(-1, icon64_pb, FALSE, NULL);
1510       g_assert(pixbuf64);
1511       icon_list = g_list_append(icon_list, pixbuf64);
1512   }
1513
1514   return icon_list;
1515 }
1516
1517 static void
1518 main_capture_cb_capture_prepared(capture_session *cap_session)
1519 {
1520     static GList *icon_list = NULL;
1521
1522     set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1523
1524     if(icon_list == NULL) {
1525         icon_list = icon_list_create(wsiconcap_16_pb_data, wsiconcap_32_pb_data, wsiconcap_48_pb_data, wsiconcap_64_pb_data);
1526     }
1527     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1528
1529     /* Disable menu items that make no sense if you're currently running
1530        a capture. */
1531     main_set_for_capture_in_progress(TRUE);
1532     set_capture_if_dialog_for_capture_in_progress(TRUE);
1533
1534     /* Don't set up main window for a capture file. */
1535     main_set_for_capture_file(FALSE);
1536 }
1537
1538 static void
1539 main_capture_cb_capture_update_started(capture_session *cap_session)
1540 {
1541     /* We've done this in "prepared" above, but it will be cleared while
1542        switching to the next multiple file. */
1543     set_titlebar_for_capture_in_progress((capture_file *)cap_session->cf);
1544
1545     main_set_for_capture_in_progress(TRUE);
1546     set_capture_if_dialog_for_capture_in_progress(TRUE);
1547
1548     /* Enable menu items that make sense if you have some captured
1549        packets (yes, I know, we don't have any *yet*). */
1550     main_set_for_captured_packets(TRUE);
1551
1552     /* Set up main window for a capture file. */
1553     main_set_for_capture_file(TRUE);
1554 }
1555
1556 static void
1557 main_capture_cb_capture_update_finished(capture_session *cap_session)
1558 {
1559     capture_file *cf = (capture_file *)cap_session->cf;
1560     static GList *icon_list = NULL;
1561
1562     /* The capture isn't stopping any more - it's stopped. */
1563     capture_stopping = FALSE;
1564
1565     if (!cf->is_tempfile && cf->filename) {
1566         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1567         add_menu_recent_capture_file(cf->filename);
1568     }
1569
1570     /* Enable menu items that make sense if you're not currently running
1571      a capture. */
1572     main_set_for_capture_in_progress(FALSE);
1573     set_capture_if_dialog_for_capture_in_progress(FALSE);
1574
1575     /* Update the main window as appropriate. This has to occur AFTER
1576      * main_set_for_capture_in_progress() or else some of the menus are
1577      * incorrectly disabled (see bug
1578      * https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8108) */
1579     main_update_for_unsaved_changes(cf);
1580
1581     /* Set up main window for a capture file. */
1582     main_set_for_capture_file(TRUE);
1583
1584     if(icon_list == NULL) {
1585         icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1586     }
1587     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1588
1589     if(global_capture_opts.quit_after_cap) {
1590         /* command line asked us to quit after the capture */
1591         /* don't pop up a dialog to ask for unsaved files etc. */
1592         main_do_quit();
1593     }
1594 }
1595
1596 static void
1597 main_capture_cb_capture_fixed_started(capture_session *cap_session _U_)
1598 {
1599     /* Don't set up main window for a capture file. */
1600     main_set_for_capture_file(FALSE);
1601 }
1602
1603 static void
1604 main_capture_cb_capture_fixed_finished(capture_session *cap_session _U_)
1605 {
1606 #if 0
1607     capture_file *cf = (capture_file *)cap_session->cf;
1608 #endif
1609     static GList *icon_list = NULL;
1610
1611     /* The capture isn't stopping any more - it's stopped. */
1612     capture_stopping = FALSE;
1613
1614     /*set_titlebar_for_capture_file(cf);*/
1615
1616     /* Enable menu items that make sense if you're not currently running
1617      a capture. */
1618     main_set_for_capture_in_progress(FALSE);
1619     set_capture_if_dialog_for_capture_in_progress(FALSE);
1620
1621     /* Restore the standard title bar message */
1622     /* (just in case we have trouble opening the capture file). */
1623     set_titlebar_for_capture_file(NULL);
1624
1625     if(icon_list == NULL) {
1626         icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1627     }
1628     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1629
1630     /* We don't have loaded the capture file, this will be done later.
1631      * For now we still have simply a blank screen. */
1632
1633     if(global_capture_opts.quit_after_cap) {
1634         /* command line asked us to quit after the capture */
1635         /* don't pop up a dialog to ask for unsaved files etc. */
1636         main_do_quit();
1637     }
1638 }
1639
1640 static void
1641 main_capture_cb_capture_stopping(capture_session *cap_session _U_)
1642 {
1643     capture_stopping = TRUE;
1644     set_menus_for_capture_stopping();
1645 #ifdef HAVE_LIBPCAP
1646     set_toolbar_for_capture_stopping();
1647
1648     set_capture_if_dialog_for_capture_stopping();
1649 #endif
1650 }
1651
1652 static void
1653 main_capture_cb_capture_failed(capture_session *cap_session _U_)
1654 {
1655     static GList *icon_list = NULL;
1656
1657     /* Capture isn't stopping any more. */
1658     capture_stopping = FALSE;
1659
1660     /* the capture failed before the first packet was captured
1661        reset title, menus and icon */
1662     set_titlebar_for_capture_file(NULL);
1663
1664     main_set_for_capture_in_progress(FALSE);
1665     set_capture_if_dialog_for_capture_in_progress(FALSE);
1666
1667     main_set_for_capture_file(FALSE);
1668
1669     if(icon_list == NULL) {
1670         icon_list = icon_list_create(wsicon_16_pb_data, wsicon_32_pb_data, wsicon_48_pb_data, wsicon_64_pb_data);
1671     }
1672     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1673
1674
1675     if(global_capture_opts.quit_after_cap) {
1676         /* command line asked us to quit after the capture */
1677         /* don't pop up a dialog to ask for unsaved files etc. */
1678         main_do_quit();
1679     }
1680 }
1681 #endif  /* HAVE_LIBPCAP */
1682
1683 static void
1684 main_cf_cb_packet_selected(gpointer data)
1685 {
1686     capture_file *cf = (capture_file *)data;
1687
1688     /* Display the GUI protocol tree and packet bytes.
1689       XXX - why do we dump core if we call "proto_tree_draw()"
1690       before calling "add_byte_views()"? */
1691     add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1692     proto_tree_draw(cf->edt->tree, tree_view_gbl);
1693
1694     /* Note: Both string and hex value searches in the packet data produce a non-zero
1695        search_pos if successful */
1696     if(cf->search_in_progress &&
1697       (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1698         highlight_field(cf->edt->tvb, cf->search_pos,
1699                         (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1700     }
1701
1702     /* A packet is selected. */
1703     set_menus_for_selected_packet(cf);
1704 }
1705
1706 static void
1707 main_cf_cb_packet_unselected(capture_file *cf)
1708 {
1709     /* No packet is being displayed; clear the hex dump pane by getting
1710        rid of all the byte views. */
1711     while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1712         gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1713
1714     /* Add a placeholder byte view so that there's at least something
1715        displayed in the byte view notebook. */
1716     add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1717
1718     /* And clear the protocol tree display as well. */
1719     proto_tree_draw(NULL, tree_view_gbl);
1720
1721     /* No packet is selected. */
1722     set_menus_for_selected_packet(cf);
1723 }
1724
1725 static void
1726 main_cf_cb_field_unselected(capture_file *cf)
1727 {
1728     set_menus_for_selected_tree_row(cf);
1729 }
1730
1731 static void
1732 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1733 {
1734     capture_file *cf = (capture_file *)data;
1735     switch(event) {
1736     case(cf_cb_file_opened):
1737         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Opened");
1738         fileset_file_opened(cf);
1739         break;
1740     case(cf_cb_file_closing):
1741         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1742         main_cf_cb_file_closing(cf);
1743         break;
1744     case(cf_cb_file_closed):
1745         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1746         main_cf_cb_file_closed(cf);
1747         fileset_file_closed();
1748         break;
1749     case(cf_cb_file_read_started):
1750         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1751         main_cf_cb_file_read_started(cf);
1752         break;
1753     case(cf_cb_file_read_finished):
1754         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1755         main_cf_cb_file_read_finished(cf);
1756         break;
1757     case(cf_cb_file_reload_started):
1758         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1759         main_cf_cb_file_read_started(cf);
1760         break;
1761     case(cf_cb_file_reload_finished):
1762         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1763         main_cf_cb_file_read_finished(cf);
1764         break;
1765     case(cf_cb_file_rescan_started):
1766         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1767         break;
1768     case(cf_cb_file_rescan_finished):
1769         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1770         main_cf_cb_file_rescan_finished(cf);
1771         break;
1772     case(cf_cb_file_fast_save_finished):
1773         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1774         main_cf_cb_file_rescan_finished(cf);
1775         break;
1776     case(cf_cb_packet_selected):
1777         main_cf_cb_packet_selected(cf);
1778         break;
1779     case(cf_cb_packet_unselected):
1780         main_cf_cb_packet_unselected(cf);
1781         break;
1782     case(cf_cb_field_unselected):
1783         main_cf_cb_field_unselected(cf);
1784         break;
1785     case(cf_cb_file_save_started):
1786         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1787         break;
1788     case(cf_cb_file_save_finished):
1789         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1790         break;
1791     case(cf_cb_file_save_failed):
1792         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1793         break;
1794     case(cf_cb_file_save_stopped):
1795         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1796         break;
1797     case(cf_cb_file_export_specified_packets_started):
1798         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1799         break;
1800     case(cf_cb_file_export_specified_packets_finished):
1801         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1802         break;
1803     case(cf_cb_file_export_specified_packets_failed):
1804         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1805         break;
1806     case(cf_cb_file_export_specified_packets_stopped):
1807         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1808         break;
1809     default:
1810         g_warning("main_cf_callback: event %u unknown", event);
1811         g_assert_not_reached();
1812     }
1813 }
1814
1815 #ifdef HAVE_LIBPCAP
1816 static void
1817 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data _U_)
1818 {
1819 #ifdef HAVE_GTKOSXAPPLICATION
1820     GtkosxApplication *theApp;
1821 #endif
1822     switch(event) {
1823     case(capture_cb_capture_prepared):
1824         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1825         main_capture_cb_capture_prepared(cap_session);
1826         break;
1827     case(capture_cb_capture_update_started):
1828         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1829         main_capture_cb_capture_update_started(cap_session);
1830 #ifdef HAVE_GTKOSXAPPLICATION
1831         theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1832         gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsiconcap_48_pb_data, FALSE, NULL));
1833 #endif
1834         break;
1835     case(capture_cb_capture_update_continue):
1836         /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1837         break;
1838     case(capture_cb_capture_update_finished):
1839         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1840         main_capture_cb_capture_update_finished(cap_session);
1841         break;
1842     case(capture_cb_capture_fixed_started):
1843         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1844         main_capture_cb_capture_fixed_started(cap_session);
1845         break;
1846     case(capture_cb_capture_fixed_continue):
1847         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1848         break;
1849     case(capture_cb_capture_fixed_finished):
1850         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1851         main_capture_cb_capture_fixed_finished(cap_session);
1852         break;
1853     case(capture_cb_capture_stopping):
1854         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1855         /* Beware: this state won't be called, if the capture child
1856          * closes the capturing on its own! */
1857 #ifdef HAVE_GTKOSXAPPLICATION
1858         theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
1859         gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
1860 #endif
1861         main_capture_cb_capture_stopping(cap_session);
1862         break;
1863     case(capture_cb_capture_failed):
1864         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1865         main_capture_cb_capture_failed(cap_session);
1866         break;
1867     default:
1868         g_warning("main_capture_callback: event %u unknown", event);
1869         g_assert_not_reached();
1870     }
1871 }
1872 #endif
1873
1874 static void
1875 get_gtk_compiled_info(GString *str)
1876 {
1877   g_string_append(str, "with ");
1878   g_string_append_printf(str,
1879 #ifdef GTK_MAJOR_VERSION
1880                     "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1881                     GTK_MICRO_VERSION);
1882 #else
1883                     "GTK+ (version unknown)");
1884 #endif
1885   g_string_append(str, ", ");
1886   /* Cairo */
1887   g_string_append(str, "with Cairo ");
1888   g_string_append(str, CAIRO_VERSION_STRING);
1889   g_string_append(str, ", ");
1890
1891   /* Pango */
1892   g_string_append(str, "with Pango ");
1893   g_string_append(str, PANGO_VERSION_STRING);
1894   g_string_append(str, ", ");
1895
1896
1897 }
1898
1899 static void
1900 get_gui_compiled_info(GString *str)
1901 {
1902   epan_get_compiled_version_info(str);
1903
1904   g_string_append(str, ", ");
1905 #ifdef HAVE_LIBPORTAUDIO
1906 #ifdef PORTAUDIO_API_1
1907   g_string_append(str, "with PortAudio <= V18");
1908 #else /* PORTAUDIO_API_1 */
1909   g_string_append(str, "with ");
1910   g_string_append(str, Pa_GetVersionText());
1911 #endif /* PORTAUDIO_API_1 */
1912 #else /* HAVE_LIBPORTAUDIO */
1913   g_string_append(str, "without PortAudio");
1914 #endif /* HAVE_LIBPORTAUDIO */
1915
1916   g_string_append(str, ", ");
1917 #ifdef HAVE_AIRPCAP
1918   get_compiled_airpcap_version(str);
1919 #else
1920   g_string_append(str, "without AirPcap");
1921 #endif
1922 }
1923
1924 static void
1925 get_gui_runtime_info(GString *str)
1926 {
1927   epan_get_runtime_version_info(str);
1928
1929 #ifdef HAVE_AIRPCAP
1930   g_string_append(str, ", ");
1931   get_runtime_airpcap_version(str);
1932 #endif
1933
1934   if(u3_active()) {
1935     g_string_append(str, ", ");
1936     u3_runtime_info(str);
1937   }
1938 }
1939
1940 static e_prefs *
1941 read_configuration_files(char **gdp_path, char **dp_path)
1942 {
1943   int                  gpf_open_errno, gpf_read_errno;
1944   int                  cf_open_errno, df_open_errno;
1945   int                  gdp_open_errno, gdp_read_errno;
1946   int                  dp_open_errno, dp_read_errno;
1947   char                *gpf_path, *pf_path;
1948   char                *cf_path, *df_path;
1949   int                  pf_open_errno, pf_read_errno;
1950   e_prefs             *prefs_p;
1951
1952   /* load the decode as entries of this profile */
1953   load_decode_as_entries();
1954
1955   /* Read the preference files. */
1956   prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1957                      &pf_open_errno, &pf_read_errno, &pf_path);
1958
1959   if (gpf_path != NULL) {
1960     if (gpf_open_errno != 0) {
1961       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1962         "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1963         g_strerror(gpf_open_errno));
1964     }
1965     if (gpf_read_errno != 0) {
1966       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1967         "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
1968         g_strerror(gpf_read_errno));
1969     }
1970   }
1971   if (pf_path != NULL) {
1972     if (pf_open_errno != 0) {
1973       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1974         "Could not open your preferences file\n\"%s\": %s.", pf_path,
1975         g_strerror(pf_open_errno));
1976     }
1977     if (pf_read_errno != 0) {
1978       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1979         "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
1980         g_strerror(pf_read_errno));
1981     }
1982     g_free(pf_path);
1983     pf_path = NULL;
1984   }
1985
1986 #ifdef _WIN32
1987   /* if the user wants a console to be always there, well, we should open one for him */
1988   if (prefs_p->gui_console_open == console_open_always) {
1989     create_console();
1990   }
1991 #endif
1992
1993   /* Read the capture filter file. */
1994   read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1995   if (cf_path != NULL) {
1996       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1997         "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1998         g_strerror(cf_open_errno));
1999       g_free(cf_path);
2000   }
2001
2002   /* Read the display filter file. */
2003   read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2004   if (df_path != NULL) {
2005       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2006         "Could not open your display filter file\n\"%s\": %s.", df_path,
2007         g_strerror(df_open_errno));
2008       g_free(df_path);
2009   }
2010
2011   /* Read the disabled protocols file. */
2012   read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2013                             dp_path, &dp_open_errno, &dp_read_errno);
2014   if (*gdp_path != NULL) {
2015     if (gdp_open_errno != 0) {
2016       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2017         "Could not open global disabled protocols file\n\"%s\": %s.",
2018         *gdp_path, g_strerror(gdp_open_errno));
2019     }
2020     if (gdp_read_errno != 0) {
2021       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2022         "I/O error reading global disabled protocols file\n\"%s\": %s.",
2023         *gdp_path, g_strerror(gdp_read_errno));
2024     }
2025     g_free(*gdp_path);
2026     *gdp_path = NULL;
2027   }
2028   if (*dp_path != NULL) {
2029     if (dp_open_errno != 0) {
2030       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2031         "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2032         g_strerror(dp_open_errno));
2033     }
2034     if (dp_read_errno != 0) {
2035       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2036         "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2037         g_strerror(dp_read_errno));
2038     }
2039     g_free(*dp_path);
2040     *dp_path = NULL;
2041   }
2042
2043   return prefs_p;
2044 }
2045
2046 /*  Check if there's something important to tell the user during startup.
2047  *  We want to do this *after* showing the main window so that any windows
2048  *  we pop up will be above the main window.
2049  */
2050 static void
2051 #ifdef _WIN32
2052 check_and_warn_user_startup(gchar *cf_name)
2053 #else
2054 check_and_warn_user_startup(gchar *cf_name _U_)
2055 #endif
2056 {
2057   gchar               *cur_user, *cur_group;
2058   gpointer             priv_warning_dialog;
2059
2060   /* Tell the user not to run as root. */
2061   if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2062     cur_user = get_cur_username();
2063     cur_group = get_cur_groupname();
2064     priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2065       "Running as user \"%s\" and group \"%s\".\n"
2066       "This could be dangerous.\n\n"
2067       "If you're running Wireshark this way in order to perform live capture, "
2068       "you may want to be aware that there is a better way documented at\n"
2069       "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2070     g_free(cur_user);
2071     g_free(cur_group);
2072     simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2073     simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2074   }
2075
2076 #ifdef _WIN32
2077   /* Warn the user if npf.sys isn't loaded. */
2078   if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2079     priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2080       "The NPF driver isn't running.  You may have trouble\n"
2081       "capturing or listing interfaces.");
2082     simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2083     simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2084   }
2085 #endif
2086
2087 }
2088
2089
2090 /* And now our feature presentation... [ fade to music ] */
2091 int
2092 main(int argc, char *argv[])
2093 {
2094   char                *init_progfile_dir_error;
2095   char                *s;
2096   int                  opt;
2097   gboolean             arg_error = FALSE;
2098
2099   extern int           info_update_freq;  /* Found in about_dlg.c. */
2100   const gchar         *filter;
2101
2102 #ifdef _WIN32
2103   WSADATA              wsaData;
2104 #endif  /* _WIN32 */
2105
2106   char                *rf_path;
2107   int                  rf_open_errno;
2108   char                *gdp_path, *dp_path;
2109   int                  err;
2110 #ifdef HAVE_LIBPCAP
2111   gboolean             start_capture = FALSE;
2112   gboolean             list_link_layer_types = FALSE;
2113   GList               *if_list;
2114   gchar               *err_str;
2115 #else
2116   gboolean             capture_option_specified = FALSE;
2117 #ifdef _WIN32
2118 #ifdef HAVE_AIRPCAP
2119   gchar               *err_str;
2120 #endif
2121 #endif
2122 #endif
2123   gint                 pl_size = 280, tv_size = 95, bv_size = 75;
2124   gchar               *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2125   dfilter_t           *rfcode = NULL;
2126   gboolean             rfilter_parse_failed = FALSE;
2127   e_prefs             *prefs_p;
2128   char                 badopt;
2129   GtkWidget           *splash_win = NULL;
2130   GLogLevelFlags       log_flags;
2131   guint                go_to_packet = 0;
2132   search_direction     jump_backwards = SD_FORWARD;
2133   dfilter_t           *jump_to_filter = NULL;
2134   int                  optind_initial;
2135   int                  status;
2136 #ifdef HAVE_GTKOSXAPPLICATION
2137   GtkosxApplication   *theApp;
2138 #endif
2139
2140 #ifdef HAVE_LIBPCAP
2141 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2142 #define OPTSTRING_B "B:"
2143 #else
2144 #define OPTSTRING_B ""
2145 #endif  /* _WIN32 or HAVE_PCAP_CREATE */
2146 #else /* HAVE_LIBPCAP */
2147 #define OPTSTRING_B ""
2148 #endif  /* HAVE_LIBPCAP */
2149 #ifdef HAVE_PCAP_REMOTE
2150 #define OPTSTRING_A "A:"
2151 #else
2152 #define OPTSTRING_A ""
2153 #endif
2154 #ifdef HAVE_PCAP_CREATE
2155 #define OPTSTRING_I "I"
2156 #else
2157 #define OPTSTRING_I ""
2158 #endif
2159
2160 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:Y:z:"
2161
2162   static const char optstring[] = OPTSTRING;
2163
2164
2165   /* Set the C-language locale to the native environment. */
2166   setlocale(LC_ALL, "");
2167 #ifdef _WIN32
2168   arg_list_utf_16to8(argc, argv);
2169   create_app_running_mutex();
2170 #endif /* _WIN32 */
2171
2172   /*
2173    * Get credential information for later use, and drop privileges
2174    * before doing anything else.
2175    * Let the user know if anything happened.
2176    */
2177   init_process_policies();
2178   relinquish_special_privs_perm();
2179
2180   /*
2181    * Attempt to get the pathname of the executable file.
2182    */
2183   init_progfile_dir_error = init_progfile_dir(argv[0], main);
2184
2185   /* initialize the funnel mini-api */
2186   initialize_funnel_ops();
2187
2188   AirPDcapInitContext(&airpdcap_ctx);
2189
2190 #ifdef _WIN32
2191   /* Load wpcap if possible. Do this before collecting the run-time version information */
2192   load_wpcap();
2193
2194   /* ... and also load the packet.dll from wpcap */
2195   wpcap_packet_load();
2196
2197 #ifdef HAVE_AIRPCAP
2198   /* Load the airpcap.dll.  This must also be done before collecting
2199    * run-time version information. */
2200   airpcap_dll_ret_val = load_airpcap();
2201
2202   switch (airpcap_dll_ret_val) {
2203   case AIRPCAP_DLL_OK:
2204     /* load the airpcap interfaces */
2205     airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2206
2207     if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2208       if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2209         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
2210         g_free(err_str);
2211       }
2212       airpcap_if_active = NULL;
2213
2214     } else {
2215
2216       /* select the first ad default (THIS SHOULD BE CHANGED) */
2217       airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2218     }
2219     break;
2220 #if 0
2221     /*
2222      * XXX - Maybe we need to warn the user if one of the following happens???
2223      */
2224     case AIRPCAP_DLL_OLD:
2225       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2226       break;
2227
2228     case AIRPCAP_DLL_ERROR:
2229       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2230       break;
2231
2232     case AIRPCAP_DLL_NOT_FOUND:
2233       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2234       break;
2235 #endif
2236   }
2237 #endif /* HAVE_AIRPCAP */
2238 #endif  /* _WIN32 */
2239
2240   /* Assemble the compile-time version information string */
2241   comp_info_str = g_string_new("Compiled ");
2242
2243   get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2244
2245   /* Assemble the run-time version information string */
2246   runtime_info_str = g_string_new("Running ");
2247   get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2248
2249 #ifdef _WIN32
2250   ws_add_crash_info(PACKAGE " " VERSION "%s\n"
2251          "\n"
2252          "%s"
2253          "\n"
2254          "%s",
2255       wireshark_svnversion, comp_info_str->str, runtime_info_str->str);
2256
2257   /* Start windows sockets */
2258   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2259 #endif  /* _WIN32 */
2260
2261   profile_store_persconffiles (TRUE);
2262
2263   /* Read the profile independent recent file.  We have to do this here so we can */
2264   /* set the profile before it can be set from the command line parameterts */
2265   recent_read_static(&rf_path, &rf_open_errno);
2266   if (rf_path != NULL && rf_open_errno != 0) {
2267     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2268                   "Could not open common recent file\n\"%s\": %s.",
2269                   rf_path, g_strerror(rf_open_errno));
2270   }
2271
2272   /* "pre-scan" the command line parameters, if we have "console only"
2273      parameters.  We do this so we don't start GTK+ if we're only showing
2274      command-line help or version information.
2275
2276      XXX - this pre-scan is done before we start GTK+, so we haven't
2277      run gtk_init() on the arguments.  That means that GTK+ arguments
2278      have not been removed from the argument list; those arguments
2279      begin with "--", and will be treated as an error by getopt().
2280
2281      We thus ignore errors - *and* set "opterr" to 0 to suppress the
2282      error messages. */
2283   opterr = 0;
2284   optind_initial = optind;
2285   while ((opt = getopt(argc, argv, optstring)) != -1) {
2286     switch (opt) {
2287       case 'C':        /* Configuration Profile */
2288         if (profile_exists (optarg, FALSE)) {
2289           set_profile_name (optarg);
2290         } else {
2291           cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2292           exit(1);
2293         }
2294         break;
2295       case 'D':        /* Print a list of capture devices and exit */
2296 #ifdef HAVE_LIBPCAP
2297         if_list = capture_interface_list(&err, &err_str,main_window_update);
2298         if (if_list == NULL) {
2299           switch (err) {
2300           case CANT_GET_INTERFACE_LIST:
2301           case DONT_HAVE_PCAP:
2302             cmdarg_err("%s", err_str);
2303             g_free(err_str);
2304             break;
2305
2306           case NO_INTERFACES_FOUND:
2307             cmdarg_err("There are no interfaces on which a capture can be done");
2308             break;
2309           }
2310           exit(2);
2311         }
2312 #ifdef _WIN32
2313         create_console();
2314 #endif /* _WIN32 */
2315         capture_opts_print_interfaces(if_list);
2316         free_interface_list(if_list);
2317 #ifdef _WIN32
2318         destroy_console();
2319 #endif /* _WIN32 */
2320         exit(0);
2321 #else /* HAVE_LIBPCAP */
2322         capture_option_specified = TRUE;
2323         arg_error = TRUE;
2324 #endif /* HAVE_LIBPCAP */
2325         break;
2326       case 'h':        /* Print help and exit */
2327         print_usage(TRUE);
2328         exit(0);
2329         break;
2330 #ifdef _WIN32
2331       case 'i':
2332         if (strcmp(optarg, "-") == 0)
2333           set_stdin_capture(TRUE);
2334         break;
2335 #endif
2336       case 'P':        /* Path settings - change these before the Preferences and alike are processed */
2337         status = filesystem_opt(opt, optarg);
2338         if(status != 0) {
2339             cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2340             exit(status);
2341         }
2342         break;
2343       case 'v':        /* Show version and exit */
2344 #ifdef _WIN32
2345         create_console();
2346 #endif
2347         show_version();
2348 #ifdef _WIN32
2349         destroy_console();
2350 #endif
2351         exit(0);
2352         break;
2353       case 'X':
2354         /*
2355          *  Extension command line options have to be processed before
2356          *  we call epan_init() as they are supposed to be used by dissectors
2357          *  or taps very early in the registration process.
2358          */
2359         ex_opt_add(optarg);
2360         break;
2361       case '?':        /* Ignore errors - the "real" scan will catch them. */
2362         break;
2363     }
2364   }
2365
2366   /* Init the "Open file" dialog directory */
2367   /* (do this after the path settings are processed) */
2368
2369   /* Read the profile dependent (static part) of the recent file. */
2370   /* Only the static part of it will be read, as we don't have the gui now to fill the */
2371   /* recent lists which is done in the dynamic part. */
2372   /* We have to do this already here, so command line parameters can overwrite these values. */
2373   recent_read_profile_static(&rf_path, &rf_open_errno);
2374   if (rf_path != NULL && rf_open_errno != 0) {
2375     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2376                   "Could not open recent file\n\"%s\": %s.",
2377                   rf_path, g_strerror(rf_open_errno));
2378   }
2379
2380   if (recent.gui_fileopen_remembered_dir &&
2381       test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2382     set_last_open_dir(recent.gui_fileopen_remembered_dir);
2383   } else {
2384     set_last_open_dir(get_persdatafile_dir());
2385   }
2386
2387   /* Set getopt index back to initial value, so it will start with the
2388      first command line parameter again.  Also reset opterr to 1, so that
2389      error messages are printed by getopt().
2390
2391      XXX - this seems to work on most platforms, but time will tell.
2392      The Single UNIX Specification says "The getopt() function need
2393      not be reentrant", so this isn't guaranteed to work.  The Mac
2394      OS X 10.4[.x] getopt() man page says
2395
2396        In order to use getopt() to evaluate multiple sets of arguments, or to
2397        evaluate a single set of arguments multiple times, the variable optreset
2398        must be set to 1 before the second and each additional set of calls to
2399        getopt(), and the variable optind must be reinitialized.
2400
2401            ...
2402
2403        The optreset variable was added to make it possible to call the getopt()
2404        function multiple times.  This is an extension to the IEEE Std 1003.2
2405        (``POSIX.2'') specification.
2406
2407      which I think comes from one of the other BSDs.
2408
2409      XXX - if we want to control all the command-line option errors, so
2410      that we can display them where we choose (e.g., in a window), we'd
2411      want to leave opterr as 0, and produce our own messages using optopt.
2412      We'd have to check the value of optopt to see if it's a valid option
2413      letter, in which case *presumably* the error is "this option requires
2414      an argument but none was specified", or not a valid option letter,
2415      in which case *presumably* the error is "this option isn't valid".
2416      Some versions of getopt() let you supply a option string beginning
2417      with ':', which means that getopt() will return ':' rather than '?'
2418      for "this option requires an argument but none was specified", but
2419      not all do. */
2420   optind = optind_initial;
2421   opterr = 1;
2422
2423 #if !GLIB_CHECK_VERSION(2,31,0)
2424   g_thread_init(NULL);
2425 #endif
2426
2427   /* Set the current locale according to the program environment.
2428    * We haven't localized anything, but some GTK widgets are localized
2429    * (the file selection dialogue, for example).
2430    * This also sets the C-language locale to the native environment. */
2431   setlocale (LC_ALL, "");
2432
2433   /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2434   gtk_init (&argc, &argv);
2435
2436   cf_callback_add(main_cf_callback, NULL);
2437 #ifdef HAVE_LIBPCAP
2438   capture_callback_add(main_capture_callback, NULL);
2439 #endif
2440   cf_callback_add(statusbar_cf_callback, NULL);
2441 #ifdef HAVE_LIBPCAP
2442   capture_callback_add(statusbar_capture_callback, NULL);
2443 #endif
2444
2445   /* Arrange that if we have no console window, and a GLib message logging
2446      routine is called to log a message, we pop up a console window.
2447
2448      We do that by inserting our own handler for all messages logged
2449      to the default domain; that handler pops up a console if necessary,
2450      and then calls the default handler. */
2451
2452   /* We might want to have component specific log levels later ... */
2453
2454   log_flags = (GLogLevelFlags)
2455             (G_LOG_LEVEL_ERROR|
2456             G_LOG_LEVEL_CRITICAL|
2457             G_LOG_LEVEL_WARNING|
2458             G_LOG_LEVEL_MESSAGE|
2459             G_LOG_LEVEL_INFO|
2460             G_LOG_LEVEL_DEBUG|
2461             G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION);
2462
2463   g_log_set_handler(NULL,
2464             log_flags,
2465             console_log_handler, NULL /* user_data */);
2466   g_log_set_handler(LOG_DOMAIN_MAIN,
2467             log_flags,
2468             console_log_handler, NULL /* user_data */);
2469
2470 #ifdef HAVE_LIBPCAP
2471   g_log_set_handler(LOG_DOMAIN_CAPTURE,
2472             log_flags,
2473             console_log_handler, NULL /* user_data */);
2474   g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2475             log_flags,
2476             console_log_handler, NULL /* user_data */);
2477
2478   /* Set the initial values in the capture options. This might be overwritten
2479      by preference settings and then again by the command line parameters. */
2480   capture_opts_init(&global_capture_opts);
2481
2482   capture_session_init(&global_capture_session, (void *)&cfile);
2483 #endif
2484
2485   /* Initialize whatever we need to allocate colors for GTK+ */
2486   colors_init();
2487
2488   /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2489   filter = get_conn_cfilter();
2490   if ( *filter != '\0' ) {
2491     info_update_freq = 1000;  /* Milliseconds */
2492   }
2493
2494   /* We won't come till here, if we had a "console only" command line parameter. */
2495   splash_win = splash_new("Loading Wireshark ...");
2496   if (init_progfile_dir_error != NULL) {
2497     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2498         "Can't get pathname of Wireshark: %s.\n"
2499         "It won't be possible to capture traffic.\n"
2500         "Report this to the Wireshark developers.",
2501         init_progfile_dir_error);
2502     g_free(init_progfile_dir_error);
2503   }
2504
2505   splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2506
2507   /* Register all dissectors; we must do this before checking for the
2508      "-G" flag, as the "-G" flag dumps information registered by the
2509      dissectors, and we must do it before we read the preferences, in
2510      case any dissectors register preferences. */
2511   epan_init(register_all_protocols,register_all_protocol_handoffs,
2512             splash_update, (gpointer) splash_win,
2513             failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2514             write_failure_alert_box);
2515
2516   splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2517
2518   /* Register all tap listeners; we do this before we parse the arguments,
2519      as the "-z" argument can specify a registered tap. */
2520
2521   /* we register the plugin taps before the other taps because
2522      stats_tree taps plugins will be registered as tap listeners
2523      by stats_tree_stat.c and need to registered before that */
2524
2525 #ifdef HAVE_PLUGINS
2526   register_all_plugin_tap_listeners();
2527 #endif
2528
2529   register_all_tap_listeners();
2530
2531   splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2532
2533   prefs_p = read_configuration_files (&gdp_path, &dp_path);
2534   /* Removed thread code:
2535    * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2536    */
2537
2538   /* this is to keep tap extensions updating once every 3 seconds */
2539   tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2540
2541   splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2542   proto_help_init();
2543   cap_file_init(&cfile);
2544
2545   /* Fill in capture options with values from the preferences */
2546   prefs_to_capture_opts();
2547
2548 /*#ifdef HAVE_LIBPCAP
2549   fill_in_local_interfaces();
2550 #endif*/
2551   /* Now get our args */
2552   while ((opt = getopt(argc, argv, optstring)) != -1) {
2553     switch (opt) {
2554       /*** capture option specific ***/
2555       case 'a':        /* autostop criteria */
2556       case 'b':        /* Ringbuffer option */
2557       case 'c':        /* Capture xxx packets */
2558       case 'f':        /* capture filter */
2559       case 'k':        /* Start capture immediately */
2560       case 'H':        /* Hide capture info dialog box */
2561       case 'p':        /* Don't capture in promiscuous mode */
2562       case 'i':        /* Use interface x */
2563 #ifdef HAVE_PCAP_CREATE
2564       case 'I':        /* Capture in monitor mode, if available */
2565 #endif
2566 #ifdef HAVE_PCAP_REMOTE
2567       case 'A':        /* Authentication */
2568 #endif
2569       case 's':        /* Set the snapshot (capture) length */
2570       case 'S':        /* "Sync" mode: used for following file ala tail -f */
2571       case 'w':        /* Write to capture file xxx */
2572       case 'y':        /* Set the pcap data link type */
2573 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2574       case 'B':        /* Buffer size */
2575 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2576 #ifdef HAVE_LIBPCAP
2577         status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2578                                       &start_capture);
2579         if(status != 0) {
2580             exit(status);
2581         }
2582 #else
2583         capture_option_specified = TRUE;
2584         arg_error = TRUE;
2585 #endif
2586         break;
2587
2588 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2589       case 'K':        /* Kerberos keytab file */
2590         read_keytab_file(optarg);
2591         break;
2592 #endif
2593
2594       /*** all non capture option specific ***/
2595       case 'C':
2596         /* Configuration profile settings were already processed just ignore them this time*/
2597         break;
2598       case 'j':        /* Search backwards for a matching packet from filter in option J */
2599         jump_backwards = SD_BACKWARD;
2600         break;
2601       case 'g':        /* Go to packet with the given packet number */
2602         go_to_packet = get_positive_int(optarg, "go to packet");
2603         break;
2604       case 'J':        /* Jump to the first packet which matches the filter criteria */
2605         jfilter = optarg;
2606         break;
2607       case 'l':        /* Automatic scrolling in live capture mode */
2608 #ifdef HAVE_LIBPCAP
2609         auto_scroll_live = TRUE;
2610 #else
2611         capture_option_specified = TRUE;
2612         arg_error = TRUE;
2613 #endif
2614         break;
2615       case 'L':        /* Print list of link-layer types and exit */
2616 #ifdef HAVE_LIBPCAP
2617         list_link_layer_types = TRUE;
2618 #else
2619         capture_option_specified = TRUE;
2620         arg_error = TRUE;
2621 #endif
2622         break;
2623       case 'm':        /* Fixed-width font for the display */
2624         g_free(prefs_p->gui_gtk2_font_name);
2625         prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2626         break;
2627       case 'n':        /* No name resolution */
2628         gbl_resolv_flags.mac_name = FALSE;
2629         gbl_resolv_flags.network_name = FALSE;
2630         gbl_resolv_flags.transport_name = FALSE;
2631         gbl_resolv_flags.concurrent_dns = FALSE;
2632         break;
2633       case 'N':        /* Select what types of addresses/port #s to resolve */
2634         badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2635         if (badopt != '\0') {
2636           cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2637             badopt);
2638           exit(1);
2639         }
2640         break;
2641       case 'o':        /* Override preference from command line */
2642         switch (prefs_set_pref(optarg)) {
2643         case PREFS_SET_OK:
2644           break;
2645         case PREFS_SET_SYNTAX_ERR:
2646           cmdarg_err("Invalid -o flag \"%s\"", optarg);
2647           exit(1);
2648           break;
2649         case PREFS_SET_NO_SUCH_PREF:
2650           /* not a preference, might be a recent setting */
2651           switch (recent_set_arg(optarg)) {
2652             case PREFS_SET_OK:
2653               break;
2654             case PREFS_SET_SYNTAX_ERR:
2655               /* shouldn't happen, checked already above */
2656               cmdarg_err("Invalid -o flag \"%s\"", optarg);
2657               exit(1);
2658               break;
2659             case PREFS_SET_NO_SUCH_PREF:
2660             case PREFS_SET_OBSOLETE:
2661               cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2662                 optarg);
2663               exit(1);
2664               break;
2665             default:
2666               g_assert_not_reached();
2667             }
2668           break;
2669         case PREFS_SET_OBSOLETE:
2670           cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2671             optarg);
2672           exit(1);
2673           break;
2674         default:
2675           g_assert_not_reached();
2676         }
2677         break;
2678       case 'P':
2679         /* Path settings were already processed just ignore them this time*/
2680         break;
2681       case 'r':        /* Read capture file xxx */
2682         /* We may set "last_open_dir" to "cf_name", and if we change
2683         "last_open_dir" later, we free the old value, so we have to
2684         set "cf_name" to something that's been allocated. */
2685         cf_name = g_strdup(optarg);
2686         break;
2687       case 'R':        /* Read file filter */
2688         rfilter = optarg;
2689         break;
2690       case 't':        /* Time stamp type */
2691         if (strcmp(optarg, "r") == 0)
2692           timestamp_set_type(TS_RELATIVE);
2693         else if (strcmp(optarg, "a") == 0)
2694           timestamp_set_type(TS_ABSOLUTE);
2695         else if (strcmp(optarg, "ad") == 0)
2696           timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2697         else if (strcmp(optarg, "d") == 0)
2698           timestamp_set_type(TS_DELTA);
2699         else if (strcmp(optarg, "dd") == 0)
2700           timestamp_set_type(TS_DELTA_DIS);
2701         else if (strcmp(optarg, "e") == 0)
2702           timestamp_set_type(TS_EPOCH);
2703         else if (strcmp(optarg, "u") == 0)
2704           timestamp_set_type(TS_UTC);
2705         else if (strcmp(optarg, "ud") == 0)
2706           timestamp_set_type(TS_UTC_WITH_DATE);
2707         else {
2708           cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2709           cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with date, \"d\" for delta,");
2710           cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative, \"u\" for UTC, ");
2711           cmdarg_err_cont("or \"ud\" for UTC with date.");
2712           exit(1);
2713         }
2714         break;
2715       case 'u':        /* Seconds type */
2716         if (strcmp(optarg, "s") == 0)
2717           timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2718         else if (strcmp(optarg, "hms") == 0)
2719           timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2720         else {
2721           cmdarg_err("Invalid seconds type \"%s\"", optarg);
2722           cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2723           exit(1);
2724         }
2725         break;
2726       case 'X':
2727           /* ext ops were already processed just ignore them this time*/
2728           break;
2729       case 'Y':
2730         dfilter = optarg;
2731         break;
2732       case 'z':
2733         /* We won't call the init function for the stat this soon
2734            as it would disallow MATE's fields (which are registered
2735            by the preferences set callback) from being used as
2736            part of a tap filter.  Instead, we just add the argument
2737            to a list of stat arguments. */
2738         if (!process_stat_cmd_arg(optarg)) {
2739           cmdarg_err("Invalid -z argument.");
2740           cmdarg_err_cont("  -z argument must be one of :");
2741           list_stat_cmd_args();
2742           exit(1);
2743         }
2744         break;
2745       default:
2746       case '?':        /* Bad flag - print usage message */
2747         arg_error = TRUE;
2748         break;
2749     }
2750   }
2751   if (!arg_error) {
2752     argc -= optind;
2753     argv += optind;
2754     if (argc >= 1) {
2755       if (cf_name != NULL) {
2756         /*
2757          * Input file name specified with "-r" *and* specified as a regular
2758          * command-line argument.
2759          */
2760         cmdarg_err("File name specified both with -r and regular argument");
2761         arg_error = TRUE;
2762       } else {
2763         /*
2764          * Input file name not specified with "-r", and a command-line argument
2765          * was specified; treat it as the input file name.
2766          *
2767          * Yes, this is different from tshark, where non-flag command-line
2768          * arguments are a filter, but this works better on GUI desktops
2769          * where a command can be specified to be run to open a particular
2770          * file - yes, you could have "-r" as the last part of the command,
2771          * but that's a bit ugly.
2772          */
2773 #ifndef HAVE_GTKOSXAPPLICATION
2774         /*
2775          * For GTK+ Mac Integration, file name passed as free argument passed
2776          * through grag-and-drop and opened twice sometimes causing crashes.
2777          * Subject to report to GTK+ MAC.
2778          */
2779         cf_name = g_strdup(argv[0]);
2780 #endif
2781       }
2782       argc--;
2783       argv++;
2784     }
2785
2786     if (argc != 0) {
2787       /*
2788        * Extra command line arguments were specified; complain.
2789        */
2790       cmdarg_err("Invalid argument: %s", argv[0]);
2791       arg_error = TRUE;
2792     }
2793   }
2794   if (arg_error) {
2795 #ifndef HAVE_LIBPCAP
2796     if (capture_option_specified) {
2797       cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2798     }
2799 #endif
2800     print_usage(FALSE);
2801     exit(1);
2802   }
2803
2804 #ifdef HAVE_LIBPCAP
2805   fill_in_local_interfaces(main_window_update);
2806   if (start_capture && list_link_layer_types) {
2807     /* Specifying *both* is bogus. */
2808     cmdarg_err("You can't specify both -L and a live capture.");
2809     exit(1);
2810   }
2811
2812   if (list_link_layer_types) {
2813     /* We're supposed to list the link-layer types for an interface;
2814        did the user also specify a capture file to be read? */
2815     if (cf_name) {
2816       /* Yes - that's bogus. */
2817       cmdarg_err("You can't specify -L and a capture file to be read.");
2818       exit(1);
2819     }
2820     /* No - did they specify a ring buffer option? */
2821     if (global_capture_opts.multi_files_on) {
2822       cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2823       exit(1);
2824     }
2825   } else {
2826     /* We're supposed to do a live capture; did the user also specify
2827        a capture file to be read? */
2828     if (start_capture && cf_name) {
2829       /* Yes - that's bogus. */
2830       cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2831       exit(1);
2832     }
2833
2834     /* No - was the ring buffer option specified and, if so, does it make
2835        sense? */
2836     if (global_capture_opts.multi_files_on) {
2837       /* Ring buffer works only under certain conditions:
2838       a) ring buffer does not work with temporary files;
2839       b) real_time_mode and multi_files_on are mutually exclusive -
2840          real_time_mode takes precedence;
2841       c) it makes no sense to enable the ring buffer if the maximum
2842          file size is set to "infinite". */
2843       if (global_capture_opts.save_file == NULL) {
2844         cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2845         global_capture_opts.multi_files_on = FALSE;
2846       }
2847       if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2848         cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2849         /* XXX - this must be redesigned as the conditions changed */
2850       }
2851     }
2852   }
2853
2854   if (start_capture || list_link_layer_types) {
2855     /* We're supposed to do a live capture or get a list of link-layer
2856        types for a live capture device; if the user didn't specify an
2857        interface to use, pick a default. */
2858     status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2859         ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2860     if (status != 0) {
2861       exit(status);
2862     }
2863   }
2864
2865   if (list_link_layer_types) {
2866     /* Get the list of link-layer types for the capture devices. */
2867     if_capabilities_t *caps;
2868     guint i;
2869     interface_t device;
2870     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2871
2872       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2873       if (device.selected) {
2874 #if defined(HAVE_PCAP_CREATE)
2875         caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str, main_window_update);
2876 #else
2877         caps = capture_get_if_capabilities(device.name, FALSE, &err_str,main_window_update);
2878 #endif
2879         if (caps == NULL) {
2880           cmdarg_err("%s", err_str);
2881           g_free(err_str);
2882           exit(2);
2883         }
2884         if (caps->data_link_types == NULL) {
2885           cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2886           exit(2);
2887         }
2888 #ifdef _WIN32
2889         create_console();
2890 #endif /* _WIN32 */
2891 #if defined(HAVE_PCAP_CREATE)
2892         capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2893 #else
2894         capture_opts_print_if_capabilities(caps, device.name, FALSE);
2895 #endif
2896 #ifdef _WIN32
2897         destroy_console();
2898 #endif /* _WIN32 */
2899         free_if_capabilities(caps);
2900       }
2901     }
2902     exit(0);
2903   }
2904
2905   capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2906   capture_opts_trim_ring_num_files(&global_capture_opts);
2907 #endif /* HAVE_LIBPCAP */
2908
2909   /* Notify all registered modules that have had any of their preferences
2910      changed either from one of the preferences file or from the command
2911      line that their preferences have changed. */
2912   prefs_apply_all();
2913
2914 #ifdef HAVE_LIBPCAP
2915   if ((global_capture_opts.num_selected == 0) &&
2916       ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2917     guint i;
2918     interface_t device;
2919     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2920       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2921       if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2922         device.selected = TRUE;
2923         global_capture_opts.num_selected++;
2924         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2925         g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2926         break;
2927       }
2928     }
2929   }
2930   if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
2931     interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
2932     device.selected = TRUE;
2933     global_capture_opts.num_selected++;
2934     global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
2935     g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
2936   }
2937 #endif
2938
2939   /* disabled protocols as per configuration file */
2940   if (gdp_path == NULL && dp_path == NULL) {
2941     set_disabled_protos_list();
2942   }
2943
2944   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2945
2946   /* read in rc file from global and personal configuration paths. */
2947   rc_file = get_datafile_path(RC_FILE);
2948 #if GTK_CHECK_VERSION(3,0,0)
2949   /* XXX resolve later */
2950 #else
2951   gtk_rc_parse(rc_file);
2952   g_free(rc_file);
2953   rc_file = get_persconffile_path(RC_FILE, FALSE);
2954   gtk_rc_parse(rc_file);
2955 #endif
2956   g_free(rc_file);
2957
2958   font_init();
2959
2960   macros_init();
2961
2962   stock_icons_init();
2963
2964   /* close the splash screen, as we are going to open the main window now */
2965   splash_destroy(splash_win);
2966
2967   /************************************************************************/
2968   /* Everything is prepared now, preferences and command line was read in */
2969
2970   /* Pop up the main window. */
2971   create_main_window(pl_size, tv_size, bv_size, prefs_p);
2972
2973   /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2974   recent_read_dynamic(&rf_path, &rf_open_errno);
2975   if (rf_path != NULL && rf_open_errno != 0) {
2976     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2977           "Could not open recent file\n\"%s\": %s.",
2978           rf_path, g_strerror(rf_open_errno));
2979   }
2980
2981   color_filters_enable(recent.packet_list_colorize);
2982
2983   /* rearrange all the widgets as we now have all recent settings ready for this */
2984   main_widgets_rearrange();
2985
2986   /* Fill in column titles.  This must be done after the top level window
2987      is displayed.
2988
2989      XXX - is that still true, with fixed-width columns? */
2990
2991   menu_recent_read_finished();
2992 #ifdef HAVE_LIBPCAP
2993   main_auto_scroll_live_changed(auto_scroll_live);
2994 #endif
2995
2996   switch (user_font_apply()) {
2997   case FA_SUCCESS:
2998       break;
2999   case FA_FONT_NOT_RESIZEABLE:
3000       /* "user_font_apply()" popped up an alert box. */
3001       /* turn off zooming - font can't be resized */
3002   case FA_FONT_NOT_AVAILABLE:
3003       /* XXX - did we successfully load the un-zoomed version earlier?
3004       If so, this *probably* means the font is available, but not at
3005       this particular zoom level, but perhaps some other failure
3006       occurred; I'm not sure you can determine which is the case,
3007       however. */
3008       /* turn off zooming - zoom level is unavailable */
3009   default:
3010       /* in any other case than FA_SUCCESS, turn off zooming */
3011       recent.gui_zoom_level = 0;
3012       /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3013   }
3014
3015   dnd_init(top_level);
3016
3017   color_filters_init();
3018   decode_as_init();
3019 #ifdef HAVE_LIBPCAP
3020   capture_filter_init();
3021 #endif
3022
3023   /* the window can be sized only, if it's not already shown, so do it now! */
3024   main_load_window_geometry(top_level);
3025
3026   g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3027
3028   /* If we were given the name of a capture file, read it in now;
3029      we defer it until now, so that, if we can't open it, and pop
3030      up an alert box, the alert box is more likely to come up on
3031      top of the main window - but before the preference-file-error
3032      alert box, so, if we get one of those, it's more likely to come
3033      up on top of us. */
3034   if (cf_name) {
3035     show_main_window(TRUE);
3036     check_and_warn_user_startup(cf_name);
3037     if (rfilter != NULL) {
3038       if (!dfilter_compile(rfilter, &rfcode)) {
3039         bad_dfilter_alert_box(top_level, rfilter);
3040         rfilter_parse_failed = TRUE;
3041       }
3042     }
3043     if (!rfilter_parse_failed) {
3044       if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3045         /* "cf_open()" succeeded, so it closed the previous
3046            capture file, and thus destroyed any previous read filter
3047            attached to "cf". */
3048
3049         cfile.rfcode = rfcode;
3050         /* Open stat windows; we do so after creating the main window,
3051            to avoid GTK warnings, and after successfully opening the
3052            capture file, so we know we have something to compute stats
3053            on, and after registering all dissectors, so that MATE will
3054            have registered its field array and we can have a tap filter
3055            with one of MATE's late-registered fields as part of the
3056            filter. */
3057         start_requested_stats();
3058
3059         /* Read the capture file. */
3060         switch (cf_read(&cfile, FALSE)) {
3061
3062         case CF_READ_OK:
3063         case CF_READ_ERROR:
3064           /* Just because we got an error, that doesn't mean we were unable
3065              to read any of the file; we handle what we could get from the
3066              file. */
3067           /* if the user told us to jump to a specific packet, do it now */
3068           if(go_to_packet != 0) {
3069             /* Jump to the specified frame number, kept for backward
3070                compatibility. */
3071             cf_goto_frame(&cfile, go_to_packet);
3072           } else if (jfilter != NULL) {
3073             /* try to compile given filter */
3074             if (!dfilter_compile(jfilter, &jump_to_filter)) {
3075               bad_dfilter_alert_box(top_level, jfilter);
3076             } else {
3077               /* Filter ok, jump to the first packet matching the filter
3078                  conditions. Default search direction is forward, but if
3079                  option d was given, search backwards */
3080               cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3081             }
3082           }
3083           break;
3084
3085         case CF_READ_ABORTED:
3086           /* Exit now. */
3087           exit(0);
3088           break;
3089         }
3090
3091         /* If the filename is not the absolute path, prepend the current dir. This happens
3092            when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3093         if (!g_path_is_absolute(cf_name)) {
3094           char *old_cf_name = cf_name;
3095           char *pwd = g_get_current_dir();
3096           cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3097           g_free(old_cf_name);
3098           g_free(pwd);
3099         }
3100
3101         /* Save the name of the containing directory specified in the
3102            path name, if any; we can write over cf_name, which is a
3103            good thing, given that "get_dirname()" does write over its
3104            argument. */
3105         s = get_dirname(cf_name);
3106         set_last_open_dir(s);
3107         g_free(cf_name);
3108         cf_name = NULL;
3109       } else {
3110         if (rfcode != NULL)
3111           dfilter_free(rfcode);
3112         cfile.rfcode = NULL;
3113         show_main_window(FALSE);
3114         /* Don't call check_and_warn_user_startup(): we did it above */
3115         main_set_for_capture_in_progress(FALSE);
3116         set_capture_if_dialog_for_capture_in_progress(FALSE);
3117       }
3118     }
3119   } else {
3120 #ifdef HAVE_LIBPCAP
3121     if (start_capture) {
3122       if (global_capture_opts.save_file != NULL) {
3123         /* Save the directory name for future file dialogs. */
3124         /* (get_dirname overwrites filename) */
3125         s = get_dirname(g_strdup(global_capture_opts.save_file));
3126         set_last_open_dir(s);
3127         g_free(s);
3128       }
3129       /* "-k" was specified; start a capture. */
3130       show_main_window(FALSE);
3131       check_and_warn_user_startup(cf_name);
3132
3133       /* If no user interfaces were specified on the command line,
3134          copy the list of selected interfaces to the set of interfaces
3135          to use for this capture. */
3136       if (global_capture_opts.ifaces->len == 0)
3137         collect_ifaces(&global_capture_opts);
3138       if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3139         /* The capture started.  Open stat windows; we do so after creating
3140            the main window, to avoid GTK warnings, and after successfully
3141            opening the capture file, so we know we have something to compute
3142            stats on, and after registering all dissectors, so that MATE will
3143            have registered its field array and we can have a tap filter with
3144            one of MATE's late-registered fields as part of the filter. */
3145         start_requested_stats();
3146       }
3147     } else {
3148       show_main_window(FALSE);
3149       check_and_warn_user_startup(cf_name);
3150       main_set_for_capture_in_progress(FALSE);
3151       set_capture_if_dialog_for_capture_in_progress(FALSE);
3152     }
3153
3154     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3155     if (!start_capture && !global_capture_opts.default_options.cfilter) {
3156       global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3157     }
3158 #else /* HAVE_LIBPCAP */
3159     show_main_window(FALSE);
3160     check_and_warn_user_startup(cf_name);
3161     main_set_for_capture_in_progress(FALSE);
3162     set_capture_if_dialog_for_capture_in_progress(FALSE);
3163 #endif /* HAVE_LIBPCAP */
3164   }
3165
3166   if (dfilter) {
3167     GtkWidget *filter_te;
3168     filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3169     gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3170
3171     /* Run the display filter so it goes in effect. */
3172     main_filter_packets(&cfile, dfilter, FALSE);
3173   }
3174
3175
3176   /* register our pid if we are being run from a U3 device */
3177   u3_register_pid();
3178
3179   profile_store_persconffiles (FALSE);
3180
3181 #ifdef HAVE_GTKOSXAPPLICATION
3182   theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3183   gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3184   gtkosx_application_ready(theApp);
3185 #endif
3186
3187   g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3188
3189 #ifdef HAVE_LIBPCAP
3190   gtk_iface_mon_start();
3191 #endif
3192
3193   software_update_init();
3194
3195   /* we'll enter the GTK loop now and hand the control over to GTK ... */
3196   gtk_main();
3197   /* ... back from GTK, we're going down now! */
3198
3199 #ifdef HAVE_LIBPCAP
3200   gtk_iface_mon_stop();
3201 #endif
3202
3203   /* deregister our pid */
3204   u3_deregister_pid();
3205
3206   epan_cleanup();
3207
3208   AirPDcapDestroyContext(&airpdcap_ctx);
3209
3210 #ifdef _WIN32
3211   /* hide the (unresponsive) main window, while asking the user to close the console window */
3212   gtk_widget_hide(top_level);
3213
3214 #ifdef HAVE_GTKOSXAPPLICATION
3215   g_object_unref(theApp);
3216 #endif
3217
3218   software_update_cleanup();
3219
3220   /* Shutdown windows sockets */
3221   WSACleanup();
3222
3223   /* For some unknown reason, the "atexit()" call in "create_console()"
3224      doesn't arrange that "destroy_console()" be called when we exit,
3225      so we call it here if a console was created. */
3226   destroy_console();
3227 #endif
3228
3229   exit(0);
3230 }
3231
3232 #ifdef _WIN32
3233
3234 /* We build this as a GUI subsystem application on Win32, so
3235    "WinMain()", not "main()", gets called.
3236
3237    Hack shamelessly stolen from the Win32 port of the GIMP. */
3238 #ifdef __GNUC__
3239 #define _stdcall  __attribute__((stdcall))
3240 #endif
3241
3242 int _stdcall
3243 WinMain (struct HINSTANCE__ *hInstance,
3244          struct HINSTANCE__ *hPrevInstance,
3245          char               *lpszCmdLine,
3246          int                 nCmdShow)
3247 {
3248   INITCOMMONCONTROLSEX comm_ctrl;
3249
3250   /*
3251    * Initialize our DLL search path. MUST be called before LoadLibrary
3252    * or g_module_open.
3253    */
3254   ws_init_dll_search_path();
3255
3256   /* Initialize our controls. Required for native Windows file dialogs. */
3257   memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3258   comm_ctrl.dwSize = sizeof(comm_ctrl);
3259   /* Includes the animate, header, hot key, list view, progress bar,
3260    * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3261    * up-down controls
3262    */
3263   comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3264   InitCommonControlsEx(&comm_ctrl);
3265
3266   /* RichEd20.DLL is needed for filter entries. */
3267   ws_load_library("riched20.dll");
3268
3269   set_has_console(FALSE);
3270   set_console_wait(FALSE);
3271   return main (__argc, __argv);
3272 }
3273
3274 #endif /* _WIN32 */
3275
3276
3277 static void
3278 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3279                     const char *message, gpointer user_data _U_)
3280 {
3281   time_t curr;
3282   struct tm *today;
3283   const char *level;
3284
3285
3286   /* ignore log message, if log_level isn't interesting based
3287      upon the console log preferences.
3288      If the preferences haven't been loaded loaded yet, display the
3289      message anyway.
3290
3291      The default console_log_level preference value is such that only
3292        ERROR, CRITICAL and WARNING level messages are processed;
3293        MESSAGE, INFO and DEBUG level messages are ignored.  */
3294   if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3295      prefs.console_log_level != 0) {
3296     return;
3297   }
3298
3299 #ifdef _WIN32
3300   if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3301     /* the user wants a console or the application will terminate immediately */
3302     create_console();
3303   }
3304   if (get_has_console()) {
3305     /* For some unknown reason, the above doesn't appear to actually cause
3306        anything to be sent to the standard output, so we'll just splat the
3307        message out directly, just to make sure it gets out. */
3308 #endif
3309     switch(log_level & G_LOG_LEVEL_MASK) {
3310     case G_LOG_LEVEL_ERROR:
3311         level = "Err ";
3312         break;
3313     case G_LOG_LEVEL_CRITICAL:
3314         level = "Crit";
3315         break;
3316     case G_LOG_LEVEL_WARNING:
3317         level = "Warn";
3318         break;
3319     case G_LOG_LEVEL_MESSAGE:
3320         level = "Msg ";
3321         break;
3322     case G_LOG_LEVEL_INFO:
3323         level = "Info";
3324         break;
3325     case G_LOG_LEVEL_DEBUG:
3326         level = "Dbg ";
3327         break;
3328     default:
3329         fprintf(stderr, "unknown log_level %u\n", log_level);
3330         level = NULL;
3331         g_assert_not_reached();
3332     }
3333
3334     /* create a "timestamp" */
3335     time(&curr);
3336     today = localtime(&curr);
3337
3338     fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3339             today->tm_hour, today->tm_min, today->tm_sec,
3340             log_domain != NULL ? log_domain : "",
3341             level, message);
3342 #ifdef _WIN32
3343     if(log_level & G_LOG_LEVEL_ERROR) {
3344         /* wait for a key press before the following error handler will terminate the program
3345            this way the user at least can read the error message */
3346         printf("\n\nPress any key to exit\n");
3347         _getch();
3348     }
3349   } else {
3350     /* XXX - on UN*X, should we just use g_log_default_handler()?
3351        We want the error messages to go to the standard output;
3352        on Mac OS X, that will cause them to show up in various
3353        per-user logs accessible through Console (details depend
3354        on whether you're running 10.0 through 10.4 or running
3355        10.5 and later), and, on other UN*X desktop environments,
3356        if they don't show up in some form of console log, that's
3357        a deficiency in that desktop environment.  (Too bad
3358        Windows doesn't set the standard output and error for
3359        GUI apps to something that shows up in such a log.) */
3360     g_log_default_handler(log_domain, log_level, message, user_data);
3361   }
3362 #endif
3363 }
3364
3365
3366 /*
3367  * Helper for main_widgets_rearrange()
3368  */
3369 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3370     gtk_container_remove(GTK_CONTAINER(data), widget);
3371 }
3372
3373 static GtkWidget *main_widget_layout(gint layout_content)
3374 {
3375     switch(layout_content) {
3376     case(layout_pane_content_none):
3377         return NULL;
3378     case(layout_pane_content_plist):
3379         return pkt_scrollw;
3380     case(layout_pane_content_pdetails):
3381         return tv_scrollw;
3382     case(layout_pane_content_pbytes):
3383         return byte_nb_ptr_gbl;
3384     default:
3385         g_assert_not_reached();
3386         return NULL;
3387     }
3388 }
3389
3390
3391 /*
3392  * Rearrange the main window widgets
3393  */
3394 void main_widgets_rearrange(void) {
3395     GtkWidget *first_pane_widget1, *first_pane_widget2;
3396     GtkWidget *second_pane_widget1, *second_pane_widget2;
3397     gboolean split_top_left = FALSE;
3398
3399     /* be a bit faster */
3400     gtk_widget_hide(main_vbox);
3401
3402     /* be sure we don't lose a widget while rearranging */
3403     g_object_ref(G_OBJECT(menubar));
3404     g_object_ref(G_OBJECT(main_tb));
3405     g_object_ref(G_OBJECT(filter_tb));
3406     g_object_ref(G_OBJECT(wireless_tb));
3407     g_object_ref(G_OBJECT(pkt_scrollw));
3408     g_object_ref(G_OBJECT(tv_scrollw));
3409     g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3410     g_object_ref(G_OBJECT(statusbar));
3411     g_object_ref(G_OBJECT(main_pane_v1));
3412     g_object_ref(G_OBJECT(main_pane_v2));
3413     g_object_ref(G_OBJECT(main_pane_h1));
3414     g_object_ref(G_OBJECT(main_pane_h2));
3415     g_object_ref(G_OBJECT(welcome_pane));
3416
3417     /* empty all containers participating */
3418     gtk_container_foreach(GTK_CONTAINER(main_vbox),     foreach_remove_a_child, main_vbox);
3419     gtk_container_foreach(GTK_CONTAINER(main_pane_v1),  foreach_remove_a_child, main_pane_v1);
3420     gtk_container_foreach(GTK_CONTAINER(main_pane_v2),  foreach_remove_a_child, main_pane_v2);
3421     gtk_container_foreach(GTK_CONTAINER(main_pane_h1),  foreach_remove_a_child, main_pane_h1);
3422     gtk_container_foreach(GTK_CONTAINER(main_pane_h2),  foreach_remove_a_child, main_pane_h2);
3423
3424     statusbar_widgets_emptying(statusbar);
3425
3426     /* add the menubar always at the top */
3427     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3428
3429     /* main toolbar */
3430     gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3431
3432     /* filter toolbar in toolbar area */
3433     if (!prefs.filter_toolbar_show_in_statusbar) {
3434         gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3435     }
3436
3437     /* airpcap toolbar */
3438     gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3439
3440     /* fill the main layout panes */
3441     switch(prefs.gui_layout_type) {
3442     case(layout_type_5):
3443         main_first_pane  = main_pane_v1;
3444         main_second_pane = main_pane_v2;
3445         split_top_left = FALSE;
3446         break;
3447     case(layout_type_2):
3448         main_first_pane  = main_pane_v1;
3449         main_second_pane = main_pane_h1;
3450         split_top_left = FALSE;
3451         break;
3452     case(layout_type_1):
3453         main_first_pane  = main_pane_v1;
3454         main_second_pane = main_pane_h1;
3455         split_top_left = TRUE;
3456         break;
3457     case(layout_type_4):
3458         main_first_pane  = main_pane_h1;
3459         main_second_pane = main_pane_v1;
3460         split_top_left = FALSE;
3461         break;
3462     case(layout_type_3):
3463         main_first_pane  = main_pane_h1;
3464         main_second_pane = main_pane_v1;
3465         split_top_left = TRUE;
3466         break;
3467     case(layout_type_6):
3468         main_first_pane  = main_pane_h1;
3469         main_second_pane = main_pane_h2;
3470         split_top_left = FALSE;
3471         break;
3472     default:
3473         main_first_pane = NULL;
3474         main_second_pane = NULL;
3475         g_assert_not_reached();
3476     }
3477     if (split_top_left) {
3478         first_pane_widget1 = main_second_pane;
3479         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3480         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3481         first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3482     } else {
3483         first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3484         first_pane_widget2 = main_second_pane;
3485         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3486         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3487     }
3488     if (first_pane_widget1 != NULL)
3489         gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3490     if (first_pane_widget2 != NULL)
3491         gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3492     if (second_pane_widget1 != NULL)
3493         gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3494     if (second_pane_widget2 != NULL)
3495         gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3496
3497     gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3498
3499     /* welcome pane */
3500     gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3501
3502     /* statusbar */
3503     gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3504
3505     /* filter toolbar in statusbar hbox */
3506     if (prefs.filter_toolbar_show_in_statusbar) {
3507         gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3508     }
3509
3510     /* statusbar widgets */
3511     statusbar_widgets_pack(statusbar);
3512
3513     /* hide widgets on users recent settings */
3514     main_widgets_show_or_hide();
3515
3516     gtk_widget_show(main_vbox);
3517 }
3518
3519 static void
3520 is_widget_visible(GtkWidget *widget, gpointer data)
3521 {
3522     gboolean *is_visible = ( gboolean *)data;
3523
3524     if (!*is_visible) {
3525         if (gtk_widget_get_visible(widget))
3526             *is_visible = TRUE;
3527     }
3528 }
3529
3530
3531 void
3532 main_widgets_show_or_hide(void)
3533 {
3534     gboolean main_second_pane_show;
3535
3536     if (recent.main_toolbar_show) {
3537         gtk_widget_show(main_tb);
3538     } else {
3539         gtk_widget_hide(main_tb);
3540     }
3541
3542     statusbar_widgets_show_or_hide(statusbar);
3543
3544     if (recent.filter_toolbar_show) {
3545         gtk_widget_show(filter_tb);
3546     } else {
3547         gtk_widget_hide(filter_tb);
3548     }
3549
3550     if (recent.wireless_toolbar_show) {
3551         gtk_widget_show(wireless_tb);
3552     } else {
3553         gtk_widget_hide(wireless_tb);
3554     }
3555
3556     if (recent.packet_list_show && have_capture_file) {
3557         gtk_widget_show(pkt_scrollw);
3558     } else {
3559         gtk_widget_hide(pkt_scrollw);
3560     }
3561
3562     if (recent.tree_view_show && have_capture_file) {
3563         gtk_widget_show(tv_scrollw);
3564     } else {
3565         gtk_widget_hide(tv_scrollw);
3566     }
3567
3568     if (recent.byte_view_show && have_capture_file) {
3569         gtk_widget_show(byte_nb_ptr_gbl);
3570     } else {
3571         gtk_widget_hide(byte_nb_ptr_gbl);
3572     }
3573
3574     if (have_capture_file) {
3575         gtk_widget_show(main_first_pane);
3576     } else {
3577         gtk_widget_hide(main_first_pane);
3578     }
3579
3580     /*
3581      * Is anything in "main_second_pane" visible?
3582      * If so, show it, otherwise hide it.
3583      */
3584     main_second_pane_show = FALSE;
3585     gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3586                           &main_second_pane_show);
3587     if (main_second_pane_show) {
3588         gtk_widget_show(main_second_pane);
3589     } else {
3590         gtk_widget_hide(main_second_pane);
3591     }
3592
3593     if (!have_capture_file) {
3594         if(welcome_pane) {
3595             gtk_widget_show(welcome_pane);
3596         }
3597     } else {
3598         gtk_widget_hide(welcome_pane);
3599     }
3600 }
3601
3602
3603 /* called, when the window state changes (minimized, maximized, ...) */
3604 static gboolean
3605 window_state_event_cb (GtkWidget *widget _U_,
3606                        GdkEvent *event,
3607                        gpointer  data _U_)
3608 {
3609     GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3610
3611     if( (event->type) == (GDK_WINDOW_STATE)) {
3612         if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3613             /* we might have dialogs popped up while we where iconified,
3614                show em now */
3615             display_queued_messages();
3616         }
3617     }
3618     return FALSE;
3619 }
3620
3621
3622
3623 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3624 static gboolean
3625 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3626 {
3627     if (event->keyval == GDK_F8) {
3628         packet_list_next();
3629         return TRUE;
3630     } else if (event->keyval == GDK_F7) {
3631         packet_list_prev();
3632         return TRUE;
3633     } else if (event->state & NO_SHIFT_MOD_MASK) {
3634         return FALSE; /* Skip control, alt, and other modifiers */
3635     /*
3636      * A comment in gdkkeysyms.h says that it's autogenerated from
3637      * freedesktop.org/x.org's keysymdef.h.  Although the GDK docs
3638      * don't explicitly say so, isprint() should work as expected
3639      * for values < 127.
3640      */
3641     } else if (isascii(event->keyval) && isprint(event->keyval)) {
3642         /* Forward the keypress on to the display filter entry */
3643         if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3644             gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3645             gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3646         }
3647         return FALSE;
3648     }
3649     return FALSE;
3650 }
3651
3652 static void
3653 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3654 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3655                     _U_
3656 #endif
3657                     )
3658 {
3659     GtkAccelGroup *accel;
3660
3661     /* Main window */
3662     top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3663     set_titlebar_for_capture_file(NULL);
3664
3665     gtk_widget_set_name(top_level, "main window");
3666     g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3667