Change a lot of http:// URLs to https://.
[metze/wireshark/wip.git] / ui / gtk / main.c
index 8bc7fed661c5758b423f7b4c0b21b158d4201b48..bf31fec78a540e36c046c7fc6bd9957730a0d196 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
-#include <ctype.h>
 #include <locale.h>
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
 
-#ifndef HAVE_GETOPT
-#include "wsutil/wsgetopt.h"
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
 #endif
 
-#ifdef _WIN32 /* Needed for console I/O */
+#ifndef HAVE_GETOPT_LONG
+#include "wsutil/wsgetopt.h"
+#endif
 
-#include <fcntl.h>
-#include <conio.h>
-#include <ui/win32/console_win32.h>
+#ifdef HAVE_LIBZ
+#include <zlib.h>      /* to get the libz version number */
 #endif
 
 #ifdef HAVE_LIBPORTAUDIO
 #include <portaudio.h>
 #endif /* HAVE_LIBPORTAUDIO */
 
+#include <wsutil/clopts_common.h>
+#include <wsutil/copyright_info.h>
 #include <wsutil/crash_info.h>
 #include <wsutil/filesystem.h>
 #include <wsutil/file_util.h>
 #include <wsutil/privileges.h>
 #include <wsutil/report_err.h>
 #include <wsutil/u3.h>
+#include <wsutil/ws_diag_control.h>
+#include <wsutil/ws_version_info.h>
 
 #include <wiretap/merge.h>
 
 #include <epan/column.h>
 #include <epan/disabled_protos.h>
 #include <epan/epan.h>
+#include <epan/proto.h>
 #include <epan/epan_dissect.h>
 #include <epan/dfilter/dfilter.h>
 #include <epan/strutil.h>
-#include <epan/emem.h>
 #include <epan/ex-opt.h>
 #include <epan/funnel.h>
 #include <epan/expert.h>
 #include <epan/prefs.h>
 #include <epan/prefs-int.h>
 #include <epan/tap.h>
-#include <epan/stat_cmd_args.h>
+#include <epan/stat_tap_ui.h>
 #include <epan/uat.h>
 #include <epan/print.h>
 #include <epan/timestamp.h>
+#include <epan/conversation_table.h>
 
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
+#include <epan/asn1.h>
+#include <epan/dissectors/packet-kerberos.h>
+#endif
+
+#include <wsutil/cmdarg_err.h>
 #include <wsutil/plugins.h>
 
 /* general (not GTK specific) */
 #include "../file.h"
 #include "../frame_tvbuff.h"
 #include "../summary.h"
-#include "../filters.h"
 #include "../color.h"
 #include "../color_filters.h"
 #include "../register.h"
 #include "../ringbuffer.h"
-#include "ui/util.h"
-#include "../clopts_common.h"
-#include "../cmdarg_err.h"
-#include "../version_info.h"
 #include "../log.h"
 
 #include "gtk_iface_monitor.h"
 
 #include "ui/alert_box.h"
+#include "ui/console.h"
 #include "ui/decode_as_utils.h"
+#include "ui/filters.h"
 #include "ui/main_statusbar.h"
 #include "ui/persfilepath_opt.h"
 #include "ui/preference_utils.h"
 #include "ui/recent.h"
 #include "ui/recent_utils.h"
 #include "ui/software_update.h"
-#include "ui/simple_dialog.h"
 #include "ui/ui_util.h"
+#include "ui/util.h"
 
 #ifdef HAVE_LIBPCAP
+#include "ui/capture_ui_utils.h"
 #include "ui/capture_globals.h"
 #include "ui/iface_lists.h"
 #endif
 
 #include "codecs/codecs.h"
 
+#include "caputils/capture-pcap-util.h"
+
 #ifdef HAVE_LIBPCAP
-#include "capture_ui_utils.h"
-#include "capture-pcap-util.h"
-#include "capture_ifinfo.h"
-#include "capture.h"
-#include "capture_sync.h"
+#include "caputils/capture_ifinfo.h"
+#include "ui/capture.h"
+#include <capchild/capture_sync.h>
 #endif
 
 #ifdef _WIN32
-#include "capture-wpcap.h"
-#include "capture_wpcap_packet.h"
+#include "caputils/capture-wpcap.h"
+#include "caputils/capture_wpcap_packet.h"
 #include <tchar.h> /* Needed for Unicode */
