From fb9cea50e8b370b6931e7b53b1a881d3b95b1c91 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 13 Dec 2019 11:32:46 +0100 Subject: main: enforce options before commands This patch turns on POSIXLY_CORRECT on the getopt parser to enforce options before commands. Users get a hint in such a case: # nft list ruleset -a Error: syntax error, options must be specified before commands nft list ruleset -a ^ ~~ This patch recovers 9fc71bc6b602 ("main: Fix for misleading error with negative chain priority"). Tests have been updated. Signed-off-by: Pablo Neira Ayuso --- src/main.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c index fde8b15c..74199f93 100644 --- a/src/main.c +++ b/src/main.c @@ -46,7 +46,7 @@ enum opt_vals { OPT_TERSE = 't', OPT_INVALID = '?', }; -#define OPTSTRING "hvcf:iI:jvnsNaeSupypTt" +#define OPTSTRING "+hvcf:iI:jvnsNaeSupypTt" static const struct option options[] = { { @@ -202,6 +202,47 @@ static const struct { }, }; +static void nft_options_error(int argc, char * const argv[], int pos) +{ + int i; + + fprintf(stderr, "Error: syntax error, options must be specified before commands\n"); + for (i = 0; i < argc; i++) + fprintf(stderr, "%s ", argv[i]); + printf("\n%4c%*s\n", '^', pos - 2, "~~"); +} + +static bool nft_options_check(int argc, char * const argv[]) +{ + bool skip = false, nonoption = false; + int pos = 0, i; + + for (i = 1; i < argc; i++) { + pos += strlen(argv[i - 1]) + 1; + if (argv[i][0] == '{') { + break; + } else if (skip) { + skip = false; + continue; + } else if (argv[i][0] == '-') { + if (nonoption) { + nft_options_error(argc, argv, pos); + return false; + } else if (argv[i][1] == 'I' || + argv[i][1] == 'f' || + !strcmp(argv[i], "--includepath") || + !strcmp(argv[i], "--file")) { + skip = true; + continue; + } + } else if (argv[i][0] != '-') { + nonoption = true; + } + } + + return true; +} + int main(int argc, char * const *argv) { char *buf = NULL, *filename = NULL; @@ -211,6 +252,9 @@ int main(int argc, char * const *argv) unsigned int len; int i, val, rc; + if (!nft_options_check(argc, argv)) + exit(EXIT_FAILURE); + nft = nft_ctx_new(NFT_CTX_DEFAULT); while (1) { -- cgit v1.2.3