Remove ability to make dissectors "private"
[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     epan_init(register_all_protocols,register_all_protocol_handoffs,
2517               splash_update, (gpointer) splash_win);
2518
2519     splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2520
2521     /* Register all tap listeners; we do this before we parse the arguments,
2522        as the "-z" argument can specify a registered tap. */
2523
2524     /* we register the plugin taps before the other taps because
2525        stats_tree taps plugins will be registered as tap listeners
2526        by stats_tree_stat.c and need to registered before that */
2527
2528 #ifdef HAVE_PLUGINS
2529     register_all_plugin_tap_listeners();
2530 #endif
2531
2532     register_all_tap_listeners();
2533     conversation_table_set_gui_info(init_conversation_table);
2534     hostlist_table_set_gui_info(init_hostlist_table);
2535     srt_table_iterate_tables(register_service_response_tables, NULL);
2536     rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
2537     new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
2538
2539     splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2540
2541     prefs_p = read_configuration_files (&gdp_path, &dp_path);
2542     /* Removed thread code:
2543      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
2544      */
2545
2546     /* this is to keep tap extensions updating once every 3 seconds */
2547     tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2548
2549     splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2550     proto_help_init();
2551     cap_file_init(&cfile);
2552
2553     /* Fill in capture options with values from the preferences */
2554     prefs_to_capture_opts();
2555
2556 /*#ifdef HAVE_LIBPCAP
2557     fill_in_local_interfaces();
2558 #endif*/
2559     /*
2560      * To reset the options parser, set optreset to 1 on platforms that
2561      * have optreset (documented in *BSD and OS X, apparently present but
2562      * not documented in Solaris - the Illumos repository seems to
2563      * suggest that the first Solaris getopt_long(), at least as of 2004,
2564      * was based on the NetBSD one, it had optreset) and set optind to 1,
2565      * and set optind to 0 otherwise (documented as working in the GNU
2566      * getopt_long().  Setting optind to 0 didn't originally work in the
2567      * NetBSD one, but that was added later - we don't want to depend on
2568      * it if we have optreset).
2569      *
2570      * Also reset opterr to 1, so that error messages are printed by
2571      * getopt_long().
2572      *
2573      * XXX - if we want to control all the command-line option errors, so
2574      * that we can display them where we choose (e.g., in a window), we'd
2575      * want to leave opterr as 0, and produce our own messages using optopt.
2576      * We'd have to check the value of optopt to see if it's a valid option
2577      * letter, in which case *presumably* the error is "this option requires
2578      * an argument but none was specified", or not a valid option letter,
2579      * in which case *presumably* the error is "this option isn't valid".
2580      * Some versions of getopt() let you supply a option string beginning
2581      * with ':', which means that getopt() will return ':' rather than '?'
2582      * for "this option requires an argument but none was specified", but
2583      * not all do.  But we're now using getopt_long() - what does it do?
2584      */
2585 #ifdef HAVE_OPTRESET
2586     optreset = 1;
2587     optind = 1;
2588 #else
2589     optind = 0;
2590 #endif
2591     opterr = 1;
2592
2593     /* Now get our args */
2594     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
2595         switch (opt) {
2596             /*** capture option specific ***/
2597             case 'a':        /* autostop criteria */
2598             case 'b':        /* Ringbuffer option */
2599             case 'c':        /* Capture xxx packets */
2600             case 'f':        /* capture filter */
2601             case 'k':        /* Start capture immediately */
2602             case 'H':        /* Hide capture info dialog box */
2603             case 'p':        /* Don't capture in promiscuous mode */
2604             case 'i':        /* Use interface x */
2605 #ifdef HAVE_PCAP_CREATE
2606             case 'I':        /* Capture in monitor mode, if available */
2607 #endif
2608 #ifdef HAVE_PCAP_REMOTE
2609             case 'A':        /* Authentication */
2610 #endif
2611             case 's':        /* Set the snapshot (capture) length */
2612             case 'S':        /* "Sync" mode: used for following file ala tail -f */
2613             case 'w':        /* Write to capture file xxx */
2614             case 'y':        /* Set the pcap data link type */
2615 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
2616             case 'B':        /* Buffer size */
2617 #endif
2618 #ifdef HAVE_LIBPCAP
2619                 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2620                                               &start_capture);
2621                 if(status != 0) {
2622                     exit(status);
2623                 }
2624 #else
2625                 capture_option_specified = TRUE;
2626                 arg_error = TRUE;
2627 #endif
2628                 break;
2629
2630 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2631             case 'K':        /* Kerberos keytab file */
2632                     read_keytab_file(optarg);
2633                 break;
2634 #endif
2635
2636             /*** all non capture option specific ***/
2637             case 'C':
2638                 /* Configuration profile settings were already processed just ignore them this time*/
2639                 break;
2640             case 'j':        /* Search backwards for a matching packet from filter in option J */
2641                 jump_backwards = SD_BACKWARD;
2642                 break;
2643             case 'g':        /* Go to packet with the given packet number */
2644                 go_to_packet = get_positive_int(optarg, "go to packet");
2645                 break;
2646             case 'J':        /* Jump to the first packet which matches the filter criteria */
2647                 jfilter = optarg;
2648                 break;
2649             case 'l':        /* Automatic scrolling in live capture mode */
2650 #ifdef HAVE_LIBPCAP
2651                 auto_scroll_live = TRUE;
2652 #else
2653                 capture_option_specified = TRUE;
2654                 arg_error = TRUE;
2655 #endif
2656                 break;
2657             case 'L':        /* Print list of link-layer types and exit */
2658 #ifdef HAVE_LIBPCAP
2659                 list_link_layer_types = TRUE;
2660 #else
2661                 capture_option_specified = TRUE;
2662                 arg_error = TRUE;
2663 #endif
2664                 break;
2665             case 'm':        /* Fixed-width font for the display */
2666                 g_free(prefs_p->gui_gtk2_font_name);
2667                 prefs_p->gui_gtk2_font_name = g_strdup(optarg);
2668                 break;
2669             case 'n':        /* No name resolution */
2670                 disable_name_resolution();
2671                 break;
2672             case 'N':        /* Select what types of addresses/port #s to resolve */
2673                 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2674                 if (badopt != '\0') {
2675                     cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
2676                                badopt);
2677                     exit(1);
2678                 }
2679                 break;
2680             case 'o':        /* Override preference from command line */
2681                 switch (prefs_set_pref(optarg)) {
2682                     case PREFS_SET_OK:
2683                         break;
2684                     case PREFS_SET_SYNTAX_ERR:
2685                         cmdarg_err("Invalid -o flag \"%s\"", optarg);
2686                         exit(1);
2687                         break;
2688                     case PREFS_SET_NO_SUCH_PREF:
2689                     /* not a preference, might be a recent setting */
2690                         switch (recent_set_arg(optarg)) {
2691                             case PREFS_SET_OK:
2692                                 break;
2693                             case PREFS_SET_SYNTAX_ERR:
2694                                 /* shouldn't happen, checked already above */
2695                                 cmdarg_err("Invalid -o flag \"%s\"", optarg);
2696                                 exit(1);
2697                                 break;
2698                             case PREFS_SET_NO_SUCH_PREF:
2699                             case PREFS_SET_OBSOLETE:
2700                                 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2701                                            optarg);
2702                                 exit(1);
2703                                 break;
2704                             default:
2705                                 g_assert_not_reached();
2706                         }
2707                         break;
2708                     case PREFS_SET_OBSOLETE:
2709                         cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2710                                    optarg);
2711                         exit(1);
2712                         break;
2713                     default:
2714                         g_assert_not_reached();
2715                 }
2716                 break;
2717             case 'P':
2718                 /* Path settings were already processed just ignore them this time*/
2719                 break;
2720             case 'r':        /* Read capture file xxx */
2721                 /* We may set "last_open_dir" to "cf_name", and if we change
2722                  "last_open_dir" later, we free the old value, so we have to
2723                  set "cf_name" to something that's been allocated. */
2724                 cf_name = g_strdup(optarg);
2725                 break;
2726             case 'R':        /* Read file filter */
2727                 rfilter = optarg;
2728                 break;
2729             case 't':        /* Time stamp type */
2730                 if (strcmp(optarg, "r") == 0)
2731                     timestamp_set_type(TS_RELATIVE);
2732                 else if (strcmp(optarg, "a") == 0)
2733                     timestamp_set_type(TS_ABSOLUTE);
2734                 else if (strcmp(optarg, "ad") == 0)
2735                     timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
2736                 else if (strcmp(optarg, "adoy") == 0)
2737                     timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
2738                 else if (strcmp(optarg, "d") == 0)
2739                     timestamp_set_type(TS_DELTA);
2740                 else if (strcmp(optarg, "dd") == 0)
2741                     timestamp_set_type(TS_DELTA_DIS);
2742                 else if (strcmp(optarg, "e") == 0)
2743                     timestamp_set_type(TS_EPOCH);
2744                 else if (strcmp(optarg, "u") == 0)
2745                     timestamp_set_type(TS_UTC);
2746                 else if (strcmp(optarg, "ud") == 0)
2747                     timestamp_set_type(TS_UTC_WITH_YMD);
2748                 else if (strcmp(optarg, "udoy") == 0)
2749                     timestamp_set_type(TS_UTC_WITH_YDOY);
2750                 else {
2751                     cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2752                     cmdarg_err_cont(
2753 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
2754                     cmdarg_err_cont(
2755 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
2756                     cmdarg_err_cont(
2757 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
2758                     cmdarg_err_cont(
2759 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
2760                     cmdarg_err_cont(
2761 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
2762                     exit(1);
2763                 }
2764                 break;
2765             case 'u':        /* Seconds type */
2766                 if (strcmp(optarg, "s") == 0)
2767                     timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2768                 else if (strcmp(optarg, "hms") == 0)
2769                     timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2770                 else {
2771                     cmdarg_err("Invalid seconds type \"%s\"", optarg);
2772                     cmdarg_err_cont(
2773 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2774                     exit(1);
2775                 }
2776                 break;
2777             case 'X':
2778                 /* ext ops were already processed just ignore them this time*/
2779                 break;
2780             case 'Y':
2781                 dfilter = optarg;
2782                 break;
2783             case 'z':
2784                 /* We won't call the init function for the stat this soon
2785                  as it would disallow MATE's fields (which are registered
2786                  by the preferences set callback) from being used as
2787                  part of a tap filter.  Instead, we just add the argument
2788                  to a list of stat arguments. */
2789                 if (strcmp("help", optarg) == 0) {
2790                   fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
2791                   list_stat_cmd_args();
2792                   exit(0);
2793                 }
2794                 if (!process_stat_cmd_arg(optarg)) {
2795                     cmdarg_err("Invalid -z argument.");
2796                     cmdarg_err_cont("  -z argument must be one of :");
2797                     list_stat_cmd_args();
2798                     exit(1);
2799                 }
2800                 break;
2801             case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
2802                 disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
2803                 break;
2804             case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
2805                 enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
2806                 break;
2807             case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
2808                 disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
2809                 break;
2810             default:
2811             case '?':        /* Bad flag - print usage message */
2812                 arg_error = TRUE;
2813                 break;
2814             }
2815     }
2816     if (!arg_error) {
2817         argc -= optind;
2818         argv += optind;
2819         if (argc >= 1) {
2820             if (cf_name != NULL) {
2821                 /*
2822                  * Input file name specified with "-r" *and* specified as a regular
2823                  * command-line argument.
2824                  */
2825                 cmdarg_err("File name specified both with -r and regular argument");
2826                 arg_error = TRUE;
2827             } else {
2828                 /*
2829                  * Input file name not specified with "-r", and a command-line argument
2830                  * was specified; treat it as the input file name.
2831                  *
2832                  * Yes, this is different from tshark, where non-flag command-line
2833                  * arguments are a filter, but this works better on GUI desktops
2834                  * where a command can be specified to be run to open a particular
2835                  * file - yes, you could have "-r" as the last part of the command,
2836                  * but that's a bit ugly.
2837                  */
2838 #ifndef HAVE_GTKOSXAPPLICATION
2839                 /*
2840                  * For GTK+ Mac Integration, file name passed as free argument passed
2841                  * through grag-and-drop and opened twice sometimes causing crashes.
2842                  * Subject to report to GTK+ MAC.
2843                  */
2844                 cf_name = g_strdup(argv[0]);
2845 #endif
2846             }
2847             argc--;
2848             argv++;
2849         }
2850
2851         if (argc != 0) {
2852             /*
2853              * Extra command line arguments were specified; complain.
2854              */
2855             cmdarg_err("Invalid argument: %s", argv[0]);
2856             arg_error = TRUE;
2857         }
2858     }
2859
2860     if (arg_error) {
2861 #ifndef HAVE_LIBPCAP
2862         if (capture_option_specified) {
2863             cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2864         }
2865 #endif
2866         print_usage(FALSE);
2867         exit(1);
2868     }
2869
2870 #ifdef HAVE_LIBPCAP
2871     fill_in_local_interfaces(main_window_update);
2872     if (start_capture && list_link_layer_types) {
2873         /* Specifying *both* is bogus. */
2874         cmdarg_err("You can't specify both -L and a live capture.");
2875         exit(1);
2876     }
2877
2878     if (list_link_layer_types) {
2879         /* We're supposed to list the link-layer types for an interface;
2880            did the user also specify a capture file to be read? */
2881         if (cf_name) {
2882             /* Yes - that's bogus. */
2883             cmdarg_err("You can't specify -L and a capture file to be read.");
2884         exit(1);
2885         }
2886         /* No - did they specify a ring buffer option? */
2887         if (global_capture_opts.multi_files_on) {
2888             cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2889             exit(1);
2890         }
2891     } else {
2892         /* We're supposed to do a live capture; did the user also specify
2893            a capture file to be read? */
2894         if (start_capture && cf_name) {
2895             /* Yes - that's bogus. */
2896             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2897             exit(1);
2898         }
2899
2900         /* No - was the ring buffer option specified and, if so, does it make
2901            sense? */
2902         if (global_capture_opts.multi_files_on) {
2903             /* Ring buffer works only under certain conditions:
2904              a) ring buffer does not work with temporary files;
2905              b) real_time_mode and multi_files_on are mutually exclusive -
2906              real_time_mode takes precedence;
2907              c) it makes no sense to enable the ring buffer if the maximum
2908              file size is set to "infinite". */
2909             if (global_capture_opts.save_file == NULL) {
2910                 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2911                 global_capture_opts.multi_files_on = FALSE;
2912             }
2913             if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2914                 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2915                 /* XXX - this must be redesigned as the conditions changed */
2916             }
2917         }
2918     }
2919
2920     if (start_capture || list_link_layer_types) {
2921         /* We're supposed to do a live capture or get a list of link-layer
2922            types for a live capture device; if the user didn't specify an
2923            interface to use, pick a default. */
2924         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
2925         ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
2926         if (status != 0) {
2927             exit(status);
2928         }
2929     }
2930
2931     if (list_link_layer_types) {
2932         /* Get the list of link-layer types for the capture devices. */
2933         if_capabilities_t *caps;
2934         guint i;
2935         interface_t device;
2936         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2937
2938             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2939             if (device.selected) {
2940                 gchar* auth_str = NULL;
2941 #ifdef HAVE_PCAP_REMOTE
2942                 if (device.remote_opts.remote_host_opts.auth_type == CAPTURE_AUTH_PWD) {
2943                     auth_str = g_strdup_printf("%s:%s", device.remote_opts.remote_host_opts.auth_username,
2944                                                device.remote_opts.remote_host_opts.auth_password);
2945                 }
2946 #endif
2947 #if defined(HAVE_PCAP_CREATE)
2948                 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, auth_str, &err_str, main_window_update);
2949 #else
2950                 caps = capture_get_if_capabilities(device.name, FALSE, auth_str, &err_str,main_window_update);
2951 #endif
2952                 g_free(auth_str);
2953                 if (caps == NULL) {
2954                     cmdarg_err("%s", err_str);
2955                     g_free(err_str);
2956                     exit(2);
2957                 }
2958             if (caps->data_link_types == NULL) {
2959                 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2960                 exit(2);
2961             }
2962 #ifdef _WIN32
2963             create_console();
2964 #endif /* _WIN32 */
2965 #if defined(HAVE_PCAP_CREATE)
2966             capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2967 #else
2968             capture_opts_print_if_capabilities(caps, device.name, FALSE);
2969 #endif
2970 #ifdef _WIN32
2971             destroy_console();
2972 #endif /* _WIN32 */
2973             free_if_capabilities(caps);
2974             }
2975         }
2976         exit(0);
2977     }
2978   capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2979   capture_opts_trim_ring_num_files(&global_capture_opts);
2980 #endif /* HAVE_LIBPCAP */
2981
2982     /* Notify all registered modules that have had any of their preferences
2983        changed either from one of the preferences file or from the command
2984        line that their preferences have changed. */
2985     prefs_apply_all();
2986
2987 #ifdef HAVE_LIBPCAP
2988     if ((global_capture_opts.num_selected == 0) &&
2989         ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
2990         guint i;
2991         interface_t device;
2992         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2993             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2994             if (!device.hidden && strstr(prefs.capture_device, device.name) != NULL) {
2995                 device.selected = TRUE;
2996                 global_capture_opts.num_selected++;
2997                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2998                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2999                 break;
3000             }
3001         }
3002     }
3003     if (global_capture_opts.num_selected == 0 && global_capture_opts.all_ifaces->len == 1) {
3004         interface_t device = g_array_index(global_capture_opts.all_ifaces, interface_t, 0);
3005         device.selected = TRUE;
3006         global_capture_opts.num_selected++;
3007         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, 0);
3008         g_array_insert_val(global_capture_opts.all_ifaces, 0, device);
3009     }
3010 #endif
3011
3012     /* disabled protocols as per configuration file */
3013     if (gdp_path == NULL && dp_path == NULL) {
3014         set_disabled_protos_list();
3015         set_disabled_heur_dissector_list();
3016     }
3017
3018     if(disable_protocol_slist) {
3019         GSList *proto_disable;
3020         for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
3021         {
3022             proto_disable_proto_by_name((char*)proto_disable->data);
3023         }
3024     }
3025
3026     if(enable_heur_slist) {
3027         GSList *heur_enable;
3028         for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
3029         {
3030             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
3031         }
3032     }
3033
3034     if(disable_heur_slist) {
3035         GSList *heur_disable;
3036         for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
3037         {
3038             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
3039         }
3040     }
3041
3042     build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
3043
3044     /* read in rc file from global and personal configuration paths. */
3045     rc_file = get_datafile_path(RC_FILE);
3046 #if GTK_CHECK_VERSION(3,0,0)
3047     /* XXX resolve later */
3048 #else
3049     gtk_rc_parse(rc_file);
3050     g_free(rc_file);
3051     rc_file = get_persconffile_path(RC_FILE, FALSE);
3052     gtk_rc_parse(rc_file);
3053 #endif
3054     g_free(rc_file);
3055
3056     font_init();
3057
3058     macros_init();
3059
3060     stock_icons_init();
3061
3062     /* close the splash screen, as we are going to open the main window now */
3063     splash_destroy(splash_win);
3064
3065     /************************************************************************/
3066     /* Everything is prepared now, preferences and command line was read in */
3067
3068     /* Pop up the main window. */
3069     create_main_window(pl_size, tv_size, bv_size, prefs_p);
3070
3071     /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
3072     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
3073         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3074                       "Could not open recent file\n\"%s\": %s.",
3075                       rf_path, g_strerror(rf_open_errno));
3076         g_free(rf_path);
3077     }
3078
3079     color_filters_enable(recent.packet_list_colorize);
3080
3081     /* rearrange all the widgets as we now have all recent settings ready for this */
3082     main_widgets_rearrange();
3083
3084     /* Fill in column titles.  This must be done after the top level window
3085      is displayed.
3086
3087      XXX - is that still true, with fixed-width columns? */
3088
3089     menu_recent_read_finished();
3090 #ifdef HAVE_LIBPCAP
3091     main_auto_scroll_live_changed(auto_scroll_live);
3092 #endif
3093
3094     switch (user_font_apply()) {
3095         case FA_SUCCESS:
3096             break;
3097         case FA_FONT_NOT_RESIZEABLE:
3098             /* "user_font_apply()" popped up an alert box. */
3099             /* turn off zooming - font can't be resized */
3100         case FA_FONT_NOT_AVAILABLE:
3101             /* XXX - did we successfully load the un-zoomed version earlier?
3102              If so, this *probably* means the font is available, but not at
3103              this particular zoom level, but perhaps some other failure
3104              occurred; I'm not sure you can determine which is the case,
3105              however. */
3106             /* turn off zooming - zoom level is unavailable */
3107         default:
3108             /* in any other case than FA_SUCCESS, turn off zooming */
3109             recent.gui_zoom_level = 0;
3110             /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3111     }
3112
3113     dnd_init(top_level);
3114
3115     color_filters_init();
3116 #ifdef HAVE_LIBPCAP
3117     capture_filter_init();
3118 #endif
3119
3120     /* the window can be sized only, if it's not already shown, so do it now! */
3121     main_load_window_geometry(top_level);
3122
3123     g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3124
3125     /* If we were given the name of a capture file, read it in now;
3126      we defer it until now, so that, if we can't open it, and pop
3127      up an alert box, the alert box is more likely to come up on
3128      top of the main window - but before the preference-file-error
3129      alert box, so, if we get one of those, it's more likely to come
3130      up on top of us. */
3131     if (cf_name) {
3132         show_main_window(TRUE);
3133         check_and_warn_user_startup(cf_name);
3134         if (rfilter != NULL) {
3135             if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
3136                 bad_dfilter_alert_box(top_level, rfilter, err_msg);
3137                 g_free(err_msg);
3138                 rfilter_parse_failed = TRUE;
3139             }
3140         }
3141         if (ex_opt_count("read_format") > 0) {
3142             in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
3143         }
3144         if (!rfilter_parse_failed) {
3145             if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
3146                 /* "cf_open()" succeeded, so it closed the previous
3147                  capture file, and thus destroyed any previous read filter
3148                  attached to "cf". */
3149
3150                 cfile.rfcode = rfcode;
3151                 /* Open stat windows; we do so after creating the main window,
3152                    to avoid GTK warnings, and after successfully opening the
3153                    capture file, so we know we have something to compute stats
3154                    on, and after registering all dissectors, so that MATE will
3155                    have registered its field array and we can have a tap filter
3156                    with one of MATE's late-registered fields as part of the
3157                    filter. */
3158                 start_requested_stats();
3159
3160                 /* Read the capture file. */
3161                 switch (cf_read(&cfile, FALSE)) {
3162
3163                     case CF_READ_OK:
3164                     case CF_READ_ERROR:
3165                         /* Just because we got an error, that doesn't mean we were unable
3166                            to read any of the file; we handle what we could get from the
3167                            file. */
3168                         /* if the user told us to jump to a specific packet, do it now */
3169                         if(go_to_packet != 0) {
3170                             /* Jump to the specified frame number, kept for backward
3171                                compatibility. */
3172                             cf_goto_frame(&cfile, go_to_packet);
3173                         } else if (jfilter != NULL) {
3174                             /* try to compile given filter */
3175                             if (!dfilter_compile(jfilter, &jump_to_filter, &err_msg)) {
3176                                 bad_dfilter_alert_box(top_level, jfilter, err_msg);
3177                                 g_free(err_msg);
3178                             } else {
3179                             /* Filter ok, jump to the first packet matching the filter
3180                                conditions. Default search direction is forward, but if
3181                                option d was given, search backwards */
3182                             cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3183                             }
3184                         }
3185                         break;
3186
3187                     case CF_READ_ABORTED:
3188                         /* Exit now. */
3189                         exit(0);
3190                         break;
3191                 }
3192
3193                 /* If the filename is not the absolute path, prepend the current dir. This happens
3194                    when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3195                 if (!g_path_is_absolute(cf_name)) {
3196                     char *old_cf_name = cf_name;
3197                     char *pwd = g_get_current_dir();
3198                     cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3199                     g_free(old_cf_name);
3200                     g_free(pwd);
3201                 }
3202
3203                 /* Save the name of the containing directory specified in the
3204                    path name, if any; we can write over cf_name, which is a
3205                    good thing, given that "get_dirname()" does write over its
3206                    argument. */
3207                 s = get_dirname(cf_name);
3208                 set_last_open_dir(s);
3209                 g_free(cf_name);
3210                 cf_name = NULL;
3211             } else {
3212                 if (rfcode != NULL)
3213                     dfilter_free(rfcode);
3214                 cfile.rfcode = NULL;
3215                 show_main_window(FALSE);
3216                 /* Don't call check_and_warn_user_startup(): we did it above */
3217                 main_set_for_capture_in_progress(FALSE);
3218                 set_capture_if_dialog_for_capture_in_progress(FALSE);
3219             }
3220         }
3221     } else {
3222 #ifdef HAVE_LIBPCAP
3223         if (start_capture) {
3224             if (global_capture_opts.save_file != NULL) {
3225                 /* Save the directory name for future file dialogs. */
3226                 /* (get_dirname overwrites filename) */
3227                 s = get_dirname(g_strdup(global_capture_opts.save_file));
3228                 set_last_open_dir(s);
3229                 g_free(s);
3230             }
3231             /* "-k" was specified; start a capture. */
3232             show_main_window(FALSE);
3233             check_and_warn_user_startup(cf_name);
3234
3235             /* If no user interfaces were specified on the command line,
3236                copy the list of selected interfaces to the set of interfaces
3237                to use for this capture. */
3238             if (global_capture_opts.ifaces->len == 0)
3239                 collect_ifaces(&global_capture_opts);
3240             if (capture_start(&global_capture_opts, &global_capture_session,main_window_update)) {
3241                 /* The capture started.  Open stat windows; we do so after creating
3242                    the main window, to avoid GTK warnings, and after successfully
3243                    opening the capture file, so we know we have something to compute
3244                    stats on, and after registering all dissectors, so that MATE will
3245                    have registered its field array and we can have a tap filter with
3246                    one of MATE's late-registered fields as part of the filter. */
3247                 start_requested_stats();
3248             }
3249         } else {
3250             show_main_window(FALSE);
3251             check_and_warn_user_startup(cf_name);
3252             main_set_for_capture_in_progress(FALSE);
3253             set_capture_if_dialog_for_capture_in_progress(FALSE);
3254         }
3255     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3256         if (!start_capture && !global_capture_opts.default_options.cfilter) {
3257             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3258         }
3259 #else /* HAVE_LIBPCAP */
3260         show_main_window(FALSE);
3261         check_and_warn_user_startup(cf_name);
3262         main_set_for_capture_in_progress(FALSE);
3263         set_capture_if_dialog_for_capture_in_progress(FALSE);
3264 #endif /* HAVE_LIBPCAP */
3265     }
3266
3267     if (dfilter) {
3268         GtkWidget *filter_te;
3269         filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3270         gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3271
3272         /* Run the display filter so it goes in effect. */
3273         main_filter_packets(&cfile, dfilter, FALSE);
3274     }
3275
3276
3277     /* register our pid if we are being run from a U3 device */
3278     u3_register_pid();
3279
3280     profile_store_persconffiles (FALSE);
3281
3282 #ifdef HAVE_GTKOSXAPPLICATION
3283     theApp = (GtkosxApplication *)g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
3284     gtkosx_application_set_dock_icon_pixbuf(theApp, gdk_pixbuf_new_from_inline(-1, wsicon_64_pb_data, FALSE, NULL));
3285     gtkosx_application_ready(theApp);
3286 #endif
3287
3288     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3289
3290 #ifdef HAVE_LIBPCAP
3291     gtk_iface_mon_start();
3292 #endif
3293
3294     software_update_init();
3295
3296     /* we'll enter the GTK loop now and hand the control over to GTK ... */
3297     gtk_main();
3298     /* ... back from GTK, we're going down now! */
3299
3300 #ifdef HAVE_LIBPCAP
3301     gtk_iface_mon_stop();
3302 #endif
3303
3304     /* deregister our pid */
3305     u3_deregister_pid();
3306
3307     epan_cleanup();
3308
3309     AirPDcapDestroyContext(&airpdcap_ctx);
3310
3311 #ifdef HAVE_GTKOSXAPPLICATION
3312     g_object_unref(theApp);
3313 #endif
3314
3315 #ifdef _WIN32
3316     /* hide the (unresponsive) main window, while asking the user to close the console window */
3317     if (G_IS_OBJECT(top_level))
3318         gtk_widget_hide(top_level);
3319
3320     software_update_cleanup();
3321
3322     /* Shutdown windows sockets */
3323     WSACleanup();
3324
3325     /* For some unknown reason, the "atexit()" call in "create_console()"
3326        doesn't arrange that "destroy_console()" be called when we exit,
3327        so we call it here if a console was created. */
3328     destroy_console();
3329 #endif
3330
3331     exit(0);
3332 }
3333
3334 #ifdef _WIN32
3335
3336 /* We build this as a GUI subsystem application on Win32, so
3337    "WinMain()", not "main()", gets called.
3338
3339    Hack shamelessly stolen from the Win32 port of the GIMP. */
3340 #ifdef __GNUC__
3341 #define _stdcall  __attribute__((stdcall))
3342 #endif
3343
3344 int _stdcall
3345 WinMain (struct HINSTANCE__ *hInstance,
3346          struct HINSTANCE__ *hPrevInstance,
3347          char               *lpszCmdLine,
3348          int                 nCmdShow)
3349 {
3350     INITCOMMONCONTROLSEX comm_ctrl;
3351
3352     /*
3353      * Initialize our DLL search path. MUST be called before LoadLibrary
3354      * or g_module_open.
3355      */
3356     ws_init_dll_search_path();
3357
3358     /* Initialize our controls. Required for native Windows file dialogs. */
3359     memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3360     comm_ctrl.dwSize = sizeof(comm_ctrl);
3361     /* Includes the animate, header, hot key, list view, progress bar,
3362      * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3363      * up-down controls
3364      */
3365     comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3366     InitCommonControlsEx(&comm_ctrl);
3367
3368     /* RichEd20.DLL is needed for filter entries. */
3369     ws_load_library("riched20.dll");
3370
3371     set_has_console(FALSE);
3372     set_console_wait(FALSE);
3373     return main (__argc, __argv);
3374 }
3375
3376 #endif /* _WIN32 */
3377
3378
3379
3380
3381 /*
3382  * Helper for main_widgets_rearrange()
3383  */
3384 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3385     gtk_container_remove(GTK_CONTAINER(data), widget);
3386 }
3387
3388 static GtkWidget *main_widget_layout(gint layout_content)
3389 {
3390     switch(layout_content) {
3391     case(layout_pane_content_none):
3392         return NULL;
3393     case(layout_pane_content_plist):
3394         return pkt_scrollw;
3395     case(layout_pane_content_pdetails):
3396         return tv_scrollw;
3397     case(layout_pane_content_pbytes):
3398         return byte_nb_ptr_gbl;
3399     default:
3400         g_assert_not_reached();
3401         return NULL;
3402     }
3403 }
3404
3405 /*
3406  * Rearrange the main window widgets
3407  */
3408 void main_widgets_rearrange(void) {
3409     GtkWidget *first_pane_widget1, *first_pane_widget2;
3410     GtkWidget *second_pane_widget1, *second_pane_widget2;
3411     gboolean split_top_left = FALSE;
3412
3413     /* be a bit faster */
3414     gtk_widget_hide(main_vbox);
3415
3416     /* be sure we don't lose a widget while rearranging */
3417     g_object_ref(G_OBJECT(menubar));
3418     g_object_ref(G_OBJECT(main_tb));
3419     g_object_ref(G_OBJECT(filter_tb));
3420     g_object_ref(G_OBJECT(wireless_tb));
3421     g_object_ref(G_OBJECT(pkt_scrollw));
3422     g_object_ref(G_OBJECT(tv_scrollw));
3423     g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3424     g_object_ref(G_OBJECT(statusbar));
3425     g_object_ref(G_OBJECT(main_pane_v1));
3426     g_object_ref(G_OBJECT(main_pane_v2));
3427     g_object_ref(G_OBJECT(main_pane_h1));
3428     g_object_ref(G_OBJECT(main_pane_h2));
3429     g_object_ref(G_OBJECT(welcome_pane));
3430
3431     /* empty all containers participating */
3432     gtk_container_foreach(GTK_CONTAINER(main_vbox),     foreach_remove_a_child, main_vbox);
3433     gtk_container_foreach(GTK_CONTAINER(main_pane_v1),  foreach_remove_a_child, main_pane_v1);
3434     gtk_container_foreach(GTK_CONTAINER(main_pane_v2),  foreach_remove_a_child, main_pane_v2);
3435     gtk_container_foreach(GTK_CONTAINER(main_pane_h1),  foreach_remove_a_child, main_pane_h1);
3436     gtk_container_foreach(GTK_CONTAINER(main_pane_h2),  foreach_remove_a_child, main_pane_h2);
3437
3438     statusbar_widgets_emptying(statusbar);
3439
3440     /* add the menubar always at the top */
3441     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3442
3443     /* main toolbar */
3444     gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3445
3446     /* filter toolbar in toolbar area */
3447     if (!prefs.filter_toolbar_show_in_statusbar) {
3448         gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3449     }
3450
3451     /* airpcap toolbar */
3452     gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3453
3454     /* fill the main layout panes */
3455     switch(prefs.gui_layout_type) {
3456     case(layout_type_5):
3457         main_first_pane  = main_pane_v1;
3458         main_second_pane = main_pane_v2;
3459         split_top_left = FALSE;
3460         break;
3461     case(layout_type_2):
3462         main_first_pane  = main_pane_v1;
3463         main_second_pane = main_pane_h1;
3464         split_top_left = FALSE;
3465         break;
3466     case(layout_type_1):
3467         main_first_pane  = main_pane_v1;
3468         main_second_pane = main_pane_h1;
3469         split_top_left = TRUE;
3470         break;
3471     case(layout_type_4):
3472         main_first_pane  = main_pane_h1;
3473         main_second_pane = main_pane_v1;
3474         split_top_left = FALSE;
3475         break;
3476     case(layout_type_3):
3477         main_first_pane  = main_pane_h1;
3478         main_second_pane = main_pane_v1;
3479         split_top_left = TRUE;
3480         break;
3481     case(layout_type_6):
3482         main_first_pane  = main_pane_h1;
3483         main_second_pane = main_pane_h2;
3484         split_top_left = FALSE;
3485         break;
3486     default:
3487         main_first_pane = NULL;
3488         main_second_pane = NULL;
3489         g_assert_not_reached();
3490     }
3491     if (split_top_left) {
3492         first_pane_widget1 = main_second_pane;
3493         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3494         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3495         first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3496     } else {
3497         first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3498         first_pane_widget2 = main_second_pane;
3499         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3500         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3501     }
3502     if (first_pane_widget1 != NULL)
3503         gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3504     if (first_pane_widget2 != NULL)
3505         gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3506     if (second_pane_widget1 != NULL)
3507         gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3508     if (second_pane_widget2 != NULL)
3509         gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3510
3511     gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3512
3513     /* welcome pane */
3514     gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3515
3516     /* statusbar */
3517     gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3518
3519     /* filter toolbar in statusbar hbox */
3520     if (prefs.filter_toolbar_show_in_statusbar) {
3521         gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3522     }
3523
3524     /* statusbar widgets */
3525     statusbar_widgets_pack(statusbar);
3526
3527     /* hide widgets on users recent settings */
3528     main_widgets_show_or_hide();
3529
3530     gtk_widget_show(main_vbox);
3531 }
3532
3533 static void
3534 is_widget_visible(GtkWidget *widget, gpointer data)
3535 {
3536     gboolean *is_visible = ( gboolean *)data;
3537
3538     if (!*is_visible) {
3539         if (gtk_widget_get_visible(widget))
3540             *is_visible = TRUE;
3541     }
3542 }
3543
3544
3545 void
3546 main_widgets_show_or_hide(void)
3547 {
3548     gboolean main_second_pane_show;
3549
3550     if (recent.main_toolbar_show) {
3551         gtk_widget_show(main_tb);
3552     } else {
3553         gtk_widget_hide(main_tb);
3554     }
3555
3556     statusbar_widgets_show_or_hide(statusbar);
3557
3558     if (recent.filter_toolbar_show) {
3559         gtk_widget_show(filter_tb);
3560     } else {
3561         gtk_widget_hide(filter_tb);
3562     }
3563
3564     if (recent.wireless_toolbar_show) {
3565         gtk_widget_show(wireless_tb);
3566     } else {
3567         gtk_widget_hide(wireless_tb);
3568     }
3569
3570     if (recent.packet_list_show && have_capture_file) {
3571         gtk_widget_show(pkt_scrollw);
3572     } else {
3573         gtk_widget_hide(pkt_scrollw);
3574     }
3575
3576     if (recent.tree_view_show && have_capture_file) {
3577         gtk_widget_show(tv_scrollw);
3578     } else {
3579         gtk_widget_hide(tv_scrollw);
3580     }
3581
3582     if (recent.byte_view_show && have_capture_file) {
3583         gtk_widget_show(byte_nb_ptr_gbl);
3584     } else {
3585         gtk_widget_hide(byte_nb_ptr_gbl);
3586     }
3587
3588     if (have_capture_file) {
3589         gtk_widget_show(main_first_pane);
3590     } else {
3591         gtk_widget_hide(main_first_pane);
3592     }
3593
3594     /*
3595      * Is anything in "main_second_pane" visible?
3596      * If so, show it, otherwise hide it.
3597      */
3598     main_second_pane_show = FALSE;
3599     gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3600                           &main_second_pane_show);
3601     if (main_second_pane_show) {
3602         gtk_widget_show(main_second_pane);
3603     } else {
3604         gtk_widget_hide(main_second_pane);
3605     }
3606
3607     if (!have_capture_file) {
3608         if(welcome_pane) {
3609             gtk_widget_show(welcome_pane);
3610         }
3611     } else {
3612         gtk_widget_hide(welcome_pane);
3613     }
3614 }
3615
3616
3617 /* called, when the window state changes (minimized, maximized, ...) */
3618 static gboolean
3619 window_state_event_cb (GtkWidget *widget _U_,
3620                        GdkEvent *event,
3621                        gpointer  data _U_)
3622 {
3623     GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3624
3625     if( (event->type) == (GDK_WINDOW_STATE)) {
3626         if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3627             /* we might have dialogs popped up while we where iconified,
3628                show em now */
3629             display_queued_messages();
3630         }
3631     }
3632     return FALSE;
3633 }
3634
3635
3636
3637 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3638 static gboolean
3639 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3640 {
3641     if (event->keyval == GDK_F8) {
3642         packet_list_next();
3643         return TRUE;
3644     } else if (event->keyval == GDK_F7) {
3645         packet_list_prev();
3646         return TRUE;
3647     } else if (event->state & NO_SHIFT_MOD_MASK) {
3648         return FALSE; /* Skip control, alt, and other modifiers */
3649     /*
3650      * A comment in gdkkeysyms.h says that it's autogenerated from
3651      * freedesktop.org/x.org's keysymdef.h.  Although the GDK docs
3652      * don't explicitly say so, g_ascii_isprint() should work as expected
3653      * for values < 127.
3654      */
3655     } else if (event->keyval < 256 && g_ascii_isprint(event->keyval)) {
3656         /* Forward the keypress on to the display filter entry */
3657         if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3658             gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3659             gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3660         }
3661         return FALSE;
3662     }
3663     return FALSE;
3664 }
3665
3666 static void
3667 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p
3668 #if !defined(HAVE_IGE_MAC_INTEGRATION) && !defined (HAVE_GTKOSXAPPLICATION)
3669                     _U_
3670 #endif
3671                     )
3672 {
3673     GtkAccelGroup *accel;
3674
3675     /* Main window */
3676     top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3677     set_titlebar_for_capture_file(NULL);
3678
3679     gtk_widget_set_name(top_level, "main window");
3680     g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3681                    NULL);
3682     g_signal_connect(G_OBJECT(top_level), "window_state_event",
3683                          G_CALLBACK(window_state_event_cb), NULL);
3684     g_signal_connect(G_OBJECT(top_level), "key-press-event",
3685                          G_CALLBACK(top_level_key_pressed_cb), NULL );
3686
3687     /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3688     main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3689
3690     gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3691     gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3692     gtk_widget_show(main_vbox);
3693
3694     /* Menu bar */
3695     menubar = main_menu_new(&accel);
3696
3697 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3698     /* Mac OS X native menus are created and displayed by main_menu_new() */
3699     if(!prefs_p->gui_macosx_style) {
3700 #endif
3701     gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3702     gtk_widget_show(menubar);
3703 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3704     } else {
3705     gtk_widget_hide(menubar);
3706     }
3707 #endif
3708
3709     /* Main Toolbar */
3710     main_tb = toolbar_new();
3711     gtk_widget_show (main_tb);
3712
3713     /* Filter toolbar */
3714     filter_tb = filter_toolbar_new();
3715
3716     /* Packet list */
3717     pkt_scrollw = packet_list_create();
3718     gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3719     gtk_widget_show_all(pkt_scrollw);
3720
3721     /* Tree view */
3722     tv_scrollw = proto_tree_view_new(&tree_view_gbl);
3723     gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3724     gtk_widget_show(tv_scrollw);
3725
3726     g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3727                    "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3728     g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3729                    g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3730     gtk_widget_show(tree_view_gbl);
3731
3732     /* Byte view. */
3733     byte_nb_ptr_gbl = byte_view_new();
3734     gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3735     gtk_widget_show(byte_nb_ptr_gbl);
3736
3737     g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3738                    g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3739
3740     /* Panes for the packet list, tree, and byte view */
3741     main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3742     gtk_widget_show(main_pane_v1);
3743     main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3744     gtk_widget_show(main_pane_v2);
3745     main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3746     gtk_widget_show(main_pane_h1);
3747     main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3748     gtk_widget_show(main_pane_h2);
3749 #ifdef HAVE_AIRPCAP
3750     wireless_tb = airpcap_toolbar_new();
3751 #else
3752     wireless_tb = ws80211_toolbar_new();
3753 #endif
3754     gtk_widget_show(wireless_tb);
3755
3756     /* status bar */
3757     statusbar = statusbar_new();
3758     gtk_widget_show(statusbar);
3759
3760     /* Pane for the welcome screen */
3761     welcome_pane = welcome_new();
3762     gtk_widget_show(welcome_pane);
3763 }
3764
3765 static void
3766 show_main_window(gboolean doing_work)
3767 {
3768     main_set_for_capture_file(doing_work);
3769
3770     /*** we have finished all init things, show the main window ***/
3771     gtk_widget_show(top_level);
3772
3773     /* the window can be maximized only, if it's visible, so do it after show! */
3774     main_load_window_geometry(top_level);
3775
3776     /* process all pending GUI events before continue */
3777     while (gtk_events_pending()) gtk_main_iteration();
3778
3779     /* Pop up any queued-up alert boxes. */
3780     display_queued_messages();
3781
3782     /* Move the main window to the front, in case it isn't already there */
3783     gdk_window_raise(gtk_widget_get_window(top_level));
3784
3785 #ifdef HAVE_AIRPCAP
3786     airpcap_toolbar_show(wireless_tb);
3787 #endif /* HAVE_AIRPCAP */
3788 }
3789
3790 static void copy_global_profile (const gchar *profile_name)
3791 {
3792     char  *pf_dir_path, *pf_dir_path2, *pf_filename;
3793
3794     if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3795         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3796             "Can't create directory\n\"%s\":\n%s.",
3797             pf_dir_path, g_strerror(errno));
3798
3799         g_free(pf_dir_path);
3800     }
3801
3802     if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3803             &pf_dir_path, &pf_dir_path2) == -1) {
3804         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3805             "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3806             pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3807
3808         g_free(pf_filename);
3809         g_free(pf_dir_path);
3810         g_free(pf_dir_path2);
3811     }
3812 }
3813
3814 /* Change configuration profile */
3815 void change_configuration_profile (const gchar *profile_name)
3816 {
3817     char  *gdp_path, *dp_path;
3818     char  *rf_path;
3819     int    rf_open_errno;
3820
3821     /* First check if profile exists */
3822     if (!profile_exists(profile_name, FALSE)) {
3823         if (profile_exists(profile_name, TRUE)) {
3824            /* Copy from global profile */
3825             copy_global_profile (profile_name);
3826         } else {
3827             /* No personal and no global profile exists */
3828             return;
3829         }
3830     }
3831
3832     /* Then check if changing to another profile */
3833     if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3834         return;
3835     }
3836
3837     /* Get the current geometry, before writing it to disk */
3838     main_save_window_geometry(top_level);
3839
3840     if (profile_exists(get_profile_name(), FALSE)) {
3841         /* Write recent file for profile we are leaving, if it still exists */
3842         write_profile_recent();
3843     }
3844
3845     /* Set profile name and update the status bar */
3846     set_profile_name (profile_name);
3847     profile_bar_update ();
3848
3849     /* Reset current preferences and apply the new */
3850     prefs_reset();
3851     menu_prefs_reset();
3852
3853     (void) read_configuration_files (&gdp_path, &dp_path);
3854
3855     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
3856         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3857             "Could not open common recent file\n\"%s\": %s.",
3858             rf_path, g_strerror(rf_open_errno));
3859         g_free(rf_path);
3860     }
3861     if (recent.gui_fileopen_remembered_dir &&
3862         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3863         set_last_open_dir(recent.gui_fileopen_remembered_dir);
3864     }
3865     timestamp_set_type (recent.gui_time_format);
3866     timestamp_set_seconds_type (recent.gui_seconds_format);
3867     color_filters_enable(recent.packet_list_colorize);
3868
3869     prefs_to_capture_opts();
3870     prefs_apply_all();
3871     macros_post_update();
3872
3873     /* Update window view and redraw the toolbar */
3874     main_titlebar_update();
3875     filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3876     toolbar_redraw_all();
3877
3878     /* Enable all protocols and disable from the disabled list */
3879     proto_enable_all();
3880     if (gdp_path == NULL && dp_path == NULL) {
3881         set_disabled_protos_list();
3882         set_disabled_heur_dissector_list();
3883     }
3884
3885     /* Reload color filters */
3886     color_filters_reload();
3887
3888     /* Reload list of interfaces on welcome page */
3889     welcome_if_panel_reload();
3890
3891     /* Recreate the packet list according to new preferences */
3892     packet_list_recreate ();
3893     cfile.columns_changed = FALSE; /* Reset value */
3894     user_font_apply();
3895
3896     /* Update menus with new recent values */
3897     menu_recent_read_finished();
3898
3899     /* Reload pane geometry, must be done after recreating the list */
3900     main_pane_load_window_geometry();
3901 }
3902
3903 void
3904 main_fields_changed (void)
3905 {
3906     /* Reload color filters */
3907     color_filters_reload();
3908
3909     /* Syntax check filter */
3910     filter_te_syntax_check_cb(main_display_filter_widget, NULL);
3911     if (cfile.dfilter) {
3912         /* Check if filter is still valid */
3913         dfilter_t *dfp = NULL;
3914         if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
3915             /* Not valid.  Enable 'Apply' button and remove dfilter. */
3916             g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
3917             g_free(cfile.dfilter);
3918             cfile.dfilter = NULL;
3919         }
3920         dfilter_free(dfp);
3921     }
3922
3923     if (have_custom_cols(&cfile.cinfo)) {
3924         /* Recreate packet list according to new/changed/deleted fields */
3925         packet_list_recreate();
3926     } else if (cfile.state != FILE_CLOSED) {
3927         /* Redissect packets if we have any */
3928         redissect_packets();
3929     }
3930     destroy_packet_wins(); /* TODO: close windows until we can recreate */
3931
3932     proto_free_deregistered_fields();
3933 }
3934
3935 /** redissect packets and update UI */
3936 void redissect_packets(void)
3937 {
3938     cf_redissect_packets(&cfile);
3939     status_expert_update();
3940 }
3941
3942 /*
3943  * Editor modelines
3944  *
3945  * Local Variables:
3946  * c-basic-offset: 4
3947  * tab-width: 8
3948  * indent-tabs-mode: nil
3949  * End:
3950  *
3951  * ex: set shiftwidth=4 tabstop=8 expandtab:
3952  * :indentSize=4:tabSize=8:noTabs=true:
3953  */