From 9b5b4443cf50aa0e5d98d8129a5c65c6c76a838b Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Sat, 18 Jun 2016 16:49:23 -0400 Subject: Refactor command-line handling of GUI options. 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 Petri-Dish: Michael Mann Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- ui/CMakeLists.txt | 1 + ui/Makefile.common | 2 + ui/commandline.c | 637 +++++++++++++++++++++++++++++++++++++++ ui/commandline.h | 86 ++++++ ui/gtk/about_dlg.c | 5 + ui/gtk/main.c | 678 +++++------------------------------------- ui/gtk/main.h | 6 +- ui/qt/about_dialog.cpp | 3 + ui/qt/wireshark_application.h | 6 +- 9 files changed, 817 insertions(+), 607 deletions(-) create mode 100644 ui/commandline.c create mode 100644 ui/commandline.h (limited to 'ui') diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 8145dd1dee..67ab6e8d5a 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -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 diff --git a/ui/Makefile.common b/ui/Makefile.common index f0db822792..2156fd2659 100644 --- a/ui/Makefile.common +++ b/ui/Makefile.common @@ -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 index 0000000000..e87ce5fc49 --- /dev/null +++ b/ui/commandline.c @@ -0,0 +1,637 @@ +/* commandline.h + * Common command line handling between GUIs + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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 + +#include +#include +#include + +#ifdef HAVE_GETOPT_H +#include +#endif + +#ifndef HAVE_GETOPT_LONG +#include "wsutil/wsgetopt.h" +#endif + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#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] ... [ ]\n"); + fprintf(output, "\n"); + +#ifdef HAVE_LIBPCAP + fprintf(output, "Capture interface:\n"); + fprintf(output, " -i name or idx of interface (def: first non-loopback)\n"); + fprintf(output, " -f packet filter in libpcap filter syntax\n"); + fprintf(output, " -s 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 size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE); +#endif + fprintf(output, " -y 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 stop after n packets (def: infinite)\n"); + fprintf(output, " -a ... 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 ... 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 : use RPCAP password authentication\n"); +#endif + /*fprintf(output, "\n");*/ + fprintf(output, "Input file:\n"); + fprintf(output, " -r set the filename to read from (no pipes or stdin!)\n"); + + fprintf(output, "\n"); + fprintf(output, "Processing:\n"); + fprintf(output, " -R packet filter in Wireshark display filter syntax\n"); + fprintf(output, " -n disable all name resolutions (def: all enabled)\n"); + fprintf(output, " -N enable specific name resolution(s): \"mnNtd\"\n"); + fprintf(output, " --disable-protocol \n"); + fprintf(output, " disable dissection of proto_name\n"); + fprintf(output, " --enable-heuristic \n"); + fprintf(output, " enable dissection of heuristic protocol\n"); + fprintf(output, " --disable-heuristic \n"); + fprintf(output, " disable dissection of heuristic protocol\n"); + + fprintf(output, "\n"); + fprintf(output, "User interface:\n"); + fprintf(output, " -C start with specified configuration profile\n"); + fprintf(output, " -Y start with the given display filter\n"); + fprintf(output, " -g go to specified packet number after \"-r\"\n"); + fprintf(output, " -J 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 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 : eXtension options, see man page for details\n"); + fprintf(output, " -z show various statistics, see man page for details\n"); + + fprintf(output, "\n"); + fprintf(output, "Output:\n"); + fprintf(output, " -w 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 : persconf:path - personal configuration files\n"); + fprintf(output, " persdata:path - personal data files\n"); + fprintf(output, " -o : ... override preference or recent setting\n"); + fprintf(output, " -K 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, + ¶m_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 index 0000000000..2f0beeec20 --- /dev/null +++ b/ui/commandline.h @@ -0,0 +1,86 @@ +/* commandline.h + * Common command line handling between GUIs + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * 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: + */ diff --git a/ui/gtk/about_dlg.c b/ui/gtk/about_dlg.c index 06c1d9a70b..aee4b171d2 100644 --- a/ui/gtk/about_dlg.c +++ b/ui/gtk/about_dlg.c @@ -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" diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 89878a55d4..cd390eca85 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c @@ -40,10 +40,6 @@ #include #endif -#ifndef HAVE_GETOPT_LONG -#include "wsutil/wsgetopt.h" -#endif - #ifdef HAVE_EXTCAP #include #endif @@ -52,7 +48,6 @@ #include #endif /* HAVE_LIBPORTAUDIO */ -#include #include #include #include @@ -114,6 +109,7 @@ #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" @@ -218,7 +214,6 @@ #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] ... [ ]\n"); - fprintf(output, "\n"); - -#ifdef HAVE_LIBPCAP - fprintf(output, "Capture interface:\n"); - fprintf(output, " -i name or idx of interface (def: first non-loopback)\n"); - fprintf(output, " -f packet filter in libpcap filter syntax\n"); - fprintf(output, " -s 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 size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE); -#endif - fprintf(output, " -y 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 stop after n packets (def: infinite)\n"); - fprintf(output, " -a ... 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 ... 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 : use RPCAP password authentication\n"); -#endif - /*fprintf(output, "\n");*/ - fprintf(output, "Input file:\n"); - fprintf(output, " -r set the filename to read from (no pipes or stdin!)\n"); - - fprintf(output, "\n"); - fprintf(output, "Processing:\n"); - fprintf(output, " -R packet filter in Wireshark display filter syntax\n"); - fprintf(output, " -n disable all name resolutions (def: all enabled)\n"); - fprintf(output, " -N enable specific name resolution(s): \"mnNtd\"\n"); - fprintf(output, " --disable-protocol \n"); - fprintf(output, " disable dissection of proto_name\n"); - fprintf(output, " --enable-heuristic \n"); - fprintf(output, " enable dissection of heuristic protocol\n"); - fprintf(output, " --disable-heuristic \n"); - fprintf(output, " disable dissection of heuristic protocol\n"); - - fprintf(output, "\n"); - fprintf(output, "User interface:\n"); - fprintf(output, " -C start with specified configuration profile\n"); - fprintf(output, " -Y start with the given display filter\n"); - fprintf(output, " -g go to specified packet number after \"-r\"\n"); - fprintf(output, " -J 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 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 : eXtension options, see man page for details\n"); - fprintf(output, " -z show various statistics, see man page for details\n"); - - fprintf(output, "\n"); - fprintf(output, "Output:\n"); - fprintf(output, " -w 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 : persconf:path - personal configuration files\n"); - fprintf(output, " persdata:path - personal data files\n"); - fprintf(output, " -o : ... override preference or recent setting\n"); - fprintf(output, " -K 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); diff --git a/ui/gtk/main.h b/ui/gtk/main.h index 472b596be9..cdf3f52c4a 100644 --- a/ui/gtk/main.h +++ b/ui/gtk/main.h @@ -53,9 +53,11 @@ */ /** 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; diff --git a/ui/qt/about_dialog.cpp b/ui/qt/about_dialog.cpp index 733fc55ece..20eb49701a 100644 --- a/ui/qt/about_dialog.cpp +++ b/ui/qt/about_dialog.cpp @@ -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 */ diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h index f04053f07e..1de706cb27 100644 --- a/ui/qt/wireshark_application.h +++ b/ui/qt/wireshark_application.h @@ -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 /* -- cgit v1.2.1