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