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