Refactor command-line handling of GUI options.
authorMichael Mann <mmann78@netscape.net>
Sat, 18 Jun 2016 20:49:23 +0000 (16:49 -0400)
committerAnders Broman <a.broman58@gmail.com>
Sun, 19 Jun 2016 05:56:45 +0000 (05:56 +0000)
Both GTK and Qt both use the same command-line options, so refactor
the parsing and (possibly) applying of those arguments to a single
location.

Ping-Bug: 12546
Change-Id: Ib31e576c509c5d3d21c33d3247640d9f9c68661b
Reviewed-on: https://code.wireshark.org/review/16006
Reviewed-by: Michael Mann <mmann78@netscape.net>
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
ui/CMakeLists.txt
ui/Makefile.common
ui/commandline.c [new file with mode: 0644]
ui/commandline.h [new file with mode: 0644]
ui/gtk/about_dlg.c
ui/gtk/main.c
ui/gtk/main.h
ui/qt/about_dialog.cpp
ui/qt/wireshark_application.h
wireshark-qt.cpp

index 8145dd1deec7ae10fef4fb9e405d01d96ae24948..67ab6e8d5a1cfc227682dab6de975ab1942d8989 100644 (file)
@@ -24,6 +24,7 @@ set(COMMON_UI_SRC
        alert_box.c
        capture.c
        capture_ui_utils.c
+       commandline.c
        console.c
        decode_as_utils.c
        export_object.c
index f0db822792edaefa5d08b4f51b62704055c11185..2156fd2659968053d63350efb93d72e116b7f5a5 100644 (file)
@@ -45,6 +45,7 @@ WIRESHARK_UI_SRC = \
        alert_box.c             \
        capture.c               \
        capture_ui_utils.c      \
+       commandline.c   \
        console.c               \
        decode_as_utils.c       \
        export_object.c         \
@@ -89,6 +90,7 @@ noinst_HEADERS = \
        capture.h               \
        capture_globals.h       \
        capture_ui_utils.h      \
+       commandline.h   \
        console.h               \
        decode_as_utils.h       \
        export_object.h         \
diff --git a/ui/commandline.c b/ui/commandline.c
new file mode 100644 (file)
index 0000000..e87ce5f
--- /dev/null
@@ -0,0 +1,637 @@
+/* commandline.h
+ * Common command line handling between GUIs
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#ifndef HAVE_GETOPT_LONG
+#include "wsutil/wsgetopt.h"
+#endif
+
+#include <ws_version_info.h>
+
+#include <wsutil/clopts_common.h>
+#include <wsutil/cmdarg_err.h>
+#include <wsutil/filesystem.h>
+
+#include <epan/ex-opt.h>
+#include <epan/addr_resolv.h>
+#include <epan/packet.h>
+#include <epan/proto.h>
+#include <epan/prefs.h>
+#include <epan/prefs-int.h>
+#include <epan/timestamp.h>
+#include <epan/stat_tap_ui.h>
+
+#include "capture_opts.h"
+#include "persfilepath_opt.h"
+#include "preference_utils.h"
+#include "console.h"
+#include "recent.h"
+
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
+#include <epan/asn1.h>
+#include <epan/dissectors/packet-kerberos.h>
+#endif
+
+#include "../file.h"
+
+#include "ui/commandline.h"
+
+#ifdef HAVE_LIBPCAP
+capture_options global_capture_opts;
+#endif
+
+void
+commandline_print_usage(gboolean for_help_option) {
+    FILE *output;
+
+#ifdef _WIN32
+    create_console();
+#endif
+
+    if (for_help_option) {
+        output = stdout;
+        fprintf(output, "Wireshark %s\n"
+            "Interactively dump and analyze network traffic.\n"
+            "See https://www.wireshark.org for more information.\n",
+            get_ws_vcs_version_info());
+    } else {
+        output = stderr;
+    }
+    fprintf(output, "\n");
+    fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
+    fprintf(output, "\n");
+
+#ifdef HAVE_LIBPCAP
+    fprintf(output, "Capture interface:\n");
+    fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
+    fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
+    fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
+    fprintf(output, "  -p                       don't capture in promiscuous mode\n");
+    fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
+    fprintf(output, "  -S                       update packet display when new packets are captured\n");
+    fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
+#ifdef HAVE_PCAP_CREATE
+    fprintf(output, "  -I                       capture in monitor mode, if available\n");
+#endif
+#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
+    fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
+#endif
+    fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
+    fprintf(output, "  -D                       print list of interfaces and exit\n");
+    fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
+    fprintf(output, "\n");
+    fprintf(output, "Capture stop conditions:\n");
+    fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
+    fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
+    fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
+    fprintf(output, "                              files:NUM - stop after NUM files\n");
+    /*fprintf(output, "\n");*/
+    fprintf(output, "Capture output:\n");
+    fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
+    fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
+    fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
+#endif  /* HAVE_LIBPCAP */
+#ifdef HAVE_PCAP_REMOTE
+    fprintf(output, "RPCAP options:\n");
+    fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
+#endif
+    /*fprintf(output, "\n");*/
+    fprintf(output, "Input file:\n");
+    fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
+
+    fprintf(output, "\n");
+    fprintf(output, "Processing:\n");
+    fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
+    fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
+    fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtd\"\n");
+    fprintf(output, "  --disable-protocol <proto_name>\n");
+    fprintf(output, "                           disable dissection of proto_name\n");
+    fprintf(output, "  --enable-heuristic <short_name>\n");
+    fprintf(output, "                           enable dissection of heuristic protocol\n");
+    fprintf(output, "  --disable-heuristic <short_name>\n");
+    fprintf(output, "                           disable dissection of heuristic protocol\n");
+
+    fprintf(output, "\n");
+    fprintf(output, "User interface:\n");
+    fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
+    fprintf(output, "  -Y <display filter>      start with the given display filter\n");
+    fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
+    fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
+    fprintf(output, "                           filter\n");
+    fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
+    fprintf(output, "  -m <font>                set the font name used for most text\n");
+    fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
+    fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
+    fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
+    fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
+
+    fprintf(output, "\n");
+    fprintf(output, "Output:\n");
+    fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
+
+    fprintf(output, "\n");
+    fprintf(output, "Miscellaneous:\n");
+    fprintf(output, "  -h                       display this help and exit\n");
+    fprintf(output, "  -v                       display version info and exit\n");
+    fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
+    fprintf(output, "                           persdata:path - personal data files\n");
+    fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
+    fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
+#ifndef _WIN32
+    fprintf(output, "  --display=DISPLAY        X display to use\n");
+#endif
+
+#ifdef _WIN32
+    destroy_console();
+#endif
+}
+
+#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
+static const struct option long_options[] = {
+        {"help", no_argument, NULL, 'h'},
+        {"read-file", required_argument, NULL, 'r' },
+        {"read-filter", required_argument, NULL, 'R' },
+        {"display-filter", required_argument, NULL, 'Y' },
+        {"version", no_argument, NULL, 'v'},
+        LONGOPT_CAPTURE_COMMON
+        {0, 0, 0, 0 }
+    };
+static const char optstring[] = OPTSTRING;
+
+void commandline_capture_options(int argc, char *argv[], commandline_capture_param_info_t* param_info)
+{
+    int opt;
+    int err;
+#ifdef HAVE_LIBPCAP
+    GList *if_list;
+    gchar *err_str;
+#endif
+
+    /*
+     * 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 GUI
+     * if we're only showing command-line help or version information.
+     *
+     * XXX - this pre-scan is done before we start GUI, so we haven't
+     * run "GUI init function" on the arguments.  That means that GUI-specific
+     * 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;
+
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
+        switch (opt) {
+            case 'C':        /* Configuration Profile */
+                if (profile_exists (optarg, FALSE)) {
+                    set_profile_name (optarg);
+                } else {
+                    cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
+                    exit(1);
+                }
+                break;
+            case 'D':        /* Print a list of capture devices and exit */
+#ifdef HAVE_LIBPCAP
+                if_list = capture_interface_list(&err, &err_str, NULL);
+                if (if_list == NULL) {
+                    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);
+                }
+#ifdef _WIN32
+                create_console();
+#endif /* _WIN32 */
+                capture_opts_print_interfaces(if_list);
+                free_interface_list(if_list);
+#ifdef _WIN32
+                destroy_console();
+#endif /* _WIN32 */
+                exit(0);
+#else /* HAVE_LIBPCAP */
+                param_info->capture_option_specified = TRUE;
+                param_info->arg_error = TRUE;
+#endif /* HAVE_LIBPCAP */
+                break;
+            case 'h':        /* Print help and exit */
+                commandline_print_usage(TRUE);
+                exit(0);
+                break;
+#ifdef _WIN32
+            case 'i':
+                if (strcmp(optarg, "-") == 0)
+                    set_stdin_capture(TRUE);
+                break;
+#endif
+            case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
+                if (!persfilepath_opt(opt, optarg)) {
+                    cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
+                    exit(2);
+                }
+                break;
+            case 'v':        /* Show version and exit */
+#ifdef _WIN32
+                create_console();
+#endif
+                show_version("Wireshark", param_info->comp_info_str, param_info->runtime_info_str);
+#ifdef _WIN32
+                destroy_console();
+#endif
+                exit(0);
+                break;
+            case 'X':
+                /*
+                 *  Extension command line options have to be processed before
+                 *  we call epan_init() as they are supposed to be used by dissectors
+                 *  or taps very early in the registration process.
+                 */
+                ex_opt_add(optarg);
+                break;
+            case '?':        /* Ignore errors - the "real" scan will catch them. */
+                break;
+        }
+    }
+}
+
+void commandline_other_options(int argc, char *argv[], commandline_param_info_t* param_info, gboolean opt_reset)
+{
+    int opt;
+#ifdef HAVE_LIBPCAP
+    int status;
+#endif
+    char badopt;
+
+    /*
+     * 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?
+     */
+    if (opt_reset) {
+#ifdef HAVE_OPTRESET
+        optreset = 1;
+        optind = 1;
+#else
+        optind = 0;
+#endif
+        opterr = 1;
+    }
+
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
+        switch (opt) {
+            /*** capture option specific ***/
+            case 'a':        /* autostop criteria */
+            case 'b':        /* Ringbuffer option */
+            case 'c':        /* Capture xxx packets */
+            case 'f':        /* capture filter */
+            case 'k':        /* Start capture immediately */
+            case 'H':        /* Hide capture info dialog box */
+            case 'p':        /* Don't capture in promiscuous mode */
+            case 'i':        /* Use interface x */
+#ifdef HAVE_PCAP_CREATE
+            case 'I':        /* Capture in monitor mode, if available */
+#endif
+#ifdef HAVE_PCAP_REMOTE
+            case 'A':        /* Authentication */
+#endif
+            case 's':        /* Set the snapshot (capture) length */
+            case 'S':        /* "Sync" mode: used for following file ala tail -f */
+            case 'w':        /* Write to capture file xxx */
+            case 'y':        /* Set the pcap data link type */
+#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
+            case 'B':        /* Buffer size */
+#endif
+#ifdef HAVE_LIBPCAP
+                status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
+                                              &param_info->start_capture);
+                if(status != 0) {
+                    exit(status);
+                }
+#else
+                capture_option_specified = TRUE;
+                param_info->arg_error = TRUE;
+#endif
+                break;
+
+#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
+            case 'K':        /* Kerberos keytab file */
+                    read_keytab_file(optarg);
+                break;
+#endif
+
+            /*** all non capture option specific ***/
+            case 'C':
+                /* Configuration profile settings were already processed just ignore them this time*/
+                break;
+            case 'j':        /* Search backwards for a matching packet from filter in option J */
+                param_info->jump_backwards = SD_BACKWARD;
+                break;
+            case 'g':        /* Go to packet with the given packet number */
+                param_info->go_to_packet = get_positive_int(optarg, "go to packet");
+                break;
+            case 'J':        /* Jump to the first packet which matches the filter criteria */
+                param_info->jfilter = optarg;
+                break;
+            case 'l':        /* Automatic scrolling in live capture mode */
+#ifdef HAVE_LIBPCAP
+                auto_scroll_live = TRUE;
+#else
+                param_info->capture_option_specified = TRUE;
+                param_info->arg_error = TRUE;
+#endif
+                break;
+            case 'L':        /* Print list of link-layer types and exit */
+#ifdef HAVE_LIBPCAP
+                param_info->list_link_layer_types = TRUE;
+#else
+                param_info->capture_option_specified = TRUE;
+                param_info->arg_error = TRUE;
+#endif
+                break;
+            case 'm':        /* Fixed-width font for the display */
+                g_free(param_info->prefs_p->gui_gtk2_font_name);
+                param_info->prefs_p->gui_gtk2_font_name = g_strdup(optarg);
+                break;
+            case 'n':        /* No name resolution */
+                disable_name_resolution();
+                break;
+            case 'N':        /* Select what types of addresses/port #s to resolve */
+                badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
+                if (badopt != '\0') {
+                    cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
+                               badopt);
+                    exit(1);
+                }
+                break;
+            case 'o':        /* Override preference from command line */
+                switch (prefs_set_pref(optarg)) {
+                    case PREFS_SET_OK:
+                        break;
+                    case PREFS_SET_SYNTAX_ERR:
+                        cmdarg_err("Invalid -o flag \"%s\"", optarg);
+                        exit(1);
+                        break;
+                    case PREFS_SET_NO_SUCH_PREF:
+                    /* not a preference, might be a recent setting */
+                        switch (recent_set_arg(optarg)) {
+                            case PREFS_SET_OK:
+                                break;
+                            case PREFS_SET_SYNTAX_ERR:
+                                /* shouldn't happen, checked already above */
+                                cmdarg_err("Invalid -o flag \"%s\"", optarg);
+                                exit(1);
+                                break;
+                            case PREFS_SET_NO_SUCH_PREF:
+                            case PREFS_SET_OBSOLETE:
+                                cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
+                                           optarg);
+                                exit(1);
+                                break;
+                            default:
+                                g_assert_not_reached();
+                        }
+                        break;
+                    case PREFS_SET_OBSOLETE:
+                        cmdarg_err("-o flag \"%s\" specifies obsolete preference",
+                                   optarg);
+                        exit(1);
+                        break;
+                    default:
+                        g_assert_not_reached();
+                }
+                break;
+            case 'P':
+                /* Path settings were already processed just ignore them this time*/
+                break;
+            case 'r':        /* Read capture file xxx */
+                /* We may set "last_open_dir" to "cf_name", and if we change
+                 "last_open_dir" later, we free the old value, so we have to
+                 set "cf_name" to something that's been allocated. */
+                param_info->cf_name = g_strdup(optarg);
+                break;
+            case 'R':        /* Read file filter */
+                param_info->rfilter = optarg;
+                break;
+            case 't':        /* Time stamp type */
+                if (strcmp(optarg, "r") == 0)
+                    timestamp_set_type(TS_RELATIVE);
+                else if (strcmp(optarg, "a") == 0)
+                    timestamp_set_type(TS_ABSOLUTE);
+                else if (strcmp(optarg, "ad") == 0)
+                    timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
+                else if (strcmp(optarg, "adoy") == 0)
+                    timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
+                else if (strcmp(optarg, "d") == 0)
+                    timestamp_set_type(TS_DELTA);
+                else if (strcmp(optarg, "dd") == 0)
+                    timestamp_set_type(TS_DELTA_DIS);
+                else if (strcmp(optarg, "e") == 0)
+                    timestamp_set_type(TS_EPOCH);
+                else if (strcmp(optarg, "u") == 0)
+                    timestamp_set_type(TS_UTC);
+                else if (strcmp(optarg, "ud") == 0)
+                    timestamp_set_type(TS_UTC_WITH_YMD);
+                else if (strcmp(optarg, "udoy") == 0)
+                    timestamp_set_type(TS_UTC_WITH_YDOY);
+                else {
+                    cmdarg_err("Invalid time stamp type \"%s\"", optarg);
+                    cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
+                    cmdarg_err_cont("\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
+                    cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
+                    cmdarg_err_cont("\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
+                    cmdarg_err_cont("or \"udoy\" for absolute UTC with YYYY/DOY date.");
+                    exit(1);
+                }
+                break;
+            case 'u':        /* Seconds type */
+                if (strcmp(optarg, "s") == 0)
+                    timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
+                else if (strcmp(optarg, "hms") == 0)
+                    timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
+                else {
+                    cmdarg_err("Invalid seconds type \"%s\"", optarg);
+                    cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
+                    exit(1);
+                }
+                break;
+            case 'X':
+                /* ext ops were already processed just ignore them this time*/
+                break;
+            case 'Y':
+                param_info->dfilter = optarg;
+                break;
+            case 'z':
+                /* We won't call the init function for the stat this soon
+                 as it would disallow MATE's fields (which are registered
+                 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 :");
+                    list_stat_cmd_args();
+                    exit(1);
+                }
+                break;
+            case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
+                param_info->disable_protocol_slist = g_slist_append(param_info->disable_protocol_slist, optarg);
+                break;
+            case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
+                param_info->enable_heur_slist = g_slist_append(param_info->enable_heur_slist, optarg);
+                break;
+            case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
+                param_info->disable_heur_slist = g_slist_append(param_info->disable_heur_slist, optarg);
+                break;
+            default:
+            case '?':        /* Bad flag - print usage message */
+                param_info->arg_error = TRUE;
+                break;
+            }
+    }
+
+    if (!param_info->arg_error) {
+        argc -= optind;
+        argv += optind;
+        if (argc >= 1) {
+            if (param_info->cf_name != NULL) {
+                /*
+                 * Input file name specified with "-r" *and* specified as a regular
+                 * command-line argument.
+                 */
+                cmdarg_err("File name specified both with -r and regular argument");
+                param_info->arg_error = TRUE;
+            } else {
+                /*
+                 * Input file name not specified with "-r", and a command-line argument
+                 * was specified; treat it as the input file name.
+                 *
+                 * Yes, this is different from tshark, where non-flag command-line
+                 * arguments are a filter, but this works better on GUI desktops
+                 * where a command can be specified to be run to open a particular
+                 * file - yes, you could have "-r" as the last part of the command,
+                 * but that's a bit ugly.
+                 */
+#ifndef HAVE_GTKOSXAPPLICATION
+                /*
+                 * For GTK+ Mac Integration, file name passed as free argument passed
+                 * through grag-and-drop and opened twice sometimes causing crashes.
+                 * Subject to report to GTK+ MAC.
+                 */
+                param_info->cf_name = g_strdup(argv[0]);
+#endif
+            }
+            argc--;
+            argv++;
+        }
+
+        if (argc != 0) {
+            /*
+             * Extra command line arguments were specified; complain.
+             */
+            cmdarg_err("Invalid argument: %s", argv[0]);
+            param_info->arg_error = TRUE;
+        }
+    }
+
+    if (param_info->arg_error) {
+#ifndef HAVE_LIBPCAP
+        if (param_info->capture_option_specified) {
+            cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
+        }
+#endif
+        commandline_print_usage(FALSE);
+        exit(1);
+    }
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/ui/commandline.h b/ui/commandline.h
new file mode 100644 (file)
index 0000000..2f0beee
--- /dev/null
@@ -0,0 +1,86 @@
+/* commandline.h
+ * Common command line handling between GUIs
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __COMMANDLINE_H__
+#define __COMMANDLINE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern void commandline_print_usage(gboolean for_help_option);
+
+typedef struct commandline_capture_param_info
+{
+    GString *comp_info_str;
+    GString *runtime_info_str;
+    gboolean arg_error;
+#ifndef HAVE_LIBPCAP
+    gboolean capture_option_specified;
+#endif
+} commandline_capture_param_info_t;
+
+extern void commandline_capture_options(int argc, char *argv[], commandline_capture_param_info_t* param_info);
+
+/* Command-line options that don't have direct API calls to handle the data */
+typedef struct commandline_param_info
+{
+    gboolean arg_error;
+#ifdef HAVE_LIBPCAP
+    gboolean list_link_layer_types;
+    gboolean start_capture;
+#else
+    gboolean capture_option_specified;
+#endif
+    e_prefs *prefs_p;
+    search_direction jump_backwards;
+    guint go_to_packet;
+    gchar* jfilter;
+    gchar* cf_name;
+    gchar* rfilter;
+    gchar* dfilter;
+    GSList *disable_protocol_slist;
+    GSList *enable_heur_slist;
+    GSList *disable_heur_slist;
+
+} commandline_param_info_t;
+
+extern void commandline_other_options(int argc, char *argv[], commandline_param_info_t* param_info, gboolean opt_reset);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __COMMANDLINE_H__ */
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
index 06c1d9a70bb7c8e7084d717afde0d0c64398073b..aee4b171d2435670567d4485ca7122decd8c9b7f 100644 (file)
@@ -301,6 +301,7 @@ about_wireshark_page_new(void)
 {
   GtkWidget *main_box, *msg_label /*, *icon*/;
   gchar     *message;
+  GString   *comp_info_str, *runtime_info_str;
 
   main_box = ws_gtk_box_new(GTK_ORIENTATION_VERTICAL, 6, FALSE);
   gtk_container_set_border_width(GTK_CONTAINER(main_box), 12);
@@ -310,6 +311,10 @@ about_wireshark_page_new(void)
 
   about_wireshark(top_level, main_box);
 
+  comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
+                                              get_gui_compiled_info);
+  runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
+
   /* Construct the message string */
   message = g_strdup_printf(
        "Version %s\n"
index 89878a55d4e57711a0929b092ecc4aa9fab328ef..cd390eca85b12ddd1084392210df82345409d36d 100644 (file)
 #include <getopt.h>
 #endif
 
-#ifndef HAVE_GETOPT_LONG
-#include "wsutil/wsgetopt.h"
-#endif
-
 #ifdef HAVE_EXTCAP
 #include <extcap.h>
 #endif
@@ -52,7 +48,6 @@
 #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 "ui/software_update.h"
 #include "ui/ui_util.h"
 #include "ui/util.h"
+#include "ui/commandline.h"
 
 #ifdef HAVE_LIBPCAP
 #include "ui/capture_ui_utils.h"
 #define RC_FILE "gtkrc"
 
 #ifdef HAVE_LIBPCAP
-capture_options global_capture_opts;
 capture_session global_capture_session;
 info_data_t global_info_data;
 #endif
@@ -242,8 +237,6 @@ GtkWidget *wireless_tb;
 int    airpcap_dll_ret_val = -1;
 #endif
 
-GString *comp_info_str, *runtime_info_str;
-
 static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
 
 static guint  tap_update_timer_id;
@@ -1148,113 +1141,6 @@ file_quit_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
         main_do_quit();
 }
 
