summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--contrib/fwd/src/fwd_xtables.c91
-rw-r--r--contrib/fwd/src/fwd_xtables.h6
2 files changed, 77 insertions, 20 deletions
diff --git a/contrib/fwd/src/fwd_xtables.c b/contrib/fwd/src/fwd_xtables.c
index e8cd641b5..dc9fab11a 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;
diff --git a/contrib/fwd/src/fwd_xtables.h b/contrib/fwd/src/fwd_xtables.h
index cd5090fc6..f894b47e4 100644
--- a/contrib/fwd/src/fwd_xtables.h
+++ b/contrib/fwd/src/fwd_xtables.h
@@ -56,10 +56,12 @@ void fwd_xt_parse_src(struct fwd_xt_rule *r, struct fwd_cidr *c, int inv);
void fwd_xt_parse_dest(struct fwd_xt_rule *r, struct fwd_cidr *c, int inv);
struct xtables_match * fwd_xt_get_match(struct fwd_xt_rule *r, const char *name);
-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, ...);
+#define fwd_xt_parse_match(r, m, ...) __fwd_xt_parse_match(r, m, __VA_ARGS__, NULL)
struct xtables_target * fwd_xt_get_target(struct fwd_xt_rule *r, const char *name);
-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, ...);
+#define fwd_xt_parse_target(r, t, ...) __fwd_xt_parse_target(r, t, __VA_ARGS__, NULL)
int fwd_xt_exec_rule(struct fwd_xt_rule *r, const char *chain);