diff options
author | João Valverde <j@v6e.pt> | 2021-07-26 17:22:36 +0100 |
---|---|---|
committer | João Valverde <j@v6e.pt> | 2021-09-17 00:43:54 +0100 |
commit | 8df2a73594fbcc812f4ea22a72ab7a79bfb63dc3 (patch) | |
tree | 7d30bc5be8e85c52c0dd295cb15cd717d5770dcb /tfshark.c | |
parent | 7462e76884942258bae110ead925f25ffa54e2a8 (diff) |
Use the musl in-tree getopt_long() everywhere
Besides the obvious limitation of being unavailable on Windows,
the standard is vague about getopt() and getopt_long() has many
non-portable pitfalls and buggy implementations, that increase
the maintainance cost a lot. Also the GNU libc code currently
in the tree is not suited for embedding and is unmaintainable.
Own maintainership for getopt_long() and use the musl implementation
everywhere. This way we don't need to worry if optreset is available,
or if the $OPERATING_SYSTEM version behaves in subtly different ways.
The API is under the Wireshark namespace to avoid conflicts with
system headers.
Side-note, the Mingw-w64 9.0 getopt_long() implementation is buggy
with opterr and known to crash. In my experience it's a headache to
use the embedded getopt implementation if the system provides one.
Diffstat (limited to 'tfshark.c')
-rw-r--r-- | tfshark.c | 95 |
1 files changed, 36 insertions, 59 deletions
@@ -19,18 +19,7 @@ #include <locale.h> #include <limits.h> -/* - * If we have getopt_long() in the system library, include <getopt.h>. - * Otherwise, we're using our own getopt_long() (either because the - * system has getopt() but not getopt_long(), as with some UN*Xes, - * or because it doesn't even have getopt(), as with Windows), so - * include our getopt_long()'s header. - */ -#ifdef HAVE_GETOPT_LONG -#include <getopt.h> -#else -#include <wsutil/wsgetopt.h> -#endif +#include <wsutil/ws_getopt.h> #include <errno.h> @@ -402,20 +391,20 @@ main(int argc, char *argv[]) * arguments we can't handle until after initializing libwireshark, * and then process them after initializing libwireshark? */ - opterr = 0; + ws_opterr = 0; - while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (opt) { case 'C': /* Configuration Profile */ - if (profile_exists (optarg, FALSE)) { - set_profile_name (optarg); + if (profile_exists (ws_optarg, FALSE)) { + set_profile_name (ws_optarg); } else { - cmdarg_err("Configuration Profile \"%s\" does not exist", optarg); + cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg); return 1; } break; case 'O': /* Only output these protocols */ - output_only = g_strdup(optarg); + output_only = g_strdup(ws_optarg); /* FALLTHROUGH */ case 'V': /* Verbose */ print_details = TRUE; @@ -429,7 +418,7 @@ main(int argc, char *argv[]) print_packet_info = TRUE; break; case 'X': - ex_opt_add(optarg); + ex_opt_add(ws_optarg); break; default: break; @@ -555,29 +544,17 @@ main(int argc, char *argv[]) output_fields = output_fields_new(); /* - * To reset the options parser, set optreset to 1 on platforms that - * have optreset (documented in *BSD and macOS, 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). + * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1. * - * Also reset opterr to 1, so that error messages are printed by + * Also reset ws_opterr to 1, so that error messages are printed by * getopt_long(). */ -#ifdef HAVE_OPTRESET - optreset = 1; - optind = 1; -#else - optind = 0; -#endif - opterr = 1; + ws_optreset = 1; + ws_optind = 1; + ws_opterr = 1; /* Now get our args */ - while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { + while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) { switch (opt) { case '2': /* Perform two pass analysis */ perform_two_pass_analysis = TRUE; @@ -587,12 +564,12 @@ main(int argc, char *argv[]) break; case 'e': /* Field entry */ - output_fields_add(output_fields, optarg); + output_fields_add(output_fields, ws_optarg); break; case 'E': /* Field option */ - if (!output_fields_set_option(output_fields, optarg)) { - cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg); + if (!output_fields_set_option(output_fields, ws_optarg)) { + cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg); output_fields_list_options(stderr); exit_status = INVALID_OPTION; goto clean_exit; @@ -634,13 +611,13 @@ main(int argc, char *argv[]) { char *errmsg = NULL; - switch (prefs_set_pref(optarg, &errmsg)) { + switch (prefs_set_pref(ws_optarg, &errmsg)) { case PREFS_SET_OK: break; case PREFS_SET_SYNTAX_ERR: - cmdarg_err("Invalid -o flag \"%s\"%s%s", optarg, + cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg, errmsg ? ": " : "", errmsg ? errmsg : ""); g_free(errmsg); return 1; @@ -648,7 +625,7 @@ main(int argc, char *argv[]) case PREFS_SET_NO_SUCH_PREF: case PREFS_SET_OBSOLETE: - cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg); + cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg); exit_status = INVALID_OPTION; goto clean_exit; break; @@ -663,35 +640,35 @@ main(int argc, char *argv[]) really_quiet = TRUE; break; case 'r': /* Read capture file x */ - cf_name = g_strdup(optarg); + cf_name = g_strdup(ws_optarg); break; case 'R': /* Read file filter */ - rfilter = optarg; + rfilter = ws_optarg; break; case 'S': /* Set the line Separator to be printed between packets */ - separator = g_strdup(optarg); + separator = g_strdup(ws_optarg); break; case 'T': /* printing Type */ - if (strcmp(optarg, "text") == 0) { + if (strcmp(ws_optarg, "text") == 0) { output_action = WRITE_TEXT; print_format = PR_FMT_TEXT; - } else if (strcmp(optarg, "ps") == 0) { + } else if (strcmp(ws_optarg, "ps") == 0) { output_action = WRITE_TEXT; print_format = PR_FMT_PS; - } else if (strcmp(optarg, "pdml") == 0) { + } else if (strcmp(ws_optarg, "pdml") == 0) { output_action = WRITE_XML; print_details = TRUE; /* Need details */ print_summary = FALSE; /* Don't allow summary */ - } else if (strcmp(optarg, "psml") == 0) { + } else if (strcmp(ws_optarg, "psml") == 0) { output_action = WRITE_XML; print_details = FALSE; /* Don't allow details */ print_summary = TRUE; /* Need summary */ - } else if (strcmp(optarg, "fields") == 0) { + } else if (strcmp(ws_optarg, "fields") == 0) { output_action = WRITE_FIELDS; print_details = TRUE; /* Need full tree info */ print_summary = FALSE; /* Don't allow summary */ } else { - cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg); /* x */ + cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */ cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n" "\t specified by the -E option.\n" "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n" @@ -728,7 +705,7 @@ main(int argc, char *argv[]) /* already processed; just ignore it now */ break; case 'Y': - dfilter = optarg; + dfilter = ws_optarg; break; case 'z': /* We won't call the init function for the stat this soon @@ -736,13 +713,13 @@ main(int argc, char *argv[]) by the preferences set callback) from being used as part of a tap filter. Instead, we just add the argument to a list of stat arguments. */ - if (strcmp("help", optarg) == 0) { + if (strcmp("help", ws_optarg) == 0) { fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n"); list_stat_cmd_args(); goto clean_exit; } - if (!process_stat_cmd_arg(optarg)) { - cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg); + if (!process_stat_cmd_arg(ws_optarg)) { + cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg); list_stat_cmd_args(); exit_status = INVALID_OPTION; goto clean_exit; @@ -756,7 +733,7 @@ main(int argc, char *argv[]) case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */ case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */ case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */ - if (!dissect_opts_handle_opt(opt, optarg)) { + if (!dissect_opts_handle_opt(opt, ws_optarg)) { exit_status = INVALID_OPTION; goto clean_exit; } @@ -792,14 +769,14 @@ main(int argc, char *argv[]) /* If no display filter has been specified, and there are still command- line arguments, treat them as the tokens of a display filter. */ - if (optind < argc) { + if (ws_optind < argc) { if (dfilter != NULL) { cmdarg_err("Display filters were specified both with \"-Y\" " "and with additional command-line arguments."); exit_status = INVALID_OPTION; goto clean_exit; } - dfilter = get_args_as_string(argc, argv, optind); + dfilter = get_args_as_string(argc, argv, ws_optind); } /* if "-q" wasn't specified, we should print packet information */ |