-static void
-print_usage(gboolean for_help_option) {
-
-    FILE *output;
-
-#ifdef _WIN32
-    create_console();
-#endif
-
-    if (for_help_option) {
-        output = stdout;
-        fprintf(output, "Wireshark %s\n"
-            "Interactively dump and analyze network traffic.\n"
-            "See https://www.wireshark.org for more information.\n",
-            get_ws_vcs_version_info());
-    } else {
-        output = stderr;
-    }
-    fprintf(output, "\n");
-    fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
-    fprintf(output, "\n");
-
-#ifdef HAVE_LIBPCAP
-    fprintf(output, "Capture interface:\n");
-    fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
-    fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
-    fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
-    fprintf(output, "  -p                       don't capture in promiscuous mode\n");
-    fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
-    fprintf(output, "  -S                       update packet display when new packets are captured\n");
-    fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
-#ifdef HAVE_PCAP_CREATE
-    fprintf(output, "  -I                       capture in monitor mode, if available\n");
-#endif
-#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
-    fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
-#endif
-    fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
-    fprintf(output, "  -D                       print list of interfaces and exit\n");
-    fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
-    fprintf(output, "\n");
-    fprintf(output, "Capture stop conditions:\n");
-    fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
-    fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
-    fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
-    fprintf(output, "                              files:NUM - stop after NUM files\n");
-    /*fprintf(output, "\n");*/
-    fprintf(output, "Capture output:\n");
-    fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
-    fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
-    fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
-#endif  /* HAVE_LIBPCAP */
-#ifdef HAVE_PCAP_REMOTE
-    fprintf(output, "RPCAP options:\n");
-    fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
-#endif
-    /*fprintf(output, "\n");*/
-    fprintf(output, "Input file:\n");
-    fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "Processing:\n");
-    fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
-    fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
-    fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtd\"\n");
-    fprintf(output, "  --disable-protocol <proto_name>\n");
-    fprintf(output, "                           disable dissection of proto_name\n");
-    fprintf(output, "  --enable-heuristic <short_name>\n");
-    fprintf(output, "                           enable dissection of heuristic protocol\n");
-    fprintf(output, "  --disable-heuristic <short_name>\n");
-    fprintf(output, "                           disable dissection of heuristic protocol\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "User interface:\n");
-    fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
-    fprintf(output, "  -Y <display filter>      start with the given display filter\n");
-    fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
-    fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
-    fprintf(output, "                           filter\n");
-    fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
-    fprintf(output, "  -m <font>                set the font name used for most text\n");
-    fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
-    fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
-    fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
-    fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "Output:\n");
-    fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "Miscellaneous:\n");
-    fprintf(output, "  -h                       display this help and exit\n");
-    fprintf(output, "  -v                       display version info and exit\n");
-    fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
-    fprintf(output, "                           persdata:path - personal data files\n");
-    fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
-    fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
-#ifndef _WIN32
-    fprintf(output, "  --display=DISPLAY        X display to use\n");
-#endif
-
-#ifdef _WIN32
-    destroy_console();
-#endif
-}
-
 /*
  * Report an error in command-line arguments.
  * Creates a console on Windows.
@@ -1941,7 +1827,7 @@ main_capture_callback(gint event, capture_session *cap_session, gpointer user_da
 }
 #endif
 
-static void
+void
 get_wireshark_gtk_compiled_info(GString *str)
 {
     g_string_append(str, "with ");
@@ -1966,7 +1852,7 @@ get_wireshark_gtk_compiled_info(GString *str)
     get_compiled_caplibs_version(str);
 }
 
-static void
+void
 get_gui_compiled_info(GString *str)
 {
     epan_get_compiled_version_info(str);
@@ -1991,7 +1877,7 @@ get_gui_compiled_info(GString *str)
 #endif
 }
 
-static void
+void
 get_wireshark_runtime_info(GString *str)
 {
 #ifdef HAVE_LIBPCAP
@@ -2166,8 +2052,6 @@ main(int argc, char *argv[])
 {
     char                *init_progfile_dir_error;
     char                *s;
-    int                  opt;
-    gboolean             arg_error = FALSE;
 
     extern int           info_update_freq;  /* Found in about_dlg.c. */
     const gchar         *filter;