+#include <wsutil/os_version_info.h>
 #include <wsutil/unicode-utils.h>
 #include <commctrl.h>
 #include <shellapi.h>
 #include "ui/gtk/proto_help.h"
 #include "ui/gtk/packet_list.h"
 #include "ui/gtk/filter_expression_save_dlg.h"
+#include "ui/gtk/conversations_table.h"
+#include "ui/gtk/hostlist_table.h"
+#include "simple_dialog.h"
 
 #include "ui/gtk/old-gtk-compat.h"
 
 #endif
 
 #ifdef HAVE_AIRPCAP
-#include <airpcap.h>
-#include "airpcap_loader.h"
+#include <caputils/airpcap.h>
+#include <caputils/airpcap_loader.h>
 #include "airpcap_dlg.h"
 #include "airpcap_gui_utils.h"
 #endif
@@ -239,9 +252,6 @@ static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cf
 
 static guint  tap_update_timer_id;
 
-static void console_log_handler(const char *log_domain,
-    GLogLevelFlags log_level, const char *message, gpointer user_data);
-
 static void create_main_window(gint, gint, gint, e_prefs*);
 static void show_main_window(gboolean);
 static void main_save_window_geometry(GtkWidget *widget);
@@ -337,6 +347,7 @@ match_selected_ptree_cb(gpointer data, MATCH_SELECTED_E action)
         filter = proto_construct_match_selected_string(cfile.finfo_selected,
                                                        cfile.edt);
         match_selected_cb_do((GtkWidget *)g_object_get_data(G_OBJECT(data), E_DFILTER_TE_KEY), action, filter);
+        wmem_free(NULL, filter);
     }
 }
 
@@ -365,6 +376,7 @@ colorize_selected_ptree_cb(GtkWidget *w _U_, gpointer data _U_, guint8 filt_nr)
             }
             packet_list_colorize_packets();
         }
+        wmem_free(NULL, filter);
     }
 }
 
