OSSP CVS Repository

ossp - Check-in [1614]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1614
Date: 2002-Jan-23 15:12:52 (local)
2002-Jan-23 14:12:52 (UTC)
User:thl
Branch:
Comment: can now read flat example.conf through include option
Tickets:
Inspections:
Files:
ossp-pkg/lmtp2nntp/example.conf      1.4 -> 1.5     44 inserted, 57 deleted
ossp-pkg/lmtp2nntp/lmtp2nntp_config.c      1.11 -> 1.12     286 inserted, 268 deleted

ossp-pkg/lmtp2nntp/example.conf 1.4 -> 1.5

--- example.conf 2002/01/14 12:23:21     1.4
+++ example.conf 2002/01/23 14:12:52     1.5
@@ -3,61 +3,48 @@
 # LMTP2NNTP example.conf
 # 
 
-#   include         "sampleconfig.two"              #    -i aka --include
-
-<daemon>
-    childsmax       10                              #see -C aka --childsmax
-    daemonize       yes                             #see -D aka --daemonize
-                                                    #    -K aka --kill is not available in the configfile
-    pidfile         /tmp/pid                        #see -P aka --pidfile
-    acl             10/8                            #see -a aka --acl
-    acl             172.16/12
-    acl             192.168/16
-    acl             127.0.0.1/32     
-    bind            127.0.0.1:12345                 #see -b aka --bind, use IPv4:port
-    #bind           /tmp/uds:600                    #    UNIX domain socket path:permissions 
-</daemon>
-
-<server> #LMTP
-    timeoutaccept   0                               #see -t aka --timeout
-    timeoutread     10 
-    timeoutwrite    10 
-    size            555000                          #see -s aka --size
-    mailfrom        any.*@example\.org              #see -m aka --mailfrom
-    nodename        gateway.example.com             #see -n aka --nodename
-</server>
-
-<client> #NNTP, multiple sections allowed
-    client          127.0.0.2                       #see -c aka --client
-    destination     news.example.com                #see -d aka --destination
-    operationmode   post                            #see -o aka --operationmode
-    timeoutconnect  360 
-    timeoutread     60 
-    timeoutwrite    60 
-</client>
-
-<gateway> #main and globals
-    groupmode       envelope                        #see -g aka --groupmode
-
-                                                    #    -l is obsolete since v1.2, see l2spec
-                                                    #    -V is obsolete since v1.2; remove the "buffer" channel from l2spec
-    l2spec          'prefix(prefix="%%b %%d %%H:%%M:%%S <%%L> lmtp2nntp[%%P]: ",timezone=local) \
-                       -> buffer(size=65536) \
-                       -> file(path=%s,append=1,perm=%d)' \
-                                                    #    -l aka --l2spec
-
-    uid             gate                            #see -u aka --uid
-                                                    #    -v aka --version is not available in the configfile
-    newsgroup       test
-    newsgroup       alt.test                        #see man page for information about newsgroup
-</gateway>
-
-<message>
-    headervalue     X-gateway "lmtp2nntp gateway"   #see -h aka --headervalue
-    restrictheader  "Cc: j\.doe@example\.org"       #see -r aka --restrictheader
-</message>
-
-<server>
-    client          1.2.3.4 #must produce an error
-</server>
+        ### DAEMON ###
 
+childsmax       10                              #see -C aka --childsmax
+daemonize       yes                             #see -D aka --daemonize
+kill            4711                            #see -K aka --kill
+pidfile         "/tmp/pid"                      #see -P aka --pidfile
+veryverbose                                     #see -V aka --veryverbose
+                                                #           obsolete since v1.2
+                                                #           remove the "buffer" channel from l2spec
+acl             10/8                            #see -a aka --acl
+acl             172.16/12
+acl             192.168/16
+acl             127.0.0.1/32     
+bind            127.0.0.1:12345                 #see -b aka --bind, use IPv4:port
+#bind           "/tmp/uds:600"                  #    UNIX domain socket path:permissions 
+
+        ### GATEWAY ###
+
+client          127.0.0.2                       #see -c aka --client
+destination     news.example.com                #see -d aka --destination
+groupmode       envelope                        #see -g aka --groupmode
+headervalue     X-gateway "lmtp2nntp gateway"   #see -h aka --headervalue
+include         "sampleconfig.two"              #    -i aka --include
+                                                #    -l is obsolete since v1.2, see l2spec
+
+l2spec          prefix(prefix="%%b %%d %%H:%%M:%%S <%%L> lmtp2nntp[%%P]: ",timezone=local) \
+                   -> buffer(size=65536) \
+                   -> file(path=%s,append=1,perm=%d) \
+                                                #    -l aka --l2spec
+
+mailfrom        "any.*@example\.org"            #see -m aka --mailfrom
+nodename        "gateway.example.com"           #see -n aka --nodename
+operationmode   post                            #see -o aka --operationmode
+restrictheader  "Cc: j\.doe@example\.org"       #see -r aka --restrictheader
+size            555000                          #see -s aka --size
+timeoutlmtpaccept  0                            #see        --timeoutlmtpaccept
+timeoutlmtpread    10                           #see        --timeoutlmtpread
+timeoutlmtpwrite   10                           #see        --timeoutlmtpwrite
+timeoutnntpconnect 360                          #see        --timeoutnntpconnect
+timeoutnntpread    60                           #see        --timeoutnntpread
+timeoutnntpwrite   60                           #see        --timeoutnntpwrite
+uid             gate                            #see -u aka --uid
+                                                #    -v aka --version is not available in the configfile
+newsgroup       "test"
+newsgroup       "alt.test"                      #see man page for information about newsgroup