@@ -2181,9 +2065,6 @@ main(int argc, char *argv[])
     char                *gdp_path, *dp_path;
     int                  err;
 #ifdef HAVE_LIBPCAP
-    gboolean             start_capture = FALSE;
-    gboolean             list_link_layer_types = FALSE;
-    GList               *if_list;
     gchar               *err_str;
     int                  status;
 #else
@@ -2195,35 +2076,21 @@ main(int argc, char *argv[])
 #endif
 #endif
     gint                 pl_size = 280, tv_size = 95, bv_size = 75;
-    gchar               *rc_file, *cf_name = NULL, *rfilter = NULL, *dfilter = NULL, *jfilter = NULL;
+    gchar               *rc_file;
     dfilter_t           *rfcode = NULL;
     gchar               *err_msg = NULL;
     gboolean             rfilter_parse_failed = FALSE;
-    e_prefs             *prefs_p;
-    char                 badopt;
     GtkWidget           *splash_win = NULL;
-    guint                go_to_packet = 0;
-    search_direction     jump_backwards = SD_FORWARD;
     dfilter_t           *jump_to_filter = NULL;
     unsigned int         in_file_type = WTAP_TYPE_AUTO;
 #ifdef HAVE_GTKOSXAPPLICATION
     GtkosxApplication   *theApp;
 #endif
-    GSList              *disable_protocol_slist = NULL;
-    GSList              *enable_heur_slist = NULL;
-    GSList              *disable_heur_slist = NULL;
-
-#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
-    static const struct option long_options[] = {
-        {"help", no_argument, NULL, 'h'},
-        {"read-file", required_argument, NULL, 'r' },
-        {"read-filter", required_argument, NULL, 'R' },
-        {"display-filter", required_argument, NULL, 'Y' },
-        {"version", no_argument, NULL, 'v'},
-        LONGOPT_CAPTURE_COMMON
-        {0, 0, 0, 0 }
-    };
-    static const char optstring[] = OPTSTRING;
+    commandline_capture_param_info_t capture_param_info;
+    commandline_param_info_t commandline_info;
+
+    /* Initialize the capture arguments */
+    memset(&capture_param_info, 0, sizeof(capture_param_info));
 
 #ifdef HAVE_GDK_GRESOURCE
     main_register_resource();
@@ -2307,11 +2174,11 @@ main(int argc, char *argv[])
 #endif  /* _WIN32 */
 
     /* Get the compile-time version information string */
-    comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
+    capture_param_info.comp_info_str = get_compiled_version_info(get_wireshark_gtk_compiled_info,
                                               get_gui_compiled_info);
 
     /* Get the run-time version information string */