@@ -379,7 +391,7 @@ static void selected_ptree_info_answered_cb(gpointer dialog _U_, gint btn, gpoin
     case(ESD_BTN_OK):
         if (cfile.finfo_selected) {
             /* open wiki page using the protocol abbreviation */
-            selected_proto_url = g_strdup_printf("http://wiki.wireshark.org/Protocols/%s", proto_abbrev);
+            selected_proto_url = g_strdup_printf("https://wiki.wireshark.org/Protocols/%s", proto_abbrev);
             browser_open_url(selected_proto_url);
             g_free(selected_proto_url);
         }
@@ -458,7 +470,7 @@ static void selected_ptree_ref_answered_cb(gpointer dialog _U_, gint btn, gpoint
     case(ESD_BTN_OK):
         if (cfile.finfo_selected) {
             /* open reference page using the protocol abbreviation */
-            selected_proto_url = g_strdup_printf("http://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
+            selected_proto_url = g_strdup_printf("https://www.wireshark.org/docs/dfref/%c/%s", proto_abbrev[0], proto_abbrev);
             browser_open_url(selected_proto_url);
             g_free(selected_proto_url);
         }
@@ -607,7 +619,7 @@ get_filter_from_packet_list_row_and_column(gpointer data)
              */
             if (strlen(cfile.cinfo.col_expr.col_expr[column]) != 0 &&
                 strlen(cfile.cinfo.col_expr.col_expr_val[column]) != 0) {
-                /* leak a little but safer than ep_ here */
+                /* leak a little; is there a safe wmem_ scope here? */
                 if (cfile.cinfo.col_fmt[column] == COL_CUSTOM) {
                     header_field_info *hfi = proto_registrar_get_byname(cfile.cinfo.col_custom_field[column]);
                     if (hfi && hfi->parent == -1) {
@@ -1153,7 +1165,7 @@ file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
 }
 
 static void
-print_usage(gboolean print_ver) {
+print_usage(gboolean for_help_option) {
 
     FILE *output;
 
@@ -1161,14 +1173,12 @@ print_usage(gboolean print_ver) {
     create_console();
 #endif
 
-    if (print_ver) {
+    if (for_help_option) {
         output = stdout;
-        fprintf(output, "Wireshark " VERSION "%s\n"
+        fprintf(output, "Wireshark %s\n"
             "Interactively dump and analyze network traffic.\n"
-            "See http://www.wireshark.org for more information.\n"
-            "\n"
-            "%s",
-            wireshark_gitversion, get_copyright_info());
+            "See https://www.wireshark.org for more information.\n",
+            get_ws_vcs_version_info());
     } else {
         output = stderr;
     }
@@ -1255,36 +1265,20 @@ print_usage(gboolean print_ver) {
 #endif
 }
 
-static void
-show_version(void)
-{
-    printf(PACKAGE " " VERSION "%s\n"
-           "\n"
-           "%s"
-           "\n"
-           "%s"
-           "\n"
-           "%s",
-        wireshark_gitversion, get_copyright_info(), comp_info_str->str,
-        runtime_info_str->str);
-}
-
 /*
  * Report an error in command-line arguments.
  * Creates a console on Windows.
+ * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
+ * terminal isn't the standard error?
  */
-void
-cmdarg_err(const char *fmt, ...)
+static void
+wireshark_cmdarg_err(const char *fmt, va_list ap)
 {
-    va_list ap;
-
 #ifdef _WIN32
     create_console();
 #endif
     fprintf(stderr, "wireshark: ");
-    va_start(ap, fmt);
     vfprintf(stderr, fmt, ap);
-    va_end(ap);
     fprintf(stderr, "\n");
 }
 
@@ -1294,18 +1288,14 @@ cmdarg_err(const char *fmt, ...)
  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
  * terminal isn't the standard error?
  */
-void
-cmdarg_err_cont(const char *fmt, ...)
+static void
+wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
 {
-    va_list ap;
-
 #ifdef _WIN32
     create_console();
 #endif
-    va_start(ap, fmt);
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    va_end(ap);
 }
 
 /*
@@ -1357,8 +1347,8 @@ main_update_for_unsaved_changes(capture_file *cf)
 void
 main_auto_scroll_live_changed(gboolean auto_scroll_live_in)
 {
-  /* Update menubar and toolbar */
-      menu_auto_scroll_live_changed(auto_scroll_live_in);
+    /* Update menubar and toolbar */
+    menu_auto_scroll_live_changed(auto_scroll_live_in);
     toolbar_auto_scroll_live_changed(auto_scroll_live_in);
 
     /* change auto scroll state */
@@ -1897,7 +1887,7 @@ main_capture_callback(gint event, capture_session *cap_session, gpointer user_da
 #endif
 
 static void
-get_gtk_compiled_info(GString *str)
+get_wireshark_gtk_compiled_info(GString *str)
 {
     g_string_append(str, "with ");
     g_string_append_printf(str,
@@ -1907,17 +1897,31 @@ get_gtk_compiled_info(GString *str)
 #else
                            "GTK+ (version unknown)");
 #endif
-    g_string_append(str, ", ");
+
     /* Cairo */
-    g_string_append(str, "with Cairo ");
+    g_string_append(str, "with Cairo ");
     g_string_append(str, CAIRO_VERSION_STRING);
-    g_string_append(str, ", ");
 
     /* Pango */
-    g_string_append(str, "with Pango ");
+    g_string_append(str, "with Pango ");
     g_string_append(str, PANGO_VERSION_STRING);
+
+    /* Capture libraries */
     g_string_append(str, ", ");
+    get_compiled_caplibs_version(str);
 
+    /* LIBZ */
+    g_string_append(str, ", ");
+#ifdef HAVE_LIBZ
+    g_string_append(str, "with libz ");
+#ifdef ZLIB_VERSION
+    g_string_append(str, ZLIB_VERSION);
+#else /* ZLIB_VERSION */
+    g_string_append(str, "(version unknown)");
+#endif /* ZLIB_VERSION */
+#else /* HAVE_LIBZ */
+    g_string_append(str, "without libz");
+#endif /* HAVE_LIBZ */
 }
 
 static void
@@ -1946,8 +1950,20 @@ get_gui_compiled_info(GString *str)
 }
 
 static void
-get_gui_runtime_info(GString *str)
+get_wireshark_runtime_info(GString *str)
 {
+#ifdef HAVE_LIBPCAP
+    /* Capture libraries */
+    g_string_append(str, ", ");
+    get_runtime_caplibs_version(str);
+#endif
+
+    /* zlib */
+#if defined(HAVE_LIBZ) && !defined(_WIN32)
+    g_string_append_printf(str, ", with libz %s", zlibVersion());
+#endif
+
+    /* stuff used by libwireshark */
     epan_get_runtime_version_info(str);
 
 #ifdef HAVE_AIRPCAP
@@ -2090,7 +2106,7 @@ check_and_warn_user_startup(gchar *cf_name _U_)
         "This could be dangerous.\n\n"
         "If you're running Wireshark this way in order to perform live capture, "
         "you may want to be aware that there is a better way documented at\n"
-        "http://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
+        "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
         g_free(cur_user);
         g_free(cur_group);
         simple_dialog_check_set(priv_warning_dialog, "Don't show this message again.");
@@ -2099,7 +2115,7 @@ check_and_warn_user_startup(gchar *cf_name _U_)
 
 #ifdef _WIN32
     /* Warn the user if npf.sys isn't loaded. */
-    if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_os_major_version() >= 6) {
+    if (!get_stdin_capture() && !cf_name && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
         priv_warning_dialog = simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
         "The NPF driver isn't running.  You may have trouble\n"
         "capturing or listing interfaces.");
@@ -2147,44 +2163,34 @@ main(int argc, char *argv[])
     gint                 pl_size = 280, tv_size = 95, bv_size = 75;
     gchar               *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
     dfilter_t           *rfcode = NULL;
+    gchar               *err_msg;
     gboolean             rfilter_parse_failed = FALSE;
     e_prefs             *prefs_p;
     char                 badopt;
     GtkWidget           *splash_win = NULL;
-    GLogLevelFlags       log_flags;
     guint                go_to_packet = 0;
     search_direction     jump_backwards = SD_FORWARD;
     dfilter_t           *jump_to_filter = NULL;
-    int                  optind_initial;
     unsigned int         in_file_type = WTAP_TYPE_AUTO;
 #ifdef HAVE_GTKOSXAPPLICATION
     GtkosxApplication   *theApp;
 #endif
 
-#ifdef HAVE_LIBPCAP
-#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
-#define OPTSTRING_B "B:"
-#else
-#define OPTSTRING_B ""
-#endif  /* _WIN32 or HAVE_PCAP_CREATE */
-#else /* HAVE_LIBPCAP */
-#define OPTSTRING_B ""
-#endif  /* HAVE_LIBPCAP */
-#ifdef HAVE_PCAP_REMOTE
-#define OPTSTRING_A "A:"
-#else
-#define OPTSTRING_A ""
-#endif
-#ifdef HAVE_PCAP_CREATE
-#define OPTSTRING_I "I"
-#else
-#define OPTSTRING_I ""
-#endif
-
-#define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:Y:z:"
-
+#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
+DIAG_OFF(cast-qual)
+    static const struct option long_options[] = {
+        {(char *)"help", no_argument, NULL, 'h'},
+        {(char *)"read-file", required_argument, NULL, 'r' },
+        {(char *)"read-filter", required_argument, NULL, 'R' },
+        {(char *)"display-filter", required_argument, NULL, 'Y' },
+        {(char *)"version", no_argument, NULL, 'v'},
+        LONGOPT_CAPTURE_COMMON
+        {0, 0, 0, 0 }
+    };
+DIAG_ON(cast-qual)
     static const char optstring[] = OPTSTRING;
 
+    cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
 
     /* Set the C-language locale to the native environment. */
     setlocale(LC_ALL, "");
@@ -2204,7 +2210,7 @@ main(int argc, char *argv[])
     /*
      * Attempt to get the pathname of the executable file.
      */
-    init_progfile_dir_error = init_progfile_dir(argv[0], main);
+    init_progfile_dir_error = init_progfile_dir(argv[0], (void *)main);
 
     /* initialize the funnel mini-api */
     initialize_funnel_ops();
@@ -2261,23 +2267,22 @@ main(int argc, char *argv[])
 #endif /* HAVE_AIRPCAP */
 #endif  /* _WIN32 */
 
-    /* Assemble the compile-time version information string */
-    comp_info_str = g_string_new("Compiled ");
-
-    get_compiled_version_info(comp_info_str, get_gtk_compiled_info, get_gui_compiled_info);
+    /* Get the compile-time version information string */
+    comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
+                                              get_gui_compiled_info);
 
-    /* Assemble the run-time version information string */
-    runtime_info_str = g_string_new("Running ");
-    get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
+    /* Get the run-time version information string */
+    runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
 
-#ifdef _WIN32
-    ws_add_crash_info(PACKAGE " " VERSION "%s\n"
+    /* Add it to the information to be reported on a crash. */
+    ws_add_crash_info("Wireshark %s\n"
         "\n"
         "%s"
         "\n"
         "%s",
-        wireshark_gitversion, comp_info_str->str, runtime_info_str->str);
+        get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
 
+#ifdef _WIN32
     /* Start windows sockets */
     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
 #endif  /* _WIN32 */
@@ -2293,20 +2298,41 @@ main(int argc, char *argv[])
                       rf_path, g_strerror(rf_open_errno));
     }
 
-    /* "pre-scan" the command line parameters, if we have "console only"
-       parameters.  We do this so we don't start GTK+ if we're only showing
-       command-line help or version information.
-
-       XXX - this pre-scan is done before we start GTK+, so we haven't
-       run gtk_init() on the arguments.  That means that GTK+ arguments
-       have not been removed from the argument list; those arguments
-       begin with "--", and will be treated as an error by getopt().
-
-       We thus ignore errors - *and* set "opterr" to 0 to suppress the
-       error messages. */
+    /*
+     * In order to have the -X opts assigned before the wslua machine starts
+     * we need to call getopt_long before epan_init() gets called.
+     *
+     * In addition, we process "console only" parameters (ones where we
+     * send output to the console and exit) here, so we don't start GTK+
+     * if we're only showing command-line help or version information.
+     *
+     * XXX - this pre-scan is done before we start GTK+, so we haven't
+     * run gtk_init() on the arguments.  That means that GTK+ arguments
+     * have not been removed from the argument list; those arguments
+     * begin with "--", and will be treated as an error by getopt_long().
+     *
+     * We thus ignore errors - *and* set "opterr" to 0 to suppress the
+     * error messages.
+     *
+     * XXX - should we, instead, first call gtk_parse_args(), without
+     * calling gtk_init(), and then call this?
+     *
+     * In order to handle, for example, -o options, we also need to call it
+     * *after* epan_init() gets called, so that the dissectors have had a
+     * chance to register their preferences, so we have another getopt_long()
+     * call later.
+     *
+     * XXX - can we do this all with one getopt_long() call, saving the
+     * arguments we can't handle until after initializing libwireshark,
+     * and then process them after initializing libwireshark?
+     *
+     * Note that we don't want to initialize libwireshark until after the
+     * GUI is up, as that can take a while, and we want a window of some
+     * sort up to show progress while that's happening.
+     */
     opterr = 0;
-    optind_initial = optind;
-    while ((opt = getopt(argc, argv, optstring)) != -1) {
+
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
         switch (opt) {
             case 'C':        /* Configuration Profile */
                 if (profile_exists (optarg, FALSE)) {
@@ -2318,18 +2344,13 @@ main(int argc, char *argv[])
                 break;
             case 'D':        /* Print a list of capture devices and exit */
 #ifdef HAVE_LIBPCAP
-                if_list = capture_interface_list(&err, &err_str,main_window_update);
+                if_list = capture_interface_list(&err, &err_str, NULL);
                 if (if_list == NULL) {
-                    switch (err) {
-                        case CANT_GET_INTERFACE_LIST:
-                        case DONT_HAVE_PCAP:
-                            cmdarg_err("%s", err_str);
-                            g_free(err_str);
-                            break;
-
-                        case NO_INTERFACES_FOUND:
-                            cmdarg_err("There are no interfaces on which a capture can be done");
-                            break;
+                    if (err == 0)
+                        cmdarg_err("There are no interfaces on which a capture can be done");
+                    else {
+                        cmdarg_err("%s", err_str);
+                        g_free(err_str);
                     }
                     exit(2);
                 }
@@ -2367,7 +2388,7 @@ main(int argc, char *argv[])
 #ifdef _WIN32
                 create_console();
 #endif
-                show_version();
+                show_version("Wireshark", comp_info_str, runtime_info_str);
 #ifdef _WIN32
                 destroy_console();
 #endif
@@ -2407,42 +2428,6 @@ main(int argc, char *argv[])
         set_last_open_dir(get_persdatafile_dir());
     }
 
-    /* Set getopt index back to initial value, so it will start with the
-       first command line parameter again.  Also reset opterr to 1, so that
-       error messages are printed by getopt().
-
-       XXX - this seems to work on most platforms, but time will tell.
-       The Single UNIX Specification says "The getopt() function need
-       not be reentrant", so this isn't guaranteed to work.  The Mac
-       OS X 10.4[.x] getopt() man page says
-
-         In order to use getopt() to evaluate multiple sets of arguments, or to
-         evaluate a single set of arguments multiple times, the variable optreset
-         must be set to 1 before the second and each additional set of calls to
-         getopt(), and the variable optind must be reinitialized.
-
-           ...
-
-         The optreset variable was added to make it possible to call the getopt()
-         function multiple times.  This is an extension to the IEEE Std 1003.2
-         (``POSIX.2'') specification.
-
-       which I think comes from one of the other BSDs.
-
-       XXX - if we want to control all the command-line option errors, so
-       that we can display them where we choose (e.g., in a window), we'd
-       want to leave opterr as 0, and produce our own messages using optopt.
-       We'd have to check the value of optopt to see if it's a valid option
-       letter, in which case *presumably* the error is "this option requires
-       an argument but none was specified", or not a valid option letter,
-       in which case *presumably* the error is "this option isn't valid".
-       Some versions of getopt() let you supply a option string beginning
-       with ':', which means that getopt() will return ':' rather than '?'
-       for "this option requires an argument but none was specified", but
-       not all do. */
-    optind = optind_initial;
-    opterr = 1;
-
 #if !GLIB_CHECK_VERSION(2,31,0)
     g_thread_init(NULL);
 #endif
@@ -2465,45 +2450,14 @@ main(int argc, char *argv[])
     capture_callback_add(statusbar_capture_callback, NULL);
 #endif
 
-    /* Arrange that if we have no console window, and a GLib message logging
-       routine is called to log a message, we pop up a console window.
-
-       We do that by inserting our own handler for all messages logged
-       to the default domain; that handler pops up a console if necessary,
-       and then calls the default handler. */
-
-    /* We might want to have component specific log levels later ... */
-
-    log_flags = (GLogLevelFlags)
-                (G_LOG_LEVEL_ERROR|
-                 G_LOG_LEVEL_CRITICAL|
-                 G_LOG_LEVEL_WARNING|
-                 G_LOG_LEVEL_MESSAGE|
-                 G_LOG_LEVEL_INFO|
-                 G_LOG_LEVEL_DEBUG|
-                 G_LOG_FLAG_FATAL|
-                 G_LOG_FLAG_RECURSION);
-
-    g_log_set_handler(NULL,
-                      log_flags,
-                      console_log_handler, NULL /* user_data */);
-    g_log_set_handler(LOG_DOMAIN_MAIN,
-                      log_flags,
-                      console_log_handler, NULL /* user_data */);
+    set_console_log_handler();
 
 #ifdef HAVE_LIBPCAP
-    g_log_set_handler(LOG_DOMAIN_CAPTURE,
-                      log_flags,
-                      console_log_handler, NULL /* user_data */);
-  g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
-                    log_flags,
-                    console_log_handler, NULL /* user_data */);
-
     /* Set the initial values in the capture options. This might be overwritten
        by preference settings and then again by the command line parameters. */
     capture_opts_init(&global_capture_opts);
 
-    capture_session_init(&global_capture_session, (void *)&cfile);
+    capture_session_init(&global_capture_session, &cfile);
 #endif
 
     init_report_err(failure_alert_box, open_failure_alert_box,
@@ -2571,6 +2525,8 @@ main(int argc, char *argv[])
 #endif
 
     register_all_tap_listeners();
+    conversation_table_set_gui_info(init_conversation_table);
+    hostlist_table_set_gui_info(init_hostlist_table);
 
     splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
 
@@ -2592,8 +2548,42 @@ main(int argc, char *argv[])
 /*#ifdef HAVE_LIBPCAP
     fill_in_local_interfaces();
 #endif*/
+    /*
+     * To reset the options parser, set optreset to 1 on platforms that
+     * have optreset (documented in *BSD and OS X, apparently present but
+     * not documented in Solaris - the Illumos repository seems to
+     * suggest that the first Solaris getopt_long(), at least as of 2004,
+     * was based on the NetBSD one, it had optreset) and set optind to 1,
+     * and set optind to 0 otherwise (documented as working in the GNU
+     * getopt_long().  Setting optind to 0 didn't originally work in the
+     * NetBSD one, but that was added later - we don't want to depend on
+     * it if we have optreset).
+     *
+     * Also reset opterr to 1, so that error messages are printed by
+     * getopt_long().
+     *
+     * XXX - if we want to control all the command-line option errors, so
+     * that we can display them where we choose (e.g., in a window), we'd
+     * want to leave opterr as 0, and produce our own messages using optopt.
+     * We'd have to check the value of optopt to see if it's a valid option
+     * letter, in which case *presumably* the error is "this option requires
+     * an argument but none was specified", or not a valid option letter,
+     * in which case *presumably* the error is "this option isn't valid".
+     * Some versions of getopt() let you supply a option string beginning
+     * with ':', which means that getopt() will return ':' rather than '?'
+     * for "this option requires an argument but none was specified", but
+     * not all do.  But we're now using getopt_long() - what does it do?
+     */
+#ifdef HAVE_OPTRESET
+    optreset = 1;
+    optind = 1;
+#else
+    optind = 0;
+#endif
+    opterr = 1;
+
     /* Now get our args */
-    while ((opt = getopt(argc, argv, optstring)) != -1) {
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
         switch (opt) {
             /*** capture option specific ***/
             case 'a':        /* autostop criteria */
@@ -2791,6 +2781,11 @@ main(int argc, char *argv[])
                  by the preferences set callback) from being used as
                  part of a tap filter.  Instead, we just add the argument
                  to a list of stat arguments. */
+                if (strcmp("help", optarg) == 0) {
+                  fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
+                  list_stat_cmd_args();
+                  exit(0);
+                }
                 if (!process_stat_cmd_arg(optarg)) {
                     cmdarg_err("Invalid -z argument.");
                     cmdarg_err_cont("  -z argument must be one of :");
@@ -3090,8 +3085,9 @@ main(int argc, char *argv[])
         show_main_window(TRUE);
         check_and_warn_user_startup(cf_name);
         if (rfilter != NULL) {
-            if (!dfilter_compile(rfilter, &rfcode)) {
-                bad_dfilter_alert_box(top_level, rfilter);
+            if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
+                bad_dfilter_alert_box(top_level, rfilter, err_msg);
+                g_free(err_msg);
                 rfilter_parse_failed = TRUE;
             }
         }
@@ -3129,8 +3125,9 @@ main(int argc, char *argv[])
                             cf_goto_frame(&cfile, go_to_packet);
                         } else if (jfilter != NULL) {
                             /* try to compile given filter */
-                            if (!dfilter_compile(jfilter, &jump_to_filter)) {
-                                bad_dfilter_alert_box(top_level, jfilter);
+                            if (!dfilter_compile(jfilter, &jump_to_filter, &err_msg)) {
+                                bad_dfilter_alert_box(top_level, jfilter, err_msg);
+                                g_free(err_msg);
                             } else {
                             /* Filter ok, jump to the first packet matching the filter
                                conditions. Default search direction is forward, but if
@@ -3270,7 +3267,8 @@ main(int argc, char *argv[])
 
 #ifdef _WIN32
     /* hide the (unresponsive) main window, while asking the user to close the console window */
-    gtk_widget_hide(top_level);
+    if (G_IS_OBJECT(top_level))
+        gtk_widget_hide(top_level);
 
     software_update_cleanup();
 
@@ -3331,93 +3329,6 @@ WinMain (struct HINSTANCE__ *hInstance,
 #endif /* _WIN32 */
 
 
-static void
-console_log_handler(const char *log_domain, GLogLevelFlags log_level,
-                    const char *message, gpointer user_data _U_)
-{
-    time_t curr;
-    struct tm *today;
-    const char *level;
-
-
-    /* ignore log message, if log_level isn't interesting based
-       upon the console log preferences.
-       If the preferences haven't been loaded loaded yet, display the
-       message anyway.
-
-       The default console_log_level preference value is such that only
-         ERROR, CRITICAL and WARNING level messages are processed;
-         MESSAGE, INFO and DEBUG level messages are ignored.  */
-    if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
-        prefs.console_log_level != 0) {
-        return;
-    }
-
-#ifdef _WIN32
-    if (prefs.gui_console_open != console_open_never || log_level & G_LOG_LEVEL_ERROR) {
-        /* the user wants a console or the application will terminate immediately */
-        create_console();
-    }
-    if (get_has_console()) {
-        /* For some unknown reason, the above doesn't appear to actually cause
-           anything to be sent to the standard output, so we'll just splat the
-           message out directly, just to make sure it gets out. */
-#endif
-        switch(log_level & G_LOG_LEVEL_MASK) {
-            case G_LOG_LEVEL_ERROR:
-                level = "Err ";
-                break;
-            case G_LOG_LEVEL_CRITICAL:
-                level = "Crit";
-                break;
-            case G_LOG_LEVEL_WARNING:
-                level = "Warn";
-                break;
-            case G_LOG_LEVEL_MESSAGE:
-                level = "Msg ";
-                break;
-            case G_LOG_LEVEL_INFO:
-                level = "Info";
-                break;
-            case G_LOG_LEVEL_DEBUG:
-                level = "Dbg ";
-                break;
-            default:
-                fprintf(stderr, "unknown log_level %u\n", log_level);
-                level = NULL;
-                g_assert_not_reached();
-        }
-
-        /* create a "timestamp" */
-        time(&curr);
-        today = localtime(&curr);
-
-        fprintf(stderr, "%02u:%02u:%02u %8s %s %s\n",
-                today->tm_hour, today->tm_min, today->tm_sec,
-                log_domain != NULL ? log_domain : "",
-                level, message);
-#ifdef _WIN32
-        if(log_level & G_LOG_LEVEL_ERROR) {
-            /* wait for a key press before the following error handler will terminate the program
-               this way the user at least can read the error message */
-            printf("\n\nPress any key to exit\n");
-            _getch();
-        }
-    } else {
-        /* XXX - on UN*X, should we just use g_log_default_handler()?
-           We want the error messages to go to the standard output;
-           on Mac OS X, that will cause them to show up in various
-           per-user logs accessible through Console (details depend
-           on whether you're running 10.0 through 10.4 or running
-           10.5 and later), and, on other UN*X desktop environments,
-           if they don't show up in some form of console log, that's
-           a deficiency in that desktop environment.  (Too bad
-           Windows doesn't set the standard output and error for
-           GUI apps to something that shows up in such a log.) */
-        g_log_default_handler(log_domain, log_level, message, user_data);
-    }
-#endif
-}
 
 
 /*
@@ -3444,7 +3355,6 @@ static GtkWidget *main_widget_layout(gint layout_content)
     }
 }
 
-
 /*
  * Rearrange the main window widgets
  */
@@ -3888,7 +3798,6 @@ void change_configuration_profile (const gchar *profile_name)
     /* Set profile name and update the status bar */
     set_profile_name (profile_name);
     profile_bar_update ();
-    filter_expression_reinit(FILTER_EXPRESSION_REINIT_DESTROY);
 
     /* Reset current preferences and apply the new */
     prefs_reset();
@@ -3943,6 +3852,38 @@ void change_configuration_profile (const gchar *profile_name)
     main_pane_load_window_geometry();
 }
 
+void
+main_fields_changed (void)
+{
+    /* Reload color filters */
+    color_filters_reload();
+
+    /* Syntax check filter */
+    filter_te_syntax_check_cb(main_display_filter_widget, NULL);
+    if (cfile.dfilter) {
+        /* Check if filter is still valid */
+        dfilter_t *dfp = NULL;
+        if (!dfilter_compile(cfile.dfilter, &dfp, NULL)) {
+            /* Not valid.  Enable 'Apply' button and remove dfilter. */
+            g_signal_emit_by_name(G_OBJECT(main_display_filter_widget), "changed");
+            g_free(cfile.dfilter);
+            cfile.dfilter = NULL;
+        }
+        dfilter_free(dfp);
+    }
+
+    if (have_custom_cols(&cfile.cinfo)) {
+        /* Recreate packet list according to new/changed/deleted fields */
+        packet_list_recreate();
+    } else if (cfile.state != FILE_CLOSED) {
+        /* Redissect packets if we have any */
+        redissect_packets();
+    }
+    destroy_packet_wins(); /* TODO: close windows until we can recreate */
+
+    proto_free_deregistered_fields();
+}
+
 /** redissect packets and update UI */
 void redissect_packets(void)
 {