This patch sources out the target getopt parsing into a separate code-block which before has been done as a side-effect of a check. This removes also a level of indentation and makes the part more understandable when reading the code. Signed-off-by: Peter Warasin <peter@xxxxxxxxxx> ---
Index: iptables/iptables.c =================================================================== --- iptables.orig/iptables.c 2008-01-06 02:59:40.000000000 +0100 +++ iptables/iptables.c 2008-01-06 03:03:03.000000000 +0100 @@ -1822,83 +1822,88 @@ exit_tryhelp(2); default: - if (!target - || !(target->parse(c - target->option_offset, - argv, invert, - &target->tflags, - &fw, &target->t))) { - for (matchp = matches; matchp; matchp = matchp->next) { - if (matchp->completed) - continue; - if (matchp->match->parse(c - matchp->match->option_offset, - argv, invert, - &matchp->match->mflags, - &fw, - &matchp->match->m)) - break; - } - m = matchp ? matchp->match : NULL; - - /* If you listen carefully, you can - actually hear this code suck. */ - - /* some explanations (after four different bugs - * in 3 different releases): If we encounter a - * parameter, that has not been parsed yet, - * it's not an option of an explicitly loaded - * match or a target. However, we support - * implicit loading of the protocol match - * extension. '-p tcp' means 'l4 proto 6' and - * at the same time 'load tcp protocol match on - * demand if we specify --dport'. - * - * To make this work, we need to make sure: - * - the parameter has not been parsed by - * a match (m above) - * - a protocol has been specified - * - the protocol extension has not been - * loaded yet, or is loaded and unused - * [think of iptables-restore!] - * - the protocol extension can be successively - * loaded - */ - if (m == NULL - && protocol - && (!find_proto(protocol, DONT_LOAD, - options&OPT_NUMERIC, NULL) - || (find_proto(protocol, DONT_LOAD, - options&OPT_NUMERIC, NULL) - && (proto_used == 0)) - ) - && (m = find_proto(protocol, TRY_LOAD, - options&OPT_NUMERIC, &matches))) { - /* Try loading protocol */ - size_t size; - - proto_used = 1; - - size = IPT_ALIGN(sizeof(struct ipt_entry_match)) - + m->size; - - m->m = fw_calloc(1, size); - m->m->u.match_size = size; - strcpy(m->m->u.user.name, m->name); - set_revision(m->m->u.user.name, - m->revision); - if (m->init != NULL) - m->init(m->m); - - opts = merge_options(opts, - m->extra_opts, &m->option_offset); + /* handles targets */ + if (target && target->parse(c - target->option_offset, + argv, invert, + &target->tflags, + &fw, &target->t)) { + continue; + } - optind--; + /* handles matches */ + for (matchp = matches; matchp; matchp = matchp->next) { + if (matchp->completed) continue; - } - if (!m) - exit_error(PARAMETER_PROBLEM, - "Unknown arg `%s'", - argv[optind-1]); + if (matchp->match->parse(c - matchp->match->option_offset, + argv, invert, + &matchp->match->mflags, + &fw, + &matchp->match->m)) + break; } + + /* handles options of autoloaded matches (explaination below) */ + m = matchp ? matchp->match : NULL; + + /* If you listen carefully, you can + actually hear this code suck. */ + + /* some explanations (after four different bugs + * in 3 different releases): If we encounter a + * parameter, that has not been parsed yet, + * it's not an option of an explicitly loaded + * match or a target. However, we support + * implicit loading of the protocol match + * extension. '-p tcp' means 'l4 proto 6' and + * at the same time 'load tcp protocol match on + * demand if we specify --dport'. + * + * To make this work, we need to make sure: + * - the parameter has not been parsed by + * a match (m above) + * - a protocol has been specified + * - the protocol extension has not been + * loaded yet, or is loaded and unused + * [think of iptables-restore!] + * - the protocol extension can be successively + * loaded + */ + if (m == NULL + && protocol + && (!find_proto(protocol, DONT_LOAD, + options&OPT_NUMERIC, NULL) + || (find_proto(protocol, DONT_LOAD, + options&OPT_NUMERIC, NULL) + && (proto_used == 0)) + ) + && (m = find_proto(protocol, TRY_LOAD, + options&OPT_NUMERIC, &matches))) { + /* Try loading protocol */ + size_t size; + + proto_used = 1; + + size = IPT_ALIGN(sizeof(struct ipt_entry_match)) + + m->size; + + m->m = fw_calloc(1, size); + m->m->u.match_size = size; + strcpy(m->m->u.user.name, m->name); + set_revision(m->m->u.user.name, + m->revision); + if (m->init != NULL) + m->init(m->m); + + opts = merge_options(opts, + m->extra_opts, &m->option_offset); + + optind--; + continue; + } + if (!m) + exit_error(PARAMETER_PROBLEM, + "Unknown arg `%s'", + argv[optind-1]); } invert = FALSE; }