-    runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
+    capture_param_info.runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
 
     /* Add it to the information to be reported on a crash. */
     ws_add_crash_info("Wireshark %s\n"
@@ -2319,7 +2186,7 @@ main(int argc, char *argv[])
         "%s"
         "\n"
         "%s",
-        get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
+        get_ws_vcs_version_info(), capture_param_info.comp_info_str->str, capture_param_info.runtime_info_str->str);
 
 #ifdef _WIN32
     /* Start windows sockets */
@@ -2337,114 +2204,7 @@ main(int argc, char *argv[])
                       rf_path, g_strerror(rf_open_errno));
     }
 
-    /*
-     * 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;
-
-    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
-        switch (opt) {
-            case 'C':        /* Configuration Profile */
-                if (profile_exists (optarg, FALSE)) {
-                    set_profile_name (optarg);
-                } else {
-                    cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
-                    exit(1);
-                }
-                break;
-            case 'D':        /* Print a list of capture devices and exit */
-#ifdef HAVE_LIBPCAP
-                if_list = capture_interface_list(&err, &err_str, NULL);
-                if (if_list == NULL) {
-                    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);
-                }
-#ifdef _WIN32
-                create_console();
-#endif /* _WIN32 */
-                capture_opts_print_interfaces(if_list);
-                free_interface_list(if_list);
-#ifdef _WIN32
-                destroy_console();
-#endif /* _WIN32 */
-                exit(0);
-#else /* HAVE_LIBPCAP */
-                capture_option_specified = TRUE;
-                arg_error = TRUE;
-#endif /* HAVE_LIBPCAP */
-                break;
-            case 'h':        /* Print help and exit */
-                print_usage(TRUE);
-                exit(0);
-                break;
-#ifdef _WIN32
-            case 'i':
-                if (strcmp(optarg, "-") == 0)
-                    set_stdin_capture(TRUE);
-                break;
-#endif
-            case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
-                if (!persfilepath_opt(opt, optarg)) {
-                    cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
-                    exit(2);
-                }
-                break;
-            case 'v':        /* Show version and exit */
-#ifdef _WIN32
-                create_console();
-#endif
-                show_version("Wireshark", comp_info_str, runtime_info_str);
-#ifdef _WIN32
-                destroy_console();
-#endif
-                exit(0);
-                break;
-            case 'X':
-                /*
-                 *  Extension command line options have to be processed before
-                 *  we call epan_init() as they are supposed to be used by dissectors
-                 *  or taps very early in the registration process.
-                 */
-                ex_opt_add(optarg);
-                break;
-            case '?':        /* Ignore errors - the "real" scan will catch them. */
-                break;
-        }
-    }
+    commandline_capture_options(argc, argv, &capture_param_info);
 
     /* Init the "Open file" dialog directory */
     /* (do this after the path settings are processed) */
@@ -2582,7 +2342,7 @@ main(int argc, char *argv[])
 
     splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win);
 
-    prefs_p = read_configuration_files (&gdp_path, &dp_path);
+    commandline_info.prefs_p = read_configuration_files (&gdp_path, &dp_path);
     /* Removed thread code:
      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
      */
