Index: ossp-pkg/lmtp2nntp/lmtp2nntp_config.c
RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.c,v
rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.c,v' 2>/dev/null
--- lmtp2nntp_config.c 2002/01/24 08:54:25 1.14
+++ lmtp2nntp_config.c 2002/01/24 12:04:46 1.15
@@ -1,3 +1,4 @@
+
/*
** Copyright (c) 2001-2002 The OSSP Project
** Copyright (c) 2001-2002 Cable & Wireless Deutschland
@@ -21,7 +22,7 @@
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA, or contact the OSSP project .
**
-** FIXME lmtp2nntp_config.c: LMTP to NNTP configuration parsing
+** lmtp2nntp_config.c: config handling
*/
#include
@@ -53,10 +54,12 @@
#if defined(HAVE_DMALLOC_H) && defined(DMALLOC)
#include "dmalloc.h"
#endif
+#include "lmtp2nntp_option.h"
#include "lmtp2nntp_config.h"
#include "lmtp2nntp_lmtp.h"
#include "lmtp2nntp_nntp.h"
#include "lmtp2nntp_msg.h"
+#include "fixme.h"
#define _LMTP2NNTP_VERSION_C_AS_HEADER_
#include "lmtp2nntp_version.c"
#undef _LMTP2NNTP_VERSION_C_AS_HEADER_
@@ -72,615 +75,7 @@
#define NUL '\0'
#endif
-static void die(char *msg)
-{
- printf("ERROR: %s\n", msg);
- exit(-1);
-}
-
-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) */
- char *descrip; /* description for autohelp */
- char *argdescrip; /* argument description for autohelp */
- optiontype_t type; /* OPT_FLAG, OPT_SINGLE, OPT_MULTI */
- optionloop_cb_t *cb; /* callback for first iteration - syntax check and include */
- void *cbctx; /* context for pass1 */
- val_t *val; /* val we are registered under */
- /**/
- int number; /* number of this option for popt */
- struct { /* option data as read from configuration */
- int f; /* OPT_FLAG */
- void *foo1, *foo2, *foo3, *foo4, *foo5, *foo6, *foo7, *foo8, *foo9;
- char *s; /* OPT_SINGLE */
- void *bar1, *bar2, *bar3, *bar4, *bar5, *bar6, *bar7, *bar8, *bar9;
- char **m; /* OPT_MULTI */
- } data;
- int ndata;
-};
-
-static val_rc_t dumper(void *ctx, const char *name, int type, const char *desc, void *data)
-{
- optionconfig_t *oc;
- int i;
-
- if (type != VAL_TYPE_PTR)
- return VAL_OK;
-
- oc = (optionconfig_t *)data;
-
- switch (oc->type) {
- case OPT_FLAG:
- printf("DEBUG: <%5s>, name=<%20s>, OPT_FLAG, desc=<%20s>, data@%.8lx->[%d]%d\n", (char *)ctx, name, desc, (long)oc, oc->ndata, oc->data.f); break;
- case OPT_SINGLE:
- printf("DEBUG: <%5s>, name=<%20s>, OPT_SINGLE, desc=<%20s>, data@%.8lx->[%d]\"%s\"\n", (char *)ctx, name, desc, (long)oc, oc->ndata, oc->data.s == NULL ? "NULL" : oc->data.s);
- break;
- 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++) {
-#if 0
- {
- int j;
- printf("DEBUG: ");
- for (j=0; j<8; j++) printf("%.2x ", (unsigned char)oc->data.m[i][j]);
- printf(" ");
- for (j=0; j<8; j++) printf("%c", isprint(oc->data.m[i][j]) ? oc->data.m[i][j] : '.');
- printf(" ");
- }
-#endif
- printf("DEBUG: [%3d] %.8lx \"%s\"\n", i, (long)oc->data.m[i], oc->data.m[i]);
- }
- break;
- default:
- break;
- }
- return VAL_OK;
-}
-//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;
-
- if (o == NULL || ocp == NULL)
- return OPTION_ERR_ARG;
-
- *ocp = o->first;
- while (*ocp != NULL && (*ocp)->number != number)
- *ocp = (*ocp)->next;
-
- return rc;
-}
-
-
-lmtp2nntp_option_rc_t option_register(lmtp2nntp_option_t *o, char *longname, char shortname, optiontype_t type, optionloop_cb_t *cb, char *cbctx, char *descrip, char *argdescrip)
-{
- lmtp2nntp_option_rc_t rc = VAL_OK;
- optionconfig_t *oc;
-
- //printf("DEBUG: enter option_register(%.8lx, \"%s\", '%c', %d, %.8lx, %.8lx, \"%s\", \"%s\")\n", (long)o, longname, shortname, type, (long)cb, (long)cbctx, descrip, argdescrip);
-
- if (o == NULL || longname == NULL)
- return OPTION_ERR_ARG;
-
- /* create a optionconfig_t structure */
- if ((oc = (optionconfig_t *)malloc(sizeof(optionconfig_t))) == NULL)
- 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);
- oc->argdescrip = argdescrip == NULL ? NULL : strdup(argdescrip);
- oc->type = type;
- oc->cb = cb;
- oc->cbctx = cbctx;
- oc->val = o->vo;
- 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;
- oc->ndata = 0;
- if ( ( oc->longname == NULL)
- || (descrip != NULL && oc->descrip == NULL)
- || (argdescrip != NULL && oc->argdescrip == NULL)
- )
- CU(OPTION_ERR_MEM);
-
- //printf("DEBUG: optionconfig_t structure created\n");
-
- /* feed lib_val */
- 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");
-
- /* feed lib_popt */
- //printf("DEBUG: o->pi=%d, o->pn=%d\n", o->pi, o->pn);
- 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));
- o->pn = 1;
- }
- else {
- //printf("DEBUG: realloc\n");
- 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;
- o->pt[o->pi].arg = NULL;
- o->pt[o->pi].val = oc->number;
- o->pt[o->pi].descrip = oc->descrip;
- o->pt[o->pi].argDescrip = oc->argdescrip;
-
- /* append POPT_AUTOHELP */
- o->pt[o->pi+1].longName = NULL;
- o->pt[o->pi+1].shortName = '\0';
- o->pt[o->pi+1].argInfo = POPT_ARG_INCLUDE_TABLE;
- o->pt[o->pi+1].arg = popt_helpoptions;
- o->pt[o->pi+1].val = 0;
- o->pt[o->pi+1].descrip = "Help options:";
- o->pt[o->pi+1].argDescrip = NULL;
-
- /* append POPT_TABLEEND */
- o->pt[o->pi+2].longName = NULL;
- o->pt[o->pi+2].shortName = '\0';
- o->pt[o->pi+2].argInfo = 0;
- o->pt[o->pi+2].arg = 0;
- o->pt[o->pi+2].val = 0;
- o->pt[o->pi+2].descrip = NULL;
- o->pt[o->pi+2].argDescrip = NULL;
- o->pi++;
- //printf("DEBUG: popt'ed\n");
-
- /* link in this new optionconfig_t structure */
- if (o->first == NULL) {
- o->first = oc;
- o->last = oc;
- }
- else {
- o->last->next = oc;
- o->last = oc;
- }
- //printf("DEBUG: linked\n");
-
- return rc;
-
- CUS:
- if (oc != NULL) {
- if (oc->argdescrip != NULL) free(oc->argdescrip);
- if (oc->descrip != NULL) free(oc->descrip);
- if (oc->longname != NULL) free(oc->longname);
- free(oc);
- }
- 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; ipt, 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");
-
- {
- int largc;
- char **largv;
- char *cpNew;
-
- if ((largv = (char **)malloc((1 + 1) * sizeof(char **))) == NULL)
- return OPTION_ERR_MEM;
- largc = 0;
- largv[largc++] = "leftover";
- largv[largc] = NULL;
- while ((cp = (char *)popt_getarg(poptCon)) != NULL) {
- //printf("DEBUG: popt_getarg returned \"%s\"\n", cp);
- if ((largv = (char **)realloc(largv, (largc + 2) * sizeof(char **))) == NULL)
- return OPTION_ERR_MEM;
- largv[largc++] = "--newsgroup";
- largv[largc] = NULL;
- if ((cpNew = strdup(cp)) == NULL)
- return OPTION_ERR_MEM;
- //printf("DEBUG: cpNew = \"%s\"\n", cpNew);
- largv[largc++] = cpNew;
- largv[largc] = NULL;
- //printf("DEBUG: largc = \"%d\"\n", largc);
-#if 0
- for (i=0; i 1)
- option_parse_internal(o, largc, largv);
- }
- //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: oc->type=%d\n", oc->type);
- switch (oc->type) {
- case OPT_FLAG:
- //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)
- return OPTION_ERR_USE;
- oc->data.f = 1;
- oc->ndata = 1;
- break;
- case OPT_SINGLE:
- //printf("DEBUG: single %20s = %s should match %s\n", oc->longname, arg, cbctx);
- if (arg == NULL)
- return OPTION_ERR_ARG;
- /* 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);
- if ((oc->data.s = strdup(arg)) == NULL)
- return OPTION_ERR_MEM;
- oc->ndata = 1;
- break;
- case OPT_MULTI:
- //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)
- 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);
- /* malloc/realloc existing + this new + terminating NULL */
- if (oc->data.m == NULL) {
- //printf("DEBUG: before malloc, oc->data.m = %.8lx - ", (long)oc->data.m);
- //printf("DEBUG: requesting %d bytes\n", ( 0 + 1 + 1) * sizeof(char **));
- if ((oc->data.m = (char **)malloc( ( 0 + 1 + 1) * sizeof(char **))) == NULL)
- return OPTION_ERR_MEM;
- //printf("DEBUG: after malloc, oc->data.m = %.8lx\n", (long)oc->data.m);
- }
- else {
- //printf("DEBUG: before realloc, oc->data.m = %.8lx\n", (long)oc->data.m);
- //printf("DEBUG: requesting %d bytes\n", (oc->ndata + 1 + 1) * sizeof(char **));
- if ((oc->data.m = (char **)realloc(oc->data.m, (oc->ndata + 1 + 1) * sizeof(char **))) == NULL)
- return OPTION_ERR_MEM;
- //printf("DEBUG: after realloc, oc->data.m = %.8lx\n", (long)oc->data.m);
- }
- if ((oc->data.m[oc->ndata] = strdup(arg)) == NULL)
- return OPTION_ERR_MEM;
- oc->ndata++;
- oc->data.m[oc->ndata] = NULL;
-#if 0
- {
- int i;
- printf("DEBUG: oc->ndata=%d\n", oc->ndata);
- for (i=0; i<=oc->ndata; i++)
- printf("DEBUG: oc->data[%3d] at %.8lx points to %.8lx = %s\n", i, (long)&oc->data.m[i], (long)oc->data.m[i], oc->data.m[i]);
- }
-#endif
- break;
- default:
- return OPTION_ERR_ARG;
- break;
- }
- return OPTION_OK;
-}
-
-static lmtp2nntp_option_rc_t includeit(optionconfig_t *oc, char *arg, char *cbctx)
+void config_context(lmtp2nntp_t *ctx)
{
- lmtp2nntp_option_t *o;
- char *cpBuf = NULL;
- int argc = 0;
- char **argv = NULL;
-
- //printf("DEBUG: enter includeit %.8lx, \"%s\", \"%s\"\n", (long)oc, arg, cbctx);
-
- if ((o = oc->parent) == NULL)
- return OPTION_ERR_USE;
-
- 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 (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: *** 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 (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 ((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 ((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, &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;
-
- 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);
- }
- }
-#endif
-
- //val_apply(o->vo, "", 9, dumper, "all" );
- rc = option_parse_internal(o, argc, argv);
- val_apply(o->vo, "", 9, dumper, "all" );
- return rc;
-}
-
-lmtp2nntp_option_rc_t option_destroy(lmtp2nntp_option_t *o)
-{
- optionconfig_t *oc;
- int i;
-
- //printf("DEBUG: option_destroy %.8lx\n", (long)o);
-
- if (o == NULL)
- return OPTION_ERR_ARG;
-
- oc = o->first;
- while (oc != NULL) {
- if (oc->type == OPT_SINGLE && oc->data.s != NULL)
- free(oc->data.s);
- if (oc->type == OPT_MULTI && oc->data.m != NULL) {
- for (i = 0; i < oc->ndata; i++)
- if (oc->data.m[i] == NULL)
- break;
- else
- free(oc->data.m[i]);
- free(oc->data.m);
- }
- oc = oc->next;
- }
- if (o->vo != NULL)
- val_destroy(o->vo);
- free(o);
-
- return OPTION_OK;
+ return;
}
Index: ossp-pkg/lmtp2nntp/lmtp2nntp_config.h
RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.h,v
rcsdiff -q -kk '-r1.5' '-r1.6' -u '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_config.h,v' 2>/dev/null
--- lmtp2nntp_config.h 2002/01/22 16:09:47 1.5
+++ lmtp2nntp_config.h 2002/01/24 12:04:46 1.6
@@ -21,67 +21,11 @@
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
** USA, or contact the OSSP project .
**
-** FIXME lmtp2nntp_option.h: LMTP to NNTP configuration parsing
+** lmtp2nntp_config.h: config handling
*/
#include "lmtp2nntp_global.h"
-#include "val.h"
-
-struct optionconfig_s;
-typedef struct optionconfig_s optionconfig_t;
-
-typedef struct {
- int childsmax;
- int daemonize;
- int kill;
- char *pidfile;
- argz_t acl;
- char *bind;
- char *client;
- argz_t destination;
- char *groupmode;
- argz_t headervalue;
- argz_t include;
- char *size;
- int *timeoutlmtpaccept;
- int *timeoutlmtpread;
- int *timeoutlmtpwrite;
- int *timeoutnntpconnect;
- int *timeoutnntpread;
- int *timeoutnntpwrite;
- char *mailfrom;
- char *nodename;
- char *operationmode;
- char *l2spec;
- char *uid;
- argz_t restrictheader;
- argz_t newsgroup;
- /*FIXME above*/
- optionconfig_t *first;
- optionconfig_t *last;
- val_t *vo; /* val_t for all options */
- int pi; /* popt index to next record */
- int pn; /* popt number of available records */
- struct popt_option *pt; /* popt table */
-
-} lmtp2nntp_option_t;
-
-typedef enum {
- OPTION_OK,
- OPTION_ERR_ARG, /* invalid args passed into function */
- OPTION_ERR_USE, /* invalid usage, bad data passed into function */
- OPTION_ERR_MEM, /* out of memory */
- OPTION_ERR_VAL /* libval failed */
-} lmtp2nntp_option_rc_t;
-
-typedef enum {
- OPT_FLAG,
- OPT_SINGLE,
- OPT_MULTI
-} optiontype_t;
-
-typedef lmtp2nntp_option_rc_t (optionloop_cb_t)(optionconfig_t *oc, char *arg, char *cbctx);
-lmtp2nntp_option_rc_t option_create (lmtp2nntp_option_t **);
-lmtp2nntp_option_rc_t option_register(lmtp2nntp_option_t *, char *, char, optiontype_t, optionloop_cb_t *, char *, char *, char *);
-lmtp2nntp_option_rc_t option_parse (lmtp2nntp_option_t *, int, char **);
-lmtp2nntp_option_rc_t option_destroy (lmtp2nntp_option_t *);
+#include "fixme.h"
+//#include "val.h"
+//void config_context(lmtp2nntp_t *);
+void config_context(lmtp2nntp_t *);
Index: ossp-pkg/lmtp2nntp/lmtp2nntp_option.c
RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_option.c,v
co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_option.c,v' | diff -u /dev/null - -L'ossp-pkg/lmtp2nntp/lmtp2nntp_option.c' 2>/dev/null
--- ossp-pkg/lmtp2nntp/lmtp2nntp_option.c
+++ - 2025-04-12 00:43:05.338343996 +0200
@@ -0,0 +1,691 @@
+/*
+** Copyright (c) 2001-2002 The OSSP Project
+** Copyright (c) 2001-2002 Cable & Wireless Deutschland
+**
+** This file is part of OSSP lmtp2nntp, an LMTP speaking local
+** mailer which forwards mails as Usenet news articles via NNTP.
+** It can be found at http://www.ossp.org/pkg/lmtp2nntp/.
+**
+** This program is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License
+** as published by the Free Software Foundation; either version
+** 2.0 of the License, or (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this file; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+** USA, or contact the OSSP project .
+**
+** lmtp2nntp_option.h: option parsing
+*/
+
+#include
+#include
+#include
+
+/* third party (included) */
+#include "lmtp2nntp_argz.h"
+#include "lmtp2nntp_popt.h"
+
+/* third party (linked in) */
+#include
+#include
+
+/* library version check (compile-time) */
+#define STR_VERSION_HEX_REQ 0x009206
+#define STR_VERSION_STR_REQ "0.9.6"
+#ifdef STR_VERSION_HEX
+#if STR_VERSION_HEX < STR_VERSION_HEX_REQ
+#error "require a newer version of OSSP Str"
+#endif
+#endif
+
+/* own headers */
+#include "lmtp2nntp_global.h"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#if defined(HAVE_DMALLOC_H) && defined(DMALLOC)
+#include "dmalloc.h"
+#endif
+#include "lmtp2nntp_option.h"
+#include "lmtp2nntp_config.h"
+#include "lmtp2nntp_lmtp.h"
+#include "lmtp2nntp_nntp.h"
+#include "lmtp2nntp_msg.h"
+#define _LMTP2NNTP_VERSION_C_AS_HEADER_
+#include "lmtp2nntp_version.c"
+#undef _LMTP2NNTP_VERSION_C_AS_HEADER_
+
+#ifndef FALSE
+#define FALSE (1 != 1)
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#ifndef NUL
+#define NUL '\0'
+#endif
+
+static void die(char *msg)
+{
+ printf("ERROR: %s\n", msg);
+ exit(-1);
+}
+
+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) */
+ char *descrip; /* description for autohelp */
+ char *argdescrip; /* argument description for autohelp */
+ optiontype_t type; /* OPT_FLAG, OPT_SINGLE, OPT_MULTI */
+ optionloop_cb_t *cb; /* callback for first iteration - syntax check and include */
+ void *cbctx; /* context for pass1 */
+ val_t *val; /* val we are registered under */
+ /**/
+ int number; /* number of this option for popt */
+ struct { /* option data as read from configuration */
+ int f; /* OPT_FLAG */
+ void *foo1, *foo2, *foo3, *foo4, *foo5, *foo6, *foo7, *foo8, *foo9;
+ char *s; /* OPT_SINGLE */
+ void *bar1, *bar2, *bar3, *bar4, *bar5, *bar6, *bar7, *bar8, *bar9;
+ char **m; /* OPT_MULTI */
+ } data;
+ int ndata;
+};
+
+static val_rc_t dumper(void *ctx, const char *name, int type, const char *desc, void *data)
+{
+ optionconfig_t *oc;
+ int i;
+
+ if (type != VAL_TYPE_PTR)
+ return VAL_OK;
+
+ oc = (optionconfig_t *)data;
+
+ switch (oc->type) {
+ case OPT_FLAG:
+ printf("DEBUG: <%5s>, name=<%20s>, OPT_FLAG, desc=<%20s>, data@%.8lx->[%d]%d\n", (char *)ctx, name, desc, (long)oc, oc->ndata, oc->data.f); break;
+ case OPT_SINGLE:
+ printf("DEBUG: <%5s>, name=<%20s>, OPT_SINGLE, desc=<%20s>, data@%.8lx->[%d]\"%s\"\n", (char *)ctx, name, desc, (long)oc, oc->ndata, oc->data.s == NULL ? "NULL" : oc->data.s);
+ break;
+ 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++) {
+#if 0
+ {
+ int j;
+ printf("DEBUG: ");
+ for (j=0; j<8; j++) printf("%.2x ", (unsigned char)oc->data.m[i][j]);
+ printf(" ");
+ for (j=0; j<8; j++) printf("%c", isprint(oc->data.m[i][j]) ? oc->data.m[i][j] : '.');
+ printf(" ");
+ }
+#endif
+ printf("DEBUG: [%3d] %.8lx \"%s\"\n", i, (long)oc->data.m[i], oc->data.m[i]);
+ }
+ break;
+ default:
+ break;
+ }
+ return VAL_OK;
+}
+//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;
+
+ if (o == NULL || ocp == NULL)
+ return OPTION_ERR_ARG;
+
+ *ocp = o->first;
+ while (*ocp != NULL && (*ocp)->number != number)
+ *ocp = (*ocp)->next;
+
+ return rc;
+}
+
+
+lmtp2nntp_option_rc_t option_register(lmtp2nntp_option_t *o, char *longname, char shortname, optiontype_t type, optionloop_cb_t *cb, char *cbctx, char *descrip, char *argdescrip)
+{
+ lmtp2nntp_option_rc_t rc = VAL_OK;
+ optionconfig_t *oc;
+
+ //printf("DEBUG: enter option_register(%.8lx, \"%s\", '%c', %d, %.8lx, %.8lx, \"%s\", \"%s\")\n", (long)o, longname, shortname, type, (long)cb, (long)cbctx, descrip, argdescrip);
+
+ if (o == NULL || longname == NULL)
+ return OPTION_ERR_ARG;
+
+ /* create a optionconfig_t structure */
+ if ((oc = (optionconfig_t *)malloc(sizeof(optionconfig_t))) == NULL)
+ 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);
+ oc->argdescrip = argdescrip == NULL ? NULL : strdup(argdescrip);
+ oc->type = type;
+ oc->cb = cb;
+ oc->cbctx = cbctx;
+ oc->val = o->vo;
+ 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;
+ oc->ndata = 0;
+ if ( ( oc->longname == NULL)
+ || (descrip != NULL && oc->descrip == NULL)
+ || (argdescrip != NULL && oc->argdescrip == NULL)
+ )
+ CU(OPTION_ERR_MEM);
+
+ //printf("DEBUG: optionconfig_t structure created\n");
+
+ /* feed lib_val */
+ 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");
+
+ /* feed lib_popt */
+ //printf("DEBUG: o->pi=%d, o->pn=%d\n", o->pi, o->pn);
+ 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));
+ o->pn = 1;
+ }
+ else {
+ //printf("DEBUG: realloc\n");
+ 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;
+ o->pt[o->pi].arg = NULL;
+ o->pt[o->pi].val = oc->number;
+ o->pt[o->pi].descrip = oc->descrip;
+ o->pt[o->pi].argDescrip = oc->argdescrip;
+
+ /* append POPT_AUTOHELP */
+ o->pt[o->pi+1].longName = NULL;
+ o->pt[o->pi+1].shortName = '\0';
+ o->pt[o->pi+1].argInfo = POPT_ARG_INCLUDE_TABLE;
+ o->pt[o->pi+1].arg = popt_helpoptions;
+ o->pt[o->pi+1].val = 0;
+ o->pt[o->pi+1].descrip = "Help options:";
+ o->pt[o->pi+1].argDescrip = NULL;
+
+ /* append POPT_TABLEEND */
+ o->pt[o->pi+2].longName = NULL;
+ o->pt[o->pi+2].shortName = '\0';
+ o->pt[o->pi+2].argInfo = 0;
+ o->pt[o->pi+2].arg = 0;
+ o->pt[o->pi+2].val = 0;
+ o->pt[o->pi+2].descrip = NULL;
+ o->pt[o->pi+2].argDescrip = NULL;
+ o->pi++;
+ //printf("DEBUG: popt'ed\n");
+
+ /* link in this new optionconfig_t structure */
+ if (o->first == NULL) {
+ o->first = oc;
+ o->last = oc;
+ }
+ else {
+ o->last->next = oc;
+ o->last = oc;
+ }
+ //printf("DEBUG: linked\n");
+
+ return rc;
+
+ CUS:
+ if (oc != NULL) {
+ if (oc->argdescrip != NULL) free(oc->argdescrip);
+ if (oc->descrip != NULL) free(oc->descrip);
+ if (oc->longname != NULL) free(oc->longname);
+ free(oc);
+ }
+ return rc;
+}
+
+lmtp2nntp_option_rc_t option_create(lmtp2nntp_option_t **op, val_t *parent)
+{
+ //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;
+ }
+ if (val_reg(parent, "option", VAL_TYPE_VAL, "option", (void *)&((*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; ipt, 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");
+
+ {
+ int largc;
+ char **largv;
+ char *cpNew;
+
+ if ((largv = (char **)malloc((1 + 1) * sizeof(char **))) == NULL)
+ return OPTION_ERR_MEM;
+ largc = 0;
+ largv[largc++] = "leftover";
+ largv[largc] = NULL;
+ while ((cp = (char *)popt_getarg(poptCon)) != NULL) {
+ //printf("DEBUG: popt_getarg returned \"%s\"\n", cp);
+ if ((largv = (char **)realloc(largv, (largc + 2) * sizeof(char **))) == NULL)
+ return OPTION_ERR_MEM;
+ largv[largc++] = "--newsgroup";
+ largv[largc] = NULL;
+ if ((cpNew = strdup(cp)) == NULL)
+ return OPTION_ERR_MEM;
+ //printf("DEBUG: cpNew = \"%s\"\n", cpNew);
+ largv[largc++] = cpNew;
+ largv[largc] = NULL;
+ //printf("DEBUG: largc = \"%d\"\n", largc);
+#if 0
+ for (i=0; i 1)
+ option_parse_internal(o, largc, largv);
+ }
+ //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: oc->type=%d\n", oc->type);
+ switch (oc->type) {
+ case OPT_FLAG:
+ //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)
+ return OPTION_ERR_USE;
+ oc->data.f = 1;
+ oc->ndata = 1;
+ break;
+ case OPT_SINGLE:
+ //printf("DEBUG: single %20s = %s should match %s\n", oc->longname, arg, cbctx);
+ if (arg == NULL)
+ return OPTION_ERR_ARG;
+ /* 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);
+ if ((oc->data.s = strdup(arg)) == NULL)
+ return OPTION_ERR_MEM;
+ oc->ndata = 1;
+ break;
+ case OPT_MULTI:
+ //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)
+ 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);
+ /* malloc/realloc existing + this new + terminating NULL */
+ if (oc->data.m == NULL) {
+ //printf("DEBUG: before malloc, oc->data.m = %.8lx - ", (long)oc->data.m);
+ //printf("DEBUG: requesting %d bytes\n", ( 0 + 1 + 1) * sizeof(char **));
+ if ((oc->data.m = (char **)malloc( ( 0 + 1 + 1) * sizeof(char **))) == NULL)
+ return OPTION_ERR_MEM;
+ //printf("DEBUG: after malloc, oc->data.m = %.8lx\n", (long)oc->data.m);
+ }
+ else {
+ //printf("DEBUG: before realloc, oc->data.m = %.8lx\n", (long)oc->data.m);
+ //printf("DEBUG: requesting %d bytes\n", (oc->ndata + 1 + 1) * sizeof(char **));
+ if ((oc->data.m = (char **)realloc(oc->data.m, (oc->ndata + 1 + 1) * sizeof(char **))) == NULL)
+ return OPTION_ERR_MEM;
+ //printf("DEBUG: after realloc, oc->data.m = %.8lx\n", (long)oc->data.m);
+ }
+ if ((oc->data.m[oc->ndata] = strdup(arg)) == NULL)
+ return OPTION_ERR_MEM;
+ oc->ndata++;
+ oc->data.m[oc->ndata] = NULL;
+#if 0
+ {
+ int i;
+ printf("DEBUG: oc->ndata=%d\n", oc->ndata);
+ for (i=0; i<=oc->ndata; i++)
+ printf("DEBUG: oc->data[%3d] at %.8lx points to %.8lx = %s\n", i, (long)&oc->data.m[i], (long)oc->data.m[i], oc->data.m[i]);
+ }
+#endif
+ break;
+ default:
+ return OPTION_ERR_ARG;
+ break;
+ }
+ return OPTION_OK;
+}
+
+static lmtp2nntp_option_rc_t includeit(optionconfig_t *oc, char *arg, char *cbctx)
+{
+ lmtp2nntp_option_t *o;
+ char *cpBuf = NULL;
+ int argc = 0;
+ char **argv = NULL;
+
+ //printf("DEBUG: enter includeit %.8lx, \"%s\", \"%s\"\n", (long)oc, arg, cbctx);
+
+ if ((o = oc->parent) == NULL)
+ return OPTION_ERR_USE;
+
+ 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 (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: *** 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 (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 ((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 ((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, &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;
+
+ 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);
+ }
+ }
+#endif
+
+ //val_apply(o->vo, "", 9, dumper, "all" );
+ rc = option_parse_internal(o, argc, argv);
+ val_apply(o->vo, "", 9, dumper, "all" );
+ return rc;
+}
+
+lmtp2nntp_option_rc_t option_destroy(lmtp2nntp_option_t *o)
+{
+ optionconfig_t *oc;
+ int i;
+
+ //printf("DEBUG: option_destroy %.8lx\n", (long)o);
+
+ if (o == NULL)
+ return OPTION_ERR_ARG;
+
+ oc = o->first;
+ while (oc != NULL) {
+ if (oc->type == OPT_SINGLE && oc->data.s != NULL)
+ free(oc->data.s);
+ if (oc->type == OPT_MULTI && oc->data.m != NULL) {
+ for (i = 0; i < oc->ndata; i++)
+ if (oc->data.m[i] == NULL)
+ break;
+ else
+ free(oc->data.m[i]);
+ free(oc->data.m);
+ }
+ oc = oc->next;
+ }
+ if (o->vo != NULL)
+ val_destroy(o->vo);
+ free(o);
+
+ return OPTION_OK;
+}
Index: ossp-pkg/lmtp2nntp/lmtp2nntp_option.h
RCS File: /v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_option.h,v
co -q -kk -p'1.1' '/v/ossp/cvs/ossp-pkg/lmtp2nntp/lmtp2nntp_option.h,v' | diff -u /dev/null - -L'ossp-pkg/lmtp2nntp/lmtp2nntp_option.h' 2>/dev/null
--- ossp-pkg/lmtp2nntp/lmtp2nntp_option.h
+++ - 2025-04-12 00:43:05.341784501 +0200
@@ -0,0 +1,87 @@
+/*
+** Copyright (c) 2001-2002 The OSSP Project
+** Copyright (c) 2001-2002 Cable & Wireless Deutschland
+**
+** This file is part of OSSP lmtp2nntp, an LMTP speaking local
+** mailer which forwards mails as Usenet news articles via NNTP.
+** It can be found at http://www.ossp.org/pkg/lmtp2nntp/.
+**
+** This program is free software; you can redistribute it and/or
+** modify it under the terms of the GNU General Public License
+** as published by the Free Software Foundation; either version
+** 2.0 of the License, or (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this file; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+** USA, or contact the OSSP project .
+**
+** lmtp2nntp_option.h: option parsing
+*/
+
+#include "lmtp2nntp_global.h"
+#include "val.h"
+
+struct optionconfig_s;
+typedef struct optionconfig_s optionconfig_t;
+
+typedef struct {
+ int childsmax;
+ int daemonize;
+ int kill;
+ char *pidfile;
+ argz_t acl;
+ char *bind;
+ char *client;
+ argz_t destination;
+ char *groupmode;
+ argz_t headervalue;
+ argz_t include;
+ char *size;
+ int *timeoutlmtpaccept;
+ int *timeoutlmtpread;
+ int *timeoutlmtpwrite;
+ int *timeoutnntpconnect;
+ int *timeoutnntpread;
+ int *timeoutnntpwrite;
+ char *mailfrom;
+ char *nodename;
+ char *operationmode;
+ char *l2spec;
+ char *uid;
+ argz_t restrictheader;
+ argz_t newsgroup;
+ /*FIXME above*/
+ optionconfig_t *first;
+ optionconfig_t *last;
+ val_t *vo; /* val_t for all options */
+ int pi; /* popt index to next record */
+ int pn; /* popt number of available records */
+ struct popt_option *pt; /* popt table */
+
+} lmtp2nntp_option_t;
+
+typedef enum {
+ OPTION_OK,
+ OPTION_ERR_ARG, /* invalid args passed into function */
+ OPTION_ERR_USE, /* invalid usage, bad data passed into function */
+ OPTION_ERR_MEM, /* out of memory */
+ OPTION_ERR_VAL /* libval failed */
+} lmtp2nntp_option_rc_t;
+
+typedef enum {
+ OPT_FLAG,
+ OPT_SINGLE,
+ OPT_MULTI
+} optiontype_t;
+
+typedef lmtp2nntp_option_rc_t (optionloop_cb_t)(optionconfig_t *oc, char *arg, char *cbctx);
+lmtp2nntp_option_rc_t option_create (lmtp2nntp_option_t **, val_t *);
+lmtp2nntp_option_rc_t option_register(lmtp2nntp_option_t *, char *, char, optiontype_t, optionloop_cb_t *, char *, char *, char *);
+lmtp2nntp_option_rc_t option_parse (lmtp2nntp_option_t *, int, char **);
+lmtp2nntp_option_rc_t option_destroy (lmtp2nntp_option_t *);