Wireshark-dev: Re: [Wireshark-dev] extcap command line parameter format

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Mon, 23 Jul 2018 11:37:48 -0700
On Jul 20, 2018, at 10:12 AM, Jaap Keuter <jaap.keuter@xxxxxxxxx> wrote:

> While having reviewed extcap documentation [Ref1] I was triggered by bug 14982 [Ref2] (usbpcap no longer recognized in 2.9) concerning the addition of --extcap-version parameter to the extcap command line. This stated that the command line parameter "--extcap-version=2.9” causes a problem with usbpcap.
> The documentation states that in Wireshark 2.9 the command line parameter “--extcap-version x.x” has been added. Note the lack of equal sign. Looking at the code this was originally so, until change 26772 [Ref3] where the equal sign was added due to a problem with some variations of getopt_long().

Yes - if you have a command-line option for which the value is optional, if you want to work with versions of getopt_long() other than the GNU one, you *must* specify the option with =:

$ cat optiontest.c
#include <getopt.h>
#include <stdio.h>

static const struct option longopts[] = {
	{ "noargument", no_argument, NULL, 'n' },
	{ "requiredargument", required_argument, NULL, 'r' },
	{ "optionalargument", optional_argument, NULL, 'o' },
	{ NULL, 0, NULL, 0 }
};

int
main(int argc, char **argv)
{
	int opt;
	int i;

	while ((opt = getopt_long(argc, argv, "nr:o:", longopts, NULL)) != -1) {
		switch (opt) {

		case 'n':
			printf("noargument specified\n");
			break;

		case 'r':
			printf("requiredargment specified, argument is \"%s\"\n",
			    optarg);
			break;

		case 'o':
			if (optarg == NULL)
				printf("optionalargument specified, no argument\n");
			else
				printf("optionalargment specified, argument is \"%s\"\n",
				    optarg);
			break;

		case ':':
			printf("Missing option argument\n");
			break;

		case '?':
			printf("Unknown/ambiguous option\n");
			break;

		default:
			printf("getopt_long returns '%c' (%d)\n", opt, opt);
			break;
		}
	}

	argc -= optind;
	argv += optind;
	for (i = 0; i < argc; i++)
		printf("argument %d is \"%s\"\n", i + 1, argv[i]);
	return 0;
}
$ gcc -o optiontest optiontest.c
$ ./optiontest
$ ./optiontest --noargument
noargument specified
$ ./optiontest --noargument --requiredargument
noargument specified
optiontest: option `--requiredargument' requires an argument
Unknown/ambiguous option
$ ./optiontest --noargument --requiredargument foo
noargument specified
requiredargment specified, argument is "foo"
$ ./optiontest --noargument --requiredargument=foo
noargument specified
requiredargment specified, argument is "foo"
$ ./optiontest --noargument --optionalargument
noargument specified
optionalargument specified, no argument
$ ./optiontest --noargument --optionalargument foo
noargument specified
optionalargument specified, no argument
argument 1 is "foo"
$ ./optiontest --noargument --optionalargument=foo
noargument specified
optionalargment specified, argument is "foo"

so if we want to allow both --extcap-version without an argument and --extcap-version with an argument, and we don't want to have to check for whether, if we have a system-supplied getopt_long(), that getopt_long() parses --optionalargument foo as "--optionalargument with an argument foo" rather than "--optionalargument with no argument" and, if it doesn't do that, use our copy of the GNU getopt_long() (or just use it even if it does), we'll have to require that the argument to --extcap-version be specified with an =.

> Doesn’t this mean that all other command line parameters with values are to be generated with equal sign?

It's a requirement for any parameter where the value is optional.

It's not a requirement for any parameter where the value is required.

> If so this could require changes across the board, changes to documentation (docbook, man page) in the least.

Yes.