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