--- lmtp2nntp_option.c 2002/03/06 14:25:39 1.16
+++ lmtp2nntp_option.c 2002/03/07 16:03:56 1.17
@@ -127,142 +127,127 @@
}
-lmtp2nntp_option_rc_t option_register(lmtp2nntp_option_t *o, char *longname, char shortname, optiontype_t type, char *def, char *descrip, char *argdescrip, optionloop_cb_t *cb, char *cbctx)
+static void option_register(lmtp2nntp_option_t *o, char *longname, char shortname, optiontype_t type, char *def, char *descrip, char *argdescrip, optionloop_cb_t *cb, char *cbctx)
{
- lmtp2nntp_option_rc_t rc = VAL_OK;
- optionval_t *oc;
+ volatile struct {
+ optionval_t *oc;
+ } v;
+ ex_t ex;
- //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 optionval_t structure */
- if ((oc = (optionval_t *)malloc(sizeof(optionval_t))) == NULL)
- return OPTION_ERR_MEM;
- //printf("DEBUG: optionval_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 */
- switch (type) {
- case OPT_FLAG: oc->data.f = 0;
- break;
- case OPT_SINGLE: oc->data.s = def == NULL ? NULL : strdup(def);
- break;
- case OPT_MULTI: oc->data.m = NULL;
- break;
- }
- oc->ndata = (type == OPT_SINGLE && def != NULL) ? 1 : 0;
- if ( ( oc->longname == NULL)
- || ( descrip != NULL && oc->descrip == NULL)
- || ( argdescrip != NULL && oc->argdescrip == NULL)
- || (type == OPT_SINGLE && def != NULL && oc->data.s == NULL)
- )
- CU(OPTION_ERR_MEM);
-
- //printf("DEBUG: optionval_t structure created, oc at %.8lx is %.8lx\n", (long)&oc, (long)oc);
-
- /* feed lib_val */
- if (val_reg(oc->val, oc->longname, VAL_TYPE_PTR, oc->descrip, NULL) != VAL_OK)
- CU(OPTION_ERR_USE);
- if (val_set(oc->val, oc->longname, oc) != VAL_OK)
- CU(OPTION_ERR_USE);
- //printf("DEBUG: val_reg'ed\n");
-
-#if 0
- {
- optionval_t *ov = 0x12345678;
+ v.oc = NULL;
+ try {
+ if (o == NULL || longname == NULL)
+ throw(option_register, o, OPTION_ERR_ARG);
- if (val_get(oc->val, oc->longname, &ov) == VAL_OK)
- printf("DEBUG: oc->val %.8lx %s in %.8lx d = \"s\"\n", (long)oc->val, oc->longname, (long)(oc));
- if (val_get(o->vo, oc->longname, &ov) == VAL_OK)
- printf("DEBUG: o->vo %.8lx %s in %.8lx d = \"s\"\n", (long)o->vo, oc->longname, (long)(ov));
- printf("DEBUG: val_get'ed\n");
- }
-#endif
-
- /* 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;
+ /* create a optionval_t structure and initialize exception-uncritical data */
+ v.oc = (optionval_t *)mallocex(sizeof(optionval_t));
+ v.oc->next = NULL;
+ v.oc->parent = o;
+ v.oc->longname = NULL;
+ v.oc->shortname = shortname;
+ v.oc->descrip = NULL;
+ v.oc->argdescrip = NULL;
+ v.oc->type = type;
+ v.oc->cb = cb;
+ v.oc->cbctx = cbctx;
+ v.oc->val = o->vo;
+ v.oc->number = o->pi + 1; /* 0 is a reserved val in popt, so offset 1 */
+ switch (type) {
+ case OPT_FLAG: v.oc->data.f = 0; break;
+ case OPT_SINGLE: v.oc->data.s = NULL; break;
+ case OPT_MULTI: v.oc->data.m = NULL; break;
+ }
+ v.oc->ndata = 0;
+ /* preinitialization complete, now initialize exception-critical data*/
+ v.oc->longname = strdupex(longname);
+ if (descrip != NULL)
+ v.oc->descrip = strdupex(descrip);
+ if (argdescrip != NULL)
+ v.oc->argdescrip = strdupex(argdescrip);
+ if (type == OPT_SINGLE && def != NULL) {
+ v.oc->data.s = strdupex(def);
+ v.oc->ndata = 1;
+ }
+
+ /* feed lib_val */
+ if (val_reg(v.oc->val, v.oc->longname, VAL_TYPE_PTR, v.oc->descrip, NULL) != VAL_OK)
+ throw(option_register, o, OPTION_ERR_USE);
+ if (val_set(v.oc->val, v.oc->longname, v.oc) != VAL_OK)
+ throw(option_register, o, OPTION_ERR_USE);
+
+ /* feed lib_popt */
+ if (o->pi >= (o->pn-2)) { /* correction by two here, in mallv.oc and reallv.oc is for AUTOHELP and TABLEEND */
+ if (o->pt == NULL) {
+ o->pt = (struct popt_option *)mallocex( (1 + 2) * sizeof(struct popt_option));
+ o->pn = 1;
+ }
+ else {
+ o->pt = (struct popt_option *)reallocex(o->pt, (o->pn * 2 + 2) * sizeof(struct popt_option));
+ o->pn = o->pn * 2;
+ }
+ }
+ o->pt[o->pi].longName = v.oc->longname;
+ o->pt[o->pi].shortName = v.oc->shortname;
+ o->pt[o->pi].argInfo = v.oc->type == OPT_FLAG ? POPT_ARG_NONE : POPT_ARG_STRING;
+ o->pt[o->pi].arg = NULL;
+ o->pt[o->pi].val = v.oc->number;
+ o->pt[o->pi].descrip = v.oc->descrip;
+ o->pt[o->pi].argDescrip = v.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++;
+
+ /* link in this new optionval_t structure */
+ if (o->first == NULL) {
+ o->first = v.oc;
+ o->last = v.oc;
}
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 optionval_t structure */
- if (o->first == NULL) {
- o->first = oc;
- o->last = oc;
- }
- else {
- o->last->next = oc;
- o->last = oc;
+ o->last->next = v.oc;
+ o->last = v.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);
+ catch(ex) {
+ if (v.oc != NULL) {
+ if (type == OPT_SINGLE && v.oc->data.s != NULL)
+ free(v.oc->data.s);
+ if (v.oc->argdescrip != NULL)
+ free(v.oc->argdescrip);
+ if (v.oc->descrip != NULL)
+ free(v.oc->descrip);
+ if (v.oc->longname != NULL)
+ free(v.oc->longname);
+ free(v.oc);
+ }
+ rethrow;
}
- return rc;
+ return;
}
+/* this public function catches all underlying exceptions and properly returns a code */
lmtp2nntp_option_rc_t option_create(lmtp2nntp_option_t **op, val_t *parent)
{
ex_t ex;
try {
- if (op == NULL)
- throw(option_create, NULL, OPTION_ERR_ARG);
+ if (op == NULL || parent == NULL)
+ return OPTION_ERR_ARG;
(*op = (lmtp2nntp_option_t *)mallocex(sizeof(lmtp2nntp_option_t)));
(*op)->first = NULL;
@@ -273,10 +258,10 @@
(*op)->pt = NULL;
if (val_create(&((*op)->vo)) != VAL_OK)
- throw(option_create, NULL, OPTION_ERR_VAL);
+ return OPTION_ERR_VAL;
if (val_reg(parent, "option", VAL_TYPE_VAL, "option", (void *)&((*op)->vo)) != VAL_OK)
- throw(option_create, NULL, OPTION_ERR_VAL);
+ return OPTION_ERR_VAL;
}
catch(ex) {
if (*op != NULL) {
@@ -284,7 +269,9 @@
val_unreg(parent, "option");
free(*op);
}
- rethrow;
+ if (ex.ex_class == (void *)option_create)
+ return (lmtp2nntp_option_rc_t)ex.ex_value;
+ return OPTION_ERR_TRY;
}
return OPTION_OK;
}
@@ -296,14 +283,20 @@
int i;
char *cp;
optionval_t *ocp;
- popt_context poptCon; /* context for parsing command-line options */
+ popt_context poptCon;
+
+ /* internal function trusts args */
+ /* init lib_popt */
poptCon = popt_getcontext(NULL, argc, (const char **)argv, o->pt, 0);
popt_setotheroptionhelp(poptCon, "[OPTIONS]* [newsgroup ...]");
+
+ /* print usage if too few argv's */
if (argc < 2) {
popt_printusage(poptCon, stderr, 0);
- exit(1); //FIXME
+ return OPTION_ERR_USE;
}
+ /* parse every option, continue when optarg missing or bad option found */
while ((i = popt_getnextopt(poptCon)) >= 0 || i == POPT_ERROR_NOARG || i == POPT_ERROR_BADOPT) {
if (i == POPT_ERROR_NOARG || i == POPT_ERROR_BADOPT) {
fprintf(stderr, "ERROR: %s (%d) \"%s\"\n", popt_strerror(i), i, popt_badoption(poptCon, POPT_BADOPTION_NOALIAS));
@@ -317,27 +310,41 @@
}
}
+ /* create a "--newsgroup" argc/argv for every leftover argument */
{
- int largc;
- char **largv;
- char *cpNew;
-
- largv = (char **)mallocex((1 + 1) * sizeof(char **));
- largc = 0;
- largv[largc++] = "leftover";
- largv[largc] = NULL;
- while ((cp = (char *)popt_getarg(poptCon)) != NULL) {
- largv = (char **)reallocex(largv, (largc + 2) * sizeof(char **));
- largv[largc++] = "--newsgroup";
- largv[largc] = NULL;
- cpNew = strdupex(cp);
- largv[largc++] = cpNew;
- largv[largc] = NULL;
+ ex_t ex;
+ volatile struct {
+ char **largv;
+ } v;
+
+ try {
+ int largc;
+ char *cpNew;
+
+ v.largv = (char **)mallocex((1 + 1) * sizeof(char **));
+ largc = 0;
+ v.largv[largc++] = "leftover";
+ v.largv[largc] = NULL;
+ while ((cp = (char *)popt_getarg(poptCon)) != NULL) {
+ v.largv = (char **)reallocex(v.largv, (largc + 2) * sizeof(char **));
+ v.largv[largc++] = "--newsgroup";
+ v.largv[largc] = NULL;
+ cpNew = strdupex(cp);
+ v.largv[largc++] = cpNew;
+ v.largv[largc] = NULL;
+ }
+ if (largc > 1) {
+ rv = option_parse_internal(o, largc, v.largv);
+ if (rc == OPTION_OK)
+ rc = rv;
+ }
}
- if (largc > 1) {
- rv = option_parse_internal(o, largc, largv);
- if (rc == OPTION_OK)
- rc = rv;
+ cleanup {
+ if (v.largv != NULL)
+ free(v.largv);
+ }
+ catch(ex) {
+ rethrow;
}
}
popt_freecontext(poptCon);
@@ -346,12 +353,8 @@
static lmtp2nntp_option_rc_t stdsyntax(optionval_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)
@@ -360,25 +363,22 @@
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;
- */
+ /* add this if repeated overwriting definitions of single values are not allowed
+ * if (oc->ndata >= 1 || oc->data.s != NULL)
+ * return OPTION_ERR_USE;
+ */
if (cbctx != NULL)
if (str_parse(arg, cbctx) <= 0) {
fprintf(stderr, "ERROR: argument \"%s\" does NOT match syntax \"%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)
@@ -388,34 +388,13 @@
fprintf(stderr, "ERROR: argument \"%s\" does NOT match syntax \"%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;
+ if (oc->data.m == NULL) /* existing + this new + terminating NULL */
+ oc->data.m = (char **)mallocex( ( 0 + 1 + 1) * sizeof(char **));
+ else
+ oc->data.m = (char **)reallocex(oc->data.m, (oc->ndata + 1 + 1) * sizeof(char **));
+ oc->data.m[oc->ndata] = strdupex(arg);
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;
@@ -431,13 +410,10 @@
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;
@@ -445,21 +421,24 @@
ex_t ex;
try {
- if (stat(filename, &sb) == -1) throw(0, 0, "stat");
- if ((cpBuf = (char *)malloc((size_t)sb.st_size + 1)) == NULL) throw(0, 0, "malloc");
- if ((fd = open(filename, O_RDONLY)) == -1) throw(0, 0, "open");
- if (read(fd, (void *)cpBuf, (size_t)sb.st_size) != (ssize_t)sb.st_size) throw(0, 0, "read");
+ if (stat(filename, &sb) == -1)
+ throw(includeit, oc, "stat");
+ cpBuf = (char *)mallocex((size_t)sb.st_size + 1);
+ if ((fd = open(filename, O_RDONLY)) == -1)
+ throw(includeit, oc, "open");
+ if (read(fd, (void *)cpBuf, (size_t)sb.st_size) != (ssize_t)sb.st_size)
+ throw(includeit, oc, "read");
cpBuf[(int)sb.st_size] = '\0';
}
cleanup {
if (fd != -1) close(fd);
}
catch (ex) {
- fprintf(stderr, "ERROR: caught %s\n", ex.ex_value == NULL ? "N/A" : (char *)ex.ex_value);
+ if (cpBuf != NULL)
+ free((char *)cpBuf);
rethrow;
}
}
- //printf("DEBUG: *** 2 *** file as it was just read in ***\n%s***\n", cpBuf);
{
char *cpI; /* pointer to next character to be read */
@@ -560,51 +539,59 @@
return option_parse_internal(o, argc, argv);
}
+/* this public function catches all underlying exceptions and properly returns a code */
lmtp2nntp_option_rc_t option_parse(lmtp2nntp_option_t *o, int argc, char **argv)
{
- if (o == NULL)
- return OPTION_ERR_ARG;
+ ex_t ex;
- (void)option_register(o, "childsmax", 'C', OPT_SINGLE, "10", "childs to spawn at max", "childsmax", &stdsyntax, "m/\\d+/" ); //"m/[0-9]+/" );
- (void)option_register(o, "daemonize", 'D', OPT_FLAG, NULL, "detach from terminal", NULL, &stdsyntax, NULL );
- (void)option_register(o, "kill", 'K', OPT_FLAG, NULL, "kill a previously run daemon", NULL, &stdsyntax, NULL );
- (void)option_register(o, "pidfile", 'P', OPT_SINGLE, NULL, "file containing pid", "pidfile", &stdsyntax, "m/.*/" );
- (void)option_register(o, "acl", 'a', OPT_MULTI, NULL, "LMTP server access control list", "addr[/mask]", &stdsyntax, "m/.*/" );
- (void)option_register(o, "bind", 'b', OPT_SINGLE, NULL, "LMTP server bind", "addr[:port]|-|path[:perms]", &stdsyntax, "m/.*/" );
- (void)option_register(o, "client", 'c', OPT_SINGLE, NULL, "NNTP client bind", "addr[:port]", &stdsyntax, "m/.*/" );
- (void)option_register(o, "destination", 'd', OPT_MULTI, NULL, "NNTP client destination", "addr[:port]", &stdsyntax, "m/.*/" );
- (void)option_register(o, "groupmode", 'g', OPT_SINGLE, "arg", "arg|envelope|header", "groupmode", &stdsyntax, "m/.*/" ); //"m/(arg|envelope|header)/" );
- (void)option_register(o, "headerrule", 'h', OPT_MULTI, NULL, "header rewriting rule", "[pri]:[regex]:header:[val]", &stdsyntax, "m/^[0-9]*:.*:.+:.*$/" );
- (void)option_register(o, "include", 'i', OPT_MULTI, NULL, "configfile to include", "configfile", &includeit, "m/.*/" );
- (void)option_register(o, "timeoutlmtp", NUL, OPT_SINGLE, NULL, "LMTP server default timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutlmtpaccept", NUL, OPT_SINGLE, "0", "LMTP server accept timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutlmtpread", NUL, OPT_SINGLE, "10", "LMTP server read timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutlmtpwrite", NUL, OPT_SINGLE, "10", "LMTP server write timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutnntp", NUL, OPT_SINGLE, NULL, "NNTP client default timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutnntpconnect", NUL, OPT_SINGLE, "360", "NNTP client connect timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutnntpread", NUL, OPT_SINGLE, "60", "NNTP client read timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "timeoutnntpwrite", NUL, OPT_SINGLE, "60", "NNTP client write timeout", "sec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "l2spec", 'l', OPT_SINGLE, NULL, "L2 channel tree specification", "l2spec", &stdsyntax, "m/.*/" );
- (void)option_register(o, "mailfrom", 'm', OPT_SINGLE, NULL, "mail from envelope restriction", "regex", &stdsyntax, "m/.*/" );
- (void)option_register(o, "nodename", 'n', OPT_SINGLE, NULL, "nodename", "name", &stdsyntax, "m/.*/" );
- (void)option_register(o, "operationmode", 'o', OPT_SINGLE, "553/5.7.1", "fakestatus or operationmode", "abc/a.d.e|post|feed", &stdsyntax, "m/.*/" ); //"m/([0-9]{3}\\/[0-9]\\.[0-9]\\.[0-9]|post|feed)/" ); /* 553 = Requested action not taken: mailbox name not allowed, 5.7.1 = Delivery not authorized, message refused */
- (void)option_register(o, "restrictheader", 'r', OPT_SINGLE, NULL, "header restriction", "regex", &stdsyntax, "m/.*/" );
- (void)option_register(o, "size", 's', OPT_SINGLE, "8388608", "maximum message size", "bytes", &stdsyntax, "m/.*/" ); //"m/[0-9]+/" );
- (void)option_register(o, "testfile", 't', OPT_MULTI, NULL, "testfile for headerrule", "testfile", &stdsyntax, "m/.*/" );
- (void)option_register(o, "user", 'u', OPT_SINGLE, NULL, "user", "uid|name", &stdsyntax, "m/.*/" );
- (void)option_register(o, "version", 'v', OPT_FLAG, NULL, "print version", NULL, &stdsyntax, NULL );
- (void)option_register(o, "newsgroup", NUL, OPT_MULTI, NULL, "article destination", "newsgroup", &stdsyntax, "m/.*/" );
+ if (o == NULL || argc < 0 || argv == NULL)
+ return OPTION_ERR_ARG;
+ try {
+ option_register(o, "childsmax", 'C', OPT_SINGLE, "10", "childs to spawn at max", "childsmax", &stdsyntax, "m/\\d+/" ); //"m/[0-9]+/" );
+ option_register(o, "daemonize", 'D', OPT_FLAG, NULL, "detach from terminal", NULL, &stdsyntax, NULL );
+ option_register(o, "kill", 'K', OPT_FLAG, NULL, "kill a previously run daemon", NULL, &stdsyntax, NULL );
+ option_register(o, "pidfile", 'P', OPT_SINGLE, NULL, "file containing pid", "pidfile", &stdsyntax, "m/.*/" );
+ option_register(o, "acl", 'a', OPT_MULTI, NULL, "LMTP server access control list", "addr[/mask]", &stdsyntax, "m/.*/" );
+ option_register(o, "bind", 'b', OPT_SINGLE, NULL, "LMTP server bind", "addr[:port]|-|path[:perms]", &stdsyntax, "m/.*/" );
+ option_register(o, "client", 'c', OPT_SINGLE, NULL, "NNTP client bind", "addr[:port]", &stdsyntax, "m/.*/" );
+ option_register(o, "destination", 'd', OPT_MULTI, NULL, "NNTP client destination", "addr[:port]", &stdsyntax, "m/.*/" );
+ option_register(o, "groupmode", 'g', OPT_SINGLE, "arg", "arg|envelope|header", "groupmode", &stdsyntax, "m/.*/" ); //"m/(arg|envelope|header)/" );
+ option_register(o, "headerrule", 'h', OPT_MULTI, NULL, "header rewriting rule", "[pri]:[regex]:header:[val]", &stdsyntax, "m/^[0-9]*:.*:.+:.*$/" );
+ option_register(o, "include", 'i', OPT_MULTI, NULL, "configfile to include", "configfile", &includeit, "m/.*/" );
+ option_register(o, "timeoutlmtp", NUL, OPT_SINGLE, NULL, "LMTP server default timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutlmtpaccept", NUL, OPT_SINGLE, "0", "LMTP server accept timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutlmtpread", NUL, OPT_SINGLE, "10", "LMTP server read timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutlmtpwrite", NUL, OPT_SINGLE, "10", "LMTP server write timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutnntp", NUL, OPT_SINGLE, NULL, "NNTP client default timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutnntpconnect", NUL, OPT_SINGLE, "360", "NNTP client connect timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutnntpread", NUL, OPT_SINGLE, "60", "NNTP client read timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "timeoutnntpwrite", NUL, OPT_SINGLE, "60", "NNTP client write timeout", "sec", &stdsyntax, "m/.*/" );
+ option_register(o, "l2spec", 'l', OPT_SINGLE, NULL, "L2 channel tree specification", "l2spec", &stdsyntax, "m/.*/" );
+ option_register(o, "mailfrom", 'm', OPT_SINGLE, NULL, "mail from envelope restriction", "regex", &stdsyntax, "m/.*/" );
+ option_register(o, "nodename", 'n', OPT_SINGLE, NULL, "nodename", "name", &stdsyntax, "m/.*/" );
+ option_register(o, "operationmode", 'o', OPT_SINGLE, "553/5.7.1", "fakestatus or operationmode", "abc/a.d.e|post|feed", &stdsyntax, "m/.*/" ); //"m/([0-9]{3}\\/[0-9]\\.[0-9]\\.[0-9]|post|feed)/" ); /* 553 = Requested action not taken: mailbox name not allowed, 5.7.1 = Delivery not authorized, message refused */
+ option_register(o, "restrictheader", 'r', OPT_SINGLE, NULL, "header restriction", "regex", &stdsyntax, "m/.*/" );
+ option_register(o, "size", 's', OPT_SINGLE, "8388608", "maximum message size", "bytes", &stdsyntax, "m/.*/" ); //"m/[0-9]+/" );
+ option_register(o, "testfile", 't', OPT_MULTI, NULL, "testfile for headerrule", "testfile", &stdsyntax, "m/.*/" );
+ option_register(o, "user", 'u', OPT_SINGLE, NULL, "user", "uid|name", &stdsyntax, "m/.*/" );
+ option_register(o, "version", 'v', OPT_FLAG, NULL, "print version", NULL, &stdsyntax, NULL );
+ option_register(o, "newsgroup", NUL, OPT_MULTI, NULL, "article destination", "newsgroup", &stdsyntax, "m/.*/" );
+ }
+ catch(ex) {
+ if (ex.ex_class == option_create)
+ return (lmtp2nntp_option_rc_t)ex.ex_value;
+ return OPTION_ERR_TRY;
+ }
return option_parse_internal(o, argc, argv);
}
+/* this public function catches all underlying exceptions and properly returns a code */
lmtp2nntp_option_rc_t option_destroy(lmtp2nntp_option_t *o)
{
optionval_t *oc;
int i;
- //printf("DEBUG: option_destroy %.8lx\n", (long)o);
-
if (o == NULL)
return OPTION_ERR_ARG;
|