OSSP CVS Repository

ossp - Difference in ossp-pkg/lmtp2nntp/lmtp2nntp_config.c versions 1.37 and 1.38
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/lmtp2nntp/lmtp2nntp_config.c 1.37 -> 1.38

--- lmtp2nntp_config.c   2002/02/04 13:52:14     1.37
+++ lmtp2nntp_config.c   2002/02/04 14:48:30     1.38
@@ -109,8 +109,6 @@
     //char *cp;
     int rc;
 
-    fprintf(stderr, "Hello, World!\n"); //FIXME
-
     /* create L2 environment */
     if (l2_env_create(&ctx->l2_env) != L2_OK) {
         fprintf(stderr, "%s:Error: failed to create L2 environment\n", ctx->progname);
@@ -158,15 +156,17 @@
     /* --childsmax SINGLE */
     try {
         if (   (val_get(ctx->val, "option.childsmax", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--childsmax = \"%s\"", ov->data.s);
 
-        if ((ctx->option_childsmax = atoi(ov->data.s)) <= 0) {
-            log1(ctx, ERROR, "option --childsmax, number (%d) out of range", ctx->option_childsmax);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_childsmax = atoi(ov->data.s)) <= 0) {
+                log1(ctx, ERROR, "option --childsmax, number (%d) out of range", ctx->option_childsmax);
+                throw(0,0,0);
+            }
     }
     catch (ex) {
         rethrow;
@@ -175,12 +175,14 @@
     /* --daemonize FLAG */
     try {
         if (   (val_get(ctx->val, "option.daemonize", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.f != 1)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.f < 0)
+            || (ov->ndata == 1 && ov->data.f > 1)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--daemonize = %d", ov->data.f);
 
-        ctx->option_daemon = TRUE;
+        ctx->option_daemon = ov->data.f == 1 ? TRUE : FALSE;
     }
     catch (ex)
         rethrow;
@@ -188,12 +190,14 @@
     /* --kill FLAG */
     try {
         if (   (val_get(ctx->val, "option.kill", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.f != 1)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.f < 0)
+            || (ov->ndata == 1 && ov->data.f > 1)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--kill = %d", ov->data.f);
 
-        ctx->option_killflag = TRUE;
+        ctx->option_killflag = ov->data.f == 1 ? TRUE : FALSE;
     }
     catch (ex)
         rethrow;
@@ -201,12 +205,14 @@
     /* --pidfile SINGLE */
     try {
         if (   (val_get(ctx->val, "option.pidfile", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--pidfile = \"%s\"", ov->data.s);
 
-        ctx->option_pidfile = ov->data.s;
+        if (ov->ndata == 1)
+            ctx->option_pidfile = ov->data.s;
     }
     catch (ex)
         rethrow;
@@ -217,42 +223,45 @@
         int i;
 
         if (   (val_get(ctx->val, "option.acl", &ov) != VAL_OK)
-            || ((ov->ndata >= 1) && (ov->data.m == NULL))
+            || (ov->ndata <  0)
+            || (ov->ndata >= 1 && ov->data.m == NULL)
               ) throw(0,0,0);
         log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
         for (i = 0; i < ov->ndata; i++)
             log2(ctx, TRACE, "--acl[%d] = \"%s\"", i, (ov->data.m)[i]);
 
-        if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0);
-        for (i = 0; i < ov->ndata; i++) {
-            cp = (ov->data.m)[i];
-            log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
-            if (cp[0] == '!') {
-                ctx->pacl[i].acl = strdup(cp + 1);
-                ctx->pacl[i].not = TRUE;
-            }
-            else {
-                ctx->pacl[i].acl = strdup(cp);
-                ctx->pacl[i].not = TRUE;
-            }
-            log2(ctx, DEBUG, "ctx->pacl[%d].not = %s", i, ctx->pacl[i].not == TRUE ? "TRUE" : "FALSE");
-            log2(ctx, DEBUG, "ctx->pacl[%d].acl = %s", i, ctx->pacl[i].acl);
-            if ((cp = strrchr(ctx->pacl[i].acl, '/')) != NULL)
-                *cp++ = NUL;
-            else
-                cp = "-1";
-            ctx->pacl[i].prefixlen = atoi(cp);
-            log2(ctx, DEBUG, "ctx->pacl[%d].prefixlen = %d", i, ctx->pacl[i].prefixlen);
-            if ((rc = sa_addr_create(&(ctx->pacl[i].saa))) != SA_OK) {
-                log1(ctx, ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(rc));
-                throw(0,0,0);
+        if (ov->ndata >= 1) {
+            if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0);
+            for (i = 0; i < ov->ndata; i++) {
+                cp = (ov->data.m)[i];
+                log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
+                if (cp[0] == '!') {
+                    ctx->pacl[i].acl = strdup(cp + 1);
+                    ctx->pacl[i].not = TRUE;
                 }
-            if ((rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) {
-                log2(ctx, ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc));
-                throw(0,0,0);
+                else {
+                    ctx->pacl[i].acl = strdup(cp);
+                    ctx->pacl[i].not = TRUE;
                 }
+                log2(ctx, DEBUG, "ctx->pacl[%d].not = %s", i, ctx->pacl[i].not == TRUE ? "TRUE" : "FALSE");
+                log2(ctx, DEBUG, "ctx->pacl[%d].acl = %s", i, ctx->pacl[i].acl);
+                if ((cp = strrchr(ctx->pacl[i].acl, '/')) != NULL)
+                    *cp++ = NUL;
+                else
+                    cp = "-1";
+                ctx->pacl[i].prefixlen = atoi(cp);
+                log2(ctx, DEBUG, "ctx->pacl[%d].prefixlen = %d", i, ctx->pacl[i].prefixlen);
+                if ((rc = sa_addr_create(&(ctx->pacl[i].saa))) != SA_OK) {
+                    log1(ctx, ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(rc));
+                    throw(0,0,0);
+                    }
+                if ((rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) {
+                    log2(ctx, ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc));
+                    throw(0,0,0);
+                    }
+            }
+            ctx->nacl = i;
         }
-        ctx->nacl = i;
     }
     catch (ex)
         rethrow;
@@ -260,90 +269,93 @@
     /* --bind SINGLE */
     try {
         if (   (val_get(ctx->val, "option.bind", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--bind = \"%s\"", ov->data.s);
 
-        /* dash means stdio */
-        if (strcmp(ov->data.s, "-") != 0) { //FIXME does this work with popt()?
-            if ((rc = sa_create(&ctx->saServerbind)) != SA_OK) {
-                log1(ctx, ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(rc));
-                throw(0,0,0);
-            }
-            if ((rc = sa_addr_create(&ctx->saaServerbind)) != SA_OK) {
-                log1(ctx, ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(rc));
-                throw(0,0,0);
-            }
-        /* slash means UNIX socket */
-            if (ov->data.s[0] == '/') {
-                char *cpPath;
-                char *cpPerm;
-                int nPerm;
-                int n;
-                int i;
-
-                cpPath = strdup(optarg);
-                cpPerm = NULL;
-                nPerm  = -1;
-                if ((cpPerm = strrchr(cpPath, ':')) != NULL) {
-                    *cpPerm++ = '\0';
-                    nPerm = 0;
-                    for (i = 0; i < 4 && cpPerm[i] != '\0'; i++) {
-                        if (!isdigit((int)cpPerm[i])) {
-                            nPerm = -1;
-                            break;
+        if (ov->ndata == 1) {
+            /* dash means stdio */
+            if (strcmp(ov->data.s, "-") != 0) { //FIXME does this work with popt()?
+                if ((rc = sa_create(&ctx->saServerbind)) != SA_OK) {
+                    log1(ctx, ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(rc));
+                    throw(0,0,0);
+                }
+                if ((rc = sa_addr_create(&ctx->saaServerbind)) != SA_OK) {
+                    log1(ctx, ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(rc));
+                    throw(0,0,0);
+                }
+            /* slash means UNIX socket */
+                if (ov->data.s[0] == '/') {
+                    char *cpPath;
+                    char *cpPerm;
+                    int nPerm;
+                    int n;
+                    int i;
+
+                    cpPath = strdup(optarg);
+                    cpPerm = NULL;
+                    nPerm  = -1;
+                    if ((cpPerm = strrchr(cpPath, ':')) != NULL) {
+                        *cpPerm++ = '\0';
+                        nPerm = 0;
+                        for (i = 0; i < 4 && cpPerm[i] != '\0'; i++) {
+                            if (!isdigit((int)cpPerm[i])) {
+                                nPerm = -1;
+                                break;
+                            }
+                            n = cpPerm[i] - '0';
+                            if (n > 7) {
+                                nPerm = -1;
+                                break;
+                            }
+                            nPerm = ((nPerm << 3) | n);
                         }
-                        n = cpPerm[i] - '0';
-                        if (n > 7) {
-                            nPerm = -1;
-                            break;
+                        if (nPerm == -1 || cpPerm[i] != '\0') {
+                            log1(ctx, ERROR, "option --bind, invalid permissions \"%s\"", cpPerm);
+                            throw(0,0,0);
                         }
-                        nPerm = ((nPerm << 3) | n);
                     }
-                    if (nPerm == -1 || cpPerm[i] != '\0') {
-                        log1(ctx, ERROR, "option --bind, invalid permissions \"%s\"", cpPerm);
+                    if ((rc = sa_addr_u2a(ctx->saaServerbind, "unix:%s", cpPath)) != SA_OK) {
+                        log2(ctx, ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(rc));
                         throw(0,0,0);
                     }
-                }
-                if ((rc = sa_addr_u2a(ctx->saaServerbind, "unix:%s", cpPath)) != SA_OK) {
-                    log2(ctx, ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(rc));
-                    throw(0,0,0);
-                }
-                if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) {
-                    log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(rc));
-                    throw(0,0,0);
-                }
-                if (nPerm != -1) {
-                    if (chmod(cpPath, nPerm) == -1) {
-                        log3(ctx, ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"", cpPath, nPerm, strerror(errno));
+                    if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) {
+                        log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(rc));
                         throw(0,0,0);
                     }
+                    if (nPerm != -1) {
+                        if (chmod(cpPath, nPerm) == -1) {
+                            log3(ctx, ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"", cpPath, nPerm, strerror(errno));
+                            throw(0,0,0);
+                        }
+                    }
+                    if (getuid() == 0 && getuid() != ctx->option_uid) {
+                        if (chown(cpPath, ctx->option_uid, -1) == -1) {
+                            log3(ctx, ERROR, "option --bind, chown (%s, %d) failed with \"%s\"", cpPath, ctx->option_uid, strerror(errno));
+                            throw(0,0,0);
+                        }
+                    }
+                    free(cpPath);
                 }
-                if (getuid() == 0 && getuid() != ctx->option_uid) {
-                    if (chown(cpPath, ctx->option_uid, -1) == -1) {
-                        log3(ctx, ERROR, "option --bind, chown (%s, %d) failed with \"%s\"", cpPath, ctx->option_uid, strerror(errno));
+            /* otherwise assume INET socket */
+                else {
+                    if ((rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", ov->data.s)) != SA_OK) {
+                        log2(ctx, ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
+                        throw(0,0,0);
+                    }
+                    if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) {
+                        log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
                         throw(0,0,0);
                     }
                 }
-                free(cpPath);
-            }
-        /* otherwise assume INET socket */
-            else {
-                if ((rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", ov->data.s)) != SA_OK) {
-                    log2(ctx, ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
-                    throw(0,0,0);
-                }
-                if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) {
-                    log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
-                    throw(0,0,0);
+            /* for either sockets */
+                if ((rc = sa_listen(ctx->saServerbind, -1)) != SA_OK) {
+                        log2(ctx, ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
+                        throw(0,0,0);
                 }
             }
-        /* for either sockets */
-            if ((rc = sa_listen(ctx->saServerbind, -1)) != SA_OK) {
-                    log2(ctx, ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
-                    throw(0,0,0);
-            }
         }
     }
     catch (ex)
@@ -352,18 +364,21 @@
     /* --client SINGLE */
     try {
         if (   (val_get(ctx->val, "option.client", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--client = \"%s\"", ov->data.s);
 
-        if ((rc = sa_addr_create(&ctx->saaClientbind)) != SA_OK) {
-            log1(ctx, ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(rc));
-            throw(0,0,0);
-        }
-        if ((rc = sa_addr_u2a(ctx->saaClientbind, "inet://%s", ov->data.s)) != SA_OK) {
-            log2(ctx, ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
-            throw(0,0,0);
+        if (ov->ndata == 1) {
+            if ((rc = sa_addr_create(&ctx->saaClientbind)) != SA_OK) {
+                log1(ctx, ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(rc));
+                throw(0,0,0);
+            }
+            if ((rc = sa_addr_u2a(ctx->saaClientbind, "inet://%s", ov->data.s)) != SA_OK) {
+                log2(ctx, ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc));
+                throw(0,0,0);
+            }
         }
     }
     catch (ex)
@@ -375,35 +390,38 @@
         int i;
 
         if (   (val_get(ctx->val, "option.destination", &ov) != VAL_OK)
-            || ((ov->ndata >= 1) && (ov->data.m == NULL))
+            || (ov->ndata <  0)
+            || (ov->ndata >= 1 && ov->data.m == NULL)
               ) throw(0,0,0);
         log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
         for (i = 0; i < ov->ndata; i++)
             log2(ctx, TRACE, "--destination[%d] = \"%s\"", i, (ov->data.m)[i]);
 
-        if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0);
-        for (i = 0; i < ov->ndata; i++) {
-            cp = (ov->data.m)[i];
-            log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
-            if (strrchr(cp, ':') == NULL)
-                cp = str_concat(cp, ":nntp", NULL); //FIXME is this a config var/val?
-            else
-                cp = str_concat(cp, NULL); /* prepare for free() */
-            if ((rc = sa_addr_create(&ctx->ns[i].saa)) != SA_OK) {
-                log1(ctx, ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(rc));
-                throw(0,0,0);
-            }
-            if ((rc = sa_addr_u2a(ctx->ns[i].saa, "inet://%s", cp)) != SA_OK) {
-                log2(ctx, ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc));
-                throw(0,0,0);
-            }
-            if ((rc = sa_create(&ctx->ns[i].sa)) != SA_OK) {
-                log2(ctx, ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc));
-                throw(0,0,0);
+        if (ov->ndata >= 1) {
+            if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0);
+            for (i = 0; i < ov->ndata; i++) {
+                cp = (ov->data.m)[i];
+                log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
+                if (strrchr(cp, ':') == NULL)
+                    cp = str_concat(cp, ":nntp", NULL); //FIXME is this a config var/val?
+                else
+                    cp = str_concat(cp, NULL); /* prepare for free() */
+                if ((rc = sa_addr_create(&ctx->ns[i].saa)) != SA_OK) {
+                    log1(ctx, ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(rc));
+                    throw(0,0,0);
+                }
+                if ((rc = sa_addr_u2a(ctx->ns[i].saa, "inet://%s", cp)) != SA_OK) {
+                    log2(ctx, ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc));
+                    throw(0,0,0);
+                }
+                if ((rc = sa_create(&ctx->ns[i].sa)) != SA_OK) {
+                    log2(ctx, ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc));
+                    throw(0,0,0);
+                }
+                free(cp);
             }
-            free(cp);
+            ctx->nns = i;
         }
-        ctx->nns = i;
     }
     catch (ex)
         rethrow;
@@ -411,20 +429,23 @@
     /* --groupmode SINGLE */
     try {
         if (   (val_get(ctx->val, "option.groupmode", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--groupmode = \"%s\"", ov->data.s);
 
-        if      (strcasecmp(ov->data.s, "arg") == 0)
-            ctx->option_groupmode = GROUPMODE_ARG;
-        else if (strcasecmp(ov->data.s, "envelope") == 0)
-            ctx->option_groupmode = GROUPMODE_ENVELOPE;
-        else if (strcasecmp(ov->data.s, "header") == 0)
-            ctx->option_groupmode = GROUPMODE_HEADER;
-        else {
-            log1(ctx, ERROR, "option --groupmode, invalid mode (%s)", ov->data.s);
-            throw(0,0,0);
+        if (ov->ndata == 1) {
+            if      (strcasecmp(ov->data.s, "arg") == 0)
+                ctx->option_groupmode = GROUPMODE_ARG;
+            else if (strcasecmp(ov->data.s, "envelope") == 0)
+                ctx->option_groupmode = GROUPMODE_ENVELOPE;
+            else if (strcasecmp(ov->data.s, "header") == 0)
+                ctx->option_groupmode = GROUPMODE_HEADER;
+            else {
+                log1(ctx, ERROR, "option --groupmode, invalid mode (%s)", ov->data.s);
+                throw(0,0,0);
+            }
         }
     }
     catch (ex)
@@ -438,35 +459,38 @@
         char *cpValue;
 
         if (   (val_get(ctx->val, "option.headervalue", &ov) != VAL_OK)
-            || ((ov->ndata >= 1) && (ov->data.m == NULL))
+            || (ov->ndata <  0)
+            || (ov->ndata >= 1 && ov->data.m == NULL)
               ) throw(0,0,0);
         log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
         for (i = 0; i < ov->ndata; i++)
             log2(ctx, TRACE, "--headervalue[%d] = \"%s\"", i, (ov->data.m)[i]);
 
-        if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0);
-        for (i = 0; i < ov->ndata; i++) {
-            cp = (ov->data.m)[i];
-            log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
-            cpHeader = strdup(cp);
-            if ((cp = strchr(cpHeader, ':')) == NULL) {
-                log1(ctx, ERROR, "option --headervalue, header (%s) terminating colon missing", (ov->data.m)[i]);
-                throw(0,0,0);
-            }
-            *cp = NUL;
-            log2(ctx, DEBUG, "header[%d] = \"%s\"", i, cpHeader);
-            cp++;
-            while (*cp == ' ') cp++; //FIXME note this in NEWS
-            if (*cp == NUL) {
-                log1(ctx, ERROR, "option --headervalue, value (%s) missing", (ov->data.m)[i]);
-                throw(0,0,0);
-            }
-            cpValue = strdup(cp);
-            log2(ctx, DEBUG, " value[%d] = \"%s\"", i, cpValue);
-            argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpHeader);
-            argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpValue);
-            free(cpHeader);
-            free(cpValue);
+        if (ov->ndata >= 1) {
+            if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0);
+            for (i = 0; i < ov->ndata; i++) {
+                cp = (ov->data.m)[i];
+                log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
+                cpHeader = strdup(cp);
+                if ((cp = strchr(cpHeader, ':')) == NULL) {
+                    log1(ctx, ERROR, "option --headervalue, header (%s) terminating colon missing", (ov->data.m)[i]);
+                    throw(0,0,0);
+                }
+                *cp = NUL;
+                log2(ctx, DEBUG, "header[%d] = \"%s\"", i, cpHeader);
+                cp++;
+                while (*cp == ' ') cp++; //FIXME note this in NEWS
+                if (*cp == NUL) {
+                    log1(ctx, ERROR, "option --headervalue, value (%s) missing", (ov->data.m)[i]);
+                    throw(0,0,0);
+                }
+                cpValue = strdup(cp);
+                log2(ctx, DEBUG, " value[%d] = \"%s\"", i, cpValue);
+                argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpHeader);
+                argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpValue);
+                free(cpHeader);
+                free(cpValue);
+            }
         }
     }
     catch (ex)
@@ -477,24 +501,27 @@
         char *cp;
 
         if (   (val_get(ctx->val, "option.mailfrom", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--mailfrom = \"%s\"", ov->data.s);
 
-        ctx->option_mailfrom = strdup(ov->data.s);
-        /* protect ourselfs from the substitution of backreferences.
-         * Missing varargs would cause segfaults.  Rewrite capturing
-         * brackets to clustering syntax. Use poor man's s///g
-         * simulator as current str library doesn't support global
-         * substitution */
-        while (str_parse(ctx->option_mailfrom, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) {
-            free(ctx->option_mailfrom);
-            ctx->option_mailfrom = cp;
-        }
-        if (str_parse("<>", ctx->option_mailfrom) == -1) {
-            log1(ctx, ERROR, "option --mailfrom, illegal regex (%s)", ctx->option_mailfrom);
-            throw(0,0,0);
+        if (ov->ndata == 1) {
+            ctx->option_mailfrom = strdup(ov->data.s);
+            /* protect ourselfs from the substitution of backreferences.
+             * Missing varargs would cause segfaults.  Rewrite capturing
+             * brackets to clustering syntax. Use poor man's s///g
+             * simulator as current str library doesn't support global
+             * substitution */
+            while (str_parse(ctx->option_mailfrom, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) {
+                free(ctx->option_mailfrom);
+                ctx->option_mailfrom = cp;
+            }
+            if (str_parse("<>", ctx->option_mailfrom) == -1) {
+                log1(ctx, ERROR, "option --mailfrom, illegal regex (%s)", ctx->option_mailfrom);
+                throw(0,0,0);
+            }
         }
     }
     catch (ex)
@@ -503,16 +530,19 @@
     /* --nodename SINGLE */
     try {
         if (   (val_get(ctx->val, "option.nodename", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--nodename = \"%s\"", ov->data.s);
 
-        if (strlen(ov->data.s) > sizeof(ctx->uname.nodename)-1) {
-            log1(ctx, ERROR, "option --nodename, name (%s) too long", ov->data.s);
-            throw(0,0,0);
+        if (ov->ndata == 1) {
+            if (strlen(ov->data.s) > sizeof(ctx->uname.nodename)-1) {
+                log1(ctx, ERROR, "option --nodename, name (%s) too long", ov->data.s);
+                throw(0,0,0);
+            }
+            strcpy(ctx->uname.nodename, ov->data.s);
         }
-        strcpy(ctx->uname.nodename, ov->data.s);
     }
     catch (ex)
         rethrow;
@@ -522,46 +552,49 @@
         char *cp;
 
         if (   (val_get(ctx->val, "option.operationmode", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--operationmode = \"%s\"", ov->data.s);
 
-        cp = strdup(ov->data.s);
-        if      (strcasecmp(cp, "post") == 0)
-            ctx->option_operationmode = OPERATIONMODE_POST;
-        else if (strcasecmp(cp, "feed") == 0)
-            ctx->option_operationmode = OPERATIONMODE_FEED;
-        else {
-            if (strlen(cp) != 9) {
-                log1(ctx, ERROR, "option --operationmode, invalid length (%s)", cp);
-                throw(0,0,0);
-            }
-            if (cp[3] != '/') {
-                log1(ctx, ERROR, "option --operationmode, missing slash (%s)", cp);
-                throw(0,0,0);
-            }
-            cp[3] = NUL;
-            ctx->option_operationmodefakestatus = &cp[0];
-            ctx->option_operationmodefakedsn    = &cp[4];
-            if (   strlen(ctx->option_operationmodefakestatus) != 3
-                || !isdigit((int)ctx->option_operationmodefakestatus[0])
-                || !isdigit((int)ctx->option_operationmodefakestatus[1])
-                || !isdigit((int)ctx->option_operationmodefakestatus[2])
-                  ) {
-                log1(ctx, ERROR, "option --operationmode, invalid status code (%s)", cp);
-                throw(0,0,0);
-            }
-            if (   (strlen(ctx->option_operationmodefakedsn) != 5)
-                || !isdigit((int)ctx->option_operationmodefakedsn[0])
-                || (ctx->option_operationmodefakedsn[1] != '.')
-                || !isdigit((int)ctx->option_operationmodefakedsn[2])
-                || (ctx->option_operationmodefakedsn[3] != '.')
-                || !isdigit((int)ctx->option_operationmodefakedsn[4])
-                || (ctx->option_operationmodefakedsn[0] != ctx->option_operationmodefakestatus[0])
-                  ) {
-                log1(ctx, ERROR, "option --operationmode, invalid dsn code (%s)", cp);
-                throw(0,0,0);
+        if (ov->ndata == 1) {
+            cp = strdup(ov->data.s);
+            if      (strcasecmp(cp, "post") == 0)
+                ctx->option_operationmode = OPERATIONMODE_POST;
+            else if (strcasecmp(cp, "feed") == 0)
+                ctx->option_operationmode = OPERATIONMODE_FEED;
+            else {
+                if (strlen(cp) != 9) {
+                    log1(ctx, ERROR, "option --operationmode, invalid length (%s)", cp);
+                    throw(0,0,0);
+                }
+                if (cp[3] != '/') {
+                    log1(ctx, ERROR, "option --operationmode, missing slash (%s)", cp);
+                    throw(0,0,0);
+                }
+                cp[3] = NUL;
+                ctx->option_operationmodefakestatus = &cp[0];
+                ctx->option_operationmodefakedsn    = &cp[4];
+                if (   strlen(ctx->option_operationmodefakestatus) != 3
+                    || !isdigit((int)ctx->option_operationmodefakestatus[0])
+                    || !isdigit((int)ctx->option_operationmodefakestatus[1])
+                    || !isdigit((int)ctx->option_operationmodefakestatus[2])
+                      ) {
+                    log1(ctx, ERROR, "option --operationmode, invalid status code (%s)", cp);
+                    throw(0,0,0);
+                }
+                if (   (strlen(ctx->option_operationmodefakedsn) != 5)
+                    || !isdigit((int)ctx->option_operationmodefakedsn[0])
+                    || (ctx->option_operationmodefakedsn[1] != '.')
+                    || !isdigit((int)ctx->option_operationmodefakedsn[2])
+                    || (ctx->option_operationmodefakedsn[3] != '.')
+                    || !isdigit((int)ctx->option_operationmodefakedsn[4])
+                    || (ctx->option_operationmodefakedsn[0] != ctx->option_operationmodefakestatus[0])
+                      ) {
+                    log1(ctx, ERROR, "option --operationmode, invalid dsn code (%s)", cp);
+                    throw(0,0,0);
+                }
             }
         }
     }
@@ -573,24 +606,27 @@
         char *cp;
 
         if (   (val_get(ctx->val, "option.restrictheader", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--restrictheader = \"%s\"", ov->data.s);
 
-        ctx->option_restrictheader = strdup(ov->data.s);
-        /* protect ourselfs from the substitution of backreferences.
-         * Missing varargs would cause segfaults.  Rewrite capturing
-         * brackets to clustering syntax. Use poor man's s///g
-         * simulator as current str library doesn't support global
-         * substitution */
-        while (str_parse(ctx->option_restrictheader, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) {
-            free(ctx->option_restrictheader);
-            ctx->option_restrictheader = cp;
-        }
-        if (str_parse("<>", ctx->option_restrictheader) == -1) {
-            log1(ctx, ERROR, "option --restrictheader, illegal regex (%s)", ctx->option_restrictheader);
-            throw(0,0,0);
+        if (ov->ndata == 1) {
+            ctx->option_restrictheader = strdup(ov->data.s);
+            /* protect ourselfs from the substitution of backreferences.
+             * Missing varargs would cause segfaults.  Rewrite capturing
+             * brackets to clustering syntax. Use poor man's s///g
+             * simulator as current str library doesn't support global
+             * substitution */
+            while (str_parse(ctx->option_restrictheader, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) {
+                free(ctx->option_restrictheader);
+                ctx->option_restrictheader = cp;
+            }
+            if (str_parse("<>", ctx->option_restrictheader) == -1) {
+                log1(ctx, ERROR, "option --restrictheader, illegal regex (%s)", ctx->option_restrictheader);
+                throw(0,0,0);
+            }
         }
     }
     catch (ex)
@@ -599,15 +635,17 @@
     /* --size SINGLE */
     try {
         if (   (val_get(ctx->val, "option.size", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--size = \"%s\"", ov->data.s);
 
-        if ((ctx->option_maxmessagesize = atoi(ov->data.s)) <= 0) {
-            log1(ctx, ERROR, "option --size, number (%d) out of range", ctx->option_maxmessagesize);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_maxmessagesize = atoi(ov->data.s)) <= 0) {
+                log1(ctx, ERROR, "option --size, number (%d) out of range", ctx->option_maxmessagesize);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -617,18 +655,21 @@
         int i;
 
         if (   (val_get(ctx->val, "option.timeoutlmtp", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutlmtp= \"%s\"", ov->data.s);
-
-        if ((i = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutlmtp, number (%d) out of range", i);
-            throw(0,0,0);
-        }
-        ctx->option_timeout_lmtp_accept = i;
-        ctx->option_timeout_lmtp_read = i;
-        ctx->option_timeout_lmtp_write = i;
+ 
+        if (ov->ndata == 1) {
+            if ((i = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutlmtp, number (%d) out of range", i);
+                throw(0,0,0);
+            }
+            ctx->option_timeout_lmtp_accept = i;
+            ctx->option_timeout_lmtp_read = i;
+            ctx->option_timeout_lmtp_write = i;
+        }
     }
     catch (ex)
         rethrow;
@@ -636,15 +677,17 @@
     /* --timeoutlmtpaccept SINGLE */
     try {
         if (   (val_get(ctx->val, "option.timeoutlmtpaccept", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutlmtpaccept = \"%s\"", ov->data.s);
 
-        if ((ctx->option_timeout_lmtp_accept = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutlmtpaccept, number (%d) out of range", ctx->option_timeout_lmtp_accept);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_timeout_lmtp_accept = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutlmtpaccept, number (%d) out of range", ctx->option_timeout_lmtp_accept);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -652,15 +695,17 @@
     /* --timeoutlmtpread SINGLE */
     try {
         if (   (val_get(ctx->val, "option.timeoutlmtpread", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutlmtpread = \"%s\"", ov->data.s);
 
-        if ((ctx->option_timeout_lmtp_read = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutlmtpread, number (%d) out of range", ctx->option_timeout_lmtp_read);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_timeout_lmtp_read = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutlmtpread, number (%d) out of range", ctx->option_timeout_lmtp_read);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -668,15 +713,17 @@
     /* --timeoutlmtpwrite SINGLE */
     try {
         if (   (val_get(ctx->val, "option.timeoutlmtpwrite", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutlmtpwrite = \"%s\"", ov->data.s);
 
-        if ((ctx->option_timeout_lmtp_write = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutlmtpwrite, number (%d) out of range", ctx->option_timeout_lmtp_write);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_timeout_lmtp_write = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutlmtpwrite, number (%d) out of range", ctx->option_timeout_lmtp_write);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -686,18 +733,21 @@
         int i;
 
         if (   (val_get(ctx->val, "option.timeoutnntp", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutnntp= \"%s\"", ov->data.s);
 
-        if ((i = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutnntp, number (%d) out of range", i);
-            throw(0,0,0);
-        }
-        ctx->option_timeout_nntp_connect = i;
-        ctx->option_timeout_nntp_read = i;
-        ctx->option_timeout_nntp_write = i;
+        if (ov->ndata == 1) {
+            if ((i = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutnntp, number (%d) out of range", i);
+                throw(0,0,0);
+            }
+            ctx->option_timeout_nntp_connect = i;
+            ctx->option_timeout_nntp_read = i;
+            ctx->option_timeout_nntp_write = i;
+        }
     }
     catch (ex)
         rethrow;
@@ -705,15 +755,17 @@
     /* --timeoutnntpconnect SINGLE */
     try {
         if (   (val_get(ctx->val, "option.timeoutnntpconnect", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutnntpconnect = \"%s\"", ov->data.s);
 
-        if ((ctx->option_timeout_nntp_connect = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutnntpconnect, number (%d) out of range", ctx->option_timeout_nntp_connect);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_timeout_nntp_connect = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutnntpconnect, number (%d) out of range", ctx->option_timeout_nntp_connect);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -721,15 +773,17 @@
     /* --timeoutnntpread SINGLE */
     try {
         if (   (val_get(ctx->val, "option.timeoutnntpread", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutnntpread = \"%s\"", ov->data.s);
 
-        if ((ctx->option_timeout_nntp_read = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutnntpread, number (%d) out of range", ctx->option_timeout_nntp_read);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_timeout_nntp_read = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutnntpread, number (%d) out of range", ctx->option_timeout_nntp_read);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -737,15 +791,17 @@
     /* --timeoutnntpwrite SINGLE */
     try {
         if (   (val_get(ctx->val, "option.timeoutnntpwrite", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--timeoutnntpwrite = \"%s\"", ov->data.s);
 
-        if ((ctx->option_timeout_nntp_write = atoi(ov->data.s)) < 0) {
-            log1(ctx, ERROR, "option --timeoutnntpwrite, number (%d) out of range", ctx->option_timeout_nntp_write);
-            throw(0,0,0);
-        }
+        if (ov->ndata == 1)
+            if ((ctx->option_timeout_nntp_write = atoi(ov->data.s)) < 0) {
+                log1(ctx, ERROR, "option --timeoutnntpwrite, number (%d) out of range", ctx->option_timeout_nntp_write);
+                throw(0,0,0);
+            }
     }
     catch (ex)
         rethrow;
@@ -755,24 +811,27 @@
         struct passwd *sPasswd;
 
         if (   (val_get(ctx->val, "option.user", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.s == NULL)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.s == NULL)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--user = \"%s\"", ov->data.s);
 
-        if (isdigit((int)ov->data.s[0])) {
-            if ((sPasswd = getpwuid((uid_t)atoi(ov->data.s))) == NULL) {
-                log1(ctx, ERROR, "option --user, uid (%s) not found", ov->data.s);
-                throw(0,0,0);
+        if (ov->ndata == 1) {
+            if (isdigit((int)ov->data.s[0])) {
+                if ((sPasswd = getpwuid((uid_t)atoi(ov->data.s))) == NULL) {
+                    log1(ctx, ERROR, "option --user, uid (%s) not found", ov->data.s);
+                    throw(0,0,0);
+                }
             }
-        }
-        else {
-            if ((sPasswd = getpwnam(ov->data.s)) == NULL) {
-                log1(ctx, ERROR, "option --user, name (%s) not found", ov->data.s);
-                throw(0,0,0);
+            else {
+                if ((sPasswd = getpwnam(ov->data.s)) == NULL) {
+                    log1(ctx, ERROR, "option --user, name (%s) not found", ov->data.s);
+                    throw(0,0,0);
+                }
             }
+            ctx->option_uid = sPasswd->pw_uid;
         }
-        ctx->option_uid = sPasswd->pw_uid;
     }
     catch (ex)
         rethrow;
@@ -780,14 +839,17 @@
     /* --version FLAG */
     try {
         if (   (val_get(ctx->val, "option.version", &ov) != VAL_OK)
-            || (ov->ndata != 1)
-            || (ov->data.f != 1)
+            || (ov->ndata <  0)
+            || (ov->ndata == 1 && ov->data.f < 0)
+            || (ov->ndata == 1 && ov->data.f > 1)
+            || (ov->ndata >  1)
               ) throw(0,0,0);
         log1(ctx, TRACE, "--version = %d", ov->data.f);
 
-        log1(ctx, INFO, "program version %s", lmtp2nntp_version.v_gnu);
-        fprintf(stdout, "%s\n", lmtp2nntp_version.v_gnu); //FIXME is fprintf really the way to go?
-
+        if (ov->data.f == 1) {
+            log1(ctx, INFO, "program version %s", lmtp2nntp_version.v_gnu);
+            fprintf(stdout, "%s\n", lmtp2nntp_version.v_gnu); //FIXME is fprintf really the way to go?
+        }
     }
     catch (ex)
         rethrow;
@@ -798,16 +860,19 @@
         int i;
 
         if (   (val_get(ctx->val, "option.newsgroup", &ov) != VAL_OK)
-            || ((ov->ndata >= 1) && (ov->data.m == NULL))
+            || (ov->ndata <  0)
+            || (ov->ndata >= 1 && ov->data.m == NULL)
               ) throw(0,0,0);
         log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
         for (i = 0; i < ov->ndata; i++)
             log2(ctx, TRACE, "--newsgroup[%d] = \"%s\"", i, (ov->data.m)[i]);
 
-        for (i = 0; i < ov->ndata; i++) {
-            cp = (ov->data.m)[i];
-            log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
-            argz_add(&ctx->azGroupargs, &ctx->asGroupargs, cp);
+        if (ov->ndata >= 1) {
+            for (i = 0; i < ov->ndata; i++) {
+                cp = (ov->data.m)[i];
+                log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp);
+                argz_add(&ctx->azGroupargs, &ctx->asGroupargs, cp);
+            }
         }
     }
     catch (ex)

CVSTrac 2.0.1