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