@@ -2597,329 +2357,43 @@ 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_long(argc, argv, optstring, long_options, NULL)) != -1) {
-        switch (opt) {
-            /*** capture option specific ***/
-            case 'a':        /* autostop criteria */
-            case 'b':        /* Ringbuffer option */
-            case 'c':        /* Capture xxx packets */
-            case 'f':        /* capture filter */
-            case 'k':        /* Start capture immediately */
-            case 'H':        /* Hide capture info dialog box */
-            case 'p':        /* Don't capture in promiscuous mode */
-            case 'i':        /* Use interface x */
-#ifdef HAVE_PCAP_CREATE
-            case 'I':        /* Capture in monitor mode, if available */
-#endif
-#ifdef HAVE_PCAP_REMOTE
-            case 'A':        /* Authentication */
-#endif
-            case 's':        /* Set the snapshot (capture) length */
-            case 'S':        /* "Sync" mode: used for following file ala tail -f */
-            case 'w':        /* Write to capture file xxx */
-            case 'y':        /* Set the pcap data link type */
-#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
-            case 'B':        /* Buffer size */
-#endif
+    /* Initialize commandline_info with default values */
+    commandline_info.jump_backwards = SD_FORWARD;
+    commandline_info.go_to_packet = 0;
+    commandline_info.jfilter = NULL;
+    commandline_info.cf_name = NULL;
+    commandline_info.rfilter = NULL;
+    commandline_info.dfilter = NULL;
 #ifdef HAVE_LIBPCAP
-                status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
-                                              &start_capture);
-                if(status != 0) {
-                    exit(status);
-                }
-#else
-                capture_option_specified = TRUE;
-                arg_error = TRUE;
+    commandline_info.start_capture = FALSE;
+    commandline_info.list_link_layer_types = FALSE;
 #endif
-                break;
+    commandline_info.disable_protocol_slist = NULL;
+    commandline_info.enable_heur_slist = NULL;
+    commandline_info.disable_heur_slist = NULL;
 
-#if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
-            case 'K':        /* Kerberos keytab file */
-                    read_keytab_file(optarg);
-                break;
-#endif
-
-            /*** all non capture option specific ***/
-            case 'C':
-                /* Configuration profile settings were already processed just ignore them this time*/
-                break;
-            case 'j':        /* Search backwards for a matching packet from filter in option J */
-                jump_backwards = SD_BACKWARD;
-                break;
-            case 'g':        /* Go to packet with the given packet number */
-                go_to_packet = get_positive_int(optarg, "go to packet");
-                break;
-            case 'J':        /* Jump to the first packet which matches the filter criteria */
-                jfilter = optarg;
-                break;
-            case 'l':        /* Automatic scrolling in live capture mode */
-#ifdef HAVE_LIBPCAP
-                auto_scroll_live = TRUE;
-#else
-                capture_option_specified = TRUE;
-                arg_error = TRUE;
-#endif
-                break;
-            case 'L':        /* Print list of link-layer types and exit */
-#ifdef HAVE_LIBPCAP
-                list_link_layer_types = TRUE;
-#else
-                capture_option_specified = TRUE;
-                arg_error = TRUE;
-#endif
-                break;
-            case 'm':        /* Fixed-width font for the display */
-                g_free(prefs_p->gui_gtk2_font_name);
-                prefs_p->gui_gtk2_font_name = g_strdup(optarg);
-                break;
-            case 'n':        /* No name resolution */
-                disable_name_resolution();
-                break;
-            case 'N':        /* Select what types of addresses/port #s to resolve */
-                badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
-                if (badopt != '\0') {
-                    cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
-                               badopt);
-                    exit(1);
-                }
-                break;
-            case 'o':        /* Override preference from command line */
-                switch (prefs_set_pref(optarg)) {
-                    case PREFS_SET_OK:
-                        break;
-                    case PREFS_SET_SYNTAX_ERR:
-                        cmdarg_err("Invalid -o flag \"%s\"", optarg);
-                        exit(1);
-                        break;
-                    case PREFS_SET_NO_SUCH_PREF:
-                    /* not a preference, might be a recent setting */
-                        switch (recent_set_arg(optarg)) {
-                            case PREFS_SET_OK:
-                                break;
-                            case PREFS_SET_SYNTAX_ERR:
-                                /* shouldn't happen, checked already above */
-                                cmdarg_err("Invalid -o flag \"%s\"", optarg);
-                                exit(1);
-                                break;
-                            case PREFS_SET_NO_SUCH_PREF:
-                            case PREFS_SET_OBSOLETE:
-                                cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
-                                           optarg);
-                                exit(1);
-                                break;
-                            default:
-                                g_assert_not_reached();
-                        }
-                        break;
-                    case PREFS_SET_OBSOLETE:
-                        cmdarg_err("-o flag \"%s\" specifies obsolete preference",
-                                   optarg);
-                        exit(1);
-                        break;
-                    default:
-                        g_assert_not_reached();
-                }
-                break;
-            case 'P':
-                /* Path settings were already processed just ignore them this time*/
-                break;
-            case 'r':        /* Read capture file xxx */
-                /* We may set "last_open_dir" to "cf_name", and if we change
-                 "last_open_dir" later, we free the old value, so we have to
-                 set "cf_name" to something that's been allocated. */
-                cf_name = g_strdup(optarg);
-                break;
-            case 'R':        /* Read file filter */
-                rfilter = optarg;
-                break;
-            case 't':        /* Time stamp type */
-                if (strcmp(optarg, "r") == 0)
-                    timestamp_set_type(TS_RELATIVE);
-                else if (strcmp(optarg, "a") == 0)
-                    timestamp_set_type(TS_ABSOLUTE);
-                else if (strcmp(optarg, "ad") == 0)
-                    timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
-                else if (strcmp(optarg, "adoy") == 0)
-                    timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
-                else if (strcmp(optarg, "d") == 0)
-                    timestamp_set_type(TS_DELTA);
-                else if (strcmp(optarg, "dd") == 0)
-                    timestamp_set_type(TS_DELTA_DIS);
-                else if (strcmp(optarg, "e") == 0)
-                    timestamp_set_type(TS_EPOCH);
-                else if (strcmp(optarg, "u") == 0)
-                    timestamp_set_type(TS_UTC);
-                else if (strcmp(optarg, "ud") == 0)
-                    timestamp_set_type(TS_UTC_WITH_YMD);
-                else if (strcmp(optarg, "udoy") == 0)
-                    timestamp_set_type(TS_UTC_WITH_YDOY);
-                else {
-                    cmdarg_err("Invalid time stamp type \"%s\"", optarg);
-                    cmdarg_err_cont(
-"It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
-                    cmdarg_err_cont(
-"\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
-                    cmdarg_err_cont(
-"\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
-                    cmdarg_err_cont(
-"\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
-                    cmdarg_err_cont(
-"or \"udoy\" for absolute UTC with YYYY/DOY date.");
-                    exit(1);
-                }
-                break;
-            case 'u':        /* Seconds type */
-                if (strcmp(optarg, "s") == 0)
-                    timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
-                else if (strcmp(optarg, "hms") == 0)
-                    timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
-                else {
-                    cmdarg_err("Invalid seconds type \"%s\"", optarg);
-                    cmdarg_err_cont(
-"It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
-                    exit(1);
-                }
-                break;
-            case 'X':
-                /* ext ops were already processed just ignore them this time*/
-                break;
-            case 'Y':
-                dfilter = optarg;
-                break;
-            case 'z':
-                /* We won't call the init function for the stat this soon
-                 as it would disallow MATE's fields (which are registered
-                 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 :");
-                    list_stat_cmd_args();
-                    exit(1);
-                }
-                break;
-            case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
-                disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
-                break;
-            case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
-                enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
-                break;
-            case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
-                disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
-                break;
-            default:
-            case '?':        /* Bad flag - print usage message */
-                arg_error = TRUE;
-                break;
-            }
-    }
-    if (!arg_error) {
-        argc -= optind;
-        argv += optind;
-        if (argc >= 1) {
-            if (cf_name != NULL) {
-                /*
-                 * Input file name specified with "-r" *and* specified as a regular
-                 * command-line argument.
-                 */
-                cmdarg_err("File name specified both with -r and regular argument");
-                arg_error = TRUE;
-            } else {
-                /*
-                 * Input file name not specified with "-r", and a command-line argument
-                 * was specified; treat it as the input file name.
-                 *
-                 * Yes, this is different from tshark, where non-flag command-line
-                 * arguments are a filter, but this works better on GUI desktops
-                 * where a command can be specified to be run to open a particular
-                 * file - yes, you could have "-r" as the last part of the command,
-                 * but that's a bit ugly.
-                 */
-#ifndef HAVE_GTKOSXAPPLICATION
-                /*
-                 * For GTK+ Mac Integration, file name passed as free argument passed
-                 * through grag-and-drop and opened twice sometimes causing crashes.
-                 * Subject to report to GTK+ MAC.
-                 */
-                cf_name = g_strdup(argv[0]);
-#endif
-            }
-            argc--;
-            argv++;
-        }
-
-        if (argc != 0) {
-            /*
-             * Extra command line arguments were specified; complain.
-             */
-            cmdarg_err("Invalid argument: %s", argv[0]);
-            arg_error = TRUE;
-        }
-    }
-
-    if (arg_error) {
+    /* Transfer capture option data to other options structure */
+    commandline_info.arg_error = capture_param_info.arg_error;
 #ifndef HAVE_LIBPCAP
-        if (capture_option_specified) {
-            cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
-        }
+    commandline_info.capture_option_specified = capture_param_info.capture_option_specified;
 #endif
-        print_usage(FALSE);
-        exit(1);
-    }
+
+    /* Now get our args */
+    commandline_other_options(argc, argv, &commandline_info, TRUE);
 
 #ifdef HAVE_LIBPCAP
     fill_in_local_interfaces(main_window_update);
-    if (start_capture && list_link_layer_types) {
+    if (commandline_info.start_capture && commandline_info.list_link_layer_types) {
         /* Specifying *both* is bogus. */
         cmdarg_err("You can't specify both -L and a live capture.");
         exit(1);
     }
 
-    if (list_link_layer_types) {
+    if (commandline_info.list_link_layer_types) {
         /* We're supposed to list the link-layer types for an interface;
            did the user also specify a capture file to be read? */
-        if (cf_name) {
+        if (commandline_info.cf_name) {
             /* Yes - that's bogus. */
             cmdarg_err("You can't specify -L and a capture file to be read.");
         exit(1);
@@ -2932,7 +2406,7 @@ main(int argc, char *argv[])
     } else {
         /* We're supposed to do a live capture; did the user also specify
            a capture file to be read? */
-        if (start_capture && cf_name) {
+        if (commandline_info.start_capture && commandline_info.cf_name) {
             /* Yes - that's bogus. */
             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
             exit(1);
@@ -2958,18 +2432,18 @@ main(int argc, char *argv[])
         }
     }
 
-    if (start_capture || list_link_layer_types) {
+    if (commandline_info.start_capture || commandline_info.list_link_layer_types) {
         /* We're supposed to do a live capture or get a list of link-layer
            types for a live capture device; if the user didn't specify an
            interface to use, pick a default. */
         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
-        ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
+        ((commandline_info.prefs_p->capture_device) && (*commandline_info.prefs_p->capture_device != '\0')) ? get_if_name(commandline_info.prefs_p->capture_device) : NULL);
         if (status != 0) {
             exit(status);
         }
     }
 
-    if (list_link_layer_types) {
+    if (commandline_info.list_link_layer_types) {
         /* Get the list of link-layer types for the capture devices. */
         if_capabilities_t *caps;
         guint i;
@@ -3027,7 +2501,7 @@ main(int argc, char *argv[])
 
 #ifdef HAVE_LIBPCAP
     if ((global_capture_opts.num_selected == 0) &&
-        ((prefs.capture_device != NULL) && (*prefs_p->capture_device != '\0'))) {
+        ((prefs.capture_device != NULL) && (*commandline_info.prefs_p->capture_device != '\0'))) {
         guint i;
         interface_t device;
         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
@@ -3056,31 +2530,31 @@ main(int argc, char *argv[])
         set_disabled_heur_dissector_list();
     }
 
-    if(disable_protocol_slist) {
+    if(commandline_info.disable_protocol_slist) {
         GSList *proto_disable;
-        for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
+        for (proto_disable = commandline_info.disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
         {
             proto_disable_proto_by_name((char*)proto_disable->data);
         }
     }
 
-    if(enable_heur_slist) {
+    if(commandline_info.enable_heur_slist) {
         GSList *heur_enable;
-        for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
+        for (heur_enable = commandline_info.enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
         {
             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
         }
     }
 
-    if(disable_heur_slist) {
+    if(commandline_info.disable_heur_slist) {
         GSList *heur_disable;
-        for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
+        for (heur_disable = commandline_info.disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
         {
             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
         }
     }
 
-    build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
+    build_column_format_array(&cfile.cinfo, commandline_info.prefs_p->num_cols, TRUE);
 
     /* read in rc file from global and personal configuration paths. */
     rc_file = get_datafile_path(RC_FILE);
@@ -3107,7 +2581,7 @@ main(int argc, char *argv[])
     /* Everything is prepared now, preferences and command line was read in */
 
     /* Pop up the main window. */
-    create_main_window(pl_size, tv_size, bv_size, prefs_p);
+    create_main_window(pl_size, tv_size, bv_size, commandline_info.prefs_p);
 
     /* Read the dynamic part of the recent file, as we have the gui now ready for it. */
     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
@@ -3169,7 +2643,7 @@ main(int argc, char *argv[])
     g_timeout_add(info_update_freq, resolv_update_cb, NULL);
 
     /* this is to keep tap extensions updating once every 3 seconds */
-    tap_update_timer_id = g_timeout_add(prefs_p->tap_update_interval, tap_update_cb, NULL);
+    tap_update_timer_id = g_timeout_add(commandline_info.prefs_p->tap_update_interval, tap_update_cb, NULL);
 
     /* If we were given the name of a capture file, read it in now;
      we defer it until now, so that, if we can't open it, and pop
@@ -3177,12 +2651,12 @@ main(int argc, char *argv[])
      top of the main window - but before the preference-file-error
      alert box, so, if we get one of those, it's more likely to come
      up on top of us. */
-    if (cf_name) {
+    if (commandline_info.cf_name) {
         show_main_window(TRUE);
-        check_and_warn_user_startup(cf_name);
-        if (rfilter != NULL) {
-            if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
-                bad_dfilter_alert_box(top_level, rfilter, err_msg);
+        check_and_warn_user_startup(commandline_info.cf_name);
+        if (commandline_info.rfilter != NULL) {
+            if (!dfilter_compile(commandline_info.rfilter, &rfcode, &err_msg)) {
+                bad_dfilter_alert_box(top_level, commandline_info.rfilter, err_msg);
                 g_free(err_msg);
                 rfilter_parse_failed = TRUE;
             }
@@ -3191,7 +2665,7 @@ main(int argc, char *argv[])
             in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
         }
         if (!rfilter_parse_failed) {
-            if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) == CF_OK) {
+            if (cf_open(&cfile, commandline_info.cf_name, in_file_type, FALSE, &err) == CF_OK) {
                 /* "cf_open()" succeeded, so it closed the previous
                  capture file, and thus destroyed any previous read filter
                  attached to "cf". */
@@ -3215,20 +2689,20 @@ main(int argc, char *argv[])
                            to read any of the file; we handle what we could get from the
                            file. */
                         /* if the user told us to jump to a specific packet, do it now */
-                        if(go_to_packet != 0) {
+                        if(commandline_info.go_to_packet != 0) {
                             /* Jump to the specified frame number, kept for backward
                                compatibility. */
-                            cf_goto_frame(&cfile, go_to_packet);
-                        } else if (jfilter != NULL) {
+                            cf_goto_frame(&cfile, commandline_info.go_to_packet);
+                        } else if (commandline_info.jfilter != NULL) {
                             /* try to compile given filter */
-                            if (!dfilter_compile(jfilter, &jump_to_filter, &err_msg)) {
-                                bad_dfilter_alert_box(top_level, jfilter, err_msg);
+                            if (!dfilter_compile(commandline_info.jfilter, &jump_to_filter, &err_msg)) {
+                                bad_dfilter_alert_box(top_level, commandline_info.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
                                option d was given, search backwards */
-                            cf_find_packet_dfilter(&cfile, jump_to_filter, jump_backwards);
+                            cf_find_packet_dfilter(&cfile, jump_to_filter, commandline_info.jump_backwards);
                             }
                         }
                         break;
@@ -3241,10 +2715,10 @@ main(int argc, char *argv[])
 
                 /* If the filename is not the absolute path, prepend the current dir. This happens
                    when wireshark is invoked from a cmd shell (e.g.,'wireshark -r file.pcap'). */
-                if (!g_path_is_absolute(cf_name)) {
-                    char *old_cf_name = cf_name;
+                if (!g_path_is_absolute(commandline_info.cf_name)) {
+                    char *old_cf_name = commandline_info.cf_name;
                     char *pwd = g_get_current_dir();
-                    cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, cf_name);
+                    commandline_info.cf_name = g_strdup_printf("%s%s%s", pwd, G_DIR_SEPARATOR_S, commandline_info.cf_name);
                     g_free(old_cf_name);
                     g_free(pwd);
                 }
@@ -3253,10 +2727,10 @@ main(int argc, char *argv[])
                    path name, if any; we can write over cf_name, which is a
                    good thing, given that "get_dirname()" does write over its
                    argument. */
-                s = get_dirname(cf_name);
+                s = get_dirname(commandline_info.cf_name);
                 set_last_open_dir(s);
-                g_free(cf_name);
-                cf_name = NULL;
+                g_free(commandline_info.cf_name);
+                commandline_info.cf_name = NULL;
             } else {
                 if (rfcode != NULL)
                     dfilter_free(rfcode);
@@ -3269,7 +2743,7 @@ main(int argc, char *argv[])
         }
     } else {
 #ifdef HAVE_LIBPCAP
-        if (start_capture) {
+        if (commandline_info.start_capture) {
             if (global_capture_opts.save_file != NULL) {
                 /* Save the directory name for future file dialogs. */
                 /* (get_dirname overwrites filename) */
@@ -3279,7 +2753,7 @@ main(int argc, char *argv[])
             }
             /* "-k" was specified; start a capture. */
             show_main_window(FALSE);
-            check_and_warn_user_startup(cf_name);
+            check_and_warn_user_startup(commandline_info.cf_name);
 
             /* If no user interfaces were specified on the command line,
                copy the list of selected interfaces to the set of interfaces
@@ -3297,29 +2771,29 @@ main(int argc, char *argv[])
             }
         } else {
             show_main_window(FALSE);
-            check_and_warn_user_startup(cf_name);
+            check_and_warn_user_startup(commandline_info.cf_name);
             main_set_for_capture_in_progress(FALSE);
             set_capture_if_dialog_for_capture_in_progress(FALSE);
         }
     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
-        if (!start_capture && !global_capture_opts.default_options.cfilter) {
+        if (!commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
         }
 #else /* HAVE_LIBPCAP */
         show_main_window(FALSE);
-        check_and_warn_user_startup(cf_name);
+        check_and_warn_user_startup(commandline_info.cf_name);
         main_set_for_capture_in_progress(FALSE);
         set_capture_if_dialog_for_capture_in_progress(FALSE);
 #endif /* HAVE_LIBPCAP */
     }
 
-    if (dfilter) {
+    if (commandline_info.dfilter) {
         GtkWidget *filter_te;
         filter_te = gtk_bin_get_child(GTK_BIN(g_object_get_data(G_OBJECT(top_level), E_DFILTER_CM_KEY)));
-        gtk_entry_set_text(GTK_ENTRY(filter_te), dfilter);
+        gtk_entry_set_text(GTK_ENTRY(filter_te), commandline_info.dfilter);
 
         /* Run the display filter so it goes in effect. */
-        main_filter_packets(&cfile, dfilter, FALSE);
+        main_filter_packets(&cfile, commandline_info.dfilter, FALSE);
     }
 
     profile_store_persconffiles (FALSE);
index 472b596be9dacf9a33a2d25029251f26c5b9cbe6..cdf3f52c4a18936daa8c4f336da7816a99d88060 100644 (file)
  */
 
 /** Global compile time version string */
-extern GString *comp_info_str;
+extern void get_wireshark_gtk_compiled_info(GString *str);
+extern void get_gui_compiled_info(GString *str);
 /** Global runtime version string */
-extern GString *runtime_info_str;
+extern void get_wireshark_runtime_info(GString *str);
+
 
 extern GtkWidget* wireless_tb;
 
index 733fc55eceaad08a8e3f2ccde84be5f4f4e8c23a..20eb49701a5cf4440e2d7042ebb7abad597620b9 100644 (file)
@@ -159,6 +159,9 @@ AboutDialog::AboutDialog(QWidget *parent) :
     gint i;
     gchar **resultArray;
 #endif
+  GString *comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
+                                              get_gui_compiled_info);
+  GString *runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
 
     /* Wireshark tab */
 
index f04053f07e914da22d8e4523715a0d3a4f73ba1f..1de706cb27afe9d413fc7562cba3fee195b48457 100644 (file)
@@ -181,10 +181,10 @@ private slots:
 extern WiresharkApplication *wsApp;
 
 /** Global compile time version string */
-extern GString *comp_info_str;
+extern void get_wireshark_qt_compiled_info(GString *str);
+extern void get_gui_compiled_info(GString *str);
 /** Global runtime version string */
-extern GString *runtime_info_str;
-
+extern void get_wireshark_runtime_info(GString *str);
 #endif // WIRESHARK_APPLICATION_H
 
 /*
index 1e286f5cbbb6368c6a84d5324971fbfb839543c0..513eed676382b7efd2859652dd08b4ab4f34b020 100644 (file)
@@ -53,6 +53,7 @@
 #include <epan/stat_tap_ui.h>
 #include <epan/column.h>
 #include <epan/disabled_protos.h>
+#include <epan/prefs.h>
 
 #ifdef HAVE_KERBEROS
 #include <epan/packet.h>
@@ -84,6 +85,7 @@
 #include "ui/recent.h"
 #include "ui/simple_dialog.h"
 #include "ui/util.h"
+#include "ui/commandline.h"
 
 #include "ui/qt/conversation_dialog.h"
 #include "ui/qt/color_utils.h"
 capture_options global_capture_opts;
 #endif
 
-GString *comp_info_str, *runtime_info_str;
-
 /* update the main window */
 void main_window_update(void)
 {
@@ -149,115 +149,6 @@ void main_window_quit(void)
 
 #endif /* HAVE_LIBPCAP */
 
-
-// xxx copied from ../gtk/main.c
-static void
-print_usage(gboolean for_help_option) {
-    FILE *output;
-
-#ifdef _WIN32
-    create_console();
-#endif
-
-    if (for_help_option) {
-        output = stdout;
-        fprintf(output, "Wireshark %s\n"
-                "Interactively dump and analyze network traffic.\n"
-                "See https://www.wireshark.org for more information.\n",
-                get_ws_vcs_version_info());
-    } else {
-        output = stderr;
-    }
-    fprintf(output, "\n");
-    fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
-    fprintf(output, "\n");
-
-#ifdef HAVE_LIBPCAP
-    fprintf(output, "Capture interface:\n");
-    fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
-    fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
-    fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
-    fprintf(output, "  -p                       don't capture in promiscuous mode\n");
-    fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
-    fprintf(output, "  -S                       update packet display when new packets are captured\n");
-    fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
-#ifdef HAVE_PCAP_CREATE
-    fprintf(output, "  -I                       capture in monitor mode, if available\n");
-#endif
-#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
-    fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
-#endif
-    fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
-    fprintf(output, "  -D                       print list of interfaces and exit\n");
-    fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
-    fprintf(output, "\n");
-    fprintf(output, "Capture stop conditions:\n");
-    fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
-    fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
-    fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
-    fprintf(output, "                              files:NUM - stop after NUM files\n");
-    /*fprintf(output, "\n");*/
-    fprintf(output, "Capture output:\n");
-    fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
-    fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
-    fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
-#endif  /* HAVE_LIBPCAP */
-#ifdef HAVE_PCAP_REMOTE
-    fprintf(output, "RPCAP options:\n");
-    fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
-#endif
-    /*fprintf(output, "\n");*/
-    fprintf(output, "Input file:\n");
-    fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "Processing:\n");
-    fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
-    fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
-    fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtd\"\n");
-    fprintf(output, "  --disable-protocol <proto_name>\n");
-    fprintf(output, "                           disable dissection of proto_name\n");
-    fprintf(output, "  --enable-heuristic <short_name>\n");
-    fprintf(output, "                           enable dissection of heuristic protocol\n");
-    fprintf(output, "  --disable-heuristic <short_name>\n");
-    fprintf(output, "                           disable dissection of heuristic protocol\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "User interface:\n");
-    fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
-    fprintf(output, "  -Y <display filter>      start with the given display filter\n");
-    fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
-    fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
-    fprintf(output, "                           filter\n");
-    fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
-    fprintf(output, "  -m <font>                set the font name used for most text\n");
-    fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
-    fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
-    fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
-    fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "Output:\n");
-    fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
-
-    fprintf(output, "\n");
-    fprintf(output, "Miscellaneous:\n");
-    fprintf(output, "  -h                       display this help and exit\n");
-    fprintf(output, "  -v                       display version info and exit\n");
-    fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
-    fprintf(output, "                           persdata:path - personal data files\n");
-    fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
-    fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
-#ifndef _WIN32
-    fprintf(output, "  --display=DISPLAY        X display to use\n");
-#endif
-    fprintf(output, "\nNOTE: Not all options are implemented in the Qt port.\n");
-
-#ifdef _WIN32
-    destroy_console();
-#endif
-}
-
 /*
  * Report an error in command-line arguments.
  * Creates a console on Windows.
@@ -292,7 +183,7 @@ wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
 }
 
 // xxx based from ../gtk/main.c:get_gtk_compiled_info
-static void
+void
 get_wireshark_qt_compiled_info(GString *str)
 {
     g_string_append(str, "with ");
@@ -309,7 +200,7 @@ get_wireshark_qt_compiled_info(GString *str)
 }
 
 // xxx copied from ../gtk/main.c
-static void
+void
 get_gui_compiled_info(GString *str)
 {
     epan_get_compiled_version_info(str);
@@ -330,7 +221,7 @@ get_gui_compiled_info(GString *str)
 }
 
 // xxx copied from ../gtk/main.c
-static void
+void
 get_wireshark_runtime_info(GString *str)
 {
 #ifdef HAVE_LIBPCAP
@@ -423,7 +314,6 @@ int main(int argc, char *argv[])
     MainWindow *main_w;
 
     int                  opt, ret_val;
-    gboolean             arg_error = FALSE;
     char               **ws_argv = argv;
 
 #ifdef _WIN32
@@ -434,10 +324,6 @@ int main(int argc, char *argv[])
     int                  rf_open_errno;
     char                *gdp_path, *dp_path;
 #ifdef HAVE_LIBPCAP
-    int                  err;
-    gboolean             start_capture = FALSE;
-    gboolean             list_link_layer_types = FALSE;
-    GList               *if_list;
     gchar               *err_str;
     int                  status;
 #else
@@ -448,14 +334,13 @@ int main(int argc, char *argv[])
 #endif
 #endif
 #endif
-    e_prefs             *prefs_p;
-    char                 badopt;
-    guint                go_to_packet = 0;
+    commandline_capture_param_info_t capture_param_info;
+    commandline_param_info_t commandline_info;
 
     QString              dfilter, read_filter;
-    GSList              *disable_protocol_slist = NULL;
-    GSList              *enable_heur_slist = NULL;
-    GSList              *disable_heur_slist = NULL;
+
+    /* Initialize the capture arguments */
+    memset(&capture_param_info, 0, sizeof(capture_param_info));
 
     cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
 
@@ -549,13 +434,11 @@ int main(int argc, char *argv[])
 #endif /* _WIN32 */
 
     /* Get the compile-time version information string */
-    // XXX qtshark
-    comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
+    capture_param_info.comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
                                               get_gui_compiled_info);
 
     /* Assemble the run-time version information string */
-    // xxx qtshark
-    runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
+    capture_param_info.runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
 
     profile_store_persconffiles(TRUE);
 
@@ -568,128 +451,7 @@ int main(int argc, char *argv[])
         g_free(rf_path);
     }
 
-    /*
-     * 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 Qt
-     * if we're only showing command-line help or version information.
-     *
-     * XXX - this pre-scan is done before we start Qt, so we haven't
-     * run WiresharkApplication's constructor on the arguments.  That
-     * means that Qt arguments have not been removed from the argument
-     * list; those arguments begin with "-", and may be treated as
-     * errors by getopt_long().
-     *
-     * We thus ignore errors - *and* set "opterr" to 0 to suppress the
-     * error messages.
-     *
-     * XXX - is there some way to parse and remove Qt arguments without
-     * starting up the GUI, which we can call before calling 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.
-     */
-    // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
-#define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
-    static const struct option long_options[] = {
-        {"help", no_argument, NULL, 'h'},
-        {"read-file", required_argument, NULL, 'r' },
-        {"read-filter", required_argument, NULL, 'R' },
-        {"display-filter", required_argument, NULL, 'Y' },
-        {"version", no_argument, NULL, 'v'},
-        LONGOPT_CAPTURE_COMMON
-        {0, 0, 0, 0 }
-    };
-    static const char optstring[] = OPTSTRING;
-
-    opterr = 0;
-
-    while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
-        switch (opt) {
-            case 'C':        /* Configuration Profile */
-                if (profile_exists (optarg, FALSE)) {
-                    set_profile_name (optarg);
-                } else {
-                    cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
-                    exit(1);
-                }
-                break;
-            case 'D':        /* Print a list of capture devices and exit */
-#ifdef HAVE_LIBPCAP
-                if_list = capture_interface_list(&err, &err_str, NULL);
-                if (if_list == NULL) {
-                    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);
-                }
-#ifdef _WIN32
-                create_console();
-#endif /* _WIN32 */
-                capture_opts_print_interfaces(if_list);
-                free_interface_list(if_list);
-#ifdef _WIN32
-                destroy_console();
-#endif /* _WIN32 */
-                exit(0);
-#else /* HAVE_LIBPCAP */
-                capture_option_specified = TRUE;
-                arg_error = TRUE;
-#endif /* HAVE_LIBPCAP */
-                break;
-            case 'h':        /* Print help and exit */
-                print_usage(TRUE);
-                exit(0);
-                break;
-#ifdef _WIN32
-            case 'i':
-                if (strcmp(optarg, "-") == 0)
-                    set_stdin_capture(TRUE);
-                break;
-#endif
-            case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
-                if (!persfilepath_opt(opt, optarg)) {
-                    cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
-                    exit(2);
-                }
-                break;
-            case 'v':        /* Show version and exit */
-#ifdef _WIN32
-                create_console();
-#endif
-                show_version("Wireshark", comp_info_str, runtime_info_str);
-#ifdef _WIN32
-                destroy_console();
-#endif
-                exit(0);
-                break;
-            case 'X':
-                /*
-                 *  Extension command line options have to be processed before
-                 *  we call epan_init() as they are supposed to be used by dissectors
-                 *  or taps very early in the registration process.
-                 */
-                ex_opt_add(optarg);
-                break;
-            case '?':        /* Ignore errors - the "real" scan will catch them. */
-                break;
-        }
-    }
+    commandline_capture_options(argc, ws_argv, &capture_param_info);
 
 #ifdef _WIN32
     reset_library_path();
@@ -714,7 +476,7 @@ int main(int argc, char *argv[])
            "%s"
            "\n"
            "%s",
-        get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
+        get_ws_vcs_version_info(), capture_param_info.comp_info_str->str, capture_param_info.runtime_info_str->str);
 
 #ifdef _WIN32
     /* Start windows sockets */
@@ -831,309 +593,39 @@ int main(int argc, char *argv[])
 
     splash_update(RA_PREFERENCES, NULL, NULL);
 
-    prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
-
-    /*
-     * 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;
+    commandline_info.prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
 
-    /* Now get our args */
-    while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
-        switch (opt) {
-        /*** capture option specific ***/
-        case 'a':        /* autostop criteria */
-        case 'b':        /* Ringbuffer option */
-        case 'c':        /* Capture xxx packets */
-        case 'f':        /* capture filter */
-        case 'k':        /* Start capture immediately */
-        case 'H':        /* Hide capture info dialog box */
-        case 'p':        /* Don't capture in promiscuous mode */
-        case 'i':        /* Use interface x */
-#ifdef HAVE_PCAP_CREATE
-        case 'I':        /* Capture in monitor mode, if available */
-#endif
-#ifdef HAVE_PCAP_REMOTE
-        case 'A':        /* Authentication */
-#endif
-        case 's':        /* Set the snapshot (capture) length */
-        case 'S':        /* "Sync" mode: used for following file ala tail -f */
-        case 'w':        /* Write to capture file xxx */
-        case 'y':        /* Set the pcap data link type */
-#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
-        case 'B':        /* Buffer size */
-#endif
+    /* Initialize commandline_info with default values */
+    commandline_info.jump_backwards = SD_FORWARD;
+    commandline_info.go_to_packet = 0;
+    commandline_info.jfilter = NULL;
+    commandline_info.cf_name = NULL;
+    commandline_info.rfilter = NULL;
+    commandline_info.dfilter = NULL;
 #ifdef HAVE_LIBPCAP
-            status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
-                                          &start_capture);
-            if(status != 0) {
-                exit(status);
-            }
-#else
-            capture_option_specified = TRUE;
-            arg_error = TRUE;
-#endif
-            break;
-#ifdef HAVE_KERBEROS
-        case 'K':        /* Kerberos keytab file */
-            read_keytab_file(optarg);
-            break;
+    commandline_info.start_capture = FALSE;
+    commandline_info.list_link_layer_types = FALSE;
 #endif
+    commandline_info.disable_protocol_slist = NULL;
+    commandline_info.enable_heur_slist = NULL;
+    commandline_info.disable_heur_slist = NULL;
 
-        /*** all non capture option specific ***/
-        case 'C':
-            /* Configuration profile settings were already processed just ignore them this time*/
-            break;
-        case 'j':        /* Search backwards for a matching packet from filter in option J */
-            /* Not supported yet */
-            break;
-        case 'g':        /* Go to packet with the given packet number */
-            go_to_packet = get_positive_int(optarg, "go to packet");
-            break;
-        case 'J':        /* Jump to the first packet which matches the filter criteria */
-            /* Not supported yet */
-            break;
-        case 'l':        /* Automatic scrolling in live capture mode */
-#ifdef HAVE_LIBPCAP
-            /* Not supported yet */
-#else
-            capture_option_specified = TRUE;
-            arg_error = TRUE;
-#endif
-            break;
-        case 'L':        /* Print list of link-layer types and exit */
-#ifdef HAVE_LIBPCAP
-                list_link_layer_types = TRUE;
-#else
-                capture_option_specified = TRUE;
-                arg_error = TRUE;
+    /* Transfer capture option data to other options structure */
+    commandline_info.arg_error = capture_param_info.arg_error;
+#ifndef HAVE_LIBPCAP
+    commandline_info.capture_option_specified = capture_param_info.capture_option_specified;
 #endif
-            break;
-        case 'm':        /* Fixed-width font for the display */
-            /* Not supported yet */
-            break;
-        case 'n':        /* No name resolution */
-            disable_name_resolution();
-            break;
-        case 'N':        /* Select what types of addresses/port #s to resolve */
-            badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
-            if (badopt != '\0') {
-                cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
-                           badopt);
-                exit(1);
-            }
-            break;
-        case 'o':        /* Override preference from command line */
-            switch (prefs_set_pref(optarg)) {
-                case PREFS_SET_OK:
-                    break;
-                case PREFS_SET_SYNTAX_ERR:
-                    cmdarg_err("Invalid -o flag \"%s\"", optarg);
-                    exit(1);
-                    break;
-                case PREFS_SET_NO_SUCH_PREF:
-                /* not a preference, might be a recent setting */
-                    switch (recent_set_arg(optarg)) {
-                        case PREFS_SET_OK:
-                            break;
-                        case PREFS_SET_SYNTAX_ERR:
-                            /* shouldn't happen, checked already above */
-                            cmdarg_err("Invalid -o flag \"%s\"", optarg);
-                            exit(1);
-                            break;
-                        case PREFS_SET_NO_SUCH_PREF:
-                        case PREFS_SET_OBSOLETE:
-                            cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
-                                       optarg);
-                            exit(1);
-                            break;
-                        default:
-                            g_assert_not_reached();
-                    }
-                    break;
-                case PREFS_SET_OBSOLETE:
-                    cmdarg_err("-o flag \"%s\" specifies obsolete preference",
-                               optarg);
-                    exit(1);
-                    break;
-                default:
-                    g_assert_not_reached();
-            }
-            break;
-        case 'P':
-            /* Path settings were already processed just ignore them this time*/
-            break;
-        case 'r':
-            cf_name = optarg;
-            break;
-        case 'R':        /* Read file filter */
-            read_filter = QString(optarg);
-            break;
-        case 't':        /* Time stamp type */
-            if (strcmp(optarg, "r") == 0)
-                timestamp_set_type(TS_RELATIVE);
-            else if (strcmp(optarg, "a") == 0)
-                timestamp_set_type(TS_ABSOLUTE);
-            else if (strcmp(optarg, "ad") == 0)
-                timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
-            else if (strcmp(optarg, "adoy") == 0)
-                timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
-            else if (strcmp(optarg, "d") == 0)
-                timestamp_set_type(TS_DELTA);
-            else if (strcmp(optarg, "dd") == 0)
-                timestamp_set_type(TS_DELTA_DIS);
-            else if (strcmp(optarg, "e") == 0)
-                timestamp_set_type(TS_EPOCH);
-            else if (strcmp(optarg, "u") == 0)
-                timestamp_set_type(TS_UTC);
-            else if (strcmp(optarg, "ud") == 0)
-                timestamp_set_type(TS_UTC_WITH_YMD);
-            else if (strcmp(optarg, "udoy") == 0)
-                timestamp_set_type(TS_UTC_WITH_YDOY);
-            else {
-                cmdarg_err("Invalid time stamp type \"%s\"", optarg);
-                cmdarg_err_cont(
-"It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
-                cmdarg_err_cont(
-"\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
-                cmdarg_err_cont(
-"\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
-                cmdarg_err_cont(
-"\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
-                cmdarg_err_cont(
-"or \"udoy\" for absolute UTC with YYYY/DOY date.");
-                exit(1);
-            }
-            break;
-        case 'u':        /* Seconds type */
-            if (strcmp(optarg, "s") == 0)
-                timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
-            else if (strcmp(optarg, "hms") == 0)
-                timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
-            else {
-                cmdarg_err("Invalid seconds type \"%s\"", optarg);
-                cmdarg_err_cont(
-"It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
-                exit(1);
-            }
-            break;
-        case 'X':
-            /* ext ops were already processed just ignore them this time*/
-            break;
-        case 'Y':
-            dfilter = QString(optarg);
-            break;
-        case 'z':
-            /* We won't call the init function for the stat this soon
-             as it would disallow MATE's fields (which are registered
-             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 :");
-                list_stat_cmd_args();
-                exit(1);
-            }
-            break;
-        case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
-            disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
-            break;
-        case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
-            enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
-            break;
-        case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
-            disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
-            break;
-
-        default:
-        case '?':        /* Bad flag - print usage message */
-            print_usage(FALSE);
-            exit(0);
-            break;
-        }
-    }
-
-    if (!arg_error) {
-        argc -= optind;
-        ws_argv += optind;
-        if (argc >= 1) {
-            if (!cf_name.isEmpty()) {
-                /*
-                 * Input file name specified with "-r" *and* specified as a regular
-                 * command-line argument.
-                 */
-                cmdarg_err("File name specified both with -r and regular argument");
-                arg_error = TRUE;
-            } else {
-                /*
-                 * Input file name not specified with "-r", and a command-line argument
-                 * was specified; treat it as the input file name.
-                 *
-                 * Yes, this is different from tshark, where non-flag command-line
-                 * arguments are a filter, but this works better on GUI desktops
-                 * where a command can be specified to be run to open a particular
-                 * file - yes, you could have "-r" as the last part of the command,
-                 * but that's a bit ugly.
-                 */
-                cf_name = ws_argv[0];
 
-            }
-            argc--;
-            ws_argv++;
-        }
+    /* Now get our args */
+    commandline_other_options(argc, argv, &commandline_info, TRUE);
 
-        if (argc != 0) {
-            /*
-             * Extra command line arguments were specified; complain.
-             */
-            cmdarg_err("Invalid argument: %s", ws_argv[0]);
-            arg_error = TRUE;
-        }
-    }
-    if (arg_error) {
-#ifndef HAVE_LIBPCAP
-        if (capture_option_specified) {
-            cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
-        }
-#endif
-        print_usage(FALSE);
-        exit(1);
-    }
+    /* Convert some command-line parameters to QStrings */
+    if (commandline_info.cf_name != NULL)
+        cf_name = QString(commandline_info.cf_name);
+    if (commandline_info.rfilter != NULL)
+        read_filter = QString(commandline_info.rfilter);
+    if (commandline_info.dfilter != NULL)
+        dfilter = QString(commandline_info.dfilter);
 
     /* Removed thread code:
      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
@@ -1147,13 +639,13 @@ int main(int argc, char *argv[])
 #ifdef HAVE_LIBPCAP
     fill_in_local_interfaces(main_window_update);
 
-    if (start_capture && list_link_layer_types) {
+    if (commandline_info.start_capture && commandline_info.list_link_layer_types) {
         /* Specifying *both* is bogus. */
         cmdarg_err("You can't specify both -L and a live capture.");
         exit(1);
     }
 
-    if (list_link_layer_types) {
+    if (commandline_info.list_link_layer_types) {
         /* We're supposed to list the link-layer types for an interface;
            did the user also specify a capture file to be read? */
         if (!cf_name.isEmpty()) {
@@ -1169,7 +661,7 @@ int main(int argc, char *argv[])
     } else {
         /* We're supposed to do a live capture; did the user also specify
            a capture file to be read? */
-        if (start_capture && !cf_name.isEmpty()) {
+        if (commandline_info.start_capture && !cf_name.isEmpty()) {
             /* Yes - that's bogus. */
             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
             exit(1);
@@ -1195,18 +687,18 @@ int main(int argc, char *argv[])
         }
     }
 
-    if (start_capture || list_link_layer_types) {
+    if (commandline_info.start_capture || commandline_info.list_link_layer_types) {
         /* We're supposed to do a live capture or get a list of link-layer
            types for a live capture device; if the user didn't specify an
            interface to use, pick a default. */
         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
-        ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
+        ((commandline_info.prefs_p->capture_device) && (*commandline_info.prefs_p->capture_device != '\0')) ? get_if_name(commandline_info.prefs_p->capture_device) : NULL);
         if (status != 0) {
             exit(status);
         }
     }
 
-    if (list_link_layer_types) {
+    if (commandline_info.list_link_layer_types) {
         /* Get the list of link-layer types for the capture devices. */
         if_capabilities_t *caps;
         guint i;
@@ -1280,31 +772,31 @@ int main(int argc, char *argv[])
         set_disabled_heur_dissector_list();
     }
 
-    if(disable_protocol_slist) {
+    if(commandline_info.disable_protocol_slist) {
         GSList *proto_disable;
-        for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
+        for (proto_disable = commandline_info.disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
         {
             proto_disable_proto_by_name((char*)proto_disable->data);
         }
     }
 
-    if(enable_heur_slist) {
+    if(commandline_info.enable_heur_slist) {
         GSList *heur_enable;
-        for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
+        for (heur_enable = commandline_info.enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
         {
             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
         }
     }
 
-    if(disable_heur_slist) {
+    if(commandline_info.disable_heur_slist) {
         GSList *heur_disable;
-        for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
+        for (heur_disable = commandline_info.disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
         {
             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
         }
     }
 
-    build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);
+    build_column_format_array(&CaptureFile::globalCapFile()->cinfo, commandline_info.prefs_p->num_cols, TRUE);
     wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
     wsApp->emitAppSignal(WiresharkApplication::RecentFilesRead); // Must be emitted after PreferencesChanged.
 
@@ -1342,7 +834,7 @@ int main(int argc, char *argv[])
 
 #ifdef HAVE_LIBPCAP
     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
-    if (!start_capture && !global_capture_opts.default_options.cfilter) {
+    if (!commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
         global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
     }
 #else /* HAVE_LIBPCAP */
@@ -1368,16 +860,16 @@ int main(int argc, char *argv[])
                filter. */
             start_requested_stats();
 
-            if(go_to_packet != 0) {
+            if(commandline_info.go_to_packet != 0) {
                 /* Jump to the specified frame number, kept for backward
                    compatibility. */
-                cf_goto_frame(CaptureFile::globalCapFile(), go_to_packet);
+                cf_goto_frame(CaptureFile::globalCapFile(), commandline_info.go_to_packet);
             }
         }
     }
 #ifdef HAVE_LIBPCAP
     else {
-        if (start_capture) {
+        if (commandline_info.start_capture) {
             if (global_capture_opts.save_file != NULL) {
                 /* Save the directory name for future file dialogs. */
                 /* (get_dirname overwrites filename) */
@@ -1406,7 +898,7 @@ int main(int argc, char *argv[])
             }
         }
     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
-        if (!start_capture && !global_capture_opts.default_options.cfilter) {
+        if (!commandline_info.start_capture && !global_capture_opts.default_options.cfilter) {
             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
         }
     }