ossp-pkg/lmtp2nntp/lmtp2nntp_config.c 1.11 -> 1.12

--- lmtp2nntp_config.c   2002/01/22 16:09:47     1.11
+++ lmtp2nntp_config.c   2002/01/23 14:12:52     1.12
@@ -27,46 +27,18 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/stat.h>
-#if 0
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/utsname.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <pwd.h>
-#endif
 
 /* third party (included) */
-#if 0
 #include "lmtp2nntp_argz.h"
-#include "lmtp2nntp_shpat.h"
-#include "lmtp2nntp_daemon.h"
-#endif
 #include "lmtp2nntp_popt.h"
-#include "val.h"
 
 /* third party (linked in) */
-#include "str.h"
-#if 0
-#include "l2.h"
-#include "var.h"
-#endif
+#include <str.h>
+#include <val.h>
 
 /* library version check (compile-time) */
-#define  L2_VERSION_HEX_REQ 0x001200
-#define  L2_VERSION_STR_REQ "0.1.0"
 #define STR_VERSION_HEX_REQ 0x009206
 #define STR_VERSION_STR_REQ "0.9.6"
-#ifdef L2_VERSION_HEX
-#if L2_VERSION_HEX < L2_VERSION_HEX_REQ
-#error "require a newer version of OSSP L2"
-#endif
-#endif
 #ifdef STR_VERSION_HEX
 #if STR_VERSION_HEX < STR_VERSION_HEX_REQ
 #error "require a newer version of OSSP Str"
@@ -85,7 +57,6 @@
 #include "lmtp2nntp_lmtp.h"
 #include "lmtp2nntp_nntp.h"
 #include "lmtp2nntp_msg.h"
-#include "sa.h"
 #define _LMTP2NNTP_VERSION_C_AS_HEADER_
 #include "lmtp2nntp_version.c"
 #undef  _LMTP2NNTP_VERSION_C_AS_HEADER_
@@ -101,129 +72,15 @@
 #define NUL '\0'
 #endif
 
-void die(char *); /* FIXME */
-void die(char *msg)
+static void die(char *msg)
 {
-        //printf("ERROR: %s\n", msg);
-            exit(-1);
+    printf("ERROR: %s\n", msg);
+    exit(-1);
 }
 
