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