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