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