contrib/fwd: make fwd_xt_parse_{match,target} variadic, properly parse inverts
authorJo-Philipp Wich <jow@openwrt.org>
Tue, 15 Dec 2009 20:57:35 +0000 (20:57 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Tue, 15 Dec 2009 20:57:35 +0000 (20:57 +0000)
contrib/fwd/src/fwd_xtables.c
contrib/fwd/src/fwd_xtables.h

index e8cd641b58bd0aa9e9ac0a3ab6213a34870631b9..dc9fab11a64828546948530f8bbe666fb73de435 100644 (file)
@@ -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;
index cd5090fc6e7345c33485b5473b228544b34f0c08..f894b47e42081f3674f3e170f7dd9fae37b35563 100644 (file)
@@ -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);