-#if 0
-
-
-
-
-    FIXME pass(optionconfig_t *o, int pass);
-    /* pass=0 for preinitialization !? */
-
-void dotconftest(int argc, char **argv) /*FIXME*/
-{
- 
-    ctx = malloc(sizeof(lmtp2nntp_config_t));
-    ctx->option_childsmax = 10;
-
-
-/* Braindump
-
-    fuer configure
-
-ich brauche eine Tabelle, die alle optionen in langer und kurzer Form
-enthaelt, Angabe ob flag, single- oder multivalue, callbacks fuer die
-syntaxpruefung des human-readable inputs, die conversion ins interne binaryformat sowie rueckwandlung in
-human-readable format. Dazu informationen fuer help.
- */
-
-    {
-        const char *filename = "example.conf";
-        struct stat sb;
-        int fd;
-
-        if (stat(filename, &sb) == -1)
-            die("stat");
-        if ((cpBuf = (char *)malloc((size_t)sb.st_size + 1)) == NULL)
-            die("malloc");
-        if ((fd = open(filename, O_RDONLY)) == -1)
-            die("open");
-        if (read(fd, (void *)cpBuf, (size_t)sb.st_size) != (ssize_t)sb.st_size)
-            die("read");
-        cpBuf[(int)sb.st_size] = '\0';
-        if (close(fd) == -1)
-            die("close");
-    }
-    //printf("DEBUG: *** 1 *** file as it was just read in ***\n%s***\n", cpBuf);
-
-    {
-        char *cpI;  /* pointer to next character to be read */
-        char *cpO;  /* pointer to next character to be written. Used for eliminating
-                       backslash+newline at a line continuation */
-        char *cpL;  /* pointer to start of line */
-        int pline;  /* current physical (disregarding line continuation) line number */
-        int lline;  /* current logical lines first physical line number */
-        int eline;  /* flag signaling empty or just whitespace-filled line */
-        char c;     /* current character */
-        char p;     /* previous character */
-        int eof;    /* flag signaling end of file detected */
-
-        cpI = cpBuf;
-        cpO = cpBuf;
-        eof = FALSE;
-        pline = 1;
-        p = NUL;
-
-        cpL = cpO;
-        lline = pline;
-        eline = TRUE;
-        while(!eof) {
-            c = *cpI++;
-            *cpO++ = c;
-            if (c == NUL)
-                eof = TRUE;
-            else
-                if (!isspace(c))
-                    eline = FALSE;
-            if (eof || (c == '\n')) {
-                pline++;
-                if (!eof && (p == '\\')) { /* line continuation situation */
-                    cpO-=2; /* need to remove both backslash+newline */
-                }
-                else {
-                    if (!eline) { /* process logical line unless it's empty */
-                        *(cpO-1) = NUL;
-                        if (lline == (pline-1))
-                            //printf("DEBUG: line[%3d] = ***%s***\n", lline, cpL);
-                        else
-                            //printf("DEBUG: [%3d-%3d] = ***%s***\n", lline, pline-1, cpL);
-                        {
-                            char *cp = cpL;
-                            char *command;
-                            char *value;
-
-                            if ((command = str_token(&cp, " \t", "\"'", "#", STR_STRIPQUOTES|STR_BACKSLASHESC)) == NULL)
-                                //printf("DEBUG: no command - comment only\n");
-                            else {
-                                //printf("DEBUG:   command = ***%s***\n", command);
-                                if ((value = str_token(&cp, " \t", "\"'", "#", STR_STRIPQUOTES|STR_BACKSLASHESC)) == NULL)
-                                    //printf("DEBUG: no value - section\n");
-                                else {
-                                    while(isspace((int)*value)) value++;
-                                    //printf("DEBUG:     value = ***%s***\n", value);
-                                }
-                            }
-                        }
-                    }
-                    cpL = cpO;
-                    lline = pline;
-                    eline = TRUE;
-                }
-            }
-            p = c;
-        }
-    }
-}
-#endif
-
 struct optionconfig_s {
     optionconfig_t *next;               /* cleanup chain for destroy */
+    lmtp2nntp_option_t *parent;         /* include needs access to parent */
                     /**/
     char               *longname;       /* the long name (optional if shortname given) */
     char                shortname;      /* the short name (optional if longname given) */
@@ -263,7 +120,7 @@
         case OPT_MULTI:
             printf("DEBUG: <%5s>, name=<%20s>, OPT_MULTI,  desc=<%20s>, data@%.8lx->[%d]%.8lx\n",  (char *)ctx, name, desc, (long)oc, oc->ndata, (long)oc->data.m);
             for (i = 0; i < oc->ndata; i++) {
-                printf("DEBUG:        [%3d]                        =<%20s>\n", i, oc->data.m[i]);
+                printf("DEBUG:        [%3d] \"%s\"\n", i, oc->data.m[i]);
             }
             break;
         default:
@@ -271,8 +128,8 @@
     }
     return VAL_OK;
 }
-lmtp2nntp_option_rc_t option_find(lmtp2nntp_option_t *o, int number, optionconfig_t **ocp);
-lmtp2nntp_option_rc_t option_find(lmtp2nntp_option_t *o, int number, optionconfig_t **ocp)
+//lmtp2nntp_option_rc_t option_find(lmtp2nntp_option_t *o, int number, optionconfig_t **ocp);
+static lmtp2nntp_option_rc_t option_find(lmtp2nntp_option_t *o, int number, optionconfig_t **ocp)
 {
     lmtp2nntp_option_rc_t rc = VAL_OK;
 
@@ -302,6 +159,7 @@
         return OPTION_ERR_MEM;
     //printf("DEBUG: optionconfig_t structure malloc'ed\n");
     oc->next         = NULL;
+    oc->parent       = o;
     oc->longname     = strdup(longname);
     oc->shortname    = shortname;
     oc->descrip      = descrip == NULL ? NULL : strdup(descrip);
@@ -310,7 +168,7 @@
     oc->cb           = cb;
     oc->cbctx        = cbctx;
     oc->val          = o->vo;
-    oc->number       = o->pi; /*FIXME + 1; 0 is a reserved val in popt, so offset 1 */
+    oc->number       = o->pi + 1; /* 0 is a reserved val in popt, so offset 1 */
     oc->data.f       = 0;
     oc->data.s       = NULL; /* just in case a pointer is larger than int */
     oc->data.m       = NULL;
@@ -324,7 +182,8 @@
     //printf("DEBUG: optionconfig_t structure created\n");
 
     /* feed lib_val */
-    (void)/*FIXME rc*/val_reg(oc->val, oc->longname, VAL_TYPE_PTR, oc->descrip, oc);
+    if (val_reg(oc->val, oc->longname, VAL_TYPE_PTR, oc->descrip, oc) != VAL_OK)
+        CU(OPTION_ERR_USE);
 
     //printf("DEBUG: val_reg'ed\n");
 
@@ -333,15 +192,17 @@
     if (o->pi >= (o->pn-2)) { /* correction by two here, in malloc and realloc is for AUTOHELP and TABLEEND */
         if (o->pt == NULL) {
             //printf("DEBUG: malloc\n");
-            o->pt = (struct popt_option *)malloc(                (1 + 2) * sizeof(struct popt_option)); /*FIXME out of mem*/
+            o->pt = (struct popt_option *)malloc(                (1 + 2) * sizeof(struct popt_option));
             o->pn = 1;
         }
         else {
             //printf("DEBUG: realloc\n");
-            o->pt = (struct popt_option *)realloc(o->pt, (o->pn * 2 + 2) * sizeof(struct popt_option)); /*FIXME out of mem*/
+            o->pt = (struct popt_option *)realloc(o->pt, (o->pn * 2 + 2) * sizeof(struct popt_option));
             o->pn = o->pn * 2;
         }
     }
+    if (o->pt == NULL)
+        CU(OPTION_ERR_MEM);
     o->pt[o->pi].longName   = oc->longname;
     o->pt[o->pi].shortName  = oc->shortname;
     o->pt[o->pi].argInfo    = oc->type == OPT_FLAG ? POPT_ARG_NONE : POPT_ARG_STRING;
@@ -393,14 +254,110 @@
     return rc;
 }
 
