Adapted version of commit 6e2e169eb66b63d2991e1c7ada931e3cdb0ced32 Author: Lorenzo Colitti Date: Thu Mar 16 16:55:01 2017 +0900 iptables: remove duplicated argument parsing code 1. Factor out repeated code to a new xs_has_arg function. 2. Add a new parse_wait_time option to parse the value of -w. 3. Make parse_wait_interval take argc and argv so its callers can be simpler. Signed-off-by: Lorenzo Colitti Signed-off-by: Pablo Neira Ayuso diff -up iptables-1.4.21/iptables/ip6tables.c.remove_duplicated_argument_parsing iptables-1.4.21/iptables/ip6tables.c --- iptables-1.4.21/iptables/ip6tables.c.remove_duplicated_argument_parsing 2017-04-05 14:51:44.033970476 +0200 +++ iptables-1.4.21/iptables/ip6tables.c 2017-04-05 14:51:44.044970566 +0200 @@ -1388,8 +1388,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_DELETE, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') { + if (xs_has_arg(argc, argv)) { rulenum = parse_rulenumber(argv[optind++]); command = CMD_DELETE_NUM; } @@ -1399,8 +1398,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_REPLACE, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); else xtables_error(PARAMETER_PROBLEM, @@ -1412,8 +1410,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_INSERT, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); else rulenum = 1; break; @@ -1422,11 +1419,9 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_LIST, CMD_ZERO | CMD_ZERO_NUM, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); break; @@ -1434,11 +1429,9 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_LIST_RULES, CMD_ZERO | CMD_ZERO_NUM, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); break; @@ -1446,8 +1439,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_FLUSH, CMD_NONE, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; break; @@ -1455,11 +1447,9 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') { + if (xs_has_arg(argc, argv)) { rulenum = parse_rulenumber(argv[optind++]); command = CMD_ZERO_NUM; } @@ -1476,8 +1466,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; break; @@ -1485,8 +1474,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) newname = argv[optind++]; else xtables_error(PARAMETER_PROBLEM, @@ -1499,8 +1487,7 @@ int do_command6(int argc, char *argv[], add_command(&command, CMD_SET_POLICY, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) policy = argv[optind++]; else xtables_error(PARAMETER_PROBLEM, @@ -1610,16 +1597,7 @@ int do_command6(int argc, char *argv[], "You cannot use `-w' from " "ip6tables-restore"); } - wait = -1; - if (optarg) { - if (sscanf(optarg, "%i", &wait) != 1) - xtables_error(PARAMETER_PROBLEM, - "wait seconds not numeric"); - } else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') - if (sscanf(argv[optind++], "%i", &wait) != 1) - xtables_error(PARAMETER_PROBLEM, - "wait seconds not numeric"); + wait = parse_wait_time(argc, argv); break; case 'W': @@ -1628,14 +1606,7 @@ int do_command6(int argc, char *argv[], "You cannot use `-W' from " "ip6tables-restore"); } - if (optarg) - parse_wait_interval(optarg, &wait_interval); - else if (optind < argc && - argv[optind][0] != '-' && - argv[optind][0] != '!') - parse_wait_interval(argv[optind++], - &wait_interval); - + parse_wait_interval(argc, argv, &wait_interval); wait_interval_set = true; break; @@ -1685,8 +1656,7 @@ int do_command6(int argc, char *argv[], bcnt = strchr(pcnt + 1, ','); if (bcnt) bcnt++; - if (!bcnt && optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (!bcnt && xs_has_arg(argc, argv)) bcnt = argv[optind++]; if (!bcnt) xtables_error(PARAMETER_PROBLEM, diff -up iptables-1.4.21/iptables/iptables.c.remove_duplicated_argument_parsing iptables-1.4.21/iptables/iptables.c --- iptables-1.4.21/iptables/iptables.c.remove_duplicated_argument_parsing 2017-04-05 14:51:44.034970484 +0200 +++ iptables-1.4.21/iptables/iptables.c 2017-04-05 14:51:44.044970566 +0200 @@ -1381,8 +1381,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_DELETE, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') { + if (xs_has_arg(argc, argv)) { rulenum = parse_rulenumber(argv[optind++]); command = CMD_DELETE_NUM; } @@ -1392,8 +1391,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_REPLACE, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); else xtables_error(PARAMETER_PROBLEM, @@ -1405,8 +1403,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_INSERT, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); else rulenum = 1; break; @@ -1415,11 +1412,9 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_LIST, CMD_ZERO | CMD_ZERO_NUM, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); break; @@ -1427,11 +1422,9 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_LIST_RULES, CMD_ZERO|CMD_ZERO_NUM, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) rulenum = parse_rulenumber(argv[optind++]); break; @@ -1439,8 +1432,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_FLUSH, CMD_NONE, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; break; @@ -1448,11 +1440,9 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') { + if (xs_has_arg(argc, argv)) { rulenum = parse_rulenumber(argv[optind++]); command = CMD_ZERO_NUM; } @@ -1469,8 +1459,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, cs.invert); if (optarg) chain = optarg; - else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + else if (xs_has_arg(argc, argv)) chain = argv[optind++]; break; @@ -1478,8 +1467,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) newname = argv[optind++]; else xtables_error(PARAMETER_PROBLEM, @@ -1492,8 +1480,7 @@ int do_command4(int argc, char *argv[], add_command(&command, CMD_SET_POLICY, CMD_NONE, cs.invert); chain = optarg; - if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (xs_has_arg(argc, argv)) policy = argv[optind++]; else xtables_error(PARAMETER_PROBLEM, @@ -1601,16 +1588,7 @@ int do_command4(int argc, char *argv[], "You cannot use `-w' from " "iptables-restore"); } - wait = -1; - if (optarg) { - if (sscanf(optarg, "%i", &wait) != 1) - xtables_error(PARAMETER_PROBLEM, - "wait seconds not numeric"); - } else if (optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') - if (sscanf(argv[optind++], "%i", &wait) != 1) - xtables_error(PARAMETER_PROBLEM, - "wait seconds not numeric"); + wait = parse_wait_time(argc, argv); break; case 'W': @@ -1619,14 +1597,7 @@ int do_command4(int argc, char *argv[], "You cannot use `-W' from " "iptables-restore"); } - if (optarg) - parse_wait_interval(optarg, &wait_interval); - else if (optind < argc && - argv[optind][0] != '-' && - argv[optind][0] != '!') - parse_wait_interval(argv[optind++], - &wait_interval); - + parse_wait_interval(argc, argv, &wait_interval); wait_interval_set = true; break; @@ -1676,8 +1647,7 @@ int do_command4(int argc, char *argv[], bcnt = strchr(pcnt + 1, ','); if (bcnt) bcnt++; - if (!bcnt && optind < argc && argv[optind][0] != '-' - && argv[optind][0] != '!') + if (!bcnt && xs_has_arg(argc, argv)) bcnt = argv[optind++]; if (!bcnt) xtables_error(PARAMETER_PROBLEM, diff -up iptables-1.4.21/iptables/xshared.c.remove_duplicated_argument_parsing iptables-1.4.21/iptables/xshared.c --- iptables-1.4.21/iptables/xshared.c.remove_duplicated_argument_parsing 2017-04-05 14:51:44.042970550 +0200 +++ iptables-1.4.21/iptables/xshared.c 2017-04-05 14:51:44.045970574 +0200 @@ -285,12 +285,36 @@ bool xtables_lock(int wait, struct timev } } -void parse_wait_interval(const char *str, struct timeval *wait_interval) +int parse_wait_time(int argc, char *argv[]) { + int wait = -1; + + if (optarg) { + if (sscanf(optarg, "%i", &wait) != 1) + xtables_error(PARAMETER_PROBLEM, + "wait seconds not numeric"); + } else if (xs_has_arg(argc, argv)) + if (sscanf(argv[optind++], "%i", &wait) != 1) + xtables_error(PARAMETER_PROBLEM, + "wait seconds not numeric"); + + return wait; +} + +void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval) +{ + const char *arg; unsigned int usec; int ret; - ret = sscanf(str, "%u", &usec); + if (optarg) + arg = optarg; + else if (xs_has_arg(argc, argv)) + arg = argv[optind++]; + else + return; + + ret = sscanf(arg, "%u", &usec); if (ret == 1) { if (usec > 999999) xtables_error(PARAMETER_PROBLEM, @@ -303,3 +327,10 @@ void parse_wait_interval(const char *str } xtables_error(PARAMETER_PROBLEM, "wait interval not numeric"); } + +inline bool xs_has_arg(int argc, char *argv[]) +{ + return optind < argc && + argv[optind][0] != '-' && + argv[optind][0] != '!'; +} diff -up iptables-1.4.21/iptables/xshared.h.remove_duplicated_argument_parsing iptables-1.4.21/iptables/xshared.h --- iptables-1.4.21/iptables/xshared.h.remove_duplicated_argument_parsing 2017-04-05 14:51:44.034970484 +0200 +++ iptables-1.4.21/iptables/xshared.h 2017-04-05 14:51:44.045970574 +0200 @@ -86,7 +86,9 @@ extern void xs_init_target(struct xtable extern void xs_init_match(struct xtables_match *); bool xtables_lock(int wait, struct timeval *wait_interval); -void parse_wait_interval(const char *str, struct timeval *wait_interval); +int parse_wait_time(int argc, char *argv[]); +void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval); +bool xs_has_arg(int argc, char *argv[]); extern const struct xtables_afinfo *afinfo;