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