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