summaryrefslogtreecommitdiffhomepage
path: root/contrib/fwd/src/fwd_xtables.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fwd/src/fwd_xtables.c')
-rw-r--r--contrib/fwd/src/fwd_xtables.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/contrib/fwd/src/fwd_xtables.c b/contrib/fwd/src/fwd_xtables.c
index e8cd641b58..dc9fab11a6 100644
--- a/contrib/fwd/src/fwd_xtables.c
+++ b/contrib/fwd/src/fwd_xtables.c
@@ -194,18 +194,45 @@ struct xtables_match * fwd_xt_get_match(
return NULL;
}
-void fwd_xt_parse_match(
- struct fwd_xt_rule *r, struct xtables_match *m,
- const char *opt, const char *val, int inv
+void __fwd_xt_parse_match(
+ struct fwd_xt_rule *r, struct xtables_match *m, ...
) {
- char optcode;
- const char *opts[3] = { "x", opt, val };
+ char optc;
+ char *s, **opts;
+ size_t len = 1;
+ int inv = 0;
- optind = 0;
- optcode = getopt_long(val ? 3 : 2, (char **)opts, "", m->extra_opts, NULL);
+ va_list ap;
+ va_start(ap, m);
+
+ opts = malloc(len * sizeof(*opts));
+ opts[0] = "x";
+
+ while( (s = (char *)va_arg(ap, char *)) != NULL )
+ {
+ opts = realloc(opts, ++len * sizeof(*opts));
+ opts[len-1] = s;
+ }
+
+ va_end(ap);
+
+ if( len > 1 )
+ {
+ optind = 0;
+
+ while( (optc = getopt_long(len, opts, "", m->extra_opts, NULL)) > -1 )
+ {
+ if( (optc == '?') && (optarg[0] == '!') && (optarg[1] == '\0') )
+ {
+ inv = 1;
+ continue;
+ }
- if( (optcode > -1) && (optcode != '?') )
- m->parse(optcode, (char **)opts, inv, &m->mflags, r->entry, &m->m);
+ m->parse(optc, opts, inv, &m->mflags, r->entry, &m->m);
+ }
+ }
+
+ free(opts);
}
@@ -241,20 +268,48 @@ struct xtables_target * fwd_xt_get_target(
return NULL;
}
-void fwd_xt_parse_target(
- struct fwd_xt_rule *r, struct xtables_target *t,
- const char *opt, const char *val, int inv
+void __fwd_xt_parse_target(
+ struct fwd_xt_rule *r, struct xtables_target *t, ...
) {
- char optcode;
- const char *opts[3] = { "x", opt, val };
+ char optc;
+ char *s, **opts;
+ size_t len = 1;
+ int inv = 0;
- optind = 0;
- optcode = getopt_long(val ? 3 : 2, (char **)opts, "", t->extra_opts, NULL);
+ va_list ap;
+ va_start(ap, t);
- if( (optcode > -1) && (optcode != '?') )
- t->parse(optcode, (char **)opts, inv, &t->tflags, r->entry, &t->t);
+ opts = malloc(len * sizeof(*opts));
+ opts[0] = "x";
+
+ while( (s = (char *)va_arg(ap, char *)) != NULL )
+ {
+ opts = realloc(opts, ++len * sizeof(*opts));
+ opts[len-1] = s;
+ }
+
+ va_end(ap);
+
+ if( len > 1 )
+ {
+ optind = 0;
+
+ while( (optc = getopt_long(len, opts, "", t->extra_opts, NULL)) > -1 )
+ {
+ if( (optc == '?') && (optarg[0] == '!') && (optarg[1] == '\0') )
+ {
+ inv = 1;
+ continue;
+ }
+
+ t->parse(optc, opts, inv, &t->tflags, r->entry, &t->t);
+ }
+ }
+
+ free(opts);
}
+
int fwd_xt_exec_rule(struct fwd_xt_rule *r, const char *chain)
{
size_t s;