From Jakub Zawadzki use gtk_box_pack_start isof gtk_container_add fixes https://bugs...
[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     static const e_addr_resolve resolv_flags = {TRUE, TRUE, TRUE, TRUE, TRUE, FALSE};
920
921     if (cfile.edt->tree) {
922         proto_tree_draw_resolve(cfile.edt->tree, tree_view_gbl, &resolv_flags);
923     }
924 }
925
926 /* Update main window items based on whether there's a capture in progress. */
927 static void
928 main_set_for_capture_in_progress(gboolean capture_in_progress)
929 {
930     set_menus_for_capture_in_progress(capture_in_progress);
931
932 #ifdef HAVE_LIBPCAP
933     set_toolbar_for_capture_in_progress(capture_in_progress);
934
935     set_capture_if_dialog_for_capture_in_progress(capture_in_progress);
936 #endif
937 }
938
939 /* Update main window items based on whether we have a capture file. */
940 static void
941 main_set_for_capture_file(gboolean have_capture_file_in)
942 {
943     have_capture_file = have_capture_file_in;
944
945     main_widgets_show_or_hide();
946 }
947
948 /* Update main window items based on whether we have captured packets. */
949 static void
950 main_set_for_captured_packets(gboolean have_captured_packets)
951 {
952     set_menus_for_captured_packets(have_captured_packets);
953     set_toolbar_for_captured_packets(have_captured_packets);
954 }
955
956 /* Update main window items based on whether we have a packet history. */
957 void
958 main_set_for_packet_history(gboolean back_history, gboolean forward_history)
959 {
960     set_menus_for_packet_history(back_history, forward_history);
961     set_toolbar_for_packet_history(back_history, forward_history);
962 }
963
964 gboolean
965 main_do_quit(void)
966 {
967     /* get the current geometry, before writing it to disk */
968     main_save_window_geometry(top_level);
969
970     /* write user's recent file to disk
971      * It is no problem to write this file, even if we do not quit */
972     write_profile_recent();
973     write_recent();
974
975     /* XXX - should we check whether the capture file is an
976        unsaved temporary file for a live capture and, if so,
977        pop up a "do you want to exit without saving the capture
978        file?" dialog, and then just return, leaving said dialog
979        box to forcibly quit if the user clicks "OK"?
980
981        If so, note that this should be done in a subroutine that
982        returns TRUE if we do so, and FALSE otherwise, and if it
983        returns TRUE we should return TRUE without nuking anything.
984
985        Note that, if we do that, we might also want to check if
986        an "Update list of packets in real time" capture is in
987        progress and, if so, ask whether they want to terminate
988        the capture and discard it, and return TRUE, before nuking
989        any child capture, if they say they don't want to do so. */
990
991 #ifdef HAVE_LIBPCAP
992     /* Nuke any child capture in progress. */
993     capture_kill_child(&global_capture_opts);
994 #endif
995
996     /* Are we in the middle of reading a capture? */
997     if (cfile.state == FILE_READ_IN_PROGRESS) {
998         /* Yes, so we can't just close the file and quit, as
999            that may yank the rug out from under the read in
1000            progress; instead, just set the state to
1001            "FILE_READ_ABORTED" and return - the code doing the read
1002            will check for that and, if it sees that, will clean
1003            up and quit. */
1004         cfile.state = FILE_READ_ABORTED;
1005
1006         /* Say that the window should *not* be deleted;
1007            that'll be done by the code that cleans up. */
1008         return TRUE;
1009     } else {
1010         /* Close any capture file we have open; on some OSes, you
1011            can't unlink a temporary capture file if you have it
1012            open.
1013            "cf_close()" will unlink it after closing it if
1014            it's a temporary file.
1015
1016            We do this here, rather than after the main loop returns,
1017            as, after the main loop returns, the main window may have
1018            been destroyed (if this is called due to a "destroy"
1019            even on the main window rather than due to the user
1020            selecting a menu item), and there may be a crash
1021            or other problem when "cf_close()" tries to
1022            clean up stuff in the main window.
1023
1024            XXX - is there a better place to put this?
1025            Or should we have a routine that *just* closes the
1026            capture file, and doesn't do anything with the UI,
1027            which we'd call here, and another routine that
1028            calls that routine and also cleans up the UI, which
1029            we'd call elsewhere? */
1030         cf_close(&cfile);
1031
1032         /* Exit by leaving the main loop, so that any quit functions
1033            we registered get called. */
1034         gtk_main_quit();
1035
1036         /* Say that the window should be deleted. */
1037         return FALSE;
1038     }
1039 }
1040
1041 static gboolean
1042 main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1043 {
1044     /* If we're in the middle of stopping a capture, don't do anything;
1045        the user can try deleting the window after the capture stops. */
1046     if (capture_stopping)
1047         return TRUE;
1048
1049     /* If there's unsaved data, let the user save it first.
1050        If they cancel out of it, don't quit. */
1051     if (do_file_close(&cfile, TRUE, " before quitting"))
1052         return main_do_quit();
1053     else
1054         return TRUE; /* will this keep the window from being deleted? */
1055 }
1056
1057
1058 static void
1059 main_pane_load_window_geometry(void)
1060 {
1061     if (recent.has_gui_geometry_main_upper_pane && recent.gui_geometry_main_upper_pane)
1062         gtk_paned_set_position(GTK_PANED(main_first_pane), recent.gui_geometry_main_upper_pane);
1063     if (recent.has_gui_geometry_main_lower_pane && recent.gui_geometry_main_lower_pane) {
1064         gtk_paned_set_position(GTK_PANED(main_second_pane), recent.gui_geometry_main_lower_pane);
1065     }
1066 }
1067
1068
1069 static void
1070 main_load_window_geometry(GtkWidget *widget)
1071 {
1072     window_geometry_t geom;
1073
1074     geom.set_pos        = prefs.gui_geometry_save_position;
1075     geom.x              = recent.gui_geometry_main_x;
1076     geom.y              = recent.gui_geometry_main_y;
1077     geom.set_size       = prefs.gui_geometry_save_size;
1078     if (recent.gui_geometry_main_width > 0 &&
1079         recent.gui_geometry_main_height > 0) {
1080         geom.width          = recent.gui_geometry_main_width;
1081         geom.height         = recent.gui_geometry_main_height;
1082         geom.set_maximized  = prefs.gui_geometry_save_maximized;
1083     } else {
1084         /* We assume this means the width and height weren't set in
1085            the "recent" file (or that there is no "recent" file),
1086            and weren't set to a default value, so we don't set the
1087            size.  (The "recent" file code rejects non-positive width
1088            and height values.) */
1089        geom.set_size = FALSE;
1090     }
1091     geom.maximized      = recent.gui_geometry_main_maximized;
1092
1093     window_set_geometry(widget, &geom);
1094
1095     main_pane_load_window_geometry();
1096     statusbar_load_window_geometry();
1097 }
1098
1099
1100 static void
1101 main_save_window_geometry(GtkWidget *widget)
1102 {
1103     window_geometry_t geom;
1104
1105     window_get_geometry(widget, &geom);
1106
1107     if (prefs.gui_geometry_save_position) {
1108         recent.gui_geometry_main_x = geom.x;
1109         recent.gui_geometry_main_y = geom.y;
1110     }
1111
1112     if (prefs.gui_geometry_save_size) {
1113         recent.gui_geometry_main_width  = geom.width;
1114         recent.gui_geometry_main_height = geom.height;
1115     }
1116
1117     if(prefs.gui_geometry_save_maximized) {
1118         recent.gui_geometry_main_maximized = geom.maximized;
1119     }
1120
1121     recent.gui_geometry_main_upper_pane     = gtk_paned_get_position(GTK_PANED(main_first_pane));
1122     recent.gui_geometry_main_lower_pane     = gtk_paned_get_position(GTK_PANED(main_second_pane));
1123     statusbar_save_window_geometry();
1124 }
1125
1126 void
1127 file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
1128 {
1129     /* If there's unsaved data, let the user save it first. */
1130     if (do_file_close(&cfile, TRUE, " before quitting"))
1131         main_do_quit();
1132 }
1133
1134 static void
1135 print_usage(gboolean print_ver) {
1136
1137   FILE *output;
1138
1139 #ifdef _WIN32
1140   create_console();
1141 #endif
1142
1143   if (print_ver) {
1144     output = stdout;
1145     fprintf(output, "Wireshark " VERSION "%s\n"
1146         "Interactively dump and analyze network traffic.\n"
1147         "See http://www.wireshark.org for more information.\n"
1148         "\n"
1149         "%s",
1150         wireshark_svnversion, get_copyright_info());
1151   } else {
1152     output = stderr;
1153   }
1154   fprintf(output, "\n");
1155   fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
1156   fprintf(output, "\n");
1157
1158 #ifdef HAVE_LIBPCAP
1159   fprintf(output, "Capture interface:\n");
1160   fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
1161   fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
1162   fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
1163   fprintf(output, "  -p                       don't capture in promiscuous mode\n");
1164   fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
1165   fprintf(output, "  -S                       update packet display when new packets are captured\n");
1166   fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
1167 #ifdef HAVE_PCAP_CREATE
1168   fprintf(output, "  -I                       capture in monitor mode, if available\n");
1169 #endif
1170 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
1171   fprintf(output, "  -B <buffer size>         size of kernel buffer (def: 1MB)\n");
1172 #endif
1173   fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
1174   fprintf(output, "  -D                       print list of interfaces and exit\n");
1175   fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
1176   fprintf(output, "\n");
1177   fprintf(output, "Capture stop conditions:\n");
1178   fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
1179   fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
1180   fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
1181   fprintf(output, "                              files:NUM - stop after NUM files\n");
1182   /*fprintf(output, "\n");*/
1183   fprintf(output, "Capture output:\n");
1184   fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
1185   fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
1186   fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
1187 #endif  /* HAVE_LIBPCAP */
1188
1189   /*fprintf(output, "\n");*/
1190   fprintf(output, "Input file:\n");
1191   fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
1192
1193   fprintf(output, "\n");
1194   fprintf(output, "Processing:\n");
1195   fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
1196   fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
1197   fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
1198
1199   fprintf(output, "\n");
1200   fprintf(output, "User interface:\n");
1201   fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
1202   fprintf(output, "  -d <display filter>      start with the given display filter\n");
1203   fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
1204   fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
1205   fprintf(output, "                           filter\n");
1206   fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
1207   fprintf(output, "  -m <font>                set the font name used for most text\n");
1208   fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");
1209   fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
1210   fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
1211   fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
1212
1213   fprintf(output, "\n");
1214   fprintf(output, "Output:\n");
1215   fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
1216
1217   fprintf(output, "\n");
1218   fprintf(output, "Miscellaneous:\n");
1219   fprintf(output, "  -h                       display this help and exit\n");
1220   fprintf(output, "  -v                       display version info and exit\n");
1221   fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
1222   fprintf(output, "                           persdata:path - personal data files\n");
1223   fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
1224   fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
1225 #ifndef _WIN32
1226   fprintf(output, "  --display=DISPLAY        X display to use\n");
1227 #endif
1228
1229 #ifdef _WIN32
1230   destroy_console();
1231 #endif
1232 }
1233
1234 static void
1235 show_version(void)
1236 {
1237 #ifdef _WIN32
1238   create_console();
1239 #endif
1240
1241   printf(PACKAGE " " VERSION "%s\n"
1242          "\n"
1243          "%s"
1244          "\n"
1245          "%s"
1246          "\n"
1247          "%s",
1248       wireshark_svnversion, get_copyright_info(), comp_info_str->str,
1249       runtime_info_str->str);
1250
1251 #ifdef _WIN32
1252   destroy_console();
1253 #endif
1254 }
1255
1256 /*
1257  * Print to the standard error.  On Windows, create a console for the
1258  * standard error to show up on, if necessary.
1259  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1260  * terminal isn't the standard error?
1261  */
1262 void
1263 vfprintf_stderr(const char *fmt, va_list ap)
1264 {
1265 #ifdef _WIN32
1266   create_console();
1267 #endif
1268   vfprintf(stderr, fmt, ap);
1269 }
1270
1271 void
1272 fprintf_stderr(const char *fmt, ...)
1273 {
1274   va_list ap;
1275
1276   va_start(ap, fmt);
1277   vfprintf_stderr(fmt, ap);
1278   va_end(ap);
1279 }
1280
1281 /*
1282  * Report an error in command-line arguments.
1283  * Creates a console on Windows.
1284  */
1285 void
1286 cmdarg_err(const char *fmt, ...)
1287 {
1288   va_list ap;
1289
1290   fprintf_stderr("wireshark: ");
1291   va_start(ap, fmt);
1292   vfprintf_stderr(fmt, ap);
1293   va_end(ap);
1294   fprintf_stderr("\n");
1295 }
1296
1297 /*
1298  * Report additional information for an error in command-line arguments.
1299  * Creates a console on Windows.
1300  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
1301  * terminal isn't the standard error?
1302  */
1303 void
1304 cmdarg_err_cont(const char *fmt, ...)
1305 {
1306   va_list ap;
1307
1308   va_start(ap, fmt);
1309   vfprintf_stderr(fmt, ap);
1310   fprintf_stderr("\n");
1311   va_end(ap);
1312 }
1313
1314 /*
1315    Once every 3 seconds we get a callback here which we use to update
1316    the tap extensions.
1317  */
1318 static gboolean
1319 tap_update_cb(gpointer data _U_)
1320 {
1321     draw_tap_listeners(FALSE);
1322     return TRUE;
1323 }
1324
1325 /* Restart the tap update display timer with new configured interval */
1326 void reset_tap_update_timer(void)
1327 {
1328     g_source_remove(tap_update_timer_id);
1329     tap_update_timer_id = g_timeout_add(prefs.tap_update_interval, tap_update_cb, NULL);
1330 }
1331
1332 void
1333 protect_thread_critical_region(void)
1334 {
1335     /* Threading support for TAP:s removed
1336      * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1337      * See the commit for removed code:
1338      * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
1339      */
1340 }
1341 void
1342 unprotect_thread_critical_region(void)
1343 {
1344     /* Threading support for TAP:s removed
1345      * http://www.wireshark.org/lists/wireshark-dev/200611/msg00199.html
1346      */
1347
1348 }
1349
1350 /*
1351  * Periodically process outstanding hostname lookups. If we have new items,
1352  * redraw the packet list and tree view.
1353  */
1354
1355 static gboolean
1356 resolv_update_cb(gpointer data _U_)
1357 {
1358   /* Anything new show up? */
1359   if (host_name_lookup_process(NULL)) {
1360     if (gtk_widget_get_window(pkt_scrollw))
1361       gdk_window_invalidate_rect(gtk_widget_get_window(pkt_scrollw), NULL, TRUE);
1362     if (gtk_widget_get_window(tv_scrollw))
1363       gdk_window_invalidate_rect(gtk_widget_get_window(tv_scrollw), NULL, TRUE);
1364   }
1365
1366   /* Always check. Even if we don't do async lookups we could still get
1367      passive updates, e.g. from DNS packets. */
1368   return TRUE;
1369 }
1370
1371
1372 /* Set main_window_name and it's icon title to the capture filename */
1373 static void
1374 set_display_filename(capture_file *cf)
1375 {
1376   gchar *display_name;
1377   gchar *window_name;
1378
1379   if (cf->filename) {
1380     display_name = cf_get_display_name(cf);
1381     window_name = g_strdup_printf("%s%s", cf->unsaved_changes ? "*" : "",
1382                                   display_name);
1383     g_free(display_name);
1384     main_set_window_name(window_name);
1385     g_free(window_name);
1386   } else {
1387     main_set_window_name("The Wireshark Network Analyzer");
1388   }
1389 }
1390
1391 /* Update various parts of the main window for a capture file "unsaved
1392    changes" change - update the title to reflect whether there are
1393    unsaved changes or not, and update the menus and toolbar to
1394    enable or disable the "Save" operation. */
1395 void
1396 main_update_for_unsaved_changes(capture_file *cf)
1397 {
1398   set_display_filename(cf);
1399   set_menus_for_capture_file(cf);
1400   set_toolbar_for_capture_file(cf);
1401 }
1402
1403 #ifdef HAVE_LIBPCAP
1404 void
1405 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
1406 {
1407   /* Update menubar and toolbar */
1408   menu_auto_scroll_live_changed(auto_scroll_live_in);
1409   toolbar_auto_scroll_live_changed(auto_scroll_live_in);
1410
1411   /* change auto scroll state */
1412   auto_scroll_live  = auto_scroll_live_in;
1413 }
1414 #endif
1415
1416 void
1417 main_colorize_changed(gboolean packet_list_colorize)
1418 {
1419   /* Update menubar and toolbar */
1420   menu_colorize_changed(packet_list_colorize);
1421   toolbar_colorize_changed(packet_list_colorize);
1422
1423   /* change colorization */
1424   if(packet_list_colorize != recent.packet_list_colorize) {
1425       recent.packet_list_colorize = packet_list_colorize;
1426       color_filters_enable(packet_list_colorize);
1427       new_packet_list_colorize_packets();
1428   }
1429 }
1430
1431 static GtkWidget           *close_dlg = NULL;
1432
1433 static void
1434 priv_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1435 {
1436     recent.privs_warn_if_elevated = !simple_dialog_check_get(dialog);
1437 }
1438
1439 #ifdef _WIN32
1440 static void
1441 npf_warning_dialog_cb(gpointer dialog, gint btn _U_, gpointer data _U_)
1442 {
1443     recent.privs_warn_if_no_npf = !simple_dialog_check_get(dialog);
1444 }
1445 #endif
1446
1447 static void
1448 main_cf_cb_file_closing(capture_file *cf)
1449 {
1450     /* if we have more than 10000 packets, show a splash screen while closing */
1451     /* XXX - don't know a better way to decide whether to show or not,
1452      * as most of the time is spend in various calls that destroy various
1453      * data structures, so it wouldn't be easy to use a progress bar,
1454      * rather than, say, a progress spinner, here! */
1455     if(cf->count > 10000) {
1456         close_dlg = simple_dialog(ESD_TYPE_STOP, ESD_BTN_NONE,
1457                                   "%sClosing file!%s\n\nPlease wait ...",
1458                                   simple_dialog_primary_start(),
1459                                   simple_dialog_primary_end());
1460         gtk_window_set_position(GTK_WINDOW(close_dlg), GTK_WIN_POS_CENTER_ON_PARENT);
1461     }
1462
1463     /* Destroy all windows that refer to the
1464        capture file we're closing. */
1465     destroy_packet_wins();
1466
1467     /* Restore the standard title bar message. */
1468     main_set_window_name("The Wireshark Network Analyzer");
1469
1470     /* Disable all menu items that make sense only if you have a capture. */
1471     set_menus_for_capture_file(NULL);
1472     set_toolbar_for_capture_file(NULL);
1473     main_set_for_captured_packets(FALSE);
1474     set_menus_for_selected_packet(cf);
1475     main_set_for_capture_in_progress(FALSE);
1476     set_capture_if_dialog_for_capture_in_progress(FALSE);
1477     set_menus_for_selected_tree_row(cf);
1478
1479     /* Set up main window for no capture file. */
1480     main_set_for_capture_file(FALSE);
1481
1482     main_window_update();
1483 }
1484
1485 static void
1486 main_cf_cb_file_closed(capture_file *cf _U_)
1487 {
1488   if(close_dlg != NULL) {
1489     splash_destroy(close_dlg);
1490     close_dlg = NULL;
1491   }
1492 }
1493
1494
1495 static void
1496 main_cf_cb_file_read_started(capture_file *cf _U_)
1497 {
1498   tap_param_dlg_update();
1499
1500   /* Set up main window for a capture file. */
1501   main_set_for_capture_file(TRUE);
1502 }
1503
1504 static void
1505 main_cf_cb_file_read_finished(capture_file *cf)
1506 {
1507     gchar *dir_path;
1508
1509     if (!cf->is_tempfile && cf->filename) {
1510         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1511         add_menu_recent_capture_file(cf->filename);
1512
1513         /* Remember folder for next Open dialog and save it in recent */
1514         dir_path = get_dirname(g_strdup(cf->filename));
1515         set_last_open_dir(dir_path);
1516         g_free(dir_path);
1517     }
1518
1519     /* Update the appropriate parts of the main window. */
1520     main_update_for_unsaved_changes(cf);
1521
1522     /* Enable menu items that make sense if you have some captured packets. */
1523     main_set_for_captured_packets(TRUE);
1524 }
1525
1526 static void
1527 main_cf_cb_file_rescan_finished(capture_file *cf)
1528 {
1529     gchar *dir_path;
1530
1531     if (!cf->is_tempfile && cf->filename) {
1532         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1533         add_menu_recent_capture_file(cf->filename);
1534
1535         /* Remember folder for next Open dialog and save it in recent */
1536         dir_path = get_dirname(g_strdup(cf->filename));
1537         set_last_open_dir(dir_path);
1538         g_free(dir_path);
1539     }
1540
1541     /* Update the appropriate parts of the main window. */
1542     main_update_for_unsaved_changes(cf);
1543 }
1544
1545 #ifdef HAVE_LIBPCAP
1546 static GList *icon_list_create(
1547     const char **icon16_xpm,
1548     const char **icon32_xpm,
1549     const char **icon48_xpm,
1550     const char **icon64_xpm)
1551 {
1552   GList *icon_list = NULL;
1553   GdkPixbuf * pixbuf16;
1554   GdkPixbuf * pixbuf32;
1555   GdkPixbuf * pixbuf48;
1556   GdkPixbuf * pixbuf64;
1557
1558
1559   if(icon16_xpm != NULL) {
1560       pixbuf16 = gdk_pixbuf_new_from_xpm_data(icon16_xpm);
1561       g_assert(pixbuf16);
1562       icon_list = g_list_append(icon_list, pixbuf16);
1563   }
1564
1565   if(icon32_xpm != NULL) {
1566       pixbuf32 = gdk_pixbuf_new_from_xpm_data(icon32_xpm);
1567       g_assert(pixbuf32);
1568       icon_list = g_list_append(icon_list, pixbuf32);
1569   }
1570
1571   if(icon48_xpm != NULL) {
1572       pixbuf48 = gdk_pixbuf_new_from_xpm_data(icon48_xpm);
1573       g_assert(pixbuf48);
1574       icon_list = g_list_append(icon_list, pixbuf48);
1575   }
1576
1577   if(icon64_xpm != NULL) {
1578       pixbuf64 = gdk_pixbuf_new_from_xpm_data(icon64_xpm);
1579       g_assert(pixbuf64);
1580       icon_list = g_list_append(icon_list, pixbuf64);
1581   }
1582
1583   return icon_list;
1584 }
1585
1586 static void
1587 main_capture_set_main_window_title(capture_options *capture_opts)
1588 {
1589     GString *title = g_string_new("");
1590
1591     g_string_append(title, "Capturing ");
1592     g_string_append_printf(title, "from %s ", cf_get_tempfile_source(capture_opts->cf));
1593     main_set_window_name(title->str);
1594     g_string_free(title, TRUE);
1595 }
1596
1597 static void
1598 main_capture_cb_capture_prepared(capture_options *capture_opts)
1599 {
1600     static GList *icon_list = NULL;
1601
1602     main_capture_set_main_window_title(capture_opts);
1603
1604     if(icon_list == NULL) {
1605         icon_list = icon_list_create(wsiconcap16_xpm, wsiconcap32_xpm, wsiconcap48_xpm, NULL);
1606     }
1607     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1608
1609     /* Disable menu items that make no sense if you're currently running
1610        a capture. */
1611     main_set_for_capture_in_progress(TRUE);
1612     set_capture_if_dialog_for_capture_in_progress(TRUE);
1613
1614     /* Don't set up main window for a capture file. */
1615     main_set_for_capture_file(FALSE);
1616 }
1617
1618 static void
1619 main_capture_cb_capture_update_started(capture_options *capture_opts)
1620 {
1621     /* We've done this in "prepared" above, but it will be cleared while
1622        switching to the next multiple file. */
1623     main_capture_set_main_window_title(capture_opts);
1624
1625     main_set_for_capture_in_progress(TRUE);
1626     set_capture_if_dialog_for_capture_in_progress(TRUE);
1627
1628     /* Enable menu items that make sense if you have some captured
1629        packets (yes, I know, we don't have any *yet*). */
1630     main_set_for_captured_packets(TRUE);
1631
1632     /* Set up main window for a capture file. */
1633     main_set_for_capture_file(TRUE);
1634 }
1635
1636 static void
1637 main_capture_cb_capture_update_finished(capture_options *capture_opts)
1638 {
1639     capture_file *cf = capture_opts->cf;
1640     static GList *icon_list = NULL;
1641
1642     /* The capture isn't stopping any more - it's stopped. */
1643     capture_stopping = FALSE;
1644
1645     if (!cf->is_tempfile && cf->filename) {
1646         /* Add this filename to the list of recent files in the "Recent Files" submenu */
1647         add_menu_recent_capture_file(cf->filename);
1648     }
1649
1650     /* Update the main window as appropriate */
1651     main_update_for_unsaved_changes(cf);
1652
1653     /* Enable menu items that make sense if you're not currently running
1654      a capture. */
1655     main_set_for_capture_in_progress(FALSE);
1656     set_capture_if_dialog_for_capture_in_progress(FALSE);
1657
1658     /* Set up main window for a capture file. */
1659     main_set_for_capture_file(TRUE);
1660
1661     if(icon_list == NULL) {
1662         icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1663     }
1664     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1665
1666     if(global_capture_opts.quit_after_cap) {
1667         /* command line asked us to quit after the capture */
1668         /* don't pop up a dialog to ask for unsaved files etc. */
1669         main_do_quit();
1670     }
1671 }
1672
1673 static void
1674 main_capture_cb_capture_fixed_started(capture_options *capture_opts _U_)
1675 {
1676     /* Don't set up main window for a capture file. */
1677     main_set_for_capture_file(FALSE);
1678 }
1679
1680 static void
1681 main_capture_cb_capture_fixed_finished(capture_options *capture_opts _U_)
1682 {
1683 #if 0
1684     capture_file *cf = capture_opts->cf;
1685 #endif
1686     static GList *icon_list = NULL;
1687
1688     /* The capture isn't stopping any more - it's stopped. */
1689     capture_stopping = FALSE;
1690
1691     /*set_display_filename(cf);*/
1692
1693     /* Enable menu items that make sense if you're not currently running
1694      a capture. */
1695     main_set_for_capture_in_progress(FALSE);
1696     set_capture_if_dialog_for_capture_in_progress(FALSE);
1697
1698     /* Restore the standard title bar message */
1699     /* (just in case we have trouble opening the capture file). */
1700     main_set_window_name("The Wireshark Network Analyzer");
1701
1702     if(icon_list == NULL) {
1703         icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1704     }
1705     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1706
1707     /* We don't have loaded the capture file, this will be done later.
1708      * For now we still have simply a blank screen. */
1709
1710     if(global_capture_opts.quit_after_cap) {
1711         /* command line asked us to quit after the capture */
1712         /* don't pop up a dialog to ask for unsaved files etc. */
1713         main_do_quit();
1714     }
1715 }
1716
1717 static void
1718 main_capture_cb_capture_stopping(capture_options *capture_opts _U_)
1719 {
1720     capture_stopping = TRUE;
1721     set_menus_for_capture_stopping();
1722 #ifdef HAVE_LIBPCAP
1723     set_toolbar_for_capture_stopping();
1724
1725     set_capture_if_dialog_for_capture_stopping();
1726 #endif
1727 }
1728
1729 static void
1730 main_capture_cb_capture_failed(capture_options *capture_opts _U_)
1731 {
1732     static GList *icon_list = NULL;
1733
1734     /* Capture isn't stopping any more. */
1735     capture_stopping = FALSE;
1736
1737     /* the capture failed before the first packet was captured
1738        reset title, menus and icon */
1739
1740     main_set_window_name("The Wireshark Network Analyzer");
1741
1742     main_set_for_capture_in_progress(FALSE);
1743     set_capture_if_dialog_for_capture_in_progress(FALSE);
1744
1745     main_set_for_capture_file(FALSE);
1746
1747     if(icon_list == NULL) {
1748         icon_list = icon_list_create(wsicon16_xpm, wsicon32_xpm, wsicon48_xpm, wsicon64_xpm);
1749     }
1750     gtk_window_set_icon_list(GTK_WINDOW(top_level), icon_list);
1751
1752
1753     if(global_capture_opts.quit_after_cap) {
1754         /* command line asked us to quit after the capture */
1755         /* don't pop up a dialog to ask for unsaved files etc. */
1756         main_do_quit();
1757     }
1758 }
1759 #endif  /* HAVE_LIBPCAP */
1760
1761 static void
1762 main_cf_cb_packet_selected(gpointer data)
1763 {
1764     capture_file *cf = data;
1765
1766     /* Display the GUI protocol tree and packet bytes.
1767       XXX - why do we dump core if we call "proto_tree_draw()"
1768       before calling "add_byte_views()"? */
1769     add_byte_views(cf->edt, tree_view_gbl, byte_nb_ptr_gbl);
1770     proto_tree_draw(cf->edt->tree, tree_view_gbl);
1771
1772     /* Note: Both string and hex value searches in the packet data produce a non-zero
1773        search_pos if successful */
1774     if(cf->search_in_progress &&
1775       (cf->search_pos != 0 || (cf->string && cf->decode_data))) {
1776         highlight_field(cf->edt->tvb, cf->search_pos,
1777                         (GtkTreeView *)tree_view_gbl, cf->edt->tree);
1778     }
1779
1780     /* A packet is selected. */
1781     set_menus_for_selected_packet(cf);
1782 }
1783
1784 static void
1785 main_cf_cb_packet_unselected(capture_file *cf)
1786 {
1787     /* No packet is being displayed; clear the hex dump pane by getting
1788        rid of all the byte views. */
1789     while (gtk_notebook_get_nth_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0) != NULL)
1790         gtk_notebook_remove_page(GTK_NOTEBOOK(byte_nb_ptr_gbl), 0);
1791
1792     /* Add a placeholder byte view so that there's at least something
1793        displayed in the byte view notebook. */
1794     add_byte_tab(byte_nb_ptr_gbl, "", NULL, NULL, tree_view_gbl);
1795
1796     /* And clear the protocol tree display as well. */
1797     proto_tree_draw(NULL, tree_view_gbl);
1798
1799     /* No packet is selected. */
1800     set_menus_for_selected_packet(cf);
1801 }
1802
1803 static void
1804 main_cf_cb_field_unselected(capture_file *cf)
1805 {
1806     set_menus_for_selected_tree_row(cf);
1807 }
1808
1809 static void
1810 main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
1811 {
1812     switch(event) {
1813     case(cf_cb_file_closing):
1814         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closing");
1815         main_cf_cb_file_closing(data);
1816         break;
1817     case(cf_cb_file_closed):
1818         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Closed");
1819         main_cf_cb_file_closed(data);
1820         break;
1821     case(cf_cb_file_read_started):
1822         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read started");
1823         main_cf_cb_file_read_started(data);
1824         break;
1825     case(cf_cb_file_read_finished):
1826         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Read finished");
1827         main_cf_cb_file_read_finished(data);
1828         break;
1829     case(cf_cb_file_reload_started):
1830         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload started");
1831         main_cf_cb_file_read_started(data);
1832         break;
1833     case(cf_cb_file_reload_finished):
1834         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Reload finished");
1835         main_cf_cb_file_read_finished(data);
1836         break;
1837     case(cf_cb_file_rescan_started):
1838         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan started");
1839         break;
1840     case(cf_cb_file_rescan_finished):
1841         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Rescan finished");
1842         main_cf_cb_file_rescan_finished(data);
1843         break;
1844     case(cf_cb_file_fast_save_finished):
1845         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Fast save finished");
1846         main_cf_cb_file_rescan_finished(data);
1847         break;
1848     case(cf_cb_packet_selected):
1849         main_cf_cb_packet_selected(data);
1850         break;
1851     case(cf_cb_packet_unselected):
1852         main_cf_cb_packet_unselected(data);
1853         break;
1854     case(cf_cb_field_unselected):
1855         main_cf_cb_field_unselected(data);
1856         break;
1857     case(cf_cb_file_save_started):
1858         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save started");
1859         break;
1860     case(cf_cb_file_save_finished):
1861         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save finished");
1862         break;
1863     case(cf_cb_file_save_failed):
1864         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
1865         break;
1866     case(cf_cb_file_save_stopped):
1867         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
1868         break;
1869     case(cf_cb_file_export_specified_packets_started):
1870         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
1871         break;
1872     case(cf_cb_file_export_specified_packets_finished):
1873         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
1874         break;
1875     case(cf_cb_file_export_specified_packets_failed):
1876         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
1877         break;
1878     case(cf_cb_file_export_specified_packets_stopped):
1879         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
1880         break;
1881     default:
1882         g_warning("main_cf_callback: event %u unknown", event);
1883         g_assert_not_reached();
1884     }
1885 }
1886
1887 #ifdef HAVE_LIBPCAP
1888 static void
1889 main_capture_callback(gint event, capture_options *capture_opts, gpointer user_data _U_)
1890 {
1891 #ifdef HAVE_GTKOSXAPPLICATION
1892     GtkOSXApplication *theApp;
1893 #endif
1894     switch(event) {
1895     case(capture_cb_capture_prepared):
1896         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture prepared");
1897         main_capture_cb_capture_prepared(capture_opts);
1898         break;
1899     case(capture_cb_capture_update_started):
1900         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update started");
1901         main_capture_cb_capture_update_started(capture_opts);
1902 #ifdef HAVE_GTKOSXAPPLICATION
1903         theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1904         gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsiconcap48_xpm));
1905 #endif
1906         break;
1907     case(capture_cb_capture_update_continue):
1908         /*g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update continue");*/
1909         break;
1910     case(capture_cb_capture_update_finished):
1911         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture update finished");
1912         main_capture_cb_capture_update_finished(capture_opts);
1913         break;
1914     case(capture_cb_capture_fixed_started):
1915         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed started");
1916         main_capture_cb_capture_fixed_started(capture_opts);
1917         break;
1918     case(capture_cb_capture_fixed_continue):
1919         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed continue");
1920         break;
1921     case(capture_cb_capture_fixed_finished):
1922         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture fixed finished");
1923         main_capture_cb_capture_fixed_finished(capture_opts);
1924         break;
1925     case(capture_cb_capture_stopping):
1926         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture stopping");
1927         /* Beware: this state won't be called, if the capture child
1928          * closes the capturing on it's own! */
1929 #ifdef HAVE_GTKOSXAPPLICATION
1930         theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
1931         gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
1932 #endif
1933         main_capture_cb_capture_stopping(capture_opts);
1934         break;
1935     case(capture_cb_capture_failed):
1936         g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: capture failed");
1937         main_capture_cb_capture_failed(capture_opts);
1938         break;
1939     default:
1940         g_warning("main_capture_callback: event %u unknown", event);
1941         g_assert_not_reached();
1942     }
1943 }
1944 #endif
1945
1946 static void
1947 get_gtk_compiled_info(GString *str)
1948 {
1949   g_string_append(str, "with ");
1950   g_string_append_printf(str,
1951 #ifdef GTK_MAJOR_VERSION
1952                     "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1953                     GTK_MICRO_VERSION);
1954 #else
1955                     "GTK+ (version unknown)");
1956 #endif
1957   g_string_append(str, ", ");
1958   /* Cairo */
1959   g_string_append(str, "with Cairo ");
1960   g_string_append(str, CAIRO_VERSION_STRING);
1961   g_string_append(str, ", ");
1962
1963   /* Pango */
1964   g_string_append(str, "with Pango ");
1965   g_string_append(str, PANGO_VERSION_STRING);
1966   g_string_append(str, ", ");
1967
1968
1969 }
1970
1971 static void
1972 get_gui_compiled_info(GString *str)
1973 {
1974   epan_get_compiled_version_info(str);
1975
1976   g_string_append(str, ", ");
1977 #ifdef HAVE_LIBPORTAUDIO
1978 #ifdef PORTAUDIO_API_1
1979   g_string_append(str, "with PortAudio <= V18");
1980 #else /* PORTAUDIO_API_1 */
1981   g_string_append(str, "with ");
1982   g_string_append(str, Pa_GetVersionText());
1983 #endif /* PORTAUDIO_API_1 */
1984 #else /* HAVE_LIBPORTAUDIO */
1985   g_string_append(str, "without PortAudio");
1986 #endif /* HAVE_LIBPORTAUDIO */
1987
1988   g_string_append(str, ", ");
1989 #ifdef HAVE_AIRPCAP
1990   get_compiled_airpcap_version(str);
1991 #else
1992   g_string_append(str, "without AirPcap");
1993 #endif
1994 }
1995
1996 static void
1997 get_gui_runtime_info(GString *str)
1998 {
1999   epan_get_runtime_version_info(str);
2000
2001 #ifdef HAVE_AIRPCAP
2002   g_string_append(str, ", ");
2003   get_runtime_airpcap_version(str);
2004 #endif
2005
2006   if(u3_active()) {
2007     g_string_append(str, ", ");
2008     u3_runtime_info(str);
2009   }
2010 }
2011
2012 static e_prefs *
2013 read_configuration_files(char **gdp_path, char **dp_path)
2014 {
2015   int                  gpf_open_errno, gpf_read_errno;
2016   int                  cf_open_errno, df_open_errno;
2017   int                  gdp_open_errno, gdp_read_errno;
2018   int                  dp_open_errno, dp_read_errno;
2019   char                *gpf_path, *pf_path;
2020   char                *cf_path, *df_path;
2021   int                  pf_open_errno, pf_read_errno;
2022   e_prefs             *prefs_p;
2023
2024   /* load the decode as entries of this profile */
2025   load_decode_as_entries();
2026
2027   /* Read the preference files. */
2028   prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
2029                      &pf_open_errno, &pf_read_errno, &pf_path);
2030
2031   if (gpf_path != NULL) {
2032     if (gpf_open_errno != 0) {
2033       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2034         "Could not open global preferences file\n\"%s\": %s.", gpf_path,
2035         g_strerror(gpf_open_errno));
2036     }
2037     if (gpf_read_errno != 0) {
2038       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2039         "I/O error reading global preferences file\n\"%s\": %s.", gpf_path,
2040         g_strerror(gpf_read_errno));
2041     }
2042   }
2043   if (pf_path != NULL) {
2044     if (pf_open_errno != 0) {
2045       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2046         "Could not open your preferences file\n\"%s\": %s.", pf_path,
2047         g_strerror(pf_open_errno));
2048     }
2049     if (pf_read_errno != 0) {
2050       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2051         "I/O error reading your preferences file\n\"%s\": %s.", pf_path,
2052         g_strerror(pf_read_errno));
2053     }
2054     g_free(pf_path);
2055     pf_path = NULL;
2056   }
2057
2058 #ifdef _WIN32
2059   /* if the user wants a console to be always there, well, we should open one for him */
2060   if (prefs_p->gui_console_open == console_open_always) {
2061     create_console();
2062   }
2063 #endif
2064
2065   /* Read the capture filter file. */
2066   read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
2067   if (cf_path != NULL) {
2068       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2069         "Could not open your capture filter file\n\"%s\": %s.", cf_path,
2070         g_strerror(cf_open_errno));
2071       g_free(cf_path);
2072   }
2073
2074   /* Read the display filter file. */
2075   read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
2076   if (df_path != NULL) {
2077       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2078         "Could not open your display filter file\n\"%s\": %s.", df_path,
2079         g_strerror(df_open_errno));
2080       g_free(df_path);
2081   }
2082
2083   /* Read the disabled protocols file. */
2084   read_disabled_protos_list(gdp_path, &gdp_open_errno, &gdp_read_errno,
2085                             dp_path, &dp_open_errno, &dp_read_errno);
2086   if (*gdp_path != NULL) {
2087     if (gdp_open_errno != 0) {
2088       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2089         "Could not open global disabled protocols file\n\"%s\": %s.",
2090         *gdp_path, g_strerror(gdp_open_errno));
2091     }
2092     if (gdp_read_errno != 0) {
2093       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2094         "I/O error reading global disabled protocols file\n\"%s\": %s.",
2095         *gdp_path, g_strerror(gdp_read_errno));
2096     }
2097     g_free(*gdp_path);
2098     *gdp_path = NULL;
2099   }
2100   if (*dp_path != NULL) {
2101     if (dp_open_errno != 0) {
2102       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2103         "Could not open your disabled protocols file\n\"%s\": %s.", *dp_path,
2104         g_strerror(dp_open_errno));
2105     }
2106     if (dp_read_errno != 0) {
2107       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2108         "I/O error reading your disabled protocols file\n\"%s\": %s.", *dp_path,
2109         g_strerror(dp_read_errno));
2110     }
2111     g_free(*dp_path);
2112     *dp_path = NULL;
2113   }
2114
2115   return prefs_p;
2116 }
2117
2118 /*  Check if there's something important to tell the user during startup.
2119  *  We want to do this *after* showing the main window so that any windows
2120  *  we pop up will be above the main window.
2121  */
2122 static void
2123 #ifdef _WIN32
2124 check_and_warn_user_startup(gchar *cf_name)
2125 #else
2126 check_and_warn_user_startup(gchar *cf_name _U_)
2127 #endif
2128 {
2129   gchar               *cur_user, *cur_group;
2130   gpointer             priv_warning_dialog;
2131
2132   /* Tell the user not to run as root. */
2133   if (running_with_special_privs() && recent.privs_warn_if_elevated) {
2134     cur_user = get_cur_username();
2135     cur_group = get_cur_groupname();
2136     priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2137       "Running as user \"%s\" and group \"%s\".\n"
2138       "This could be dangerous.\n\n"
2139       "If you're running Wireshark this way in order to perform live capture, "
2140       "you may want to be aware that there is a better way documented at\n"
2141       "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
2142     g_free(cur_user);
2143     g_free(cur_group);
2144     simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2145     simple_dialog_set_cb(priv_warning_dialog, priv_warning_dialog_cb, NULL);
2146   }
2147
2148 #ifdef _WIN32
2149   /* Warn the user if npf.sys isn't loaded. */
2150   if (!stdin_capture && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
2151     priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2152       "The NPF driver isn't running.  You may have trouble\n"
2153       "capturing or listing interfaces.");
2154     simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
2155     simple_dialog_set_cb(priv_warning_dialog, npf_warning_dialog_cb, NULL);
2156   }
2157 #endif
2158
2159 }
2160
2161
2162 /* And now our feature presentation... [ fade to music ] */
2163 int
2164 main(int argc, char *argv[])
2165 {
2166   char                *init_progfile_dir_error;
2167   char                *s;
2168   int                  opt;
2169   gboolean             arg_error = FALSE;
2170
2171   extern int           info_update_freq;  /* Found in about_dlg.c. */
2172   const gchar         *filter;
2173
2174 #ifdef _WIN32
2175   WSADATA              wsaData;
2176 #endif  /* _WIN32 */
2177
2178   char                *rf_path;
2179   int                  rf_open_errno;
2180   char                *gdp_path, *dp_path;
2181   int                  err;
2182 #ifdef HAVE_LIBPCAP
2183   gboolean             start_capture = FALSE;
2184   gboolean             list_link_layer_types = FALSE;
2185   GList               *if_list;
2186   gchar               *err_str;
2187 #else
2188   gboolean             capture_option_specified = FALSE;
2189 #ifdef _WIN32
2190 #ifdef HAVE_AIRPCAP
2191   gchar               *err_str;
2192 #endif
2193 #endif
2194 #endif
2195   gint                 pl_size = 280, tv_size = 95, bv_size = 75;
2196   gchar               *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
2197   dfilter_t           *rfcode = NULL;
2198   gboolean             rfilter_parse_failed = FALSE;
2199   e_prefs             *prefs_p;
2200   char                 badopt;
2201   GtkWidget           *splash_win = NULL;
2202   GLogLevelFlags       log_flags;
2203   guint                go_to_packet = 0;
2204   gboolean             jump_backwards = FALSE;
2205   dfilter_t           *jump_to_filter = NULL;
2206   int                  optind_initial;
2207   int                  status;
2208 #ifdef HAVE_GTKOSXAPPLICATION
2209   GtkOSXApplication   *theApp;
2210 #endif
2211
2212 #ifdef HAVE_LIBPCAP
2213 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2214 #define OPTSTRING_B "B:"
2215 #else
2216 #define OPTSTRING_B ""
2217 #endif  /* _WIN32 or HAVE_PCAP_CREATE */
2218 #else /* HAVE_LIBPCAP */
2219 #define OPTSTRING_B ""
2220 #endif  /* HAVE_LIBPCAP */
2221
2222 #ifdef HAVE_PCAP_CREATE
2223 #define OPTSTRING_I "I"
2224 #else
2225 #define OPTSTRING_I ""
2226 #endif
2227
2228 #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:"
2229
2230   static const char optstring[] = OPTSTRING;
2231
2232   /* Set the C-language locale to the native environment. */
2233   setlocale(LC_ALL, "");
2234 #ifdef _WIN32
2235   arg_list_utf_16to8(argc, argv);
2236 #endif /* _WIN32 */
2237
2238   /*
2239    * Get credential information for later use, and drop privileges
2240    * before doing anything else.
2241    * Let the user know if anything happened.
2242    */
2243   init_process_policies();
2244   relinquish_special_privs_perm();
2245
2246   /*
2247    * Attempt to get the pathname of the executable file.
2248    */
2249   init_progfile_dir_error = init_progfile_dir(argv[0], main);
2250
2251   /* initialize the funnel mini-api */
2252   initialize_funnel_ops();
2253
2254   AirPDcapInitContext(&airpdcap_ctx);
2255
2256 #ifdef _WIN32
2257   /* Load wpcap if possible. Do this before collecting the run-time version information */
2258   load_wpcap();
2259
2260   /* ... and also load the packet.dll from wpcap */
2261   wpcap_packet_load();
2262
2263 #ifdef HAVE_AIRPCAP
2264   /* Load the airpcap.dll.  This must also be done before collecting
2265    * run-time version information. */
2266   airpcap_dll_ret_val = load_airpcap();
2267
2268   switch (airpcap_dll_ret_val) {
2269   case AIRPCAP_DLL_OK:
2270     /* load the airpcap interfaces */
2271     airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
2272
2273     if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
2274       if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
2275         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
2276         g_free(err_str);
2277       }
2278       airpcap_if_active = NULL;
2279
2280     } else {
2281
2282       /* select the first ad default (THIS SHOULD BE CHANGED) */
2283       airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
2284           }
2285     break;
2286 #if 0
2287     /*
2288      * XXX - Maybe we need to warn the user if one of the following happens???
2289      */
2290     case AIRPCAP_DLL_OLD:
2291       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
2292       break;
2293
2294     case AIRPCAP_DLL_ERROR:
2295       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
2296       break;
2297
2298     case AIRPCAP_DLL_NOT_FOUND:
2299       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
2300       break;
2301 #endif
2302   }
2303 #endif /* HAVE_AIRPCAP */
2304
2305   /* Start windows sockets */
2306   WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
2307 #endif  /* _WIN32 */
2308
2309   profile_store_persconffiles (TRUE);
2310
2311   /* Assemble the compile-time version information string */
2312   comp_info_str = g_string_new("Compiled ");
2313
2314   get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
2315
2316   /* Assemble the run-time version information string */
2317   runtime_info_str = g_string_new("Running ");
2318   get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
2319
2320   /* Read the profile independent recent file.  We have to do this here so we can */
2321   /* set the profile before it can be set from the command line parameterts */
2322   recent_read_static(&rf_path, &rf_open_errno);
2323   if (rf_path != NULL && rf_open_errno != 0) {
2324     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2325                   "Could not open common recent file\n\"%s\": %s.",
2326                   rf_path, g_strerror(rf_open_errno));
2327   }
2328
2329   /* "pre-scan" the command line parameters, if we have "console only"
2330      parameters.  We do this so we don't start GTK+ if we're only showing
2331      command-line help or version information.
2332
2333      XXX - this pre-scan is done before we start GTK+, so we haven't
2334      run gtk_init() on the arguments.  That means that GTK+ arguments
2335      have not been removed from the argument list; those arguments
2336      begin with "--", and will be treated as an error by getopt().
2337
2338      We thus ignore errors - *and* set "opterr" to 0 to suppress the
2339      error messages. */
2340   opterr = 0;
2341   optind_initial = optind;
2342   while ((opt = getopt(argc, argv, optstring)) != -1) {
2343     switch (opt) {
2344       case 'C':        /* Configuration Profile */
2345         if (profile_exists (optarg, FALSE)) {
2346           set_profile_name (optarg);
2347         } else {
2348           cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
2349           exit(1);
2350         }
2351         break;
2352       case 'D':        /* Print a list of capture devices and exit */
2353 #ifdef HAVE_LIBPCAP
2354         if_list = capture_interface_list(&err, &err_str);
2355         if (if_list == NULL) {
2356           switch (err) {
2357           case CANT_GET_INTERFACE_LIST:
2358           case DONT_HAVE_PCAP:
2359             cmdarg_err("%s", err_str);
2360             g_free(err_str);
2361             break;
2362
2363           case NO_INTERFACES_FOUND:
2364             cmdarg_err("There are no interfaces on which a capture can be done");
2365             break;
2366           }
2367           exit(2);
2368         }
2369         capture_opts_print_interfaces(if_list);
2370         free_interface_list(if_list);
2371         exit(0);
2372 #else
2373         capture_option_specified = TRUE;
2374         arg_error = TRUE;
2375 #endif
2376         break;
2377       case 'h':        /* Print help and exit */
2378         print_usage(TRUE);
2379         exit(0);
2380         break;
2381 #ifdef _WIN32
2382       case 'i':
2383         if (strcmp(optarg, "-") == 0)
2384           stdin_capture = TRUE;
2385         break;
2386 #endif
2387       case 'P':        /* Path settings - change these before the Preferences and alike are processed */
2388         status = filesystem_opt(opt, optarg);
2389         if(status != 0) {
2390             cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
2391             exit(status);
2392         }
2393         break;
2394       case 'v':        /* Show version and exit */
2395         show_version();
2396         exit(0);
2397         break;
2398       case 'X':
2399         /*
2400          *  Extension command line options have to be processed before
2401          *  we call epan_init() as they are supposed to be used by dissectors
2402          *  or taps very early in the registration process.
2403          */
2404         ex_opt_add(optarg);
2405         break;
2406       case '?':        /* Ignore errors - the "real" scan will catch them. */
2407         break;
2408     }
2409   }
2410
2411   /* Init the "Open file" dialog directory */
2412   /* (do this after the path settings are processed) */
2413
2414   /* Read the profile dependent (static part) of the recent file. */
2415   /* Only the static part of it will be read, as we don't have the gui now to fill the */
2416   /* recent lists which is done in the dynamic part. */
2417   /* We have to do this already here, so command line parameters can overwrite these values. */
2418   recent_read_profile_static(&rf_path, &rf_open_errno);
2419   if (rf_path != NULL && rf_open_errno != 0) {
2420     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2421                   "Could not open recent file\n\"%s\": %s.",
2422                   rf_path, g_strerror(rf_open_errno));
2423   }
2424
2425   if (recent.gui_fileopen_remembered_dir &&
2426       test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
2427     set_last_open_dir(recent.gui_fileopen_remembered_dir);
2428   } else {
2429     set_last_open_dir(get_persdatafile_dir());
2430   }
2431
2432   /* Set getopt index back to initial value, so it will start with the
2433      first command line parameter again.  Also reset opterr to 1, so that
2434      error messages are printed by getopt().
2435
2436      XXX - this seems to work on most platforms, but time will tell.
2437      The Single UNIX Specification says "The getopt() function need
2438      not be reentrant", so this isn't guaranteed to work.  The Mac
2439      OS X 10.4[.x] getopt() man page says
2440
2441        In order to use getopt() to evaluate multiple sets of arguments, or to
2442        evaluate a single set of arguments multiple times, the variable optreset
2443        must be set to 1 before the second and each additional set of calls to
2444        getopt(), and the variable optind must be reinitialized.
2445
2446            ...
2447
2448        The optreset variable was added to make it possible to call the getopt()
2449        function multiple times.  This is an extension to the IEEE Std 1003.2
2450        (``POSIX.2'') specification.
2451
2452      which I think comes from one of the other BSDs.
2453
2454      XXX - if we want to control all the command-line option errors, so
2455      that we can display them where we choose (e.g., in a window), we'd
2456      want to leave opterr as 0, and produce our own messages using optopt.
2457      We'd have to check the value of optopt to see if it's a valid option
2458      letter, in which case *presumably* the error is "this option requires
2459      an argument but none was specified", or not a valid option letter,
2460      in which case *presumably* the error is "this option isn't valid".
2461      Some versions of getopt() let you supply a option string beginning
2462      with ':', which means that getopt() will return ':' rather than '?'
2463      for "this option requires an argument but none was specified", but
2464      not all do. */
2465   optind = optind_initial;
2466   opterr = 1;
2467
2468 #if !GLIB_CHECK_VERSION(2,31,0)
2469   g_thread_init(NULL);
2470 #endif
2471
2472   /* Set the current locale according to the program environment.
2473    * We haven't localized anything, but some GTK widgets are localized
2474    * (the file selection dialogue, for example).
2475    * This also sets the C-language locale to the native environment. */
2476   setlocale (LC_ALL, "");
2477
2478   /* Let GTK get its args (will need an X server, so do this after command line only commands handled) */
2479   gtk_init (&argc, &argv);
2480
2481   cf_callback_add(main_cf_callback, NULL);
2482 #ifdef HAVE_LIBPCAP
2483   capture_callback_add(main_capture_callback, NULL);
2484 #endif
2485   cf_callback_add(statusbar_cf_callback, NULL);
2486 #ifdef HAVE_LIBPCAP
2487   capture_callback_add(statusbar_capture_callback, NULL);
2488 #endif
2489
2490   /* Arrange that if we have no console window, and a GLib message logging
2491      routine is called to log a message, we pop up a console window.
2492
2493      We do that by inserting our own handler for all messages logged
2494      to the default domain; that handler pops up a console if necessary,
2495      and then calls the default handler. */
2496
2497   /* We might want to have component specific log levels later ... */
2498
2499   log_flags =
2500             G_LOG_LEVEL_ERROR|
2501             G_LOG_LEVEL_CRITICAL|
2502             G_LOG_LEVEL_WARNING|
2503             G_LOG_LEVEL_MESSAGE|
2504             G_LOG_LEVEL_INFO|
2505             G_LOG_LEVEL_DEBUG|
2506             G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
2507
2508   g_log_set_handler(NULL,
2509             log_flags,
2510             console_log_handler, NULL /* user_data */);
2511   g_log_set_handler(LOG_DOMAIN_MAIN,
2512             log_flags,
2513             console_log_handler, NULL /* user_data */);
2514
2515 #ifdef HAVE_LIBPCAP
2516   g_log_set_handler(LOG_DOMAIN_CAPTURE,
2517             log_flags,
2518             console_log_handler, NULL /* user_data */);
2519   g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
2520             log_flags,
2521             console_log_handler, NULL /* user_data */);
2522
2523   /* Set the initial values in the capture options. This might be overwritten
2524      by preference settings and then again by the command line parameters. */
2525   capture_opts_init(&global_capture_opts, &cfile);
2526 #endif
2527
2528   /* Initialize whatever we need to allocate colors for GTK+ */
2529   colors_init();
2530
2531   /* Non-blank filter means we're remote. Throttle splash screen and resolution updates. */
2532   filter = get_conn_cfilter();
2533   if ( *filter != '\0' ) {
2534     info_update_freq = 1000;  /* Milliseconds */
2535   }
2536
2537   /* We won't come till here, if we had a "console only" command line parameter. */
2538   splash_win = splash_new("Loading Wireshark ...");
2539   if (init_progfile_dir_error != NULL) {
2540     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2541         "Can't get pathname of Wireshark: %s.\n"
2542         "It won't be possible to capture traffic.\n"
2543         "Report this to the Wireshark developers.",
2544         init_progfile_dir_error);
2545     g_free(init_progfile_dir_error);
2546   }
2547
2548   splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win);
2549
2550   /* Register all dissectors; we must do this before checking for the
2551      "-G" flag, as the "-G" flag dumps information registered by the
2552      dissectors, and we must do it before we read the preferences, in
2553      case any dissectors register preferences. */
2554   epan_init(register_all_protocols,register_all_protocol_handoffs,
2555             splash_update, (gpointer) splash_win,
2556             failure_alert_box,open_failure_alert_box,read_failure_alert_box,
2557             write_failure_alert_box);
2558
2559   splash_update(RA_LISTENERS, NULL, (gpointer)splash_win);
2560
2561   /* Register all tap listeners; we do this before we parse the arguments,
2562      as the "-z" argument can specify a registered tap. */
2563
2564   /* we register the plugin taps before the other taps because
2565      stats_tree taps plugins will be registered as tap listeners
2566      by stats_tree_stat.c and need to registered before that */
2567
2568 #ifdef HAVE_PLUGINS
2569   register_all_plugin_tap_listeners();
2570 #endif
2571
2572   register_all_tap_listeners();
2573
2574   splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
2575
2576   prefs_p = read_configuration_files (&gdp_path, &dp_path);
2577   /* Removed thread code:
2578    * http://anonsvn.wireshark.org/viewvc/viewvc.cgi?view=rev&revision=35027
2579    */
2580
2581   /* this is to keep tap extensions updating once every 3 seconds */
2582   tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
2583
2584   splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win);
2585   proto_help_init();
2586   cap_file_init(&cfile);
2587
2588   /* Fill in capture options with values from the preferences */
2589   prefs_to_capture_opts();
2590
2591 /*#ifdef HAVE_LIBPCAP
2592   fill_in_local_interfaces(&global_capture_opts);
2593 #endif*/
2594   /* Now get our args */
2595   while ((opt = getopt(argc, argv, optstring)) != -1) {
2596     switch (opt) {
2597       /*** capture option specific ***/
2598       case 'a':        /* autostop criteria */
2599       case 'b':        /* Ringbuffer option */
2600       case 'c':        /* Capture xxx packets */
2601       case 'f':        /* capture filter */
2602       case 'k':        /* Start capture immediately */
2603       case 'H':        /* Hide capture info dialog box */
2604       case 'p':        /* Don't capture in promiscuous mode */
2605       case 'i':        /* Use interface x */
2606 #ifdef HAVE_PCAP_CREATE
2607       case 'I':        /* Capture in monitor mode, if available */
2608 #endif
2609       case 's':        /* Set the snapshot (capture) length */
2610       case 'S':        /* "Sync" mode: used for following file ala tail -f */
2611       case 'w':        /* Write to capture file xxx */
2612       case 'y':        /* Set the pcap data link type */
2613 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
2614       case 'B':        /* Buffer size */
2615 #endif /* _WIN32 or HAVE_PCAP_CREATE */
2616 #ifdef HAVE_LIBPCAP
2617         status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
2618                                       &start_capture);
2619         if(status != 0) {
2620             exit(status);
2621         }
2622 #else
2623         capture_option_specified = TRUE;
2624         arg_error = TRUE;
2625 #endif
2626         break;
2627
2628 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
2629       case 'K':        /* Kerberos keytab file */
2630         read_keytab_file(optarg);
2631         break;
2632 #endif
2633
2634       /*** all non capture option specific ***/
2635       case 'C':
2636         /* Configuration profile settings were already processed just ignore them this time*/
2637         break;
2638       case 'd':
2639         dfilter = optarg;
2640         break;
2641       case 'j':        /* Search backwards for a matching packet from filter in option J */
2642         jump_backwards = TRUE;
2643         break;
2644       case 'g':        /* Go to packet with the given packet number */
2645         go_to_packet = get_positive_int(optarg, "go to packet");
2646         break;
2647       case 'J':        /* Jump to the first packet which matches the filter criteria */
2648         jfilter = optarg;
2649         break;
2650       case 'l':        /* Automatic scrolling in live capture mode */
2651 #ifdef HAVE_LIBPCAP
2652         auto_scroll_live = TRUE;
2653 #else
2654         capture_option_specified = TRUE;
2655         arg_error = TRUE;
2656 #endif
2657         break;
2658       case 'L':        /* Print list of link-layer types and exit */
2659 #ifdef HAVE_LIBPCAP
2660         list_link_layer_types = TRUE;
2661 #else
2662         capture_option_specified = TRUE;
2663         arg_error = TRUE;
2664 #endif
2665         break;
2666       case 'm':        /* Fixed-width font for the display */
2667         g_free(prefs_p->gui_font_name);
2668         prefs_p->gui_font_name = g_strdup(optarg);
2669         break;
2670       case 'n':        /* No name resolution */
2671         gbl_resolv_flags.mac_name = FALSE;
2672         gbl_resolv_flags.network_name = FALSE;
2673         gbl_resolv_flags.transport_name = FALSE;
2674         gbl_resolv_flags.concurrent_dns = FALSE;
2675         break;
2676       case 'N':        /* Select what types of addresses/port #s to resolve */
2677         badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
2678         if (badopt != '\0') {
2679           cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
2680             badopt);
2681           exit(1);
2682         }
2683         break;
2684       case 'o':        /* Override preference from command line */
2685         switch (prefs_set_pref(optarg)) {
2686         case PREFS_SET_OK:
2687           break;
2688         case PREFS_SET_SYNTAX_ERR:
2689           cmdarg_err("Invalid -o flag \"%s\"", optarg);
2690           exit(1);
2691           break;
2692         case PREFS_SET_NO_SUCH_PREF:
2693           /* not a preference, might be a recent setting */
2694           switch (recent_set_arg(optarg)) {
2695             case PREFS_SET_OK:
2696               break;
2697             case PREFS_SET_SYNTAX_ERR:
2698               /* shouldn't happen, checked already above */
2699               cmdarg_err("Invalid -o flag \"%s\"", optarg);
2700               exit(1);
2701               break;
2702             case PREFS_SET_NO_SUCH_PREF:
2703             case PREFS_SET_OBSOLETE:
2704               cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
2705                 optarg);
2706               exit(1);
2707               break;
2708             default:
2709               g_assert_not_reached();
2710             }
2711           break;
2712         case PREFS_SET_OBSOLETE:
2713           cmdarg_err("-o flag \"%s\" specifies obsolete preference",
2714             optarg);
2715           exit(1);
2716           break;
2717         default:
2718           g_assert_not_reached();
2719         }
2720         break;
2721       case 'P':
2722         /* Path settings were already processed just ignore them this time*/
2723         break;
2724       case 'r':        /* Read capture file xxx */
2725         /* We may set "last_open_dir" to "cf_name", and if we change
2726         "last_open_dir" later, we free the old value, so we have to
2727         set "cf_name" to something that's been allocated. */
2728         cf_name = g_strdup(optarg);
2729         break;
2730       case 'R':        /* Read file filter */
2731         rfilter = optarg;
2732         break;
2733       case 't':        /* Time stamp type */
2734         if (strcmp(optarg, "r") == 0)
2735           timestamp_set_type(TS_RELATIVE);
2736         else if (strcmp(optarg, "a") == 0)
2737           timestamp_set_type(TS_ABSOLUTE);
2738         else if (strcmp(optarg, "ad") == 0)
2739           timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
2740         else if (strcmp(optarg, "d") == 0)
2741           timestamp_set_type(TS_DELTA);
2742         else if (strcmp(optarg, "dd") == 0)
2743           timestamp_set_type(TS_DELTA_DIS);
2744         else if (strcmp(optarg, "e") == 0)
2745           timestamp_set_type(TS_EPOCH);
2746         else if (strcmp(optarg, "u") == 0)
2747           timestamp_set_type(TS_UTC);
2748         else if (strcmp(optarg, "ud") == 0)
2749           timestamp_set_type(TS_UTC_WITH_DATE);
2750         else {
2751           cmdarg_err("Invalid time stamp type \"%s\"", optarg);
2752           cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
2753           cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
2754           exit(1);
2755         }
2756         break;
2757       case 'u':        /* Seconds type */
2758         if (strcmp(optarg, "s") == 0)
2759           timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
2760         else if (strcmp(optarg, "hms") == 0)
2761           timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
2762         else {
2763           cmdarg_err("Invalid seconds type \"%s\"", optarg);
2764           cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
2765           exit(1);
2766         }
2767         break;
2768       case 'X':
2769           /* ext ops were already processed just ignore them this time*/
2770           break;
2771       case 'z':
2772         /* We won't call the init function for the stat this soon
2773            as it would disallow MATE's fields (which are registered
2774            by the preferences set callback) from being used as
2775            part of a tap filter.  Instead, we just add the argument
2776            to a list of stat arguments. */
2777         if (!process_stat_cmd_arg(optarg)) {
2778           cmdarg_err("Invalid -z argument.");
2779           cmdarg_err_cont("  -z argument must be one of :");
2780           list_stat_cmd_args();
2781           exit(1);
2782         }
2783         break;
2784       default:
2785       case '?':        /* Bad flag - print usage message */
2786         arg_error = TRUE;
2787         break;
2788     }
2789   }
2790   if (!arg_error) {
2791     argc -= optind;
2792     argv += optind;
2793     if (argc >= 1) {
2794       if (cf_name != NULL) {
2795         /*
2796          * Input file name specified with "-r" *and* specified as a regular
2797          * command-line argument.
2798          */
2799         cmdarg_err("File name specified both with -r and regular argument");
2800         arg_error = TRUE;
2801       } else {
2802         /*
2803          * Input file name not specified with "-r", and a command-line argument
2804          * was specified; treat it as the input file name.
2805          *
2806          * Yes, this is different from tshark, where non-flag command-line
2807          * arguments are a filter, but this works better on GUI desktops
2808          * where a command can be specified to be run to open a particular
2809          * file - yes, you could have "-r" as the last part of the command,
2810          * but that's a bit ugly.
2811          */
2812         cf_name = g_strdup(argv[0]);
2813       }
2814       argc--;
2815       argv++;
2816     }
2817
2818     if (argc != 0) {
2819       /*
2820        * Extra command line arguments were specified; complain.
2821        */
2822       cmdarg_err("Invalid argument: %s", argv[0]);
2823       arg_error = TRUE;
2824     }
2825   }
2826   if (arg_error) {
2827 #ifndef HAVE_LIBPCAP
2828     if (capture_option_specified) {
2829       cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
2830     }
2831 #endif
2832     print_usage(FALSE);
2833     exit(1);
2834   }
2835   
2836 #ifdef HAVE_LIBPCAP
2837   fill_in_local_interfaces(&global_capture_opts);
2838   if (start_capture && list_link_layer_types) {
2839     /* Specifying *both* is bogus. */
2840     cmdarg_err("You can't specify both -L and a live capture.");
2841     exit(1);
2842   }
2843
2844   if (list_link_layer_types) {
2845     /* We're supposed to list the link-layer types for an interface;
2846        did the user also specify a capture file to be read? */
2847     if (cf_name) {
2848       /* Yes - that's bogus. */
2849       cmdarg_err("You can't specify -L and a capture file to be read.");
2850       exit(1);
2851     }
2852     /* No - did they specify a ring buffer option? */
2853     if (global_capture_opts.multi_files_on) {
2854       cmdarg_err("Ring buffer requested, but a capture isn't being done.");
2855       exit(1);
2856     }
2857   } else {
2858     /* We're supposed to do a live capture; did the user also specify
2859        a capture file to be read? */
2860     if (start_capture && cf_name) {
2861       /* Yes - that's bogus. */
2862       cmdarg_err("You can't specify both a live capture and a capture file to be read.");
2863       exit(1);
2864     }
2865
2866     /* No - was the ring buffer option specified and, if so, does it make
2867        sense? */
2868     if (global_capture_opts.multi_files_on) {
2869       /* Ring buffer works only under certain conditions:
2870       a) ring buffer does not work with temporary files;
2871       b) real_time_mode and multi_files_on are mutually exclusive -
2872          real_time_mode takes precedence;
2873       c) it makes no sense to enable the ring buffer if the maximum
2874          file size is set to "infinite". */
2875       if (global_capture_opts.save_file == NULL) {
2876         cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
2877         global_capture_opts.multi_files_on = FALSE;
2878       }
2879       if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
2880         cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
2881         /* XXX - this must be redesigned as the conditions changed */
2882       }
2883     }
2884   }
2885
2886   if (start_capture || list_link_layer_types) {
2887     /* Did the user specify an interface to use? */
2888     if (!capture_opts_trim_iface(&global_capture_opts,
2889         (prefs_p->capture_device) ? get_if_name(prefs_p->capture_device) : NULL)) {
2890         exit(2);
2891     }
2892   }
2893
2894   if (list_link_layer_types) {
2895     /* Get the list of link-layer types for the capture devices. */
2896     if_capabilities_t *caps;
2897     guint i;
2898     interface_t device;
2899     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2900
2901       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2902       if (device.selected) {
2903 #if defined(HAVE_PCAP_CREATE)
2904         caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, &err_str);
2905 #else
2906         caps = capture_get_if_capabilities(device.name, FALSE, &err_str);
2907 #endif
2908         if (caps == NULL) {
2909           cmdarg_err("%s", err_str);
2910           g_free(err_str);
2911           exit(2);
2912         }
2913         if (caps->data_link_types == NULL) {
2914           cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
2915           exit(2);
2916         }
2917 #if defined(HAVE_PCAP_CREATE)
2918         capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
2919 #else
2920         capture_opts_print_if_capabilities(caps, device.name, FALSE);
2921 #endif
2922         free_if_capabilities(caps);
2923       }
2924     }
2925     exit(0);
2926   }
2927
2928   capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
2929   capture_opts_trim_ring_num_files(&global_capture_opts);
2930 #endif /* HAVE_LIBPCAP */
2931
2932   /* Notify all registered modules that have had any of their preferences
2933      changed either from one of the preferences file or from the command
2934      line that their preferences have changed. */
2935   prefs_apply_all();
2936
2937 #ifdef HAVE_LIBPCAP
2938   if ((global_capture_opts.num_selected == 0) &&
2939       (prefs.capture_device != NULL)) {
2940     guint i;
2941     interface_t device;
2942     for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
2943       device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
2944       if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
2945         device.selected = TRUE;
2946         global_capture_opts.num_selected++;
2947         global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
2948         g_array_insert_val(global_capture_opts.all_ifaces, i, device);
2949         break;
2950       }
2951     }
2952   }
2953 #endif
2954
2955   /* disabled protocols as per configuration file */
2956   if (gdp_path == NULL && dp_path == NULL) {
2957     set_disabled_protos_list();
2958   }
2959
2960   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
2961
2962   /* read in rc file from global and personal configuration paths. */
2963   rc_file = get_datafile_path(RC_FILE);
2964 #if GTK_CHECK_VERSION(3,0,0)
2965   /* XXX resolve later */
2966 #else
2967   gtk_rc_parse(rc_file);
2968   g_free(rc_file);
2969   rc_file = get_persconffile_path(RC_FILE, FALSE, FALSE);
2970   gtk_rc_parse(rc_file);
2971 #endif
2972   g_free(rc_file);
2973
2974   font_init();
2975
2976   macros_init();
2977
2978   stock_icons_init();
2979
2980   /* close the splash screen, as we are going to open the main window now */
2981   splash_destroy(splash_win);
2982
2983   /************************************************************************/
2984   /* Everything is prepared now, preferences and command line was read in */
2985
2986   /* Pop up the main window. */
2987   create_main_window(pl_size, tv_size, bv_size, prefs_p);
2988
2989   /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
2990   recent_read_dynamic(&rf_path, &rf_open_errno);
2991   if (rf_path != NULL && rf_open_errno != 0) {
2992     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
2993           "Could not open recent file\n\"%s\": %s.",
2994           rf_path, g_strerror(rf_open_errno));
2995   }
2996
2997   color_filters_enable(recent.packet_list_colorize);
2998
2999   /* rearrange all the widgets as we now have all recent settings ready for this */
3000   main_widgets_rearrange();
3001
3002   /* Fill in column titles.  This must be done after the top level window
3003      is displayed.
3004
3005      XXX - is that still true, with fixed-width columns? */
3006
3007   menu_recent_read_finished();
3008 #ifdef HAVE_LIBPCAP
3009   main_auto_scroll_live_changed(auto_scroll_live);
3010 #endif
3011
3012   switch (user_font_apply()) {
3013   case FA_SUCCESS:
3014       break;
3015   case FA_FONT_NOT_RESIZEABLE:
3016       /* "user_font_apply()" popped up an alert box. */
3017       /* turn off zooming - font can't be resized */
3018   case FA_FONT_NOT_AVAILABLE:
3019       /* XXX - did we successfully load the un-zoomed version earlier?
3020       If so, this *probably* means the font is available, but not at
3021       this particular zoom level, but perhaps some other failure
3022       occurred; I'm not sure you can determine which is the case,
3023       however. */
3024       /* turn off zooming - zoom level is unavailable */
3025   default:
3026       /* in any other case than FA_SUCCESS, turn off zooming */
3027       recent.gui_zoom_level = 0;
3028       /* XXX: would it be a good idea to disable zooming (insensitive GUI)? */
3029   }
3030
3031   dnd_init(top_level);
3032
3033   color_filters_init();
3034   decode_as_init();
3035 #ifdef HAVE_LIBPCAP
3036   capture_filter_init();
3037 #endif
3038
3039   /* the window can be sized only, if it's not already shown, so do it now! */
3040   main_load_window_geometry(top_level);
3041
3042   g_timeout_add(info_update_freq, resolv_update_cb, NULL);
3043
3044   if (dfilter) {
3045     GtkWidget *filter_te;
3046     filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
3047     gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
3048
3049     /* Run the display filter so it goes in effect. */
3050     main_filter_packets(&cfile, dfilter, FALSE);
3051   }
3052
3053   /* If we were given the name of a capture file, read it in now;
3054      we defer it until now, so that, if we can't open it, and pop
3055      up an alert box, the alert box is more likely to come up on
3056      top of the main window - but before the preference-file-error
3057      alert box, so, if we get one of those, it's more likely to come
3058      up on top of us. */
3059   if (cf_name) {
3060     show_main_window(TRUE);
3061     check_and_warn_user_startup(cf_name);
3062     if (rfilter != NULL) {
3063       if (!dfilter_compile(rfilter, &rfcode)) {
3064         bad_dfilter_alert_box(top_level, rfilter);
3065         rfilter_parse_failed = TRUE;
3066       }
3067     }
3068     if (!rfilter_parse_failed) {
3069       if (cf_open(&cfile, cf_name, FALSE, &err) == CF_OK) {
3070         /* "cf_open()" succeeded, so it closed the previous
3071            capture file, and thus destroyed any previous read filter
3072            attached to "cf". */
3073
3074         cfile.rfcode = rfcode;
3075         /* Open stat windows; we do so after creating the main window,
3076            to avoid GTK warnings, and after successfully opening the
3077            capture file, so we know we have something to compute stats
3078            on, and after registering all dissectors, so that MATE will
3079            have registered its field array and we can have a tap filter
3080            with one of MATE's late-registered fields as part of the
3081            filter. */
3082         start_requested_stats();
3083
3084         /* Read the capture file. */
3085         switch (cf_read(&cfile, FALSE)) {
3086
3087         case CF_READ_OK:
3088         case CF_READ_ERROR:
3089           /* Just because we got an error, that doesn't mean we were unable
3090              to read any of the file; we handle what we could get from the
3091              file. */
3092           /* if the user told us to jump to a specific packet, do it now */
3093           if(go_to_packet != 0) {
3094             /* Jump to the specified frame number, kept for backward
3095                compatibility. */
3096             cf_goto_frame(&cfile, go_to_packet);
3097           } else if (jfilter != NULL) {
3098             /* try to compile given filter */
3099             if (!dfilter_compile(jfilter, &jump_to_filter)) {
3100               bad_dfilter_alert_box(top_level, jfilter);
3101             } else {
3102               /* Filter ok, jump to the first packet matching the filter
3103                  conditions. Default search direction is forward, but if
3104                  option d was given, search backwards */
3105               cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
3106             }
3107           }
3108           break;
3109
3110         case CF_READ_ABORTED:
3111           /* Exit now. */
3112           exit(0);
3113           break;
3114         }
3115
3116         /* If the filename is not the absolute path, prepend the current dir. This happens
3117            when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
3118         if (!g_path_is_absolute(cf_name)) {
3119           char *old_cf_name = cf_name;
3120           char *pwd = g_get_current_dir();
3121           cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
3122           g_free(old_cf_name);
3123           g_free(pwd);
3124         }
3125
3126         /* Save the name of the containing directory specified in the
3127            path name, if any; we can write over cf_name, which is a
3128            good thing, given that "get_dirname()" does write over its
3129            argument. */
3130         s = get_dirname(cf_name);
3131         set_last_open_dir(s);
3132         g_free(cf_name);
3133         cf_name = NULL;
3134       } else {
3135         if (rfcode != NULL)
3136           dfilter_free(rfcode);
3137         cfile.rfcode = NULL;
3138         show_main_window(FALSE);
3139         /* Don't call check_and_warn_user_startup(): we did it above */
3140         main_set_for_capture_in_progress(FALSE);
3141         set_capture_if_dialog_for_capture_in_progress(FALSE);
3142       }
3143     }
3144   } else {
3145 #ifdef HAVE_LIBPCAP
3146     if (start_capture) {
3147       if (global_capture_opts.save_file != NULL) {
3148         /* Save the directory name for future file dialogs. */
3149         /* (get_dirname overwrites filename) */
3150         s = get_dirname(g_strdup(global_capture_opts.save_file));
3151         set_last_open_dir(s);
3152         g_free(s);
3153       }
3154       /* "-k" was specified; start a capture. */
3155       show_main_window(FALSE);
3156       check_and_warn_user_startup(cf_name);
3157
3158       /* If no user interfaces were specified on the command line,
3159          copy the list of selected interfaces to the set of interfaces
3160          to use for this capture. */
3161       if (global_capture_opts.ifaces->len == 0)
3162         collect_ifaces(&global_capture_opts);
3163       if (capture_start(&global_capture_opts)) {
3164         /* The capture started.  Open stat windows; we do so after creating
3165            the main window, to avoid GTK warnings, and after successfully
3166            opening the capture file, so we know we have something to compute
3167            stats on, and after registering all dissectors, so that MATE will
3168            have registered its field array and we can have a tap filter with
3169            one of MATE's late-registered fields as part of the filter. */
3170         start_requested_stats();
3171       }
3172     } else {
3173       show_main_window(FALSE);
3174       check_and_warn_user_startup(cf_name);
3175       main_set_for_capture_in_progress(FALSE);
3176       set_capture_if_dialog_for_capture_in_progress(FALSE);
3177     }
3178
3179     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
3180     if (!start_capture && !global_capture_opts.default_options.cfilter) {
3181       global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
3182     }
3183 #else /* HAVE_LIBPCAP */
3184     show_main_window(FALSE);
3185     check_and_warn_user_startup(cf_name);
3186     main_set_for_capture_in_progress(FALSE);
3187     set_capture_if_dialog_for_capture_in_progress(FALSE);
3188 #endif /* HAVE_LIBPCAP */
3189   }
3190
3191   /* register our pid if we are being run from a U3 device */
3192   u3_register_pid();
3193
3194   profile_store_persconffiles (FALSE);
3195
3196 #ifdef HAVE_GTKOSXAPPLICATION
3197   theApp = g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
3198   gtk_osxapplication_set_dock_icon_pixbuf(theApp,gdk_pixbuf_new_from_xpm_data(wsicon64_xpm));
3199   gtk_osxapplication_ready(theApp);
3200 #endif
3201
3202   g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
3203
3204 #ifdef HAVE_LIBPCAP
3205   gtk_iface_mon_start();
3206 #endif
3207
3208   /* we'll enter the GTK loop now and hand the control over to GTK ... */
3209   gtk_main();
3210   /* ... back from GTK, we're going down now! */
3211
3212 #ifdef HAVE_LIBPCAP
3213   gtk_iface_mon_stop();
3214 #endif
3215
3216   /* deregister our pid */
3217   u3_deregister_pid();
3218
3219   epan_cleanup();
3220
3221   AirPDcapDestroyContext(&airpdcap_ctx);
3222
3223 #ifdef _WIN32
3224   /* hide the (unresponsive) main window, while asking the user to close the console window */
3225   gtk_widget_hide(top_level);
3226
3227 #ifdef HAVE_GTKOSXAPPLICATION
3228   g_object_unref(theApp);
3229 #endif
3230
3231   /* Shutdown windows sockets */
3232   WSACleanup();
3233
3234   /* For some unknown reason, the "atexit()" call in "create_console()"
3235      doesn't arrange that "destroy_console()" be called when we exit,
3236      so we call it here if a console was created. */
3237   destroy_console();
3238 #endif
3239
3240   exit(0);
3241 }
3242
3243 #ifdef _WIN32
3244
3245 /* We build this as a GUI subsystem application on Win32, so
3246    "WinMain()", not "main()", gets called.
3247
3248    Hack shamelessly stolen from the Win32 port of the GIMP. */
3249 #ifdef __GNUC__
3250 #define _stdcall  __attribute__((stdcall))
3251 #endif
3252
3253 int _stdcall
3254 WinMain (struct HINSTANCE__ *hInstance,
3255          struct HINSTANCE__ *hPrevInstance,
3256          char               *lpszCmdLine,
3257          int                 nCmdShow)
3258 {
3259   INITCOMMONCONTROLSEX comm_ctrl;
3260
3261   /*
3262    * Initialize our DLL search path. MUST be called before LoadLibrary
3263    * or g_module_open.
3264    */
3265   ws_init_dll_search_path();
3266
3267   /* Initialize our controls. Required for native Windows file dialogs. */
3268   memset (&comm_ctrl, 0, sizeof(comm_ctrl));
3269   comm_ctrl.dwSize = sizeof(comm_ctrl);
3270   /* Includes the animate, header, hot key, list view, progress bar,
3271    * status bar, tab, tooltip, toolbar, trackbar, tree view, and
3272    * up-down controls
3273    */
3274   comm_ctrl.dwICC = ICC_WIN95_CLASSES;
3275   InitCommonControlsEx(&comm_ctrl);
3276
3277   /* RichEd20.DLL is needed for filter entries. */
3278   ws_load_library("riched20.dll");
3279
3280   has_console = FALSE;
3281   console_wait = FALSE;
3282   return main (__argc, __argv);
3283 }
3284
3285 /* The code to create and desstroy console windows should not be necessary,
3286    at least as I read the GLib source code, as it looks as if GLib is, on
3287    Win32, *supposed* to create a console window into which to display its
3288    output.
3289
3290    That doesn't happen, however.  I suspect there's something completely
3291    broken about that code in GLib-for-Win32, and that it may be related
3292    to the breakage that forces us to just call "printf()" on the message
3293    rather than passing the message on to "g_log_default_handler()"
3294    (which is the routine that does the aforementioned non-functional
3295    console window creation).  */
3296
3297 /*
3298  * If this application has no console window to which its standard output
3299  * would go, create one.
3300  */
3301 void
3302 create_console(void)
3303 {
3304   if (stdin_capture) {
3305     /* We've been handed "-i -". Don't mess with stdio. */
3306     return;
3307   }
3308
3309   if (!has_console) {
3310     /* We have no console to which to print the version string, so
3311        create one and make it the standard input, output, and error. */
3312
3313     /*
3314      * See if we have an existing console (i.e. we were run from a
3315      * command prompt)
3316      */
3317     if (!AttachConsole(ATTACH_PARENT_PROCESS)) {
3318       if (AllocConsole()) {
3319         console_wait = TRUE;
3320         SetConsoleTitle(_T("Wireshark Debug Console"));
3321       } else {
3322         return;   /* couldn't create console */
3323       }
3324     }
3325
3326     ws_freopen("CONIN$", "r", stdin);
3327     ws_freopen("CONOUT$", "w", stdout);
3328     ws_freopen("CONOUT$", "w", stderr);
3329     fprintf(stdout, "\n");
3330     fprintf(stderr, "\n");
3331
3332     /* Now register "destroy_console()" as a routine to be called just
3333        before the application exits, so that we can destroy the console
3334        after the user has typed a key (so that the console doesn't just
3335        disappear out from under them, giving the user no chance to see
3336        the message(s) we put in there). */
3337     atexit(destroy_console);
3338
3339     /* Well, we have a console now. */
3340     has_console = TRUE;
3341   }
3342 }
3343
3344 static void
3345 destroy_console(void)
3346 {
3347   if (console_wait) {
3348     printf("\n\nPress any key to exit\n");
3349     _getch();
3350   }
3351   FreeConsole();
3352 }
3353 #endif /* _WIN32 */
3354
3355
3356 static void
3357 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
3358                     const char *message, gpointer user_data _U_)
3359 {
3360   time_t curr;
3361   struct tm *today;
3362   const char *level;
3363
3364
3365   /* ignore log message, if log_level isn't interesting based
3366      upon the console log preferences.
3367      If the preferences haven't been loaded loaded yet, display the
3368      message anyway.
3369
3370      The default console_log_level preference value is such that only
3371        ERROR, CRITICAL and WARNING level messages are processed;
3372        MESSAGE, INFO and DEBUG level messages are ignored.  */
3373   if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
3374      prefs.console_log_level != 0) {
3375     return;
3376   }
3377
3378 #ifdef _WIN32
3379   if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
3380     /* the user wants a console or the application will terminate immediately */
3381     create_console();
3382   }
3383   if (has_console) {
3384     /* For some unknown reason, the above doesn't appear to actually cause
3385        anything to be sent to the standard output, so we'll just splat the
3386        message out directly, just to make sure it gets out. */
3387 #endif
3388     switch(log_level & G_LOG_LEVEL_MASK) {
3389     case G_LOG_LEVEL_ERROR:
3390         level = "Err ";
3391         break;
3392     case G_LOG_LEVEL_CRITICAL:
3393         level = "Crit";
3394         break;
3395     case G_LOG_LEVEL_WARNING:
3396         level = "Warn";
3397         break;
3398     case G_LOG_LEVEL_MESSAGE:
3399         level = "Msg ";
3400         break;
3401     case G_LOG_LEVEL_INFO:
3402         level = "Info";
3403         break;
3404     case G_LOG_LEVEL_DEBUG:
3405         level = "Dbg ";
3406         break;
3407     default:
3408         fprintf(stderr, "unknown log_level %u\n", log_level);
3409         level = NULL;
3410         g_assert_not_reached();
3411     }
3412
3413     /* create a "timestamp" */
3414     time(&curr);
3415     today = localtime(&curr);
3416
3417     fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
3418             today->tm_hour, today->tm_min, today->tm_sec,
3419             log_domain != NULL ? log_domain : "",
3420             level, message);
3421 #ifdef _WIN32
3422     if(log_level & G_LOG_LEVEL_ERROR) {
3423         /* wait for a key press before the following error handler will terminate the program
3424            this way the user at least can read the error message */
3425         printf("\n\nPress any key to exit\n");
3426         _getch();
3427     }
3428   } else {
3429     /* XXX - on UN*X, should we just use g_log_default_handler()?
3430        We want the error messages to go to the standard output;
3431        on Mac OS X, that will cause them to show up in various
3432        per-user logs accessible through Console (details depend
3433        on whether you're running 10.0 through 10.4 or running
3434        10.5 and later), and, on other UN*X desktop environments,
3435        if they don't show up in some form of console log, that's
3436        a deficiency in that desktop environment.  (Too bad
3437        Windows doesn't set the standard output and error for
3438        GUI apps to something that shows up in such a log.) */
3439     g_log_default_handler(log_domain, log_level, message, user_data);
3440   }
3441 #endif
3442 }
3443
3444
3445 /*
3446  * Helper for main_widgets_rearrange()
3447  */
3448 static void foreach_remove_a_child(GtkWidget *widget, gpointer data) {
3449     gtk_container_remove(GTK_CONTAINER(data), widget);
3450 }
3451
3452 static GtkWidget *main_widget_layout(gint layout_content)
3453 {
3454     switch(layout_content) {
3455     case(layout_pane_content_none):
3456         return NULL;
3457     case(layout_pane_content_plist):
3458         return pkt_scrollw;
3459     case(layout_pane_content_pdetails):
3460         return tv_scrollw;
3461     case(layout_pane_content_pbytes):
3462         return byte_nb_ptr_gbl;
3463     default:
3464         g_assert_not_reached();
3465         return NULL;
3466     }
3467 }
3468
3469
3470 /*
3471  * Rearrange the main window widgets
3472  */
3473 void main_widgets_rearrange(void) {
3474     GtkWidget *first_pane_widget1, *first_pane_widget2;
3475     GtkWidget *second_pane_widget1, *second_pane_widget2;
3476     gboolean split_top_left = FALSE;
3477
3478     /* be a bit faster */
3479     gtk_widget_hide(main_vbox);
3480
3481     /* be sure we don't lose a widget while rearranging */
3482     g_object_ref(G_OBJECT(menubar));
3483     g_object_ref(G_OBJECT(main_tb));
3484     g_object_ref(G_OBJECT(filter_tb));
3485     g_object_ref(G_OBJECT(wireless_tb));
3486     g_object_ref(G_OBJECT(pkt_scrollw));
3487     g_object_ref(G_OBJECT(tv_scrollw));
3488     g_object_ref(G_OBJECT(byte_nb_ptr_gbl));
3489     g_object_ref(G_OBJECT(statusbar));
3490     g_object_ref(G_OBJECT(main_pane_v1));
3491     g_object_ref(G_OBJECT(main_pane_v2));
3492     g_object_ref(G_OBJECT(main_pane_h1));
3493     g_object_ref(G_OBJECT(main_pane_h2));
3494     g_object_ref(G_OBJECT(welcome_pane));
3495
3496     /* empty all containers participating */
3497     gtk_container_foreach(GTK_CONTAINER(main_vbox),     foreach_remove_a_child, main_vbox);
3498     gtk_container_foreach(GTK_CONTAINER(main_pane_v1),  foreach_remove_a_child, main_pane_v1);
3499     gtk_container_foreach(GTK_CONTAINER(main_pane_v2),  foreach_remove_a_child, main_pane_v2);
3500     gtk_container_foreach(GTK_CONTAINER(main_pane_h1),  foreach_remove_a_child, main_pane_h1);
3501     gtk_container_foreach(GTK_CONTAINER(main_pane_h2),  foreach_remove_a_child, main_pane_h2);
3502
3503     statusbar_widgets_emptying(statusbar);
3504
3505     /* add the menubar always at the top */
3506     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
3507
3508     /* main toolbar */
3509     gtk_box_pack_start(GTK_BOX(main_vbox), main_tb, FALSE, TRUE, 0);
3510
3511     /* filter toolbar in toolbar area */
3512     if (!prefs.filter_toolbar_show_in_statusbar) {
3513         gtk_box_pack_start(GTK_BOX(main_vbox), filter_tb, FALSE, TRUE, 1);
3514     }
3515
3516     /* airpcap toolbar */
3517     gtk_box_pack_start(GTK_BOX(main_vbox), wireless_tb, FALSE, TRUE, 1);
3518
3519     /* fill the main layout panes */
3520     switch(prefs.gui_layout_type) {
3521     case(layout_type_5):
3522         main_first_pane  = main_pane_v1;
3523         main_second_pane = main_pane_v2;
3524         split_top_left = FALSE;
3525         break;
3526     case(layout_type_2):
3527         main_first_pane  = main_pane_v1;
3528         main_second_pane = main_pane_h1;
3529         split_top_left = FALSE;
3530         break;
3531     case(layout_type_1):
3532         main_first_pane  = main_pane_v1;
3533         main_second_pane = main_pane_h1;
3534         split_top_left = TRUE;
3535         break;
3536     case(layout_type_4):
3537         main_first_pane  = main_pane_h1;
3538         main_second_pane = main_pane_v1;
3539         split_top_left = FALSE;
3540         break;
3541     case(layout_type_3):
3542         main_first_pane  = main_pane_h1;
3543         main_second_pane = main_pane_v1;
3544         split_top_left = TRUE;
3545         break;
3546     case(layout_type_6):
3547         main_first_pane  = main_pane_h1;
3548         main_second_pane = main_pane_h2;
3549         split_top_left = FALSE;
3550         break;
3551     default:
3552         main_first_pane = NULL;
3553         main_second_pane = NULL;
3554         g_assert_not_reached();
3555     }
3556     if (split_top_left) {
3557         first_pane_widget1 = main_second_pane;
3558         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3559         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_2);
3560         first_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3561     } else {
3562         first_pane_widget1 = main_widget_layout(prefs.gui_layout_content_1);
3563         first_pane_widget2 = main_second_pane;
3564         second_pane_widget1 = main_widget_layout(prefs.gui_layout_content_2);
3565         second_pane_widget2 = main_widget_layout(prefs.gui_layout_content_3);
3566     }
3567     if (first_pane_widget1 != NULL)
3568         gtk_paned_add1(GTK_PANED(main_first_pane), first_pane_widget1);
3569     if (first_pane_widget2 != NULL)
3570         gtk_paned_add2(GTK_PANED(main_first_pane), first_pane_widget2);
3571     if (second_pane_widget1 != NULL)
3572         gtk_paned_pack1(GTK_PANED(main_second_pane), second_pane_widget1, TRUE, TRUE);
3573     if (second_pane_widget2 != NULL)
3574         gtk_paned_pack2(GTK_PANED(main_second_pane), second_pane_widget2, FALSE, FALSE);
3575
3576     gtk_box_pack_start(GTK_BOX(main_vbox), main_first_pane, TRUE, TRUE, 0);
3577
3578     /* welcome pane */
3579     gtk_box_pack_start(GTK_BOX(main_vbox), welcome_pane, TRUE, TRUE, 0);
3580
3581     /* statusbar */
3582     gtk_box_pack_start(GTK_BOX(main_vbox), statusbar, FALSE, TRUE, 0);
3583
3584     /* filter toolbar in statusbar hbox */
3585     if (prefs.filter_toolbar_show_in_statusbar) {
3586         gtk_box_pack_start(GTK_BOX(statusbar), filter_tb, FALSE, TRUE, 1);
3587     }
3588
3589     /* statusbar widgets */
3590     statusbar_widgets_pack(statusbar);
3591
3592     /* hide widgets on users recent settings */
3593     main_widgets_show_or_hide();
3594
3595     gtk_widget_show(main_vbox);
3596 }
3597
3598 static void
3599 is_widget_visible(GtkWidget *widget, gpointer data)
3600 {
3601     gboolean *is_visible = data;
3602
3603     if (!*is_visible) {
3604         if (gtk_widget_get_visible(widget))
3605             *is_visible = TRUE;
3606     }
3607 }
3608
3609
3610 void
3611 main_widgets_show_or_hide(void)
3612 {
3613     gboolean main_second_pane_show;
3614
3615     if (recent.main_toolbar_show) {
3616         gtk_widget_show(main_tb);
3617     } else {
3618         gtk_widget_hide(main_tb);
3619     }
3620
3621     statusbar_widgets_show_or_hide(statusbar);
3622
3623     if (recent.filter_toolbar_show) {
3624         gtk_widget_show(filter_tb);
3625     } else {
3626         gtk_widget_hide(filter_tb);
3627     }
3628
3629     if (recent.wireless_toolbar_show) {
3630         gtk_widget_show(wireless_tb);
3631     } else {
3632         gtk_widget_hide(wireless_tb);
3633     }
3634
3635     if (recent.packet_list_show && have_capture_file) {
3636         gtk_widget_show(pkt_scrollw);
3637     } else {
3638         gtk_widget_hide(pkt_scrollw);
3639     }
3640
3641     if (recent.tree_view_show && have_capture_file) {
3642         gtk_widget_show(tv_scrollw);
3643     } else {
3644         gtk_widget_hide(tv_scrollw);
3645     }
3646
3647     if (recent.byte_view_show && have_capture_file) {
3648         gtk_widget_show(byte_nb_ptr_gbl);
3649     } else {
3650         gtk_widget_hide(byte_nb_ptr_gbl);
3651     }
3652
3653     if (have_capture_file) {
3654         gtk_widget_show(main_first_pane);
3655     } else {
3656         gtk_widget_hide(main_first_pane);
3657     }
3658
3659     /*
3660      * Is anything in "main_second_pane" visible?
3661      * If so, show it, otherwise hide it.
3662      */
3663     main_second_pane_show = FALSE;
3664     gtk_container_foreach(GTK_CONTAINER(main_second_pane), is_widget_visible,
3665                           &main_second_pane_show);
3666     if (main_second_pane_show) {
3667         gtk_widget_show(main_second_pane);
3668     } else {
3669         gtk_widget_hide(main_second_pane);
3670     }
3671
3672     if (!have_capture_file) {
3673         if(welcome_pane) {
3674             gtk_widget_show(welcome_pane);
3675         }
3676     } else {
3677         gtk_widget_hide(welcome_pane);
3678     }
3679 }
3680
3681
3682 /* called, when the window state changes (minimized, maximized, ...) */
3683 static gboolean
3684 window_state_event_cb (GtkWidget *widget _U_,
3685                        GdkEvent *event,
3686                        gpointer  data _U_)
3687 {
3688     GdkWindowState new_window_state = ((GdkEventWindowState*)event)->new_window_state;
3689
3690     if( (event->type) == (GDK_WINDOW_STATE)) {
3691         if(!(new_window_state & GDK_WINDOW_STATE_ICONIFIED)) {
3692             /* we might have dialogs popped up while we where iconified,
3693                show em now */
3694             display_queued_messages();
3695         }
3696     }
3697     return FALSE;
3698 }
3699
3700
3701
3702 #define NO_SHIFT_MOD_MASK (GDK_MODIFIER_MASK & ~(GDK_SHIFT_MASK|GDK_MOD2_MASK|GDK_LOCK_MASK))
3703 static gboolean
3704 top_level_key_pressed_cb(GtkWidget *w _U_, GdkEventKey *event, gpointer user_data _U_)
3705 {
3706     if (event->keyval == GDK_F8) {
3707         new_packet_list_next();
3708         return TRUE;
3709     } else if (event->keyval == GDK_F7) {
3710         new_packet_list_prev();
3711         return TRUE;
3712     } else if (event->state & NO_SHIFT_MOD_MASK) {
3713         return FALSE; /* Skip control, alt, and other modifiers */
3714     /*
3715      * A comment in gdkkeysyms.h says that it's autogenerated from
3716      * freedesktop.org/x.org's keysymdef.h.  Although the GDK docs
3717      * don't explicitly say so, isprint() should work as expected
3718      * for values < 127.
3719      */
3720     } else if (isascii(event->keyval) && isprint(event->keyval)) {
3721         /* Forward the keypress on to the display filter entry */
3722         if (main_display_filter_widget && !gtk_widget_is_focus(main_display_filter_widget)) {
3723             gtk_window_set_focus(GTK_WINDOW(top_level), main_display_filter_widget);
3724             gtk_editable_set_position(GTK_EDITABLE(main_display_filter_widget), -1);
3725         }
3726         return FALSE;
3727     }
3728     return FALSE;
3729 }
3730
3731 static void
3732 create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs_p)
3733 {
3734     GtkAccelGroup *accel;
3735
3736     /* Main window */
3737     top_level = window_new(GTK_WINDOW_TOPLEVEL, "");
3738     main_set_window_name("The Wireshark Network Analyzer");
3739
3740     gtk_widget_set_name(top_level, "main window");
3741     g_signal_connect(top_level, "delete_event", G_CALLBACK(main_window_delete_event_cb),
3742                    NULL);
3743     g_signal_connect(G_OBJECT(top_level), "window_state_event",
3744                          G_CALLBACK(window_state_event_cb), NULL);
3745     g_signal_connect(G_OBJECT(top_level), "key-press-event",
3746                          G_CALLBACK(top_level_key_pressed_cb), NULL );
3747
3748     /* Vertical container for menu bar, toolbar(s), paned windows and progress/info box */
3749     main_vbox = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 1, FALSE);
3750
3751         gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0);
3752     gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
3753     gtk_widget_show(main_vbox);
3754
3755     /* Menu bar */
3756     menubar = main_menu_new(&accel);
3757
3758 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined (HAVE_GTKOSXAPPLICATION)
3759     /* Mac OS X native menus are created and displayed by main_menu_new() */
3760     if(!prefs_p->gui_macosx_style) {
3761 #endif
3762     gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
3763     gtk_widget_show(menubar);
3764 #if defined(HAVE_IGE_MAC_INTEGRATION) || defined(HAVE_GTKOSXAPPLICATION)
3765     }
3766 #endif
3767
3768     /* Main Toolbar */
3769     main_tb = toolbar_new();
3770     gtk_widget_show (main_tb);
3771
3772     /* Filter toolbar */
3773     filter_tb = filter_toolbar_new();
3774
3775     /* Packet list */
3776     pkt_scrollw = new_packet_list_create();
3777     gtk_widget_set_size_request(pkt_scrollw, -1, pl_size);
3778     gtk_widget_show_all(pkt_scrollw);
3779
3780     /* Tree view */
3781     tv_scrollw = proto_tree_view_new(prefs_p, &tree_view_gbl);
3782     gtk_widget_set_size_request(tv_scrollw, -1, tv_size);
3783     gtk_widget_show(tv_scrollw);
3784
3785     g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_gbl)),
3786                    "changed", G_CALLBACK(tree_view_selection_changed_cb), NULL);
3787     g_signal_connect(tree_view_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3788                    g_object_get_data(G_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
3789     gtk_widget_show(tree_view_gbl);
3790
3791     /* Byte view. */
3792     byte_nb_ptr_gbl = byte_view_new();
3793     gtk_widget_set_size_request(byte_nb_ptr_gbl, -1, bv_size);
3794     gtk_widget_show(byte_nb_ptr_gbl);
3795
3796     g_signal_connect(byte_nb_ptr_gbl, "button_press_event", G_CALLBACK(popup_menu_handler),
3797                    g_object_get_data(G_OBJECT(popup_menu_object), PM_BYTES_VIEW_KEY));
3798
3799     /* Panes for the packet list, tree, and byte view */
3800     main_pane_v1 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3801     gtk_widget_show(main_pane_v1);
3802     main_pane_v2 = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
3803     gtk_widget_show(main_pane_v2);
3804     main_pane_h1 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3805     gtk_widget_show(main_pane_h1);
3806     main_pane_h2 = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
3807     gtk_widget_show(main_pane_h2);
3808 #ifdef HAVE_AIRPCAP
3809     wireless_tb = airpcap_toolbar_new();
3810 #else
3811     wireless_tb = ws80211_toolbar_new();
3812 #endif
3813     gtk_widget_show(wireless_tb);
3814
3815     /* status bar */
3816     statusbar = statusbar_new();
3817     gtk_widget_show(statusbar);
3818
3819     /* Pane for the welcome screen */
3820     welcome_pane = welcome_new();
3821     gtk_widget_show(welcome_pane);
3822 }
3823
3824 static void
3825 show_main_window(gboolean doing_work)
3826 {
3827   main_set_for_capture_file(doing_work);
3828
3829   /*** we have finished all init things, show the main window ***/
3830   gtk_widget_show(top_level);
3831
3832   /* the window can be maximized only, if it's visible, so do it after show! */
3833   main_load_window_geometry(top_level);
3834
3835   /* process all pending GUI events before continue */
3836   while (gtk_events_pending()) gtk_main_iteration();
3837
3838   /* Pop up any queued-up alert boxes. */
3839   display_queued_messages();
3840
3841   /* Move the main window to the front, in case it isn't already there */
3842   gdk_window_raise(gtk_widget_get_window(top_level));
3843
3844 #ifdef HAVE_AIRPCAP
3845   airpcap_toolbar_show(wireless_tb);
3846 #endif /* HAVE_AIRPCAP */
3847 }
3848
3849 /* Fill in capture options with values from the preferences */
3850 void
3851 prefs_to_capture_opts(void)
3852 {
3853 #ifdef HAVE_LIBPCAP
3854   /* Set promiscuous mode from the preferences setting. */
3855   /* the same applies to other preferences settings as well. */
3856     global_capture_opts.default_options.promisc_mode = prefs.capture_prom_mode;
3857     global_capture_opts.use_pcapng                   = prefs.capture_pcap_ng;
3858     global_capture_opts.show_info                    = prefs.capture_show_info;
3859     global_capture_opts.real_time_mode               = prefs.capture_real_time;
3860     auto_scroll_live                                 = prefs.capture_auto_scroll;
3861 #endif /* HAVE_LIBPCAP */
3862 }
3863
3864 static void copy_global_profile (const gchar *profile_name)
3865 {
3866     char  *pf_dir_path, *pf_dir_path2, *pf_filename;
3867
3868     if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
3869         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3870             "Can't create directory\n\"%s\":\n%s.",
3871             pf_dir_path, g_strerror(errno));
3872
3873         g_free(pf_dir_path);
3874     }
3875
3876     if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
3877             &pf_dir_path, &pf_dir_path2) == -1) {
3878         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3879             "Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
3880             pf_filename, pf_dir_path2, pf_dir_path, g_strerror(errno));
3881
3882         g_free(pf_filename);
3883         g_free(pf_dir_path);
3884         g_free(pf_dir_path2);
3885     }
3886 }
3887
3888 /* Change configuration profile */
3889 void change_configuration_profile (const gchar *profile_name)
3890 {
3891     char  *gdp_path, *dp_path;
3892     char  *rf_path;
3893     int    rf_open_errno;
3894
3895     /* First check if profile exists */
3896     if (!profile_exists(profile_name, FALSE)) {
3897         if (profile_exists(profile_name, TRUE)) {
3898            /* Copy from global profile */
3899             copy_global_profile (profile_name);
3900         } else {
3901             /* No personal and no global profile exists */
3902             return;
3903         }
3904     }
3905
3906     /* Then check if changing to another profile */
3907     if (profile_name && strcmp (profile_name, get_profile_name()) == 0) {
3908         return;
3909     }
3910
3911     /* Get the current geometry, before writing it to disk */
3912     main_save_window_geometry(top_level);
3913
3914     if (profile_exists(get_profile_name(), FALSE)) {
3915         /* Write recent file for profile we are leaving, if it still exists */
3916         write_profile_recent();
3917     }
3918
3919     /* Set profile name and update the status bar */
3920     set_profile_name (profile_name);
3921     profile_bar_update ();
3922     filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
3923
3924     /* Reset current preferences and apply the new */
3925     prefs_reset();
3926     menu_prefs_reset();
3927
3928     (void) read_configuration_files (&gdp_path, &dp_path);
3929
3930     recent_read_profile_static(&rf_path, &rf_open_errno);
3931     if (rf_path != NULL && rf_open_errno != 0) {
3932         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
3933             "Could not open common recent file\n\"%s\": %s.",
3934             rf_path, g_strerror(rf_open_errno));
3935     }
3936     if (recent.gui_fileopen_remembered_dir &&
3937         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
3938         set_last_open_dir(recent.gui_fileopen_remembered_dir);
3939     }
3940     timestamp_set_type (recent.gui_time_format);
3941     timestamp_set_seconds_type (recent.gui_seconds_format);
3942     color_filters_enable(recent.packet_list_colorize);
3943
3944     prefs_to_capture_opts();
3945     prefs_apply_all();
3946     macros_post_update();
3947
3948     /* Update window view and redraw the toolbar */
3949     main_titlebar_update();
3950     filter_expression_reinit(FILTER_EXPRESSION_REINIT_CREATE);
3951     toolbar_redraw_all();
3952
3953     /* Enable all protocols and disable from the disabled list */
3954     proto_enable_all();
3955     if (gdp_path == NULL && dp_path == NULL) {
3956         set_disabled_protos_list();
3957     }
3958
3959     /* Reload color filters */
3960     color_filters_reload();
3961
3962     /* Reload list of interfaces on welcome page */
3963     welcome_if_panel_reload();
3964
3965     /* Recreate the packet list according to new preferences */
3966     new_packet_list_recreate ();
3967     cfile.cinfo.columns_changed = FALSE; /* Reset value */
3968     user_font_apply();
3969
3970     /* Update menus with new recent values */
3971     menu_recent_read_finished();
3972
3973     /* Reload pane geometry, must be done after recreating the list */
3974     main_pane_load_window_geometry();
3975 }
3976
3977 /** redissect packets and update UI */
3978 void redissect_packets(void)
3979 {
3980     cf_redissect_packets(&cfile);
3981     status_expert_update();
3982 }