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