+lmtp2nntp_option_rc_t option_create(lmtp2nntp_option_t **op)
+{
+    //printf("DEBUG: enter option_create(%.8lx)\n", (long)op);
+
+    if (op == NULL)
+        return OPTION_ERR_ARG;
+
+    if ((*op = (lmtp2nntp_option_t *)malloc(sizeof(lmtp2nntp_option_t))) == NULL)
+        return OPTION_ERR_MEM;
+    (*op)->childsmax = 0;
+    (*op)->daemonize = 0;
+    (*op)->kill = 0;
+    (*op)->pidfile = 0;
+    (*op)->acl.as = 0;
+    (*op)->acl.az = NULL;
+    (*op)->bind = NULL;
+    (*op)->client = NULL;
+    (*op)->destination.as = 0;
+    (*op)->destination.az = NULL;
+    (*op)->groupmode = NULL;
+    (*op)->headervalue.as = 0;
+    (*op)->headervalue.az = NULL;
+    (*op)->include.as = 0;
+    (*op)->include.az = NULL;
+    (*op)->size = 0;
+    (*op)->timeoutlmtpaccept = 0;
+    (*op)->timeoutlmtpread = 0;
+    (*op)->timeoutlmtpwrite = 0;
+    (*op)->timeoutnntpconnect = 0;
+    (*op)->timeoutnntpread = 0;
+    (*op)->timeoutnntpwrite = 0;
+    (*op)->mailfrom = NULL;
+    (*op)->nodename = NULL;
+    (*op)->operationmode = NULL;
+    (*op)->l2spec = NULL;
+    (*op)->uid = NULL;
+    (*op)->restrictheader.as = 0;
+    (*op)->restrictheader.az = NULL;
+    (*op)->newsgroup.as = 0;
+    (*op)->newsgroup.az = NULL;
+                    /**/
+    (*op)->first = NULL;
+    (*op)->last = NULL;
+    (*op)->vo = NULL;
+    (*op)->pn = 0;
+    (*op)->pi = 0;
+    (*op)->pt = NULL;
+
+    if (val_create(&((*op)->vo)) != VAL_OK) {
+        free(*op);
+        return OPTION_ERR_VAL;
+    }
+    return OPTION_OK;
+}
+
+static lmtp2nntp_option_rc_t option_parse_internal(lmtp2nntp_option_t *o, int argc, char **argv)
+{
+    int i;
+    char *cp;
+    optionconfig_t *ocp;
+    popt_context poptCon;   /* context for parsing command-line options */
+
+#if 0
+    {
+        int i; 
+    
+        for (i=0; i<argc; i++)
+            printf("DEBUG: argv[%3d] = ***%s***\n", i, argv[i]);
+    }
+#endif
+
+    poptCon = popt_getcontext(NULL, argc, (const char **)argv, o->pt, 0);
+    popt_setotheroptionhelp(poptCon, "[OPTIONS]* [newsgroup ...]");
+    //printf("DEBUG: argc=%d\n", argc);
+    if (argc < 2) {
+        popt_printusage(poptCon, stderr, 0);
+        exit(1);
+    }
+    while ((i = popt_getnextopt(poptCon)) >= 0) {
+        (void)option_find(o, i, &ocp);
+        //printf("DEBUG: ocp->type=%d\n", ocp->type);
+        if (ocp->cb != NULL)
+            ocp->cb(ocp, cp = (ocp->type == OPT_FLAG ? NULL : (char *)popt_getoptarg(poptCon)), ocp->cbctx);
+        //printf("DEBUG: popt_getnextopt returned  %d \"%s\", \"%s\"\n", i-1, o->pt[i-1].longName, ocp->longname);
+        //printf("DEBUG: popt_getoptarg  returned  \"%s\"\n", cp);
+    }
+    //printf("DEBUG: current popt error is \"%s\"(%d)\n", popt_strerror(i), i);
+    //printf("DEBUG: ----\n");
+    while ((cp = (char *)popt_getarg(poptCon)) != NULL) {
+        printf("DEBUG: popt_getarg returned \"%s\"\n", cp);
+    }
+    //printf("DEBUG: current popt error is \"%s\"(%d)\n", popt_strerror(i), i);
+    popt_freecontext(poptCon);
+    return OPTION_OK;
+}
+
 static lmtp2nntp_option_rc_t stdsyntax(optionconfig_t *oc, char *arg, char *cbctx)
 {
-    printf("DEBUG: enter stdsyntax %.8lx, \"%s\", \"%s\"\n", (long)oc, arg, cbctx);
+    //printf("DEBUG: enter stdsyntax %.8lx, \"%s\", \"%s\"\n", (long)oc, arg, cbctx);
 
     //printf("DEBUG: oc->type=%d\n", oc->type);
     switch (oc->type) {
         case OPT_FLAG:
-            printf("DEBUG: flag\n");
+            printf("DEBUG: flag   %20s = %s should match %s\n", oc->longname, arg, cbctx);
             if (arg != NULL || cbctx != NULL)
                 return OPTION_ERR_ARG;
             if (oc->ndata >= 1)
@@ -409,23 +366,25 @@
             oc->ndata = 1;
             break;
         case OPT_SINGLE:
-            printf("DEBUG: single\n");
+            printf("DEBUG: single %20s = %s should match %s\n", oc->longname, arg, cbctx);
             if (arg == NULL)
                 return OPTION_ERR_ARG;
-            if (oc->ndata >= 1 || oc->data.s != NULL)
-                    return OPTION_ERR_USE;
+            /* use this if repeated overwriting definitions are not allowed
+             *  if (oc->ndata >= 1 || oc->data.s != NULL)
+             *      return OPTION_ERR_USE;
+             */
             if (cbctx != NULL)
                 if (str_parse(arg, cbctx) <= 0) {
                     //printf("DEBUG: \"%s\" does NOT match \"%s\"\n", arg, cbctx);
                     return OPTION_ERR_USE;
                 }
-            printf("DEBUG: \"%s\" does match \"%s\"\n", arg, cbctx);
+            //printf("DEBUG: \"%s\" does match \"%s\"\n", arg, cbctx);
             if ((oc->data.s = strdup(arg)) == NULL)
                     return OPTION_ERR_MEM;
             oc->ndata = 1;
             break;
         case OPT_MULTI:
-            //printf("DEBUG: multi\n");
+            printf("DEBUG: multi  %20s = %s should match %s\n", oc->longname, arg, cbctx);
             if (arg == NULL)
                 return OPTION_ERR_ARG;
             if (oc->ndata >= 1 && oc->data.m == NULL)
@@ -458,130 +417,189 @@
 
 static lmtp2nntp_option_rc_t includeit(optionconfig_t *oc, char *arg, char *cbctx)
 {
-    return OPTION_OK;
-}
+    lmtp2nntp_option_t *o;
+    char *cpBuf = NULL;
+    int argc = 0;
+    char **argv = NULL;
 
-lmtp2nntp_option_rc_t option_create(lmtp2nntp_option_t **op)
-{
-    //printf("DEBUG: enter option_create(%.8lx)\n", (long)op);
+    //printf("DEBUG: enter includeit %.8lx, \"%s\", \"%s\"\n", (long)oc, arg, cbctx);
 
-    if (op == NULL)
-        return OPTION_ERR_ARG;
+    if ((o = oc->parent) == NULL)
+        return OPTION_ERR_USE;
 
-    if ((*op = (lmtp2nntp_option_t *)malloc(sizeof(lmtp2nntp_option_t))) == NULL)
-        return OPTION_ERR_MEM;
-    (*op)->childsmax = 0;
-    (*op)->daemonize = 0;
-    (*op)->kill = 0;
-    (*op)->pidfile = 0;
-    (*op)->acl.as = 0;
-    (*op)->acl.az = NULL;
-    (*op)->bind = NULL;
-    (*op)->client = NULL;
-    (*op)->destination.as = 0;
-    (*op)->destination.az = NULL;
-    (*op)->groupmode = NULL;
-    (*op)->headervalue.as = 0;
-    (*op)->headervalue.az = NULL;
-    (*op)->include.as = 0;
-    (*op)->include.az = NULL;
-    (*op)->size = 0;
-    (*op)->timeoutlmtpaccept = 0;
-    (*op)->timeoutlmtpread = 0;
-    (*op)->timeoutlmtpwrite = 0;
-    (*op)->timeoutnntpconnect = 0;
-    (*op)->timeoutnntpread = 0;
-    (*op)->timeoutnntpwrite = 0;
-    (*op)->mailfrom = NULL;
-    (*op)->nodename = NULL;
-    (*op)->operationmode = NULL;
-    (*op)->l2spec = NULL;
-    (*op)->uid = NULL;
-    (*op)->restrictheader.as = 0;
-    (*op)->restrictheader.az = NULL;
-    (*op)->newsgroup.as = 0;
-    (*op)->newsgroup.az = NULL;
-                    /**/
-    (*op)->first = NULL;
-    (*op)->last = NULL;
-    (*op)->vo = NULL;
-    (*op)->pn = 0;
-    (*op)->pi = 0;
-    (*op)->pt = NULL;
+    stdsyntax(oc, arg, cbctx);
+    //printf("DEBUG: *** 1 *** file going to be read in now\n");
+    {
+        const char *filename = arg;
+        struct stat sb;
+        int fd;
 
-    if (val_create(&((*op)->vo)) != VAL_OK) {
-        free(*op);
-        return OPTION_ERR_VAL;
+        if (stat(filename, &sb) == -1) die("stat");
+        if ((cpBuf = (char *)malloc((size_t)sb.st_size + 1)) == NULL) die("malloc");
+        if ((fd = open(filename, O_RDONLY)) == -1) die("open");
+        if (read(fd, (void *)cpBuf, (size_t)sb.st_size) != (ssize_t)sb.st_size) die("read");
+        cpBuf[(int)sb.st_size] = '\0';
+        if (close(fd) == -1)
+            die("close");
     }
-    return OPTION_OK;
+    //printf("DEBUG: *** 2 *** file as it was just read in ***\n%s***\n", cpBuf);
+
+    {
+        char *cpI;  /* pointer to next character to be read */
+        char *cpO;  /* pointer to next character to be written. Used for eliminating
+                       backslash+newline at a line continuation */
+        char *cpL;  /* pointer to start of line */
+        int pline;  /* current physical (disregarding line continuation) line number */
+        int lline;  /* current logical lines first physical line number */
+        int eline;  /* flag signaling empty or just whitespace-filled line */
+        char c;     /* current character */
+        char p;     /* previous character */
+        int eof;    /* flag signaling end of file detected */
+
+        cpI = cpBuf;
+        cpO = cpBuf;
+        eof = FALSE;
+        pline = 1;
+        p = NUL;
+
+        cpL = cpO;
+        lline = pline;
+        eline = TRUE;
+        while(!eof) {
+            c = *cpI++;
+            *cpO++ = c;
+            if (c == NUL)
+                eof = TRUE;
+            else
+                if (!isspace(c))
+                    eline = FALSE;
+            if (eof || (c == '\n')) {
+                pline++;
+                if (!eof && (p == '\\')) { /* line continuation situation */
+                    cpO-=2; /* need to remove both backslash+newline */
+                }
+                else {
+                    if (!eline) { /* process logical line unless it's empty */
+                        *(cpO-1) = NUL;
+                        if (lline == (pline-1))
+                            ;//printf("DEBUG: line[%3d] = ***%s***\n", lline, cpL);
+                        else
+                            ;//printf("DEBUG: [%3d-%3d] = ***%s***\n", lline, pline-1, cpL);
+                        {
+                            char *cp = cpL;
+                            char *option;
+                            char *value;
+                            char *cpNew;
+                            argz_t Newarg;
+
+                            Newarg.as = 0;
+                            Newarg.az = NULL;
+                            if ((option = str_token(&cp, " \t", "\"'", "#", STR_STRIPQUOTES|STR_BACKSLASHESC)) == NULL)
+                                //printf("DEBUG: no command - comment only\n")
+                                ;/* don't care about comments */
+                            else {
+                                //printf("DEBUG:    option = ***%s***\n", option);
+                                if ((value = str_token(&cp, " \t", "\"'", "#", STR_STRIPQUOTES|STR_BACKSLASHESC)) == NULL)
+                                    ;//printf("DEBUG: no value - section\n");
+                                else {
+                                    while(isspace((int)*value)) value++;
+                                    //printf("DEBUG:     value = ***%s***\n", value);
+
+                                    if (argv == NULL) {
+                                        if ((argv = (char **)malloc(   (   1 + 1) * sizeof(char **))) == NULL)
+                                            return OPTION_ERR_MEM;
+                                        argc = 0;
+                                        argv[argc++] = "include";
+                                        argv[argc] = NULL;
+                                    }
+
+                                    if ((cpNew = (char *)malloc(2 + strlen(option) + 1)) == NULL)
+                                        return OPTION_ERR_MEM;
+                                    cpNew[0]=NUL;
+                                    strcat(cpNew, "--");
+                                    strcat(cpNew, option);
+                                    if ((argv = (char **)realloc(argv, (argc + 1) * sizeof(char **))) == NULL)
+                                        return OPTION_ERR_MEM;
+                                    argv[argc++] = cpNew;
+                                    argv[argc] = NULL;
+
+                                    if ((cpNew = strdup(value)) == NULL)
+                                        return OPTION_ERR_MEM;
+                                    if ((argv = (char **)realloc(argv, (argc + 1) * sizeof(char **))) == NULL)
+                                        return OPTION_ERR_MEM;
+                                    argv[argc++] = cpNew;
+                                    argv[argc] = NULL;
+                                }
+                            }
+                        }
+                    }
+                    cpL = cpO;
+                    lline = pline;
+                    eline = TRUE;
+                }
+            }
+            p = c;
+        }
+    }
+    
+    return option_parse_internal(o, argc, argv);
 }
 
 lmtp2nntp_option_rc_t option_parse(lmtp2nntp_option_t *o, int argc, char **argv)
 {
+    lmtp2nntp_option_rc_t rc;
     //printf("DEBUG: enter option_parse(%.8lx, %d, %.8lx)\n", (long)o, argc, (long)argv);
 
     if (o == NULL)
         return OPTION_ERR_ARG;
 
-    (void)option_register(o, "childsmax",           'C', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "childsmax" );
-    (void)option_register(o, "daemonize",           'D', OPT_FLAG,   NULL,       NULL,                  "foo", NULL );
-    (void)option_register(o, "kill",                'K', OPT_FLAG,   NULL,       NULL,                  "foo", NULL );
-    (void)option_register(o, "pidfile",             'P', OPT_SINGLE, &stdsyntax, "m/.{,255}/",          "foo", "pidfile" );
-    (void)option_register(o, "veryverbose",         'V', OPT_FLAG,   NULL,       NULL,                  "foo", NULL );
-    (void)option_register(o, "acl",                 'a', OPT_MULTI,  &stdsyntax, "m/[0-9.](/[0-9]2)?/", "foo", "addr[/mask]" );
-    (void)option_register(o, "bind",                'b', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "addr[:port]|-|path[:perms]" );
-    (void)option_register(o, "client",              'c', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "addr[:port]" );
-    (void)option_register(o, "destination",         'd', OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "addr[:port]" );
-    (void)option_register(o, "groupmode",           'g', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "groupmode" );
-    (void)option_register(o, "headervalue",         'h', OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "header: value" );
-    (void)option_register(o, "include",             'i', OPT_MULTI,  &includeit, "m/.*/",               "foo", "configfile" );
-    (void)option_register(o, "size",                's', OPT_SINGLE, &stdsyntax, "m/[0-9]+/",           "foo", "bytes" );
-    (void)option_register(o, "timeoutlmtpaccept",   NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "sec" );
-    (void)option_register(o, "timeoutlmtpread",     NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "sec" );
-    (void)option_register(o, "timeoutlmtpwrite",    NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "sec" );
-    (void)option_register(o, "timeoutnntpconnect",  NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "sec" );
-    (void)option_register(o, "timeoutnntpread",     NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "sec" );
-    (void)option_register(o, "timeoutnntpwrite",    NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "sec" );
-    (void)option_register(o, "mailfrom",            'm', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "regex" );
-    (void)option_register(o, "nodename",            'n', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "nodename" );
-    (void)option_register(o, "operationmode",       'o', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "post|feed" );
-    (void)option_register(o, "l2spec",              'l', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "spec" );
-    (void)option_register(o, "uid",                 'u', OPT_SINGLE, &stdsyntax, "m/.*/",               "foo", "number|name" );
-    (void)option_register(o, "restrictheader",      'r', OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "regex" );
-    (void)option_register(o, "newsgroup",           NUL, OPT_MULTI,  &stdsyntax, "m/.*/",               "foo", "newsgroup");
-    //val_apply(o->vo, "", 9, dumper, "all" );
-    
+    (void)option_register(o, "childsmax",          'C', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "childsmax" );
+    (void)option_register(o, "daemonize",          'D', OPT_FLAG,   &stdsyntax, NULL,    "foo", NULL );
+    (void)option_register(o, "kill",               'K', OPT_FLAG,   &stdsyntax, NULL,    "foo", NULL );
+    (void)option_register(o, "pidfile",            'P', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "pidfile" );
+    (void)option_register(o, "veryverbose",        'V', OPT_FLAG,   &stdsyntax, NULL,    "foo", NULL );
+    (void)option_register(o, "acl",                'a', OPT_MULTI,  &stdsyntax, "m/.*/", "foo", "addr[/mask]" );
+    (void)option_register(o, "bind",               'b', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "addr[:port]|-|path[:perms]" );
+    (void)option_register(o, "client",             'c', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "addr[:port]" );
+    (void)option_register(o, "destination",        'd', OPT_MULTI,  &stdsyntax, "m/.*/", "foo", "addr[:port]" );
+    (void)option_register(o, "groupmode",          'g', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "groupmode" );
+    (void)option_register(o, "headervalue",        'h', OPT_MULTI,  &stdsyntax, "m/.*/", "foo", "header: value" );
+    (void)option_register(o, "include",            'i', OPT_MULTI,  &includeit, "m/.*/", "foo", "configfile" );
+    (void)option_register(o, "size",               's', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "bytes" );
+    (void)option_register(o, "timeoutlmtpaccept",  NUL, OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "sec" );
+    (void)option_register(o, "timeoutlmtpread",    NUL, OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "sec" );
+    (void)option_register(o, "timeoutlmtpwrite",   NUL, OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "sec" );
+    (void)option_register(o, "timeoutnntpconnect", NUL, OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "sec" );
+    (void)option_register(o, "timeoutnntpread",    NUL, OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "sec" );
+    (void)option_register(o, "timeoutnntpwrite",   NUL, OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "sec" );
+    (void)option_register(o, "mailfrom",           'm', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "regex" );
+    (void)option_register(o, "nodename",           'n', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "nodename" );
+    (void)option_register(o, "operationmode",      'o', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "post|feed" );
+    (void)option_register(o, "l2spec",             'l', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "spec" );
+    (void)option_register(o, "uid",                'u', OPT_SINGLE, &stdsyntax, "m/.*/", "foo", "number|name" );
+    (void)option_register(o, "restrictheader",     'r', OPT_MULTI,  &stdsyntax, "m/.*/", "foo", "regex" );
+    (void)option_register(o, "newsgroup",          NUL, OPT_MULTI,  &stdsyntax, "m/.*/", "foo", "newsgroup");
+
+#if 0
     {
         int i;
-        char *cp;
-        optionconfig_t *ocp;
-        popt_context poptCon;   /* context for parsing command-line options */
-
-        poptCon = popt_getcontext(NULL, argc, (const char **)argv, o->pt, 0);
-        popt_setotheroptionhelp(poptCon, "[OPTIONS]* [newsgroup ...]");
-        //printf("DEBUG: argc=%d\n", argc);
-        if (argc < 2) {
-            popt_printusage(poptCon, stderr, 0);
-            exit(1);
-        }
-        while ((i = popt_getnextopt(poptCon)) >= 0) {
-            (void)option_find(o, i, &ocp);
-            printf("DEBUG: ocp->type=%d\n", ocp->type);
-            if (ocp->cb != NULL)
-                ocp->cb(ocp, cp = (ocp->type == OPT_FLAG ? NULL : (char *)popt_getoptarg(poptCon)), ocp->cbctx);
-            //printf("DEBUG: popt_getnextopt returned  %d \"%s\", \"%s\"\n", i, o->pt[i].longName, ocp->longname);
-            //printf("DEBUG: popt_getoptarg  returned  \"%s\"\n", cp);
-        }
-        //printf("DEBUG: current popt error is \"%s\"(%d)\n", popt_strerror(i), i);
-        //printf("DEBUG: ----\n");
-        while ((cp = (char *)popt_getarg(poptCon)) != NULL) {
-            //printf("DEBUG: popt_getarg returned \"%s\"\n", cp);
+
+        for (i=0; i<26; i++) {
+            printf("DEBUG: o->pt[%3d].longName   = %s   \n", i,       o->pt[i].longName  );
+            printf("DEBUG: o->pt[%3d].shortName  = %c   \n", i,       o->pt[i].shortName );
+            printf("DEBUG: o->pt[%3d].argInfo    = %d   \n", i,       o->pt[i].argInfo   );
+            printf("DEBUG: o->pt[%3d].arg        = %.8lx\n", i, (long)o->pt[i].arg       );
+            printf("DEBUG: o->pt[%3d].val        = %d   \n", i,       o->pt[i].val       );
+            printf("DEBUG: o->pt[%3d].descrip    = %s   \n", i,       o->pt[i].descrip   );
+            printf("DEBUG: o->pt[%3d].argDescrip = %s   \n", i,       o->pt[i].argDescrip);
         }
-        //printf("DEBUG: current popt error is \"%s\"(%d)\n", popt_strerror(i), i);
-        popt_freecontext(poptCon);
     }
+#endif
+
+    //val_apply(o->vo, "", 9, dumper, "all" );
+    rc = option_parse_internal(o, argc, argv);
     val_apply(o->vo, "", 9, dumper, "all" );
-    return OPTION_OK;
+    return rc;
 }
 
 lmtp2nntp_option_rc_t option_destroy(lmtp2nntp_option_t *o)

CVSTrac 2.0.1