head 1.96; access; symbols LMTP2NNTP_1_4_1:1.96 LMTP2NNTP_1_4_0:1.96 LMTP2NNTP_1_3_0:1.96 LMTP2NNTP_1_3b2:1.96 LMTP2NNTP_1_3b1:1.96 LMTP2NNTP_1_3a3:1.96 LMTP2NNTP_1_3a2:1.96 LMTP2NNTP_1_3a1:1.96 LMTP2NNTP_1_2_0:1.93 LMTP2NNTP_1_2b4:1.93 LMTP2NNTP_1_2b3:1.92 LMTP2NNTP_1_2b2:1.92 LMTP2NNTP_1_2b1:1.91 LMTP2NNTP_1_2a8:1.91 LMTP2NNTP_1_2a7:1.90 LMTP2NNTP_1_2a6:1.80 LMTP2NNTP_1_2a5:1.77 LMTP2NNTP_1_2a4:1.69 LMTP2NNTP_1_2a3:1.64; locks; strict; comment @ * @; 1.96 date 2004.04.02.13.55.37; author thl; state Exp; branches; next 1.95; 1.95 date 2004.04.02.13.52.50; author thl; state Exp; branches; next 1.94; 1.94 date 2004.04.02.08.22.46; author thl; state Exp; branches; next 1.93; 1.93 date 2003.02.12.16.16.29; author rse; state Exp; branches; next 1.92; 1.92 date 2003.02.10.13.51.34; author thl; state Exp; branches; next 1.91; 1.91 date 2003.02.06.10.51.40; author thl; state Exp; branches; next 1.90; 1.90 date 2003.01.30.19.45.20; author rse; state Exp; branches; next 1.89; 1.89 date 2003.01.30.19.42.12; author rse; state Exp; branches; next 1.88; 1.88 date 2003.01.30.19.27.29; author rse; state Exp; branches; next 1.87; 1.87 date 2003.01.30.19.18.57; author rse; state Exp; branches; next 1.86; 1.86 date 2003.01.30.15.19.55; author thl; state Exp; branches; next 1.85; 1.85 date 2003.01.30.14.37.01; author thl; state Exp; branches; next 1.84; 1.84 date 2003.01.30.14.33.07; author thl; state Exp; branches; next 1.83; 1.83 date 2003.01.30.14.26.38; author thl; state Exp; branches; next 1.82; 1.82 date 2003.01.30.14.22.14; author thl; state Exp; branches; next 1.81; 1.81 date 2003.01.30.14.17.01; author thl; state Exp; branches; next 1.80; 1.80 date 2002.08.14.21.19.01; author thl; state Exp; branches; next 1.79; 1.79 date 2002.07.17.11.28.06; author thl; state Exp; branches; next 1.78; 1.78 date 2002.07.02.07.49.01; author rse; state Exp; branches; next 1.77; 1.77 date 2002.05.28.14.14.44; author thl; state Exp; branches; next 1.76; 1.76 date 2002.05.28.14.03.32; author thl; state Exp; branches; next 1.75; 1.75 date 2002.05.28.14.02.40; author thl; state Exp; branches; next 1.74; 1.74 date 2002.05.28.12.43.14; author thl; state Exp; branches; next 1.73; 1.73 date 2002.05.27.15.09.50; author thl; state Exp; branches; next 1.72; 1.72 date 2002.04.18.15.38.59; author thl; state Exp; branches; next 1.71; 1.71 date 2002.04.18.14.09.25; author thl; state Exp; branches; next 1.70; 1.70 date 2002.04.18.13.31.27; author thl; state Exp; branches; next 1.69; 1.69 date 2002.03.13.16.22.09; author thl; state Exp; branches; next 1.68; 1.68 date 2002.03.13.14.50.37; author thl; state Exp; branches; next 1.67; 1.67 date 2002.03.13.14.41.13; author thl; state Exp; branches; next 1.66; 1.66 date 2002.03.13.13.58.39; author thl; state Exp; branches; next 1.65; 1.65 date 2002.03.06.14.26.33; author thl; state Exp; branches; next 1.64; 1.64 date 2002.03.04.15.54.28; author thl; state Exp; branches; next 1.63; 1.63 date 2002.02.28.15.57.09; author thl; state Exp; branches; next 1.62; 1.62 date 2002.02.28.15.21.02; author thl; state Exp; branches; next 1.61; 1.61 date 2002.02.28.14.07.43; author thl; state Exp; branches; next 1.60; 1.60 date 2002.02.28.14.02.25; author thl; state Exp; branches; next 1.59; 1.59 date 2002.02.28.12.57.55; author thl; state Exp; branches; next 1.58; 1.58 date 2002.02.27.12.17.34; author thl; state Exp; branches; next 1.57; 1.57 date 2002.02.27.10.22.38; author thl; state Exp; branches; next 1.56; 1.56 date 2002.02.27.10.02.59; author thl; state Exp; branches; next 1.55; 1.55 date 2002.02.27.09.55.55; author thl; state Exp; branches; next 1.54; 1.54 date 2002.02.27.09.34.41; author thl; state Exp; branches; next 1.53; 1.53 date 2002.02.26.15.56.08; author thl; state Exp; branches; next 1.52; 1.52 date 2002.02.21.15.47.54; author thl; state Exp; branches; next 1.51; 1.51 date 2002.02.20.15.42.26; author thl; state Exp; branches; next 1.50; 1.50 date 2002.02.14.15.11.08; author thl; state Exp; branches; next 1.49; 1.49 date 2002.02.14.11.03.52; author thl; state Exp; branches; next 1.48; 1.48 date 2002.02.13.16.25.38; author thl; state Exp; branches; next 1.47; 1.47 date 2002.02.07.13.36.16; author thl; state Exp; branches; next 1.46; 1.46 date 2002.02.07.12.53.45; author thl; state Exp; branches; next 1.45; 1.45 date 2002.02.07.09.01.04; author thl; state Exp; branches; next 1.44; 1.44 date 2002.02.06.13.51.38; author thl; state Exp; branches; next 1.43; 1.43 date 2002.02.05.15.58.21; author thl; state Exp; branches; next 1.42; 1.42 date 2002.02.05.14.56.47; author thl; state Exp; branches; next 1.41; 1.41 date 2002.02.05.14.14.54; author thl; state Exp; branches; next 1.40; 1.40 date 2002.02.05.10.40.51; author thl; state Exp; branches; next 1.39; 1.39 date 2002.02.04.15.43.01; author thl; state Exp; branches; next 1.38; 1.38 date 2002.02.04.14.48.30; author thl; state Exp; branches; next 1.37; 1.37 date 2002.02.04.13.52.14; author thl; state Exp; branches; next 1.36; 1.36 date 2002.01.31.15.59.12; author thl; state Exp; branches; next 1.35; 1.35 date 2002.01.31.15.54.53; author thl; state Exp; branches; next 1.34; 1.34 date 2002.01.31.15.53.43; author thl; state Exp; branches; next 1.33; 1.33 date 2002.01.31.15.42.31; author thl; state Exp; branches; next 1.32; 1.32 date 2002.01.31.15.32.51; author thl; state Exp; branches; next 1.31; 1.31 date 2002.01.31.15.13.16; author thl; state Exp; branches; next 1.30; 1.30 date 2002.01.31.15.09.25; author thl; state Exp; branches; next 1.29; 1.29 date 2002.01.31.15.03.51; author thl; state Exp; branches; next 1.28; 1.28 date 2002.01.31.15.03.23; author thl; state Exp; branches; next 1.27; 1.27 date 2002.01.31.14.47.13; author thl; state Exp; branches; next 1.26; 1.26 date 2002.01.31.14.43.52; author thl; state Exp; branches; next 1.25; 1.25 date 2002.01.31.14.20.09; author thl; state Exp; branches; next 1.24; 1.24 date 2002.01.31.13.54.21; author thl; state Exp; branches; next 1.23; 1.23 date 2002.01.31.13.48.27; author thl; state Exp; branches; next 1.22; 1.22 date 2002.01.31.13.44.05; author thl; state Exp; branches; next 1.21; 1.21 date 2002.01.31.10.40.07; author thl; state Exp; branches; next 1.20; 1.20 date 2002.01.31.10.14.54; author thl; state Exp; branches; next 1.19; 1.19 date 2002.01.31.09.03.58; author thl; state Exp; branches; next 1.18; 1.18 date 2002.01.30.16.41.02; author thl; state Exp; branches; next 1.17; 1.17 date 2002.01.30.14.22.23; author thl; state Exp; branches; next 1.16; 1.16 date 2002.01.24.16.25.54; author thl; state Exp; branches; next 1.15; 1.15 date 2002.01.24.12.04.46; author thl; state Exp; branches; next 1.14; 1.14 date 2002.01.24.08.54.25; author thl; state Exp; branches; next 1.13; 1.13 date 2002.01.23.15.55.21; author thl; state Exp; branches; next 1.12; 1.12 date 2002.01.23.14.12.52; author thl; state Exp; branches; next 1.11; 1.11 date 2002.01.22.16.09.47; author thl; state Exp; branches; next 1.10; 1.10 date 2002.01.21.16.21.16; author thl; state Exp; branches; next 1.9; 1.9 date 2002.01.17.17.01.55; author thl; state Exp; branches; next 1.8; 1.8 date 2002.01.16.14.22.14; author thl; state Exp; branches; next 1.7; 1.7 date 2002.01.16.14.19.07; author thl; state Exp; branches; next 1.6; 1.6 date 2002.01.16.09.46.52; author thl; state Exp; branches; next 1.5; 1.5 date 2002.01.15.13.04.09; author thl; state Exp; branches; next 1.4; 1.4 date 2002.01.15.13.02.20; author thl; state Exp; branches; next 1.3; 1.3 date 2002.01.14.12.23.21; author thl; state Exp; branches; next 1.2; 1.2 date 2002.01.10.10.37.38; author thl; state Exp; branches; next 1.1; 1.1 date 2002.01.09.13.54.25; author thl; state Exp; branches; next ; desc @@ 1.96 log @fix problem where ACLs could not be set due to improper assumption of C compiler operator precedence. Reported by Amos Gouaux @ text @/* ** OSSP lmtp2nntp - Mail to News Gateway ** Copyright (c) 2002-2003 Ralf S. Engelschall ** Copyright (c) 2002-2003 The OSSP Project ** Copyright (c) 2002-2003 Cable & Wireless Germany ** ** 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/tool/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_config.c: config handling */ #include #include #include #include #include #include /* third party (included) */ #include "lmtp2nntp_argz.h" /* third party (linked in) */ #include "l2.h" #include "pcre.h" #include "popt.h" #include "str.h" #include "var.h" #include "val.h" /* 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(WITH_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 "lmtp2nntp_common.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 l2_result_t formatter_prefix(l2_context_t *_ctx, const char id, const char *param, char *bufptr, size_t bufsize, size_t *buflen, va_list *ap) { lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx->vp; if ((ctx->msg != NULL) && (ctx->msg->cpFid != NULL)) { sprintf(bufptr, "%s: ", ctx->msg->cpFid); *buflen = strlen(bufptr); } else *buflen = 0; return L2_OK; } static var_syntax_t syntax_regex = { '\\', /* escape */ '$', /* varinit */ '{', /* startdelim */ '}', /* enddelim */ NUL, /* startindex */ NUL, /* endindex */ NUL, /* current_index */ "0-9" /* namechars */ }; lmtp2nntp_config_rc_t config_context(lmtp2nntp_t *ctx) { lmtp2nntp_config_rc_t rc = CONFIG_OK; ex_t ex; optionval_t *ov; sa_rc_t sa_rc; /* create L2 environment */ if (l2_env_create(&ctx->l2_env) != L2_OK) { fprintf(stderr, "%s:Error: failed to create L2 environment\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_env_levels(ctx->l2_env, L2_LEVEL_ALL, L2_LEVEL_NONE) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to set global logging level defaults\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_env_formatter(ctx->l2_env, 'P', formatter_prefix, &ctx->ctx) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to register prefix formatter\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_env_formatter(ctx->l2_env, 'D', l2_util_fmt_dump, NULL) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to register dump formatter\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_env_formatter(ctx->l2_env, 'S', l2_util_fmt_string, NULL) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to register string formatter\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_env_formatter(ctx->l2_env, 'm', l2_util_fmt_errno, NULL) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to register errno formatter\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (val_get(ctx->val, "option.l2spec", &ov) != VAL_OK) { fprintf(stderr, "%s:Error: (internal) config did not register 'l2spec' option\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (ov->data.s != NULL) { l2_channel_t *ch; if (l2_env_handler(ctx->l2_env, &l2_handler_var) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to register \"%s\" handler \n", ctx->progname, l2_handler_var.name); CU(CONFIG_ERR_LOG); } if ((l2_channel_create(&ctx->l2, ctx->l2_env, l2_handler_var.name)) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to create \"%s\" channel\n", ctx->progname, l2_handler_var.name); CU(CONFIG_ERR_LOG); } if ((l2_channel_configure(ctx->l2, "", ctx->config_varctx)) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to configure \"%s\" channel\n", ctx->progname, l2_handler_var.name); CU(CONFIG_ERR_LOG); } if ((l2_spec(&ch, ctx->l2_env, "%s", ov->data.s)) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to create stream\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_channel_link(ctx->l2, L2_LINK_CHILD, ch, NULL) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to link child channel\n", ctx->progname); CU(CONFIG_ERR_LOG); } if (l2_channel_open(ctx->l2) != L2_OK) { fprintf(stderr, "%s:Error: logging failed to open channel stream\n", ctx->progname); CU(CONFIG_ERR_LOG); } } /* from this point on logging is up and running and fprintf(stderr, ...) * should not be used in the remainder of the program flow. */ logbook(ctx->l2, L2_LEVEL_NOTICE, "startup, version %s", lmtp2nntp_version.v_gnu); /* --version FLAG */ try { if ( (val_get(ctx->val, "option.version", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.f < 0) || (ov->ndata == 1 && ov->data.f > 1) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--version = %d", ov->data.f); if (ov->data.f == 1) { fprintf(stdout, "%s\n", lmtp2nntp_version.v_gnu); CU(CONFIG_OK_DRY); } } catch (ex) rethrow; /* --childsmax SINGLE */ try { if ( (val_get(ctx->val, "option.childsmax", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--childsmax = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_childsmax = atoi(ov->data.s)) <= 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --childsmax, number (%d) out of range", ctx->option_childsmax); throw(0,0,0); } } catch (ex) { rethrow; } /* --daemonize FLAG */ try { if ( (val_get(ctx->val, "option.daemonize", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.f < 0) || (ov->ndata == 1 && ov->data.f > 1) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--daemonize = %d", ov->data.f); ctx->option_daemon = ov->data.f == 1 ? TRUE : FALSE; } catch (ex) rethrow; /* --kill FLAG */ try { if ( (val_get(ctx->val, "option.kill", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.f < 0) || (ov->ndata == 1 && ov->data.f > 1) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--kill = %d", ov->data.f); ctx->option_killflag = ov->data.f == 1 ? TRUE : FALSE; } catch (ex) rethrow; /* --pidfile SINGLE */ try { if ( (val_get(ctx->val, "option.pidfile", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--pidfile = \"%s\"", ov->data.s); if (ov->ndata == 1) ctx->option_pidfile = strdupex(ov->data.s); } catch (ex) rethrow; /* --acl MULTI */ try { char *cp; int i; int somepass; if ( (val_get(ctx->val, "option.acl", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata >= 1 && ov->data.m == NULL) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_DEBUG, "ov->ndata = %d", ov->ndata); for (i = 0; i < ov->ndata; i++) logbook(ctx->l2, L2_LEVEL_TRACE, "--acl[%d] = \"%s\"", i, (ov->data.m)[i]); /* check if only blocking ACLs exist */ somepass = FALSE; if (ov->ndata >= 1) { for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; if (cp[0] != '!') { somepass = TRUE; break; } } } /* if only blocking ACLs exist, reserve space for two additional pass-through wildcards */ ctx->pacl = (struct acl *)mallocex((ov->ndata + (somepass ? 0 : 2 )) * sizeof(struct acl)); if (ov->ndata >= 1) { for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; logbook(ctx->l2, L2_LEVEL_DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); if (cp[0] == '!') { ctx->pacl[i].acl = strdup(cp + 1); ctx->pacl[i].not = TRUE; } else { ctx->pacl[i].acl = strdup(cp); ctx->pacl[i].not = FALSE; } logbook(ctx->l2, L2_LEVEL_DEBUG, "ctx->pacl[%d].not = %s", i, ctx->pacl[i].not == TRUE ? "TRUE" : "FALSE"); logbook(ctx->l2, L2_LEVEL_DEBUG, "ctx->pacl[%d].acl = %s", i, ctx->pacl[i].acl); if ((cp = strrchr(ctx->pacl[i].acl, '/')) != NULL) *cp++ = NUL; else cp = "-1"; ctx->pacl[i].prefixlen = atoi(cp); logbook(ctx->l2, L2_LEVEL_DEBUG, "ctx->pacl[%d].prefixlen = %d", i, ctx->pacl[i].prefixlen); if ((sa_rc = sa_addr_create(&(ctx->pacl[i].saa))) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create address (internal) failed with \"%s\" (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing address (%s) failed with \"%s\" (%d) %", ctx->pacl[i].acl, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(sa_rc)); throw(0,0,0); } } ctx->nacl = i; } /* if only blocking ACLs exist, append a wildcard pass-through for IPv4 */ if (!somepass) { i = ctx->nacl; ctx->pacl[i].acl = "0.0.0.0"; ctx->pacl[i].not = FALSE; ctx->pacl[i].prefixlen = 0; if ((sa_rc = sa_addr_create(&ctx->pacl[i].saa)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv4 pass-through address (internal) failed with \"%s\" (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv4 pass-through address (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv4 pass-through address (%s) failed with \"%s\" (%d) %s", ctx->pacl[i].acl, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv4 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(sa_rc)); throw(0,0,0); } i++; ctx->nacl = i; } /* if only blocking ACLs exist, append a wildcard pass-through for IPv6 */ if (!somepass) { i = ctx->nacl; ctx->pacl[i].acl = "[::]"; ctx->pacl[i].not = FALSE; ctx->pacl[i].prefixlen = 0; if ((sa_rc = sa_addr_create(&ctx->pacl[i].saa)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv6 pass-through address (internal) failed with \"%s\" (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv6 pass-through address (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv6 pass-through address (%s) failed with \"%s\" (%d) %s", ctx->pacl[i].acl, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv6 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(sa_rc)); throw(0,0,0); } i++; ctx->nacl = i; } } catch (ex) rethrow; /* --bind SINGLE */ try { char *cp; if ( (val_get(ctx->val, "option.bind", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--bind = \"%s\"", ov->data.s); if (ov->ndata == 1) { /* dash means stdio */ if (strcmp(ov->data.s, "-") != 0) { if ((sa_rc = sa_create(&ctx->saServerbind)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\" (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_addr_create(&ctx->saaServerbind)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, create address (internal) failed with \"%s\", (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } /* slash means UNIX socket */ if (ov->data.s[0] == '/') { char *cpPath; char *cpPerm; int nPerm; int n; int i; cpPath = strdup(ov->data.s); cpPerm = NULL; nPerm = -1; if ((cpPerm = strrchr(cpPath, ':')) != NULL) { *cpPerm++ = '\0'; nPerm = 0; for (i = 0; i < 4 && cpPerm[i] != '\0'; i++) { if (!isdigit((int)cpPerm[i])) { nPerm = -1; break; } n = cpPerm[i] - '0'; if (n > 7) { nPerm = -1; break; } nPerm = ((nPerm << 3) | n); } if (nPerm == -1 || cpPerm[i] != '\0') { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, invalid permissions \"%s\"", cpPerm); throw(0,0,0); } } if ((sa_rc = sa_addr_u2a(ctx->saaServerbind, "unix:%s", cpPath)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\" (%d) %s", cpPath, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\" (%d) %s", cpPath, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(sa_rc)); throw(0,0,0); } if (nPerm != -1) { if (chmod(cpPath, nPerm) == -1) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"", cpPath, nPerm, strerror(errno)); throw(0,0,0); } } if (getuid() == 0 && getuid() != ctx->option_uid) { if (chown(cpPath, ctx->option_uid, -1) == -1) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, chown (%s, %d) failed with \"%s\"", cpPath, ctx->option_uid, strerror(errno)); throw(0,0,0); } } free(cpPath); } /* otherwise assume INET socket */ else { cp = ov->data.s; if (strrchr(cp, ':') == NULL) cp = str_concat(cp, ":24", NULL); /* http://www.iana.org/assignments/port-numbers (and names) */ else cp = str_concat(cp, NULL); /* prepare for free() */ logbook(ctx->l2, L2_LEVEL_DEBUG, "data.s = \"%s\", cp = \"%s\"", ov->data.s, cp); if ((sa_rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", cp)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\" (%d) %s", ov->data.s, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\" (%d) %s", ov->data.s, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); throw(0,0,0); } free(cp); } /* for either sockets */ if ((sa_rc = sa_listen(ctx->saServerbind, -1)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, listen (%s) failed with \"%s\" (%d) %s", ov->data.s, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); throw(0,0,0); } } } } catch (ex) rethrow; /* --client SINGLE */ try { if ( (val_get(ctx->val, "option.client", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--client = \"%s\"", ov->data.s); if (ov->ndata == 1) { if ((sa_rc = sa_addr_create(&ctx->saaClientbind)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, create address (internal) failed with \"%s\" (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_addr_u2a(ctx->saaClientbind, (strchr(ov->data.s, ':') == NULL) ? "inet://%s:0" : "inet://%s", ov->data.s)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\" (%d) %s", ov->data.s, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); throw(0,0,0); } } } catch (ex) rethrow; /* --destination MULTI */ try { char *cp; int i; if ( (val_get(ctx->val, "option.destination", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata >= 1 && ov->data.m == NULL) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_DEBUG, "ov->ndata = %d", ov->ndata); for (i = 0; i < ov->ndata; i++) logbook(ctx->l2, L2_LEVEL_TRACE, "--destination[%d] = \"%s\"", i, (ov->data.m)[i]); if (ov->ndata >= 1) { if ((ctx->pns = (struct ns *)malloc(ov->ndata * sizeof(struct ns))) == NULL) throw(0,0,0); for (i = 0; i < ov->ndata;) { cp = (ov->data.m)[i]; if (strrchr(cp, ':') == NULL) cp = str_concat(cp, ":nntp", NULL); /* http://www.iana.org/assignments/port-numbers (and names) */ else cp = str_concat(cp, NULL); /* prepare for free() */ logbook(ctx->l2, L2_LEVEL_DEBUG, "(data.m)[%d] = \"%s\", cp = \"%s\"", i, (ov->data.m)[i], cp); if ((sa_rc = sa_addr_create(&ctx->pns[i].saa)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, create address (internal) failed with \"%s\" (%d) %s", sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_addr_u2a(ctx->pns[i].saa, "inet://%s", cp)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, parsing host address (%s) failed with \"%s\", (%d) %s", cp, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp, sa_error(sa_rc)); throw(0,0,0); } if ((sa_rc = sa_create(&ctx->pns[i].sa)) != SA_OK) { if (sa_rc == SA_ERR_SYS) logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\" (%d) %s", cp, sa_error(sa_rc), errno, strerror(errno)); else logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp, sa_error(sa_rc)); throw(0,0,0); } ctx->pns[i].nntp = NULL; ctx->pns[i].rc = NNTP_OK; ctx->pns[i].l2 = ctx->l2; free(cp); ctx->nns = ++i; } } } catch (ex) rethrow; /* --groupmode SINGLE */ try { if ( (val_get(ctx->val, "option.groupmode", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--groupmode = \"%s\"", ov->data.s); if (ov->ndata == 1) { if (strcasecmp(ov->data.s, "arg") == 0) ctx->option_groupmode = GROUPMODE_ARG; else if (strcasecmp(ov->data.s, "envelope") == 0) ctx->option_groupmode = GROUPMODE_ENVELOPE; else if (strcasecmp(ov->data.s, "header") == 0) ctx->option_groupmode = GROUPMODE_HEADER; else { logbook(ctx->l2, L2_LEVEL_ERROR, "option --groupmode, invalid mode (%s)", ov->data.s); throw(0,0,0); } } } catch (ex) rethrow; /* --headerrule MULTI */ { volatile headerrule_t *hrNew = NULL; /* declare and initialize variables which might have resources allocated that need to be cleaned up when an exception is caught */ try { char *cp, *cpP; int n; int i; headerrule_t *hrI; headerrule_t *hrP; const char *cpError; int iError; if ( (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata >= 1 && ov->data.m == NULL) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_DEBUG, "ov->ndata = %d", ov->ndata); for (i = 0; i < ov->ndata; i++) logbook(ctx->l2, L2_LEVEL_TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]); if (ov->ndata >= 1) { for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; logbook(ctx->l2, L2_LEVEL_DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); hrNew = (headerrule_t *)mallocex(sizeof(headerrule_t)); hrNew->next = NULL; hrNew->pri = 500; /* default priority */ hrNew->regex = NULL; hrNew->name = NULL; hrNew->val = NULL; hrNew->pcreRegex = NULL; hrNew->pcreExtra = NULL; /* priority */ cpP = cp; if ((cp = strchr(cp, ':')) == NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } cp++; n = cp - cpP; if (n >= 2) /* mandatory colon and at least one more char */ hrNew->pri = atoi(cpP); /* regex */ cpP = cp; if ((cp = strchr(cp, ':')) == NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } cp++; n = cp - cpP; if (n >= 2) /* mandatory colon and at least one more char */ hrNew->regex = str_dupex(cpP, n); /* header */ cpP = cp; if ((cp = strchr(cp, ':')) == NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } cp++; n = cp - cpP; if (n == 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, header (%s) missing", (ov->data.m)[i]); throw(0,0,0); } hrNew->name = str_dupex(cpP, n); /* value */ cpP = cp; n = strlen(cpP); if (n >= 1) hrNew->val = str_dupex(cpP, n); if (hrNew->regex != NULL) { /* compile regular expression into finite state machine and optimize */ if ((hrNew->pcreRegex = pcre_compile(hrNew->regex, PCRE_CASELESS, &cpError, &iError, NULL)) == NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, regex (%s) failed at pos %d with %s", hrNew->regex, iError, cpError); throw(0,0,0); } hrNew->pcreExtra = pcre_study(hrNew->pcreRegex, 0, &cpError); if (cpError != NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, regex optimization failed with %s", cpError); throw(0,0,0); } } if (ctx->option_firstheaderrule == NULL) ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* first */ else { for (hrP = NULL, hrI = ctx->option_firstheaderrule; hrI != NULL && hrI->pri <= hrNew->pri; hrP = hrI, hrI = hrI->next); if (hrI != NULL) hrNew->next = hrI; /* insert */ if (hrP != NULL) hrP->next = (headerrule_t *)hrNew; /* append */ else ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* new first */ } hrNew = NULL; /* release cleanup responsibility */ } /* establish variable expansion context */ { var_rc_t rc2; if ((rc2 = var_create(&ctx->config_varregex)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, create regex context failed with %s (%d)", var_strerror(ctx->config_varregex, rc2, &cp) == VAR_OK ? cp : "Unknown Error", rc2); throw(0,0,0); } if ((rc2 = var_config(ctx->config_varregex, VAR_CONFIG_SYNTAX, &syntax_regex)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, config regex context failed with %s (%d)", var_strerror(ctx->config_varregex, rc2, &cp) == VAR_OK ? cp : "Unknown Error", rc2); throw(0,0,0); } } } } cleanup { if (hrNew != NULL) { if (hrNew->pcreExtra != NULL) free(hrNew->pcreExtra); if (hrNew->pcreRegex != NULL) free(hrNew->pcreRegex); if (hrNew->val != NULL) freeex(hrNew->val); if (hrNew->name != NULL) freeex(hrNew->name); if (hrNew->regex != NULL) freeex(hrNew->regex); freeex((headerrule_t *)hrNew); } } catch (ex) rethrow; } /* --mailfrom SINGLE */ try { char *cp; if ( (val_get(ctx->val, "option.mailfrom", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--mailfrom = \"%s\"", ov->data.s); if (ov->ndata == 1) { ctx->option_mailfrom = strdup(ov->data.s); /* protect ourselfs from the substitution of backreferences. * Missing varargs would cause segfaults. Rewrite capturing * brackets to clustering syntax. Use poor man's s///g * simulator as current str library doesn't support global * substitution */ while (str_parse(ctx->option_mailfrom, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) { free(ctx->option_mailfrom); ctx->option_mailfrom = cp; } if (str_parse("<>", ctx->option_mailfrom) == -1) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --mailfrom, illegal regex (%s)", ctx->option_mailfrom); throw(0,0,0); } } } catch (ex) rethrow; /* --nodename SINGLE */ try { if ( (val_get(ctx->val, "option.nodename", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--nodename = \"%s\"", ov->data.s); if (ov->ndata == 1) { ctx->option_nodename = strdupex(ov->data.s); } else { struct utsname name; if (uname(&name) == -1) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --nodename, uname() failed %m"); throw(0,0,0); } ctx->option_nodename = strdupex(name.nodename); } } catch (ex) rethrow; /* --operationmode SINGLE */ try { char *cp; if ( (val_get(ctx->val, "option.operationmode", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--operationmode = \"%s\"", ov->data.s); if (ov->ndata == 1) { cp = strdup(ov->data.s); if (strcasecmp(cp, "post") == 0) ctx->option_operationmode = OPERATIONMODE_POST; else if (strcasecmp(cp, "feed") == 0) ctx->option_operationmode = OPERATIONMODE_FEED; else { ctx->option_operationmode = OPERATIONMODE_FAKE; if (strlen(cp) != 9) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --operationmode, invalid length (%s)", cp); throw(0,0,0); } if (cp[3] != '/') { logbook(ctx->l2, L2_LEVEL_ERROR, "option --operationmode, missing slash (%s)", cp); throw(0,0,0); } cp[3] = NUL; ctx->option_operationmodefakestatus = &cp[0]; ctx->option_operationmodefakedsn = &cp[4]; if ( strlen(ctx->option_operationmodefakestatus) != 3 || !isdigit((int)ctx->option_operationmodefakestatus[0]) || !isdigit((int)ctx->option_operationmodefakestatus[1]) || !isdigit((int)ctx->option_operationmodefakestatus[2]) ) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --operationmode, invalid status code (%s)", cp); throw(0,0,0); } if ( (strlen(ctx->option_operationmodefakedsn) != 5) || !isdigit((int)ctx->option_operationmodefakedsn[0]) || (ctx->option_operationmodefakedsn[1] != '.') || !isdigit((int)ctx->option_operationmodefakedsn[2]) || (ctx->option_operationmodefakedsn[3] != '.') || !isdigit((int)ctx->option_operationmodefakedsn[4]) || (ctx->option_operationmodefakedsn[0] != ctx->option_operationmodefakestatus[0]) ) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --operationmode, invalid dsn code (%s)", cp); throw(0,0,0); } } } else { logbook(ctx->l2, L2_LEVEL_ERROR, "option --operationmode, is mandatory but neither given nor preset (internal)"); throw(0,0,0); } } catch (ex) rethrow; /* --restrictheader SINGLE */ try { char *cp; if ( (val_get(ctx->val, "option.restrictheader", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--restrictheader = \"%s\"", ov->data.s); if (ov->ndata == 1) { ctx->option_restrictheader = strdup(ov->data.s); /* protect ourselfs from the substitution of backreferences. * Missing varargs would cause segfaults. Rewrite capturing * brackets to clustering syntax. Use poor man's s///g * simulator as current str library doesn't support global * substitution */ while (str_parse(ctx->option_restrictheader, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) { free(ctx->option_restrictheader); ctx->option_restrictheader = cp; } if (str_parse("<>", ctx->option_restrictheader) == -1) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --restrictheader, illegal regex (%s)", ctx->option_restrictheader); throw(0,0,0); } } } catch (ex) rethrow; /* --size SINGLE */ try { if ( (val_get(ctx->val, "option.size", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--size = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_maxmessagesize = atoi(ov->data.s)) <= 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --size, number (%d) out of range", ctx->option_maxmessagesize); throw(0,0,0); } } catch (ex) rethrow; /* --timeoutlmtp SINGLE */ try { int i; if ( (val_get(ctx->val, "option.timeoutlmtp", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutlmtp= \"%s\"", ov->data.s); if (ov->ndata == 1) { if ((i = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutlmtp, number (%d) out of range", i); throw(0,0,0); } ctx->option_timeout_lmtp_accept = i; ctx->option_timeout_lmtp_read = i; ctx->option_timeout_lmtp_write = i; } } catch (ex) rethrow; /* --timeoutlmtpaccept SINGLE */ try { if ( (val_get(ctx->val, "option.timeoutlmtpaccept", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutlmtpaccept = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_timeout_lmtp_accept = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutlmtpaccept, number (%d) out of range", ctx->option_timeout_lmtp_accept); throw(0,0,0); } } catch (ex) rethrow; /* --timeoutlmtpread SINGLE */ try { if ( (val_get(ctx->val, "option.timeoutlmtpread", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutlmtpread = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_timeout_lmtp_read = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutlmtpread, number (%d) out of range", ctx->option_timeout_lmtp_read); throw(0,0,0); } } catch (ex) rethrow; /* --timeoutlmtpwrite SINGLE */ try { if ( (val_get(ctx->val, "option.timeoutlmtpwrite", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutlmtpwrite = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_timeout_lmtp_write = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutlmtpwrite, number (%d) out of range", ctx->option_timeout_lmtp_write); throw(0,0,0); } } catch (ex) rethrow; /* --timeoutnntp SINGLE */ try { int i; if ( (val_get(ctx->val, "option.timeoutnntp", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutnntp= \"%s\"", ov->data.s); if (ov->ndata == 1) { if ((i = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutnntp, number (%d) out of range", i); throw(0,0,0); } ctx->option_timeout_nntp_connect = i; ctx->option_timeout_nntp_read = i; ctx->option_timeout_nntp_write = i; } } catch (ex) rethrow; /* --timeoutnntpconnect SINGLE */ try { if ( (val_get(ctx->val, "option.timeoutnntpconnect", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutnntpconnect = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_timeout_nntp_connect = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutnntpconnect, number (%d) out of range", ctx->option_timeout_nntp_connect); throw(0,0,0); } } catch (ex) rethrow; /* --timeoutnntpread SINGLE */ try { if ( (val_get(ctx->val, "option.timeoutnntpread", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutnntpread = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_timeout_nntp_read = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutnntpread, number (%d) out of range", ctx->option_timeout_nntp_read); throw(0,0,0); } } catch (ex) rethrow; /* --timeoutnntpwrite SINGLE */ try { if ( (val_get(ctx->val, "option.timeoutnntpwrite", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--timeoutnntpwrite = \"%s\"", ov->data.s); if (ov->ndata == 1) if ((ctx->option_timeout_nntp_write = atoi(ov->data.s)) < 0) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --timeoutnntpwrite, number (%d) out of range", ctx->option_timeout_nntp_write); throw(0,0,0); } } catch (ex) rethrow; /* --user SINGLE */ try { struct passwd *sPasswd; if ( (val_get(ctx->val, "option.user", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.s == NULL) || (ov->ndata > 1) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_TRACE, "--user = \"%s\"", ov->data.s); if (ov->ndata == 1) { if (isdigit((int)ov->data.s[0])) { if ((sPasswd = getpwuid((uid_t)atoi(ov->data.s))) == NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --user, uid (%s) not found", ov->data.s); throw(0,0,0); } } else { if ((sPasswd = getpwnam(ov->data.s)) == NULL) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --user, name (%s) not found", ov->data.s); throw(0,0,0); } } ctx->option_uid = sPasswd->pw_uid; } } catch (ex) rethrow; /* --newsgroup MULTI */ try { char *cp; int i; if ( (val_get(ctx->val, "option.newsgroup", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata >= 1 && ov->data.m == NULL) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_DEBUG, "ov->ndata = %d", ov->ndata); for (i = 0; i < ov->ndata; i++) logbook(ctx->l2, L2_LEVEL_TRACE, "--newsgroup[%d] = \"%s\"", i, (ov->data.m)[i]); if (ov->ndata >= 1) { for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; logbook(ctx->l2, L2_LEVEL_DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); argz_add(&ctx->azGroupargs, &ctx->asGroupargs, cp); } } } catch (ex) rethrow; /* --testfile MULTI */ try { char *cp; int i; char *cpBuf = NULL; if ( (val_get(ctx->val, "option.testfile", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata >= 1 && ov->data.m == NULL) ) throw(0,0,0); logbook(ctx->l2, L2_LEVEL_DEBUG, "ov->ndata = %d", ov->ndata); for (i = 0; i < ov->ndata; i++) logbook(ctx->l2, L2_LEVEL_TRACE, "--testfile[%d] = \"%s\"", i, (ov->data.m)[i]); if (ov->ndata >= 1) { for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; logbook(ctx->l2, L2_LEVEL_DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); { const char *filename = cp; struct stat sb; volatile int fd = -1; /* 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"); 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); rethrow; } } { volatile msg_t *msg = NULL; msg_rc_t rc2; try { ctx->msgcount++; if ((msg = msg_create(ctx->prival)) == NULL) throw(0, 0, "msg_create"); msg->l2 = ctx->l2; msg->cpMsg = cpBuf; if ((rc2 = msg_split((msg_t *)msg)) != MSG_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "Error splitting message: %s", msg_error(rc2)); throw(0, 0, "msg_split"); } msg_headermatrixbuildup((msg_t *)msg); ctx->msg = (msg_t *)msg; headerrewrite(ctx); msg_headermatrixteardwn((msg_t *)msg); argz_add(&((msg_t *)msg)->azNewsgroups, &((msg_t *)msg)->asNewsgroups, "invalid.test"); if ((rc2 = msg_join((msg_t *)msg)) != MSG_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "Error joining message: %s", msg_error(rc2)); throw(0, 0, "msg_join"); } printf("%s", msg->cpMsg); } cleanup { if (msg != NULL) msg_destroy((msg_t *)msg); ctx->msg = NULL; } catch (ex) { rethrow; } } } CU(CONFIG_OK_DRY); } } catch (ex) rethrow; CU(CONFIG_OK); CUS: return rc; } @ 1.95 log @print errno and associated message whenever sa returns SA_ERR_SYS @ text @d289 1 a289 1 ctx->pacl = (struct acl *)mallocex((ov->ndata + somepass ? 0 : 2 ) * sizeof(struct acl)); @ 1.94 log @default Serverbind to tcp port 24; align two related logbook calls @ text @d312 4 a315 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(sa_rc)); d319 4 a322 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(sa_rc)); d336 4 a339 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv4 pass-through address (internal) failed with \"%s\"", sa_error(sa_rc)); d343 4 a346 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv4 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(sa_rc)); d360 4 a363 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv6 pass-through address (internal) failed with \"%s\"", sa_error(sa_rc)); d367 4 a370 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv6 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(sa_rc)); d395 4 a398 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(sa_rc)); d402 4 a405 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(sa_rc)); d440 4 a443 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(sa_rc)); d447 4 a450 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(sa_rc)); d476 4 a479 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); d483 4 a486 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); d493 3 d497 1 a497 1 throw(0,0,0); d516 4 a519 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(sa_rc)); d525 4 a528 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(sa_rc)); d559 4 a562 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(sa_rc)); d566 4 a569 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp, sa_error(sa_rc)); d573 4 a576 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp, sa_error(sa_rc)); @ 1.93 log @finish DMalloc support @ text @d364 2 d439 7 a445 1 if ((sa_rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", ov->data.s)) != SA_OK) { d453 1 a507 1 logbook(ctx->l2, L2_LEVEL_DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); d512 1 @ 1.92 log @plug two memory leaks @ text @d61 1 a61 1 #if defined(HAVE_DMALLOC_H) && defined(DMALLOC) @ 1.91 log @defeat double free(3) @ text @d289 1 a289 1 if ((ctx->pacl = (struct acl *)malloc((ov->ndata + somepass ? 0 : 2 ) * sizeof(struct acl))) == NULL) throw(0,0,0); @ 1.90 log @remove trailing whitespaces from source tree @ text @d257 1 a257 1 ctx->option_pidfile = ov->data.s; @ 1.89 log @Apply the standard OSSP copyright header, document ASCII art and fix URL to lmtp2nntp homepage. @ text @d85 1 a85 1 static l2_result_t d90 1 a90 1 d101 4 a104 4 '\\', /* escape */ '$', /* varinit */ '{', /* startdelim */ '}', /* enddelim */ d471 2 a472 2 if ((sa_rc = sa_addr_u2a(ctx->saaClientbind, (strchr(ov->data.s, ':') == NULL) ? "inet://%s:0" : "inet://%s", d585 1 a585 1 d861 1 a861 1 @ 1.88 log @Implement the decision from yesterday evening and finally rename fixme.h to lmtp2nntp_common.h because there is little chance this this stuff ever can be moved into more local source contexts. @ text @a0 1 d2 4 a5 2 ** Copyright (c) 2001-2002 The OSSP Project ** Copyright (c) 2001-2002 Cable & Wireless Deutschland d9 1 a9 1 ** It can be found at http://www.ossp.org/pkg/lmtp2nntp/. @ 1.87 log @Fix a big security hole: the l2_spec() is a varargs function which gets a format string and variable arguments. In case only a fixed string is used we have to use "%s" as the format string or else "%x" in the string is treated like a formatter (and hence cause a segfault or whatever else if it tries to fetch args from the stack). This especially also no longer requires the formatting constricts to be written %%X... @ text @d68 1 a68 1 #include "fixme.h" @ 1.86 log @remove all exit(3) but those within daemonizer and signal handler @ text @d161 1 a161 1 if ((l2_spec(&ch, ctx->l2_env, ov->data.s)) != L2_OK) { @ 1.85 log @decide to keep lib_sa out of lmtp2nntp_option.c @ text @d110 1 a110 1 void config_context(lmtp2nntp_t *ctx) d112 1 d115 1 a115 1 int rc; d120 1 a120 1 CU(ERR_EXECUTION); d124 1 a124 1 CU(ERR_EXECUTION); d128 1 a128 1 CU(ERR_EXECUTION); d132 1 a132 1 CU(ERR_EXECUTION); d136 1 a136 1 CU(ERR_EXECUTION); d140 1 a140 1 CU(ERR_EXECUTION); d144 1 a144 1 CU(ERR_EXECUTION); d151 1 a151 1 CU(ERR_EXECUTION); d153 1 a153 1 if ((rc = l2_channel_create(&ctx->l2, ctx->l2_env, l2_handler_var.name)) != L2_OK) { d155 1 a155 1 CU(ERR_EXECUTION); d157 1 a157 1 if ((rc = l2_channel_configure(ctx->l2, "", ctx->config_varctx)) != L2_OK) { d159 1 a159 1 CU(ERR_EXECUTION); d161 1 a161 1 if ((rc = l2_spec(&ch, ctx->l2_env, ov->data.s)) != L2_OK) { d163 1 a163 1 CU(ERR_EXECUTION); d167 1 a167 1 CU(ERR_EXECUTION); d171 1 a171 1 CU(ERR_EXECUTION); d191 1 a191 1 exit(0); /* FIXME */ d310 2 a311 2 if ((rc = sa_addr_create(&(ctx->pacl[i].saa))) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(rc)); d314 2 a315 2 if ((rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d328 2 a329 2 if ((rc = sa_addr_create(&ctx->pacl[i].saa)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv4 pass-through address (internal) failed with \"%s\"", sa_error(rc)); d332 2 a333 2 if ((rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv4 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d346 2 a347 2 if ((rc = sa_addr_create(&ctx->pacl[i].saa)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, create IPv6 pass-through address (internal) failed with \"%s\"", sa_error(rc)); d350 2 a351 2 if ((rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --acl, parsing IPv6 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d373 2 a374 2 if ((rc = sa_create(&ctx->saServerbind)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(rc)); d377 2 a378 2 if ((rc = sa_addr_create(&ctx->saaServerbind)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(rc)); d412 2 a413 2 if ((rc = sa_addr_u2a(ctx->saaServerbind, "unix:%s", cpPath)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(rc)); d416 2 a417 2 if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(rc)); d436 2 a437 2 if ((rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", ov->data.s)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d440 2 a441 2 if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d446 2 a447 2 if ((rc = sa_listen(ctx->saServerbind, -1)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d466 2 a467 2 if ((rc = sa_addr_create(&ctx->saaClientbind)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(rc)); d470 1 a470 1 if ((rc = sa_addr_u2a(ctx->saaClientbind, d473 1 a473 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d503 2 a504 2 if ((rc = sa_addr_create(&ctx->pns[i].saa)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(rc)); d507 2 a508 2 if ((rc = sa_addr_u2a(ctx->pns[i].saa, "inet://%s", cp)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp, sa_error(rc)); d511 2 a512 2 if ((rc = sa_create(&ctx->pns[i].sa)) != SA_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp, sa_error(rc)); d1133 1 a1133 1 exit(0); /* FIXME */ d1138 3 a1140 2 CUS: return; @ 1.84 log @this is the official name and fair enough as a default @ text @d507 1 a507 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /* FIXME again, option vs. config */, sa_error(rc)); d511 1 a511 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /* FIXME again, option vs. config */, sa_error(rc)); @ 1.83 log @no problem here, option.destionation can be queried successfully @ text @d499 1 a499 1 cp = str_concat(cp, ":nntp", NULL); /* FIXME is this a config var/val? */ @ 1.82 log @it works but don't confuse correct -l aka --l2spec with wrong -l2spec @ text @a176 1 /* logbook(ctx->l2, L2_LEVEL_NOTICE, "FIXME>>>${option.destination[0]}<<>>${option.destination[1]}<<<"); */ @ 1.81 log @it feeds ctx->config_varctx into lmtp2nntp_l2.c:hook_configure() @ text @a159 1 /* FIXME this is cut off on command line!? fprintf(stderr, "DEBUG: ov->data.s = \"%s\"\n", ov->data.s); */ @ 1.80 log @bump version for release @ text @a155 1 //FIXME rse!20020717 this l2_channel_configure call is currently a dummy! What is it used for? @ 1.79 log @errno formatter is now part of l2 @ text @d156 1 @ 1.78 log @get rid of all warnings under gcc 3.1 @ text @a98 9 static l2_result_t formatter_errno(l2_context_t *_ctx, const char id, const char *param, char *bufptr, size_t bufsize, size_t *buflen, va_list *ap) { sprintf(bufptr, "(%d) %s", errno, strerror(errno)); *buflen = strlen(bufptr); return L2_OK; } d137 1 a137 1 if (l2_env_formatter(ctx->l2_env, 'm', formatter_errno, NULL) != L2_OK) { @ 1.77 log @FIXMEs reviewed @ text @d169 1 a169 1 //FIXME this is cut off on command line!? fprintf(stderr, "DEBUG: ov->data.s = \"%s\"\n", ov->data.s); d187 1 a187 1 //logbook(ctx->l2, L2_LEVEL_NOTICE, "FIXME>>>${option.destination[0]}<<>>${option.destination[1]}<<<"); d201 1 a201 1 exit(0); //FIXME d510 1 a510 1 cp = str_concat(cp, ":nntp", NULL); //FIXME is this a config var/val? d518 1 a518 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); d522 1 a522 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); d563 1 a563 1 volatile headerrule_t *hrNew = NULL; // declare and initialize variables which might have resources allocated that need to be cleaned up when an exception is caught d664 1 a664 1 var_rc_t rc; d666 2 a667 2 if ((rc = var_create(&ctx->config_varregex)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, create regex context failed with %s (%d)", var_strerror(ctx->config_varregex, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d670 2 a671 2 if ((rc = var_config(ctx->config_varregex, VAR_CONFIG_SYNTAX, &syntax_regex)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, config regex context failed with %s (%d)", var_strerror(ctx->config_varregex, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1092 1 a1092 1 //ex_t ex; d1111 1 a1111 1 msg_rc_t rc; d1118 2 a1119 2 if ((rc = msg_split((msg_t *)msg)) != MSG_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "Error splitting message: %s", msg_error(rc)); d1127 2 a1128 2 if ((rc = msg_join((msg_t *)msg)) != MSG_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "Error joining message: %s", msg_error(rc)); d1143 1 a1143 1 exit(0); //FIXME @ 1.76 log @copy'n'paste bug @ text @d1126 1 a1126 1 argz_add(&((msg_t *)msg)->azNewsgroups, &((msg_t *)msg)->asNewsgroups, "invalid.tst"); //FIXME d1131 1 a1131 1 printf("%s", msg->cpMsg); //FIXME @ 1.75 log @remove debugging code blocks @ text @d1129 1 a1129 1 throw(0, 0, "msg_split"); @ 1.74 log @rename @ text @a1108 1 //printf("DEBUG: *** 1 *** file as it was just read in ***\n%s***\n", cpBuf); a1121 9 {//FIXME char *cp; cp = NULL; logbook(msg->l2, L2_LEVEL_DEBUG, "FIXME trace #20"); while ((cp = argz_next(msg->azHeaders, msg->asHeaders, cp)) != NULL) { logbook(msg->l2, L2_LEVEL_DEBUG, "header=\"%s\"", cp); } logbook(msg->l2, L2_LEVEL_DEBUG, "FIXME trace #21"); } a1125 9 {//FIXME char *cp; cp = NULL; logbook(msg->l2, L2_LEVEL_DEBUG, "FIXME trace #30"); while ((cp = argz_next(msg->azHeaders, msg->asHeaders, cp)) != NULL) { logbook(msg->l2, L2_LEVEL_DEBUG, "header=\"%s\"", cp); } logbook(msg->l2, L2_LEVEL_DEBUG, "FIXME trace #31"); } @ 1.73 log @createmessageid now using lib_val; added support for long nodenames @ text @d590 1 a590 1 hrNew->header = NULL; d627 1 a627 1 hrNew->header = str_dupex(cpP, n); d685 2 a686 2 if (hrNew->header != NULL) freeex(hrNew->header); @ 1.72 log @use correct context for var_strerror @ text @d31 1 d737 7 a743 2 if (strlen(ov->data.s) > sizeof(ctx->uname.nodename)-1) { logbook(ctx->l2, L2_LEVEL_ERROR, "option --nodename, name (%s) too long", ov->data.s); d746 1 a746 1 strcpy(ctx->uname.nodename, ov->data.s); d1115 2 a1116 1 if ((msg = msg_create()) == NULL) throw(0, 0, "msg_create"); @ 1.71 log @no change, only a code move @ text @d666 1 a666 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, create regex context failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d670 1 a670 1 logbook(ctx->l2, L2_LEVEL_ERROR, "option --headerrule, config regex context failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); @ 1.70 log @updated documentation, aligned and sorted source; @ text @a1163 461 static void headerdestroy(headerdata_t *hdC) { int i; if (hdC->ndata > 1) { for (i = 0; i < hdC->ndata; i++) { if (hdC->data.m[i] == NULL) break; free(hdC->data.m[i]); } free (hdC->data.m); } else if (hdC->ndata == 1) if (hdC->data.s != NULL) free(hdC->data.s); if (hdC->name != NULL) free(hdC->name); if (hdC->prev != NULL && hdC->prev->next == hdC) throw(0,0,0); if (hdC->next != NULL && hdC->next->prev == hdC) throw(0,0,0); free(hdC); } static void headerdelete(headerdata_t *hdC) { if (hdC->prev != NULL) hdC->prev->next = hdC->next; hdC->next = NULL; if (hdC->next != NULL) hdC->next->prev = hdC->prev; hdC->prev = NULL; headerdestroy(hdC); } static void headerreplace(headerdata_t *hdC, headerdata_t *hdNew) { hdNew->prev = hdC->prev; hdC->prev = NULL; hdNew->next = hdC->next; hdC->next = NULL; if (hdNew->prev != NULL) hdNew->prev->next = hdNew; if (hdNew->next != NULL) hdNew->next->prev = hdNew; headerdestroy(hdC); } static headerdata_t *headercreate(void) { ex_t ex; volatile headerdata_t *hdNew = NULL; try { hdNew = mallocex(sizeof(headerdata_t)); hdNew->prev = NULL; hdNew->next = NULL; hdNew->name = NULL; hdNew->ndata = 0; } catch (ex) { if (hdNew != NULL) free((headerdata_t *)hdNew); rethrow; } return (headerdata_t *)hdNew; } struct regex_ctx_st; //FIXME go into a header! typedef struct regex_ctx_st regex_ctx_t; struct regex_ctx_st { int nMatch; const char **acpMatch; l2_env_t *l2_env; l2_channel_t *l2; }; static var_rc_t regex_lookup( var_t *var, void *_ctx, const char *var_ptr, size_t var_len, int var_idx, const char **val_ptr, size_t *val_len, size_t *val_size) { regex_ctx_t *ctx = (regex_ctx_t *)_ctx; var_rc_t rc; char *cp; int i; logbook(ctx->l2, L2_LEVEL_DEBUG, "rgx_lookup variable \"%s\" (%d)", var_ptr, var_len); rc = VAR_ERR_UNDEFINED_VARIABLE; i = atoi(var_ptr); /* works with both '}' and '\0' termination */ if (i < ctx->nMatch) { *val_ptr = ctx->acpMatch[i]; *val_len = strlen(ctx->acpMatch[i]); *val_size = 0; rc = VAR_OK; } if (rc == VAR_OK) logbook(ctx->l2, L2_LEVEL_DEBUG, "rgx_lookup variable \"%s\" (%d) ok: result is \"%s\" (%d)", var_ptr, var_len, *val_ptr, *val_len); else logbook(ctx->l2, L2_LEVEL_DEBUG, "rgx_lookup variable \"%s\" (%d) failed: %s (%d)", var_ptr, var_len, var_strerror(var, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); return rc; } static var_rc_t operate_cb( var_t *var, void *ctx, const char *op_ptr, size_t op_len, const char *arg_ptr, size_t arg_len, const char *val_ptr, size_t val_len, char **out_ptr, size_t *out_len, size_t *out_size) { int i; if (val_ptr == NULL) { *out_ptr = ""; *out_len = 0; *out_size = 0; return VAR_OK; } if (op_len == 6 && strncmp(op_ptr, "return", 6) == 0) { *out_ptr = malloc(arg_len); *out_len = arg_len; *out_size = arg_len; memcpy(*out_ptr, arg_ptr, arg_len); return VAR_OK; } else if (op_len == 5 && strncmp(op_ptr, "upper", 5) == 0) { *out_ptr = malloc(val_len); *out_len = val_len; *out_size = val_len; for (i = 0; i < val_len; i++) (*out_ptr)[i] = (char)toupper((int)(val_ptr[i])); return VAR_OK; } else if (op_len == 5 && strncmp(op_ptr, "lower", 5) == 0) { *out_ptr = malloc(val_len); *out_len = val_len; *out_size = val_len; for (i = 0; i < val_len; i++) (*out_ptr)[i] = (char)tolower((int)(val_ptr[i])); return VAR_OK; } else return VAR_ERR_UNDEFINED_OPERATION; } void msg_headermatrixbuildup(msg_t *msg) { ex_t ex; volatile headerdata_t *hdNew = NULL; try { headerdata_t *hdI, *hdP; char *cp; cp = NULL; while ((cp = argz_next(msg->azHeaders, msg->asHeaders, cp)) != NULL) { /* for each message header */ /*FIXME we want O(1) here */ for (hdP = NULL, hdI = msg->hdFirst; hdI != NULL; hdP = hdI, hdI = hdI->next) { /* for each matrix header */ if (hdI->name == NULL || strlen(hdI->name) == 0 || hdI->ndata == 0) continue; if (strcasecmp(cp, hdI->name) == 0) break; } if (hdI == NULL) { hdNew = headercreate(); /* not found, create new */ hdNew->name = strdupex(cp); hdI = (headerdata_t *)hdNew; hdNew = NULL; /* ex cleanup */ if (hdP == NULL) msg->hdFirst = hdI; /* no previous? this is the first */ else { hdP->next = hdI; hdI->prev = hdP; } } cp = argz_next(msg->azHeaders, msg->asHeaders, cp); if (hdI->ndata == 0) { logbook(msg->l2, L2_LEVEL_DEBUG, "header=%s, currently empty", hdI->name); hdI->data.s = strdupex(cp); hdI->ndata = 1; } else if(hdI->ndata == 1) { char *cpOld; cpOld = hdI->data.s; logbook(msg->l2, L2_LEVEL_DEBUG, "header=%s, currently single valued", hdI->name); hdI->data.m = (char **)mallocex(3 * sizeof(char *)); hdI->data.m[0] = strdupex(cpOld); //FIXME hdI->data.m[1] = strdupex(cp); hdI->data.m[2] = NULL; hdI->ndata = 2; } else { logbook(msg->l2, L2_LEVEL_DEBUG, "header=%s, currently multi valued %d", hdI->name, hdI->ndata); hdI->data.m = (char **)reallocex(hdI->data.m, (hdI->ndata + 2) * sizeof(char *)); hdI->data.m[hdI->ndata++] = strdupex(cp); hdI->data.m[hdI->ndata] = NULL; } } } cleanup { if (hdNew != NULL) free((headerdata_t *)hdNew); } catch(ex) { rethrow; } } void msg_headermatrixteardwn(msg_t *msg) { ex_t ex; try { headerdata_t *hdI; if (msg->azHeaders != NULL) free(msg->azHeaders); msg->azHeaders = NULL; msg->asHeaders = 0; for (hdI = msg->hdFirst; hdI != NULL; hdI = hdI->next) { /* for each matrix header */ logbook(msg->l2, L2_LEVEL_DEBUG, "FIXME trace loop hdI=%.8lx, hI->name=\"%s\"", hdI, hdI->name); if (hdI->name == NULL || strlen(hdI->name) == 0 || hdI->ndata == 0) continue; if (hdI->ndata == 0) { logbook(msg->l2, L2_LEVEL_DEBUG, "header=%s, no data", hdI->name); } else if(hdI->ndata == 1) { /* header data is single valued */ logbook(msg->l2, L2_LEVEL_DEBUG, "header=%s, data=%s", hdI->name, hdI->data.s); argz_add(&msg->azHeaders, &msg->asHeaders, hdI->name); argz_add(&msg->azHeaders, &msg->asHeaders, hdI->data.s); } else { /* header data is multi valued */ int i; for (i = 0; i < hdI->ndata; i++) { logbook(msg->l2, L2_LEVEL_DEBUG, "header=%s[%d], data=%s", hdI->name, i, hdI->data.m[i]); argz_add(&msg->azHeaders, &msg->asHeaders, hdI->name); argz_add(&msg->azHeaders, &msg->asHeaders, hdI->data.m[i]); } } } } catch(ex) { rethrow; } } void headerrewrite(lmtp2nntp_t *ctx) { headerrule_t *hrI; headerdata_t *hdI, *hdNew; regex_ctx_t *regex_ctx; #define OVECSIZE 30 int ovec[OVECSIZE]; var_rc_t rc; char *cp; //FIXME what a bad name, it's not the returncode of this function /* short circuit in case no headerrules were set up */ if (ctx->option_firstheaderrule == NULL) return; { //FIXME debug code block int i; headerrule_t *hrD; headerdata_t *hdD; logbook(ctx->l2, L2_LEVEL_DEBUG, "FIXME trace ---------- headerrewrite() ----------"); for (hrD = ctx->option_firstheaderrule; hrD != NULL; hrD = hrD->next) logbook(ctx->l2, L2_LEVEL_DEBUG, "hrD->header=%s", hrD->header); for (hdD = ctx->msg->hdFirst; hdD != NULL; hdD = hdD->next) { if (hdD->ndata == 0) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); if (hdD->ndata == 1) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); if (hdD->ndata > 1) for (i = 0; i < hdD->ndata; i++) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); } } regex_ctx = (regex_ctx_t *)mallocex(sizeof(regex_ctx_t)); regex_ctx->nMatch = 0; regex_ctx->acpMatch = NULL; regex_ctx->l2_env = ctx->l2_env; regex_ctx->l2 = ctx->l2; if ((rc = var_config(ctx->config_varregex, VAR_CONFIG_CB_VALUE, regex_lookup, regex_ctx)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "configure regex callback failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); throw(0,0,0); } if ((rc = var_config(ctx->config_varregex, VAR_CONFIG_CB_OPERATION, operate_cb, NULL)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "configure operate callback failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); throw(0,0,0); } for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next) { /* for each rule */ { //FIXME debug code block int i; headerrule_t *hrD; headerdata_t *hdD; logbook(ctx->l2, L2_LEVEL_DEBUG, "FIXME trace ---------- headerrewrite() ---------- MIDDLE"); for (hrD = ctx->option_firstheaderrule; hrD != NULL; hrD = hrD->next) logbook(ctx->l2, L2_LEVEL_DEBUG, "hrD->header=%s", hrD->header); for (hdD = ctx->msg->hdFirst; hdD != NULL; hdD = hdD->next) { //logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD=%.8lx, hdD->name=%.8lx, hdD->data.s=%.8lx", (long)hdD, (long)&hdD->name, (long)&hdD->data.s); if (hdD->ndata == 0) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); if (hdD->ndata == 1) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); if (hdD->ndata > 1) for (i = 0; i < hdD->ndata; i++) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); } } if (hrI->regex != NULL) { logbook(ctx->l2, L2_LEVEL_DEBUG, "rule has regex %s", hrI->regex); for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) { /* for each header */ if (hdI->name == NULL || strlen(hdI->name) == 0 || hdI->ndata == 0) continue; regex_ctx->nMatch = pcre_exec(hrI->pcreRegex, hrI->pcreExtra, hdI->name, strlen(hdI->name), 0, 0, ovec, OVECSIZE); if (regex_ctx->nMatch >= 1) { int i; char *cp; logbook(ctx->l2, L2_LEVEL_DEBUG, "regex matches, %d references", regex_ctx->nMatch); pcre_get_substring_list(hdI->name, ovec, regex_ctx->nMatch, ®ex_ctx->acpMatch); if (regex_ctx->acpMatch != NULL) for (i = 0; i < regex_ctx->nMatch; i++) logbook(ctx->l2, L2_LEVEL_DEBUG, "regex reference[%d]=\'%s\'", i, regex_ctx->acpMatch[i] == NULL ? "(UNDEFINED)" : regex_ctx->acpMatch[i]); hdNew = headercreate(); /* expanding regex references into header name */ { var_rc_t var_rc; char *res_ptr; logbook(ctx->l2, L2_LEVEL_DEBUG, "expanding regex references in headername '%s'", hrI->header); if ((var_rc = var_expand(ctx->config_varregex, hrI->header, strlen(hrI->header), &res_ptr, NULL, FALSE)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "expansion of '%s' failed: %s", hrI->header, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); } logbook(ctx->l2, L2_LEVEL_DEBUG, "expansion result '%s'", res_ptr); if (strlen(res_ptr) == 0) { logbook(ctx->l2, L2_LEVEL_DEBUG, "marking deleted - emtpy headername"); hdNew->name = NULL; //FIXME rename ->header to ->name /*FIXME clean up data.s and data.m */ hdNew->ndata = 0; } else { hdNew->name = res_ptr; //FIXME rename ->header to ->name } } if (hrI->val == NULL) { logbook(ctx->l2, L2_LEVEL_DEBUG, "marking deleted - empty headervalue before expansion"); /*FIXME clean up data.s and data.m */ hdNew->ndata = 0; } else { /* expanding regex references into header value */ { var_rc_t var_rc; char *res_ptr; logbook(ctx->l2, L2_LEVEL_DEBUG, "expanding regex references in header value '%s'", hrI->val); if ((var_rc = var_expand(ctx->config_varregex, hrI->val, strlen(hrI->val), &res_ptr, NULL, FALSE)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); } logbook(ctx->l2, L2_LEVEL_DEBUG, "expansion result '%s'", res_ptr); cp = res_ptr; } /* expanding variables into header value */ if (hrI->val != NULL) { var_rc_t var_rc; char *res_ptr; logbook(ctx->l2, L2_LEVEL_DEBUG, "expanding variables in header value '%s'", hrI->val); if ((var_rc = var_expand(ctx->config_varctx, cp, strlen(cp), &res_ptr, NULL, FALSE)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "expansion of '%s' failed: %s", cp, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); } logbook(ctx->l2, L2_LEVEL_DEBUG, "expansion result '%s'", res_ptr); if (strlen(res_ptr) == 0) { logbook(ctx->l2, L2_LEVEL_DEBUG, "marking deleted - empty headervalue after expansion"); /*FIXME clean up data.s and data.m */ hdNew->ndata = 0; } else { hdNew->data.s = res_ptr; hdNew->ndata = 1; } } } /*FIXME clean up data.m */ headerreplace(hdI, hdNew); if (hdNew->prev == NULL) ctx->msg->hdFirst = hdNew; hdI = hdNew; } } } else { logbook(ctx->l2, L2_LEVEL_DEBUG, "rule has no regex but static header %s", hrI->header); hdNew = headercreate(); hdNew->name = strdupex(hrI->header); //FIXME rename ->header to ->name if (hrI->val == NULL) { logbook(ctx->l2, L2_LEVEL_DEBUG, "marking deleted"); /*FIXME clean up data.s and data.m */ hdNew->ndata = 0; } else { /*FIXME clean up data.m */ /* expanding variables into header value */ var_rc_t var_rc; char *res_ptr; logbook(ctx->l2, L2_LEVEL_DEBUG, "expanding variables in header value '%s'", hrI->val); if ((var_rc = var_expand(ctx->config_varctx, hrI->val, strlen(hrI->val), &res_ptr, NULL, FALSE)) != VAR_OK) { logbook(ctx->l2, L2_LEVEL_ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); } logbook(ctx->l2, L2_LEVEL_DEBUG, "expansion result '%s'", res_ptr); if (strlen(res_ptr) == 0) { logbook(ctx->l2, L2_LEVEL_DEBUG, "marking deleted - empty headervalue after expansion"); /*FIXME clean up data.s and data.m */ hdNew->ndata = 0; } else { hdNew->data.s = res_ptr; hdNew->ndata = 1; } } for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) { /* for each header */ if (hdI->name == NULL || strlen(hdI->name) == 0) continue; logbook(ctx->l2, L2_LEVEL_DEBUG, "hrI->header=%s, hdI->name=%s", hrI->header, hdI->name); if (strcasecmp(hrI->header, hdI->name) == 0) break; } if (hdI != NULL) { logbook(ctx->l2, L2_LEVEL_DEBUG, "replacing header %s", hrI->header); headerreplace(hdI, hdNew); if (hdNew->prev == NULL) { logbook(ctx->l2, L2_LEVEL_DEBUG, "FIXME trace #1"); ctx->msg->hdFirst = hdNew; } } else { logbook(ctx->l2, L2_LEVEL_DEBUG, "appending header %s", hrI->header); for (hdI = ctx->msg->hdFirst; hdI->next != NULL; hdI = hdI->next); hdI->next = hdNew; hdNew->prev = hdI; } } } { //FIXME debug code block int i; headerrule_t *hrD; headerdata_t *hdD; logbook(ctx->l2, L2_LEVEL_DEBUG, "FIXME trace ---------- headerrewrite() ---------- FINISH"); for (hrD = ctx->option_firstheaderrule; hrD != NULL; hrD = hrD->next) logbook(ctx->l2, L2_LEVEL_DEBUG, "hrD->header=%s", hrD->header); for (hdD = ctx->msg->hdFirst; hdD != NULL; hdD = hdD->next) { if (hdD->ndata == 0) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); if (hdD->ndata == 1) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); if (hdD->ndata > 1) for (i = 0; i < hdD->ndata; i++) logbook(ctx->l2, L2_LEVEL_DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); } } } @ 1.69 log @flush while looking for the var_expand reentrance problem @ text @d1266 42 d1450 4 d1525 1 a1525 1 /* expanding header and other variables into header value */ d1564 1 a1564 1 /* expanding header and other variables into header value */ @ 1.68 log @since env exists, default is there; l2_spec sets channel_levels @ text @d186 1 @ 1.67 log @move from log macro to logbook function @ text @d129 4 a174 4 CU(ERR_EXECUTION); } if (l2_channel_levels(ctx->l2, L2_LEVEL_ALL, L2_LEVEL_NONE) != L2_OK) { /* FIXME should this globalmask and flushmask be user-configurable? */ fprintf(stderr, "%s:Error: logging failed to set global logging level\n", ctx->progname); @ 1.66 log @implemented var_expand inside l2 @ text @d185 1 a185 1 log1(ctx, NOTICE, "startup, version %s", lmtp2nntp_version.v_gnu); d195 1 a195 1 log1(ctx, TRACE, "--version = %d", ov->data.f); d212 1 a212 1 log1(ctx, TRACE, "--childsmax = \"%s\"", ov->data.s); d216 1 a216 1 log1(ctx, ERROR, "option --childsmax, number (%d) out of range", ctx->option_childsmax); d232 1 a232 1 log1(ctx, TRACE, "--daemonize = %d", ov->data.f); d247 1 a247 1 log1(ctx, TRACE, "--kill = %d", ov->data.f); d261 1 a261 1 log1(ctx, TRACE, "--pidfile = \"%s\"", ov->data.s); d279 1 a279 1 log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); d281 1 a281 1 log2(ctx, TRACE, "--acl[%d] = \"%s\"", i, (ov->data.m)[i]); d301 1 a301 1 log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); d310 2 a311 2 log2(ctx, DEBUG, "ctx->pacl[%d].not = %s", i, ctx->pacl[i].not == TRUE ? "TRUE" : "FALSE"); log2(ctx, DEBUG, "ctx->pacl[%d].acl = %s", i, ctx->pacl[i].acl); d317 1 a317 1 log2(ctx, DEBUG, "ctx->pacl[%d].prefixlen = %d", i, ctx->pacl[i].prefixlen); d319 1 a319 1 log1(ctx, ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(rc)); d323 1 a323 1 log2(ctx, ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d337 1 a337 1 log1(ctx, ERROR, "option --acl, create IPv4 pass-through address (internal) failed with \"%s\"", sa_error(rc)); d341 1 a341 1 log2(ctx, ERROR, "option --acl, parsing IPv4 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d355 1 a355 1 log1(ctx, ERROR, "option --acl, create IPv6 pass-through address (internal) failed with \"%s\"", sa_error(rc)); d359 1 a359 1 log2(ctx, ERROR, "option --acl, parsing IPv6 pass-through address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d376 1 a376 1 log1(ctx, TRACE, "--bind = \"%s\"", ov->data.s); d382 1 a382 1 log1(ctx, ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(rc)); d386 1 a386 1 log1(ctx, ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(rc)); d416 1 a416 1 log1(ctx, ERROR, "option --bind, invalid permissions \"%s\"", cpPerm); d421 1 a421 1 log2(ctx, ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(rc)); d425 1 a425 1 log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(rc)); d430 1 a430 1 log3(ctx, ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"", cpPath, nPerm, strerror(errno)); d436 1 a436 1 log3(ctx, ERROR, "option --bind, chown (%s, %d) failed with \"%s\"", cpPath, ctx->option_uid, strerror(errno)); d445 1 a445 1 log2(ctx, ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d449 1 a449 1 log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d455 1 a455 1 log2(ctx, ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d471 1 a471 1 log1(ctx, TRACE, "--client = \"%s\"", ov->data.s); d475 1 a475 1 log1(ctx, ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(rc)); d481 1 a481 1 log2(ctx, ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d498 1 a498 1 log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); d500 1 a500 1 log2(ctx, TRACE, "--destination[%d] = \"%s\"", i, (ov->data.m)[i]); d506 1 a506 1 log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); d512 1 a512 1 log1(ctx, ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(rc)); d516 1 a516 1 log2(ctx, ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); d520 1 a520 1 log2(ctx, ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); d541 1 a541 1 log1(ctx, TRACE, "--groupmode = \"%s\"", ov->data.s); d551 1 a551 1 log1(ctx, ERROR, "option --groupmode, invalid mode (%s)", ov->data.s); d575 1 a575 1 log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); d577 1 a577 1 log2(ctx, TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]); d582 1 a582 1 log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); d596 1 a596 1 log1(ctx, ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]); d606 1 a606 1 log1(ctx, ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]); d616 1 a616 1 log1(ctx, ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]); d622 1 a622 1 log1(ctx, ERROR, "option --headerrule, header (%s) missing", (ov->data.m)[i]); d635 1 a635 1 log3(ctx, ERROR, "option --headerrule, regex (%s) failed at pos %d with %s", hrNew->regex, iError, cpError); d640 1 a640 1 log1(ctx, ERROR, "option --headerrule, regex optimization failed with %s", cpError); d665 1 a665 1 log2(ctx, ERROR, "option --headerrule, create regex context failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d669 1 a669 1 log2(ctx, ERROR, "option --headerrule, config regex context failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d703 1 a703 1 log1(ctx, TRACE, "--mailfrom = \"%s\"", ov->data.s); d717 1 a717 1 log1(ctx, ERROR, "option --mailfrom, illegal regex (%s)", ctx->option_mailfrom); d732 1 a732 1 log1(ctx, TRACE, "--nodename = \"%s\"", ov->data.s); d736 1 a736 1 log1(ctx, ERROR, "option --nodename, name (%s) too long", ov->data.s); d754 1 a754 1 log1(ctx, TRACE, "--operationmode = \"%s\"", ov->data.s); d765 1 a765 1 log1(ctx, ERROR, "option --operationmode, invalid length (%s)", cp); d769 1 a769 1 log1(ctx, ERROR, "option --operationmode, missing slash (%s)", cp); d780 1 a780 1 log1(ctx, ERROR, "option --operationmode, invalid status code (%s)", cp); d791 1 a791 1 log1(ctx, ERROR, "option --operationmode, invalid dsn code (%s)", cp); d797 1 a797 1 log0(ctx, ERROR, "option --operationmode, is mandatory but neither given nor preset (internal)"); d813 1 a813 1 log1(ctx, TRACE, "--restrictheader = \"%s\"", ov->data.s); d827 1 a827 1 log1(ctx, ERROR, "option --restrictheader, illegal regex (%s)", ctx->option_restrictheader); d842 1 a842 1 log1(ctx, TRACE, "--size = \"%s\"", ov->data.s); d846 1 a846 1 log1(ctx, ERROR, "option --size, number (%d) out of range", ctx->option_maxmessagesize); d862 1 a862 1 log1(ctx, TRACE, "--timeoutlmtp= \"%s\"", ov->data.s); d866 1 a866 1 log1(ctx, ERROR, "option --timeoutlmtp, number (%d) out of range", i); d884 1 a884 1 log1(ctx, TRACE, "--timeoutlmtpaccept = \"%s\"", ov->data.s); d888 1 a888 1 log1(ctx, ERROR, "option --timeoutlmtpaccept, number (%d) out of range", ctx->option_timeout_lmtp_accept); d902 1 a902 1 log1(ctx, TRACE, "--timeoutlmtpread = \"%s\"", ov->data.s); d906 1 a906 1 log1(ctx, ERROR, "option --timeoutlmtpread, number (%d) out of range", ctx->option_timeout_lmtp_read); d920 1 a920 1 log1(ctx, TRACE, "--timeoutlmtpwrite = \"%s\"", ov->data.s); d924 1 a924 1 log1(ctx, ERROR, "option --timeoutlmtpwrite, number (%d) out of range", ctx->option_timeout_lmtp_write); d940 1 a940 1 log1(ctx, TRACE, "--timeoutnntp= \"%s\"", ov->data.s); d944 1 a944 1 log1(ctx, ERROR, "option --timeoutnntp, number (%d) out of range", i); d962 1 a962 1 log1(ctx, TRACE, "--timeoutnntpconnect = \"%s\"", ov->data.s); d966 1 a966 1 log1(ctx, ERROR, "option --timeoutnntpconnect, number (%d) out of range", ctx->option_timeout_nntp_connect); d980 1 a980 1 log1(ctx, TRACE, "--timeoutnntpread = \"%s\"", ov->data.s); d984 1 a984 1 log1(ctx, ERROR, "option --timeoutnntpread, number (%d) out of range", ctx->option_timeout_nntp_read); d998 1 a998 1 log1(ctx, TRACE, "--timeoutnntpwrite = \"%s\"", ov->data.s); d1002 1 a1002 1 log1(ctx, ERROR, "option --timeoutnntpwrite, number (%d) out of range", ctx->option_timeout_nntp_write); d1018 1 a1018 1 log1(ctx, TRACE, "--user = \"%s\"", ov->data.s); d1023 1 a1023 1 log1(ctx, ERROR, "option --user, uid (%s) not found", ov->data.s); d1029 1 a1029 1 log1(ctx, ERROR, "option --user, name (%s) not found", ov->data.s); d1048 1 a1048 1 log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); d1050 1 a1050 1 log2(ctx, TRACE, "--newsgroup[%d] = \"%s\"", i, (ov->data.m)[i]); d1055 1 a1055 1 log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); d1073 1 a1073 1 log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); d1075 1 a1075 1 log2(ctx, TRACE, "--testfile[%d] = \"%s\"", i, (ov->data.m)[i]); d1080 1 a1080 1 log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); d1112 1 a1112 1 log1(ctx, ERROR, "Error splitting message: %s", msg_error(rc)); d1118 1 a1118 1 log0(msg, DEBUG, "FIXME trace #20"); d1120 1 a1120 1 log1(msg, DEBUG, "header=\"%s\"", cp); d1122 1 a1122 1 log0(msg, DEBUG, "FIXME trace #21"); d1131 1 a1131 1 log0(msg, DEBUG, "FIXME trace #30"); d1133 1 a1133 1 log1(msg, DEBUG, "header=\"%s\"", cp); d1135 1 a1135 1 log0(msg, DEBUG, "FIXME trace #31"); d1139 1 a1139 1 log1(ctx, ERROR, "Error joining message: %s", msg_error(rc)); d1249 1 a1249 1 log2(ctx, DEBUG, "rgx_lookup variable \"%s\" (%d)", var_ptr, var_len); d1259 1 a1259 1 log4(ctx, DEBUG, "rgx_lookup variable \"%s\" (%d) ok: result is \"%s\" (%d)", var_ptr, var_len, *val_ptr, *val_len); d1261 1 a1261 1 log4(ctx, DEBUG, "rgx_lookup variable \"%s\" (%d) failed: %s (%d)", var_ptr, var_len, var_strerror(var, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1297 1 a1297 1 log1(msg, DEBUG, "header=%s, currently empty", hdI->name); d1304 1 a1304 1 log1(msg, DEBUG, "header=%s, currently single valued", hdI->name); d1312 1 a1312 1 log2(msg, DEBUG, "header=%s, currently multi valued %d", hdI->name, hdI->ndata); d1340 1 a1340 1 log2(msg, DEBUG, "FIXME trace loop hdI=%.8lx, hI->name=\"%s\"", hdI, hdI->name); d1344 1 a1344 1 log1(msg, DEBUG, "header=%s, no data", hdI->name); d1347 1 a1347 1 log2(msg, DEBUG, "header=%s, data=%s", hdI->name, hdI->data.s); d1354 1 a1354 1 log3(msg, DEBUG, "header=%s[%d], data=%s", hdI->name, i, hdI->data.m[i]); d1384 1 a1384 1 log0(ctx, DEBUG, "FIXME trace ---------- headerrewrite() ----------"); d1386 1 a1386 1 log1(ctx, DEBUG, "hrD->header=%s", hrD->header); d1389 1 a1389 1 log1(ctx, DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); d1391 1 a1391 1 log2(ctx, DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); d1394 1 a1394 1 log3(ctx, DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); d1404 1 a1404 1 log2(ctx, ERROR, "configure regex callback failed with %s (%d)", var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1413 1 a1413 1 log0(ctx, DEBUG, "FIXME trace ---------- headerrewrite() ---------- MIDDLE"); d1415 1 a1415 1 log1(ctx, DEBUG, "hrD->header=%s", hrD->header); d1417 1 a1417 1 //log3(ctx, DEBUG, "hdD=%.8lx, hdD->name=%.8lx, hdD->data.s=%.8lx", (long)hdD, (long)&hdD->name, (long)&hdD->data.s); d1419 1 a1419 1 log1(ctx, DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); d1421 1 a1421 1 log2(ctx, DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); d1424 1 a1424 1 log3(ctx, DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); d1428 1 a1428 1 log1(ctx, DEBUG, "rule has regex %s", hrI->regex); d1436 1 a1436 1 log1(ctx, DEBUG, "regex matches, %d references", regex_ctx->nMatch); d1440 1 a1440 1 log2(ctx, DEBUG, "regex reference[%d]=\'%s\'", i, regex_ctx->acpMatch[i] == NULL ? "(UNDEFINED)" : regex_ctx->acpMatch[i]); d1446 1 a1446 1 log1(ctx, DEBUG, "expanding regex references in headername '%s'", hrI->header); d1448 1 a1448 1 log3(ctx, ERROR, "expansion of '%s' failed: %s", hrI->header, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1450 1 a1450 1 log1(ctx, DEBUG, "expansion result '%s'", res_ptr); d1452 1 a1452 1 log0(ctx, DEBUG, "marking deleted - emtpy headername"); d1462 1 a1462 1 log0(ctx, DEBUG, "marking deleted - empty headervalue before expansion"); d1471 1 a1471 1 log1(ctx, DEBUG, "expanding regex references in header value '%s'", hrI->val); d1473 1 a1473 1 log3(ctx, ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1475 1 a1475 1 log1(ctx, DEBUG, "expansion result '%s'", res_ptr); d1482 1 a1482 1 log1(ctx, DEBUG, "expanding variables in header value '%s'", hrI->val); d1484 1 a1484 1 log3(ctx, ERROR, "expansion of '%s' failed: %s", cp, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1486 1 a1486 1 log1(ctx, DEBUG, "expansion result '%s'", res_ptr); d1488 1 a1488 1 log0(ctx, DEBUG, "marking deleted - empty headervalue after expansion"); d1507 1 a1507 1 log1(ctx, DEBUG, "rule has no regex but static header %s", hrI->header); d1511 1 a1511 1 log0(ctx, DEBUG, "marking deleted"); d1520 1 a1520 1 log1(ctx, DEBUG, "expanding variables in header value '%s'", hrI->val); d1522 1 a1522 1 log3(ctx, ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(ctx->config_varctx, rc, &cp) == VAR_OK ? cp : "Unknown Error", rc); d1524 1 a1524 1 log1(ctx, DEBUG, "expansion result '%s'", res_ptr); d1526 1 a1526 1 log0(ctx, DEBUG, "marking deleted - empty headervalue after expansion"); d1538 1 a1538 1 log2(ctx, DEBUG, "hrI->header=%s, hdI->name=%s", hrI->header, hdI->name); d1543 1 a1543 1 log1(ctx, DEBUG, "replacing header %s", hrI->header); d1546 1 a1546 1 log0(ctx, DEBUG, "FIXME trace #1"); d1551 1 a1551 1 log1(ctx, DEBUG, "appending header %s", hrI->header); d1564 1 a1564 1 log0(ctx, DEBUG, "FIXME trace ---------- headerrewrite() ---------- FINISH"); d1566 1 a1566 1 log1(ctx, DEBUG, "hrD->header=%s", hrD->header); d1569 1 a1569 1 log1(ctx, DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); d1571 1 a1571 1 log2(ctx, DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); d1574 1 a1574 1 log3(ctx, DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); @ 1.65 log @wipe out obsolete stuff @ text @a121 1 //char *cp; d150 14 d165 1 a165 1 if ((rc = l2_spec(&ctx->l2, ctx->l2_env, ov->data.s)) != L2_OK) { d167 4 @ 1.64 log @Integration done replacing headervalue with new headerrule stuff. This version is v1.2a3 and runs live on visp.engelschall.com @ text @a1045 1 //headersimulation(ctx); //FIXME @ 1.63 log @wipe out some debug stuff, reducing FIXMEs @ text @a106 4 static void msg_headermatrixbuildup(msg_t *msg); static void msg_headermatrixteardwn(msg_t *msg); static void headerrewrite(lmtp2nntp_t *ctx); d1249 1 a1249 1 static void msg_headermatrixbuildup(msg_t *msg) d1312 1 a1312 1 static void msg_headermatrixteardwn(msg_t *msg) d1350 1 a1350 1 static void headerrewrite(lmtp2nntp_t *ctx) d1358 4 @ 1.62 log @header now gets deleted when name or value is empty after expansion @ text @a106 1 static void headersimulation(lmtp2nntp_t *); //FIXME a110 19 static void extest(void) { ex_t ex; try { fprintf(stderr, "try\n"); throw(0,0,0); } cleanup { fprintf(stderr, "cleanup\n"); } catch (ex) { fprintf(stderr, "catch\n"); rethrow; } exit(0); } a128 2 //FIXME ex is broken!? extest(); a579 1 //FIXME cp = hrNew->carve = strdupex(cp); a1146 74 #if 0 //void testpcre(void) { char *szRegex; pcre *pcreRegex; pcre_extra *pcreExtra; const char *szError; int nErrorOffset; int iCheck; int opt; char *buf; int buf_size; #define OVECSIZE 30 int ovec[OVECSIZE]; int i; const char **cpList; // 0 1 2 // 012345678901234567890 buf = "In-Reply-To: MailTo: Tom & Jerry"; buf_size = strlen(buf); szRegex = "(To|Cc|Bcc):.*(Tom|Snoopy).+&(.*)"; fprintf(stderr, "DEBUG: 0 1 2 3 4\n"); fprintf(stderr, "DEBUG: 01234567890123456789012345678901234567890\n"); fprintf(stderr, "DEBUG: buf =\"%s\"\n", buf); fprintf(stderr, "DEBUG: szRegex=\"%s\"\n", szRegex); /* buf = "In-Reply-To: MailTo: Tom & Jerry"; szRegex = "(To|Cc|Bcc):.*(Tom|Snoopy).+&(.*)"; iCheck=4 [0]="To: MailTo: Tom & Jerry" [1]="To" [2]="Tom" [3]=" Jerry" */ /* compile regular expression into finite state machine */ opt = 0; // opt |= PCRE_CASELESS; // opt |= PCRE_ANCHORED; if ((pcreRegex = pcre_compile(szRegex, opt, &szError, &nErrorOffset, NULL)) == NULL) { fprintf(stderr, "DEBUG: \"%s\" '%c'\n", szError, szRegex[nErrorOffset]); throw(0,0,0); } /* study finite state machine for more performance */ pcreExtra = pcre_study(pcreRegex, 0, &szError); if (szError != NULL) { free(pcreRegex); pcreRegex = NULL; fprintf(stderr, "DEBUG: \"%s\"\n", szError); throw(0,0,0); } /* apply filter */ iCheck = pcre_exec(pcreRegex, pcreExtra, buf, buf_size, 0, 0, ovec, OVECSIZE); fprintf(stderr, "DEBUG: iCheck=%d\n", iCheck); for (i = 0; i < iCheck; i++) fprintf(stderr, "DEBUG: ovec[%d]=%3d, ovec[%d]=%3d\n", 2*i, ovec[2*i], 2*i+1, ovec[2*i+1]); pcre_get_substring_list(buf, ovec, iCheck, &cpList); if (cpList != NULL) for (i = 0; i < iCheck; i++) fprintf(stderr, "DEBUG: list[%d]=\"%s\"\n", i, cpList[i] == NULL ? "(NULL)" : cpList[i]); /* destroy channel configuration */ if (cpList != NULL) pcre_free_substring_list(cpList); if (pcreRegex != NULL) free(pcreRegex); if (pcreExtra != NULL) free(pcreExtra); } #endif a1150 2 d1169 1 a1169 1 return; //FIXME still linked, cannot be destroyed d1171 1 a1171 1 return; //FIXME still linked, cannot be destroyed a1262 1 //log2(msg, DEBUG, "FIXME trace loop cp=%.8lx, cp=\"%s\"", cp, cp); a1265 1 //log2(msg, DEBUG, "FIXME trace loop hdI=%.8lx, hI->name=\"%s\"", hdI, hdI->name); a1305 17 #if 0 { //FIXME debug code block int i; headerdata_t *hdD; log0(msg, DEBUG, "FIXME trace ---------- msg_headermatrixbuildup() ----------"); for (hdD = msg->hdFirst; hdD != NULL; hdD = hdD->next) { if (hdD->ndata == 0) log1(msg, DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); if (hdD->ndata == 1) log2(msg, DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); if (hdD->ndata > 1) for (i = 0; i < hdD->ndata; i++) log3(msg, DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); } } #endif a1347 17 #if 0 { //FIXME debug code block int i; headerdata_t *hdD; log0(msg, DEBUG, "FIXME trace ---------- msg_headermatrixteardwn() ----------"); for (hdD = msg->hdFirst; hdD != NULL; hdD = hdD->next) { if (hdD->ndata == 0) log1(msg, DEBUG, "hdD->name=%s: (NO DATA)", hdD->name); if (hdD->ndata == 1) log2(msg, DEBUG, "hdD->name:hdD->data.s %s %s", hdD->name, hdD->data.s); if (hdD->ndata > 1) for (i = 0; i < hdD->ndata; i++) log3(msg, DEBUG, "hdD->name:hdD->data.m[%d] %s %s", i, hdD->name, hdD->data.m[i]); } } #endif a1353 1 a1357 23 /* char *cp; int i; char *cpPri; char *cpRegex; char *cpHeader; char *cpVal; headerrule_t *hrP; hrNew->pri = atoi(cpPri); hrNew->regex = cpRegex; hrNew->header = cpHeader; hrNew->val = cpVal; char *szRegex; pcre *pcreRegex; pcre_extra *pcreExtra; const char *szError; int nErrorOffset; int opt; char *buf; int buf_size; int ovec[OVECSIZE]; const char **cpList; */ a1391 1 //log1(ctx, DEBUG, "FIXME trace loop hrI=%.8lx", hrI); a1413 1 //log2(ctx, DEBUG, "FIXME trace loop hdI=%.8lx, hI->name=\"%s\"", hdI, hdI->name); d1521 1 a1521 1 continue; //FIXME header w/o name cannot happen normally a1527 3 log3(ctx, DEBUG, "ctx->msg->hdFirst=%.8lx, hdI =%.8lx, hdNew =%.8lx", ctx->msg->hdFirst, hdI, hdNew); log2(ctx, DEBUG, " hdI->prev=%.8lx, hdNew->prev=%.8lx", hdI->prev, hdNew->prev); log2(ctx, DEBUG, " hdI->next=%.8lx, hdNew->next=%.8lx", hdI->next, hdNew->next); a1528 3 log3(ctx, DEBUG, "ctx->msg->hdFirst=%.8lx, hdI =%.8lx, hdNew =%.8lx", ctx->msg->hdFirst, hdI, hdNew); log2(ctx, DEBUG, " hdI->prev=%.8lx, hdNew->prev=%.8lx", hdI->prev, hdNew->prev); log2(ctx, DEBUG, " hdI->next=%.8lx, hdNew->next=%.8lx", hdI->next, hdNew->next); a1560 53 } static void headersimulation(lmtp2nntp_t *ctx) { headerdata_t *hdI, *hdNew; char *replyto[4] = { "foo@@example.com", "bar@@example.com", "quux@@example.com", NULL }; log0(ctx, DEBUG, "FIXME simulation - GO"); ctx->msg = msg_create(); hdNew = headercreate(); hdNew->name = "To"; hdNew->data.s = "foo@@invalid.com"; hdNew->ndata = 1; ctx->msg->hdFirst = hdNew; hdNew->prev = NULL; hdI = hdNew; hdNew = headercreate(); hdNew->name = "Reply-To"; hdNew->data.m = replyto; hdNew->ndata = 3; hdI->next = hdNew; hdNew->prev = hdI; hdI = hdNew; hdNew = headercreate(); hdNew->name = "Subject"; hdNew->data.s = "a tiny little test"; hdNew->ndata = 1; hdI->next = hdNew; hdNew->prev = hdI; hdI = hdNew; hdNew = headercreate(); hdNew->name = "Date"; hdNew->data.s = "Mon, 18 Feb 2002 09:43:52 +0100"; hdNew->ndata = 1; hdI->next = hdNew; hdNew->prev = hdI; hdI = hdNew; hdNew = headercreate(); hdNew->name = "Message-ID"; hdNew->data.s = "<200201172300.AAA29400@@procter012.pg-cw.de>"; hdNew->ndata = 1; hdI->next = hdNew; hdNew->prev = hdI; hdI = hdNew; hdI->next = NULL; headerrewrite(ctx); @ 1.61 log @headername comparisons must not be case sensitive @ text @a1591 1 //if ((var_rc = var_expand(hrI->header, strlen(hrI->header), &res_ptr, NULL, regex_lookup, regex_ctx, ®ex_lookup_cfg, FALSE)) != VAR_OK) { d1596 9 a1604 1 hdNew->name = res_ptr; //FIXME rename ->header to ->name d1607 1 a1607 1 log0(ctx, DEBUG, "marking deleted"); a1616 1 //if ((var_rc = var_expand(hrI->val, strlen(hrI->val), &res_ptr, NULL, regex_lookup, regex_ctx, ®ex_lookup_cfg, FALSE)) != VAR_OK) { a1627 1 //if ((var_rc = var_expand(cp, strlen(cp), &res_ptr, NULL, ctx_lookup, ctx, &ctx_lookup_cfg, FALSE)) != VAR_OK) { d1632 9 a1640 2 hdNew->data.s = res_ptr; hdNew->ndata = 1; a1665 1 //if ((var_rc = var_expand(cp, strlen(cp), &res_ptr, NULL, ctx_lookup, ctx, &ctx_lookup_cfg, FALSE)) != VAR_OK) { d1670 9 a1678 2 hdNew->data.s = res_ptr; hdNew->ndata = 1; @ 1.60 log @var callback now supports message header lookups @ text @d1369 1 a1369 1 if (strcmp(cp, hdI->name) == 0) d1666 1 a1666 1 if (strcmp(hrI->header, hdI->name) == 0) @ 1.59 log @integrated new lib_var API; lib_var patch fixed expansion problem @ text @a1621 4 var_rc_t var_expand(var_t *var, const char *src_ptr, size_t src_len, char **dst_ptr, size_t *dst_len, int force_expand); d1649 11 a1659 1 hdNew->data.s = strdupex(hrI->val); a1660 1 /*FIXME clean up data.m */ @ 1.58 log @ctx_lookup provides access to options through lib_val now @ text @d130 12 d670 13 a1315 67 #if 0 #endif static var_config_t ctx_lookup_cfg = { '$', /* varinit */ '{', /* startdelim */ '}', /* enddelim */ '[', /* startindex */ ']', /* endindex */ '#', /* current_index */ '\\', /* escape */ "a-zA-Z0-9_.-" /* namechars */ }; static var_rc_t ctx_lookup( void *_ctx, const char *var_ptr, size_t var_len, int var_idx, const char **val_ptr, size_t *val_len, size_t *val_size) { lmtp2nntp_t *ctx = (lmtp2nntp_t *)_ctx; /*FIXME const char *name; size_t len; */ var_rc_t rc; char *cp; optionval_t *ov; log2(ctx, DEBUG, "ctx_lookup variable \"%s\" (%d)", var_ptr, var_len); rc = VAR_ERR_UNDEFINED_VARIABLE; if (strncasecmp(var_ptr, "option.", strlen("option.")) == 0) { cp = str_dupex(var_ptr, var_len); if (val_get(ctx->val, cp, &ov) == VAL_OK) { //log3(ctx, DEBUG, "FIXME var_idx=%d, ov->type=%d, ov->ndata=%d", var_idx, ov->type, ov->ndata); if ((var_idx == 0) && (ov->ndata == 1) && (ov->type == OPT_SINGLE)) { /* request first/only single value */ *val_ptr = ov->data.s; *val_len = strlen(ov->data.s); *val_size = 0; rc = VAR_OK; } else if ((var_idx == 0) && (ov->ndata == 1) && (ov->type == OPT_FLAG)) { /* request first/only single value */ *val_ptr = ov->data.f == TRUE ? "yes" : "no"; *val_len = strlen(ov->data.s); *val_size = 0; rc = VAR_OK; } else if ((var_idx < ov->ndata) && (ov->type == OPT_MULTI)) { /* request second+ from multi value */ *val_ptr = ov->data.m[var_idx]; *val_len = strlen(ov->data.m[var_idx]); *val_size = 0; rc = VAR_OK; } } free(cp); } else if (strncasecmp(var_ptr, "xyz", var_len) == 0) { *val_ptr = "Hello, World!"; *val_len = strlen("Hello, World!"); *val_size = 0; rc = VAR_OK; } if (rc == VAR_OK) log4(ctx, DEBUG, "ctx_lookup variable \"%s\" (%d) ok: result is \"%s\" (%d)", var_ptr, var_len, *val_ptr, *val_len); else log3(ctx, DEBUG, "ctx_lookup variable \"%s\" (%d) failed: %s", var_ptr, var_len, var_strerror(rc)); return rc; } a1325 11 static var_config_t regex_lookup_cfg = { '$', /* varinit */ '{', /* startdelim */ '}', /* enddelim */ '[', /* startindex */ //FIXME ']', /* endindex */ //FIXME '#', /* current_index */ //FIXME '\\', /* escape */ "0-9" /* namechars */ //FIXME bug in lib_val }; d1327 1 a1327 1 void *_ctx, d1332 1 a1332 3 /*FIXME const char *name; size_t len; a1333 2 */ var_rc_t rc; d1348 1 a1348 1 log3(ctx, DEBUG, "rgx_lookup variable \"%s\" (%d) failed: %s", var_ptr, var_len, var_strerror(rc)); d1520 1 d1546 4 d1592 3 a1594 3 if ((var_rc = var_expand(hrI->header, strlen(hrI->header), &res_ptr, NULL, regex_lookup, regex_ctx, ®ex_lookup_cfg, FALSE)) != VAR_OK) { log2(ctx, ERROR, "expansion of '%s' failed: %s", hrI->header, var_strerror(var_rc)); d1610 3 a1612 3 if ((var_rc = var_expand(hrI->val, strlen(hrI->val), &res_ptr, NULL, regex_lookup, regex_ctx, ®ex_lookup_cfg, FALSE)) != VAR_OK) { log2(ctx, ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(var_rc)); d1622 7 a1628 3 if ((var_rc = var_expand(cp, strlen(cp), &res_ptr, NULL, ctx_lookup, ctx, &ctx_lookup_cfg, FALSE)) != VAR_OK) { log2(ctx, ERROR, "expansion of '%s' failed: %s", cp, var_strerror(var_rc)); @ 1.57 log @removed odd incl./excl. problem @ text @a1313 1 char *cp; d1316 2 d1321 24 a1344 1 if (strncasecmp(var_ptr, "test", var_len) == 0) { d1376 1 a1376 1 "0-9" /* namechars */ d1645 1 a1645 1 regex_lookup, regex_ctx, ®ex_lookup_cfg, TRUE)) != VAR_OK) { d1663 1 a1663 1 regex_lookup, regex_ctx, ®ex_lookup_cfg, TRUE)) != VAR_OK) { d1675 1 a1675 1 ctx_lookup, ctx, &ctx_lookup_cfg, TRUE)) != VAR_OK) { @ 1.56 log @eh, azNewsgroups is value only @ text @d1372 1 a1372 1 if (i <= ctx->nMatch) { @ 1.55 log @support for useless but possible --headerrule :match:header: where "header" doesn't matter as the absence of a value causes deletion of any matching header anyway. However, previously the program segfaulted. @ text @a1122 1 argz_add(&((msg_t *)msg)->azNewsgroups, &((msg_t *)msg)->asNewsgroups, "Newsgroups:"); //FIXME @ 1.54 log @changed semantic of --headerrule to "keep the colon" @ text @d1628 17 a1644 8 /* expanding regex references into header value */ { var_rc_t var_rc; char *res_ptr; log1(ctx, DEBUG, "expanding regex references in header value '%s'", hrI->val); if ((var_rc = var_expand(hrI->val, strlen(hrI->val), &res_ptr, NULL, regex_lookup, regex_ctx, ®ex_lookup_cfg, TRUE)) != VAR_OK) { log2(ctx, ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(var_rc)); d1646 12 a1657 11 log1(ctx, DEBUG, "expansion result '%s'", res_ptr); cp = res_ptr; } /* expanding header and other variables into header value */ { var_rc_t var_rc; char *res_ptr; log1(ctx, DEBUG, "expanding variables in header value '%s'", hrI->val); if ((var_rc = var_expand(cp, strlen(cp), &res_ptr, NULL, ctx_lookup, ctx, &ctx_lookup_cfg, TRUE)) != VAR_OK) { log2(ctx, ERROR, "expansion of '%s' failed: %s", cp, var_strerror(var_rc)); a1658 3 log1(ctx, DEBUG, "expansion result '%s'", res_ptr); hdNew->data.s = res_ptr; hdNew->ndata = 1; @ 1.53 log @added --testfile option for header rewrite testing. Transformation from argz to linked list of elements and back implemented for integration into the gateway's "inner loop". Have trouble with lib_ex segfaulting when throwing exception and tried to track down this issue with no luck. @ text @d560 2 a561 1 char *cp; a562 4 char *cpPri; char *cpRegex; char *cpHeader; char *cpVal; d583 4 a586 1 hrNew->carve = NULL; d590 1 a590 1 cp = hrNew->carve = strdupex(cp); d592 1 a592 1 cpPri = cp; a596 3 *cp = NUL; if (strlen(cpPri) == 0) cpPri = "0"; d598 3 d602 1 a602 1 cpRegex = cp; a606 3 *cp = NUL; if (strlen(cpRegex) == 0) cpRegex = NULL; d608 3 d612 1 a612 1 cpHeader = cp; d617 3 a619 2 *cp = NUL; if (strlen(cpHeader) == 0) { d623 1 a623 1 cp++; d625 4 a628 8 cpVal = cp; if (strlen(cpVal) == 0) cpVal = NULL; hrNew->pri = atoi(cpPri); hrNew->regex = cpRegex; hrNew->header = cpHeader; hrNew->val = cpVal; d630 1 a630 1 if (cpRegex != NULL) { d632 2 a633 2 if ((hrNew->pcreRegex = pcre_compile(cpRegex, PCRE_CASELESS, &cpError, &iError, NULL)) == NULL) { log3(ctx, ERROR, "option --headerrule, regex (%s) failed at pos %d with %s", cpRegex, iError, cpError); d662 2 a663 2 if (hrNew->carve != NULL) freeex(hrNew->carve); d666 6 a671 2 if (hrNew->pcreExtra != NULL) free(hrNew->pcreExtra); d1396 1 a1396 1 log2(msg, DEBUG, "FIXME trace loop cp=%.8lx, cp=\"%s\"", cp, cp); d1400 1 a1400 1 log2(msg, DEBUG, "FIXME trace loop hdI=%.8lx, hI->name=\"%s\"", hdI, hdI->name); d1451 1 a1451 1 log2(msg, DEBUG, "hdD->name:hdD->data.s %s: %s", hdD->name, hdD->data.s); d1454 1 a1454 1 log3(msg, DEBUG, "hdD->name:hdD->data.m[%d] %s: %s", i, hdD->name, hdD->data.m[i]); d1510 1 a1510 1 log2(msg, DEBUG, "hdD->name:hdD->data.s %s: %s", hdD->name, hdD->data.s); d1513 1 a1513 1 log3(msg, DEBUG, "hdD->name:hdD->data.m[%d] %s: %s", i, hdD->name, hdD->data.m[i]); d1567 1 a1567 1 log2(ctx, DEBUG, "hdD->name:hdD->data.s %s: %s", hdD->name, hdD->data.s); d1570 1 a1570 1 log3(ctx, DEBUG, "hdD->name:hdD->data.m[%d] %s: %s", i, hdD->name, hdD->data.m[i]); d1594 1 a1594 1 log2(ctx, DEBUG, "hdD->name:hdD->data.s %s: %s", hdD->name, hdD->data.s); d1597 1 a1597 1 log3(ctx, DEBUG, "hdD->name:hdD->data.m[%d] %s: %s", i, hdD->name, hdD->data.m[i]); d1717 1 a1717 1 log2(ctx, DEBUG, "hdD->name:hdD->data.s %s: %s", hdD->name, hdD->data.s); d1720 1 a1720 1 log3(ctx, DEBUG, "hdD->name:hdD->data.m[%d] %s: %s", i, hdD->name, hdD->data.m[i]); @ 1.52 log @Basic loop of desired new header rewriting feature now supports deleting a header and regex matching replaces backreferencing arguments in header name and header value. @ text @d108 3 d112 18 d137 2 d1047 99 a1145 1 headersimulation(ctx); //FIXME d1147 1 d1217 1 a1291 20 //headermatrix() { volatile header_t *hNew = NULL; try { char *cp; cp = NULL; while ((cp = argz_next(ctx->msg->azHeaders, ctx->msg->asHeaders, cp)) != NULL) { hNew = mallocex(sizeof(header_t)); //FIXME } } cleanup { if (hNew != NULL) free(hNew); } catch(ex) { rethrow; } } d1371 1 a1371 1 i = atoi(var_ptr); /* works w '}' but '\0' termination as well */ d1385 138 a1546 1 #define OVECSIZE 30 d1551 1 d1727 3 a1731 3 log0(ctx, DEBUG, "FIXME simulation - GO"); char *replyto[4] = { "foo@@example.com", "bar@@example.com", "quux@@example.com", NULL }; @ 1.51 log @flush work done this week. New structure for headers. Basic loop of desired new header rewriting feature currently supports replacing a header, adding a header and regex matching finds the correct header and calls lib_var. Try ./lmtp2nntp -i 1.conf -h ':Reply-To:New-Reply:${xyz}' -h ::To:bv -h 21::ch:cv @ text @d1143 4 d1215 1 a1215 1 log2(ctx, DEBUG, "lookup variable \"%s\" (%d)", var_ptr, var_len); d1226 1 a1226 1 log4(ctx, DEBUG, "lookup variable \"%s\" (%d) ok: result is \"%s\" (%d)", var_ptr, var_len, *val_ptr, *val_len); d1228 51 a1278 1 log3(ctx, DEBUG, "lookup variable \"%s\" (%d) failed: %s", var_ptr, var_len, var_strerror(rc)); a1307 1 int i; d1310 2 a1311 2 int ovec[OVECSIZE]; int iCheck; d1315 2 d1319 10 a1328 10 for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next) log1(ctx, DEBUG, "hrI->header=%s", hrI->header); for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) { if (hdI->ndata == 0) log1(ctx, DEBUG, "hdI->name=%s, (NO DATA)", hdI->name); if (hdI->ndata == 1) log2(ctx, DEBUG, "hdI->name=%s, hdI->data.s=%s", hdI->name, hdI->data.s); if (hdI->ndata > 1) for (i = 0; i < hdI->ndata; i++) log3(ctx, DEBUG, "hdI->name=%s, hdI->data.m[%d]=%s", hdI->name, i, hdI->data.m[i]); d1332 5 d1339 19 d1362 11 a1372 6 if (hdI->name == NULL || strlen(hdI->name) == 0) continue; //FIXME header w/o name cannot happen normally iCheck = pcre_exec(hrI->pcreRegex, hrI->pcreExtra, hdI->name, strlen(hdI->name), 0, 0, ovec, OVECSIZE); log1(ctx, DEBUG, "FIXME trace iCheck=%d", iCheck); if (iCheck >= 1) { log0(ctx, DEBUG, "regex matches"); d1374 25 a1398 1 hdNew->name = strdupex(hrI->header); //FIXME rename ->header to ->name d1400 10 a1409 5 var_rc_t var_rc; char *res_ptr; if ((var_rc = var_expand(hrI->val, strlen(hrI->val), &res_ptr, NULL, ctx_lookup, ctx, &ctx_lookup_cfg, TRUE)) != VAR_OK) { log2(ctx, ERROR, "expansion of '%s' failed: %s", hrI->val, var_strerror(var_rc)); a1410 3 log2(ctx, ERROR, "expansion of '%s' succeeded: %s", hrI->val, res_ptr); hdNew->data.s = res_ptr; hdNew->ndata = 1; a1415 1 } d1423 10 a1432 3 hdNew->data.s = strdupex(hrI->val); hdNew->ndata = 1; /*FIXME clean up data.m */ d1442 3 d1446 5 a1450 1 if (hdNew->prev == NULL) d1452 1 d1465 2 d1469 10 a1478 10 for (hrI = ctx->option_firstheaderrule; hrI != NULL; hrI = hrI->next) log1(ctx, DEBUG, "hrI->header=%s", hrI->header); for (hdI = ctx->msg->hdFirst; hdI != NULL; hdI = hdI->next) { if (hdI->ndata == 0) log1(ctx, DEBUG, "hdI->name=%s, (NO DATA)", hdI->name); if (hdI->ndata == 1) log2(ctx, DEBUG, "hdI->name=%s, hdI->data.s=%s", hdI->name, hdI->data.s); if (hdI->ndata > 1) for (i = 0; i < hdI->ndata; i++) log3(ctx, DEBUG, "hdI->name=%s, hdI->data.m[%d]=%s", hdI->name, i, hdI->data.m[i]); d1497 1 d1505 1 d1513 1 d1521 1 d1529 1 d1532 1 @ 1.50 log @working experimental code for evaluating pcre @ text @d42 1 d107 2 d545 2 d562 4 a565 2 hrNew->next = NULL; hrNew->carve = NULL; // initialize variables which might have resources allocated that need to be cleaned up when an exception is caught d610 13 d624 1 a624 1 ctx->option_firstheaderrule = (headerrule_t *)hrNew; // interesting point since hrNew is declared volatile we have to cast it. This makes me unhappy as it enlarges the code which is far from the spirit of lib_ex d634 1 a634 1 ctx->option_firstheaderrule = (headerrule_t *)hrNew; /* newfirst */ d636 1 a636 8 /* after linking the structure into a parental-controlled structure we expect that the parental cleanup will handle normal and exceptional resource releasing and therefore we *must* reset this variable initialization to avoid accidental local cleanup! In fact, this code will fail if the next statement is omitted. */ hrNew = NULL; // initialize variables which might have resources allocated that need to be cleaned up when an exception is caught d640 1 a640 1 cleanup { // make sure the conditional variables are *always* proper initialized and cleared volatile d644 4 d1024 2 d1098 304 @ 1.49 log @Please review! Attempt to use lib_ex for proper cleanup. I discovered some tweaks and quirks regarding the volatile nature of the hrNew structure temporary allocating resources. Two wrappers, strdupex() and mallocex() are used to throw exceptions. It was a pain, or at least a different kind of programming, to always ensure that hrNew resoures are cleaned up completely when they should and to stop the cleanup code from releasing resources in the non-exceptional case. Although, the declaration of a volatile structure requires casting where i do not want to use it. Maybe i did something wrong, and life becomes easier in this particular case when i put the exeptional cleanup code in the catch construct, because in this try-cleanup-catch block i only want cleanup in the exeptional case. However, this would only remove the "hrNew = NULL" line at the buttom of the for() loop. Would this help, should it work? Unsure ... @ text @d38 3 a42 2 #include "popt.h" #include "l2.h" d1006 70 @ 1.48 log @new -h option and config @ text @d530 93 a622 70 try { char *cp; int i; char *cpPri; char *cpRegex; char *cpHeader; char *cpVal; headerrule_t *hrNew; headerrule_t *hrI; headerrule_t *hrP; if ( (val_get(ctx->val, "option.headerrule", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata >= 1 && ov->data.m == NULL) ) throw(0,0,0); log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); for (i = 0; i < ov->ndata; i++) log2(ctx, TRACE, "--headerule[%d] = \"%s\"", i, (ov->data.m)[i]); if (ov->ndata >= 1) { for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); cp = strdup(cp); //FIXME /* priority */ cpPri = cp; if ((cp = strchr(cp, ':')) == NULL) { log1(ctx, ERROR, "option --headerrule, priority (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } *cp = NUL; cp++; /* regex */ cpRegex = cp; if ((cp = strchr(cp, ':')) == NULL) { log1(ctx, ERROR, "option --headerrule, regex (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } *cp = NUL; cp++; /* header */ cpHeader = cp; if ((cp = strchr(cp, ':')) == NULL) { log1(ctx, ERROR, "option --headerrule, header (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } *cp = NUL; cp++; /* value */ cpVal = cp; if ((hrNew = (headerrule_t *)malloc(sizeof(headerrule_t))) == NULL) throw(0,0,0); hrNew->next = NULL; hrNew->pri = atoi(cpPri); hrNew->regex = cpRegex; hrNew->header = cpHeader; hrNew->val = cpVal; if (ctx->option_firstheaderrule == NULL) ctx->option_firstheaderrule = hrNew; else { for (hrP = NULL, hrI = ctx->option_firstheaderrule; hrI != NULL && hrI->pri <= hrNew->pri; hrP = hrI, hrI = hrI->next); if (hrI != NULL) hrNew->next = hrI; /* insert */ if (hrP != NULL) hrP->next = hrNew; /* append */ else ctx->option_firstheaderrule = hrNew; /* newfirst */ d626 9 a635 2 catch (ex) rethrow; @ 1.47 log @keep the colon @ text @d529 1 a529 1 /* --headervalue MULTI */ d533 2 d536 4 a539 1 char *cpValue; d541 1 a541 1 if ( (val_get(ctx->val, "option.headervalue", &ov) != VAL_OK) d547 1 a547 1 log2(ctx, TRACE, "--headervalue[%d] = \"%s\"", i, (ov->data.m)[i]); d553 5 a557 3 cpHeader = strdup(cp); if ((cp = strchr(cpHeader, ':')) == NULL) { log1(ctx, ERROR, "option --headervalue, header (%s) terminating colon missing", (ov->data.m)[i]); d560 1 d562 6 a568 1 log2(ctx, DEBUG, "header[%d] = \"%s\"", i, cpHeader); d570 4 a573 3 while (*cp == ' ') cp++; //FIXME note this in NEWS if (*cp == NUL) { log1(ctx, ERROR, "option --headervalue, value (%s) missing", (ov->data.m)[i]); d576 25 a600 6 cpValue = strdup(cp); log2(ctx, DEBUG, " value[%d] = \"%s\"", i, cpValue); argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpHeader); argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpValue); free(cpHeader); free(cpValue); @ 1.46 log @fix to calculate nns correctly @ text @d553 1 @ 1.45 log @eliminate a nasty copy'n'paste bug which caused segfaults @ text @d474 1 a474 1 for (i = 0; i < ov->ndata; i++) { d497 1 a497 1 ctx->nns = i; @ 1.44 log @Fixed bug in --destionation and main() not initializing data correctly causing segfaults. Deactivated leftover code from the static ns array with nsc counter where memcpy segfaults. Fixed bug in option_register() not strdup()ing the default value causing free() to fail on cleanup. Added '-b -' to test.sh cause defaultng to stdio does not currenly work. Deactivated l2_channel_destroy() because it's cleanup fails and it hangs in a infinite loop in user space. @ text @a544 1 if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); @ 1.43 log @yes popt supports dash optargs. Bugfix optarg. @ text @d493 3 d497 1 a498 1 ctx->nns = i; @ 1.42 log @"make check" works again! --operationmode now correctly sets OPERATIONMODE_FAKE and detects internal error when this mandatory option was neither given nor preset through option_register(). Found missing functionality where option_parse_internal() does not fail on syntax errors or unknown options. Corrected --timeout* options in "test.sh". @ text @d350 1 a350 1 if (strcmp(ov->data.s, "-") != 0) { //FIXME does this work with popt()? d367 1 a367 1 cpPath = strdup(optarg); @ 1.41 log @--version should print then exit the program. It's use is mutually exclusive and it should be checked very soon in the config process. Fixed a bug in --childsmax where sa_addr_u2a expects a colon. Started to work on testsuite which needs major corrections and exhibits lots of bugs in lmtp2nntp. Found a bug where --l2spec does not work when specified on command line. @ text @d640 1 d672 4 @ 1.40 log @moved --destination from nsc/ns to nns/pns and fixed a copynpaste bug @ text @d138 1 d157 18 d448 3 a450 1 if ((rc = sa_addr_u2a(ctx->saaClientbind, "inet://%s", ov->data.s)) != SA_OK) { a905 18 } } catch (ex) rethrow; /* --version FLAG */ try { if ( (val_get(ctx->val, "option.version", &ov) != VAL_OK) || (ov->ndata < 0) || (ov->ndata == 1 && ov->data.f < 0) || (ov->ndata == 1 && ov->data.f > 1) || (ov->ndata > 1) ) throw(0,0,0); log1(ctx, TRACE, "--version = %d", ov->data.f); if (ov->data.f == 1) { log1(ctx, INFO, "program version %s", lmtp2nntp_version.v_gnu); fprintf(stdout, "%s\n", lmtp2nntp_version.v_gnu); //FIXME is fprintf really the way to go? @ 1.39 log @merged new --acl option with obsolete post-option processing @ text @d452 1 a452 1 if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); d460 1 a460 1 if ((rc = sa_addr_create(&ctx->ns[i].saa)) != SA_OK) { d464 1 a464 1 if ((rc = sa_addr_u2a(ctx->ns[i].saa, "inet://%s", cp)) != SA_OK) { d468 1 a468 1 if ((rc = sa_create(&ctx->ns[i].sa)) != SA_OK) { @ 1.38 log @options are optional now ;-) @ text @d224 1 d234 15 a249 1 if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); d259 1 a259 1 ctx->pacl[i].not = TRUE; d278 36 @ 1.37 log @application defaults now set through option_register() @ text @a111 2 fprintf(stderr, "Hello, World!\n"); //FIXME d159 3 a161 2 || (ov->ndata != 1) || (ov->data.s == NULL) d165 5 a169 4 if ((ctx->option_childsmax = atoi(ov->data.s)) <= 0) { log1(ctx, ERROR, "option --childsmax, number (%d) out of range", ctx->option_childsmax); throw(0,0,0); } d178 4 a181 2 || (ov->ndata != 1) || (ov->data.f != 1) d185 1 a185 1 ctx->option_daemon = TRUE; d193 4 a196 2 || (ov->ndata != 1) || (ov->data.f != 1) d200 1 a200 1 ctx->option_killflag = TRUE; d208 3 a210 2 || (ov->ndata != 1) || (ov->data.s == NULL) d214 2 a215 1 ctx->option_pidfile = ov->data.s; d226 2 a227 1 || ((ov->ndata >= 1) && (ov->data.m == NULL)) d233 8 a240 23 if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); if (cp[0] == '!') { ctx->pacl[i].acl = strdup(cp + 1); ctx->pacl[i].not = TRUE; } else { ctx->pacl[i].acl = strdup(cp); ctx->pacl[i].not = TRUE; } log2(ctx, DEBUG, "ctx->pacl[%d].not = %s", i, ctx->pacl[i].not == TRUE ? "TRUE" : "FALSE"); log2(ctx, DEBUG, "ctx->pacl[%d].acl = %s", i, ctx->pacl[i].acl); if ((cp = strrchr(ctx->pacl[i].acl, '/')) != NULL) *cp++ = NUL; else cp = "-1"; ctx->pacl[i].prefixlen = atoi(cp); log2(ctx, DEBUG, "ctx->pacl[%d].prefixlen = %d", i, ctx->pacl[i].prefixlen); if ((rc = sa_addr_create(&(ctx->pacl[i].saa))) != SA_OK) { log1(ctx, ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(rc)); throw(0,0,0); d242 3 a244 3 if ((rc = sa_addr_u2a(ctx->pacl[i].saa, "inet://%s:0", ctx->pacl[i].acl)) != SA_OK) { log2(ctx, ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); throw(0,0,0); d246 18 a264 1 ctx->nacl = i; d272 3 a274 2 || (ov->ndata != 1) || (ov->data.s == NULL) d278 36 a313 28 /* dash means stdio */ if (strcmp(ov->data.s, "-") != 0) { //FIXME does this work with popt()? if ((rc = sa_create(&ctx->saServerbind)) != SA_OK) { log1(ctx, ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(rc)); throw(0,0,0); } if ((rc = sa_addr_create(&ctx->saaServerbind)) != SA_OK) { log1(ctx, ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(rc)); throw(0,0,0); } /* slash means UNIX socket */ if (ov->data.s[0] == '/') { char *cpPath; char *cpPerm; int nPerm; int n; int i; cpPath = strdup(optarg); cpPerm = NULL; nPerm = -1; if ((cpPerm = strrchr(cpPath, ':')) != NULL) { *cpPerm++ = '\0'; nPerm = 0; for (i = 0; i < 4 && cpPerm[i] != '\0'; i++) { if (!isdigit((int)cpPerm[i])) { nPerm = -1; break; d315 3 a317 4 n = cpPerm[i] - '0'; if (n > 7) { nPerm = -1; break; a318 1 nPerm = ((nPerm << 3) | n); d320 6 a325 2 if (nPerm == -1 || cpPerm[i] != '\0') { log1(ctx, ERROR, "option --bind, invalid permissions \"%s\"", cpPerm); d328 13 d342 4 a345 11 if ((rc = sa_addr_u2a(ctx->saaServerbind, "unix:%s", cpPath)) != SA_OK) { log2(ctx, ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(rc)); throw(0,0,0); } if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) { log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(rc)); throw(0,0,0); } if (nPerm != -1) { if (chmod(cpPath, nPerm) == -1) { log3(ctx, ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"", cpPath, nPerm, strerror(errno)); d348 2 a349 4 } if (getuid() == 0 && getuid() != ctx->option_uid) { if (chown(cpPath, ctx->option_uid, -1) == -1) { log3(ctx, ERROR, "option --bind, chown (%s, %d) failed with \"%s\"", cpPath, ctx->option_uid, strerror(errno)); d353 4 a356 11 free(cpPath); } /* otherwise assume INET socket */ else { if ((rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", ov->data.s)) != SA_OK) { log2(ctx, ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); throw(0,0,0); } if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) { log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); throw(0,0,0); a358 5 /* for either sockets */ if ((rc = sa_listen(ctx->saServerbind, -1)) != SA_OK) { log2(ctx, ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); throw(0,0,0); } d367 3 a369 2 || (ov->ndata != 1) || (ov->data.s == NULL) d373 9 a381 7 if ((rc = sa_addr_create(&ctx->saaClientbind)) != SA_OK) { log1(ctx, ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(rc)); throw(0,0,0); } if ((rc = sa_addr_u2a(ctx->saaClientbind, "inet://%s", ov->data.s)) != SA_OK) { log2(ctx, ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); throw(0,0,0); d393 2 a394 1 || ((ov->ndata >= 1) && (ov->data.m == NULL)) d400 22 a421 19 if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); if (strrchr(cp, ':') == NULL) cp = str_concat(cp, ":nntp", NULL); //FIXME is this a config var/val? else cp = str_concat(cp, NULL); /* prepare for free() */ if ((rc = sa_addr_create(&ctx->ns[i].saa)) != SA_OK) { log1(ctx, ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(rc)); throw(0,0,0); } if ((rc = sa_addr_u2a(ctx->ns[i].saa, "inet://%s", cp)) != SA_OK) { log2(ctx, ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); throw(0,0,0); } if ((rc = sa_create(&ctx->ns[i].sa)) != SA_OK) { log2(ctx, ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); throw(0,0,0); d423 1 a423 1 free(cp); a424 1 ctx->nns = i; d432 3 a434 2 || (ov->ndata != 1) || (ov->data.s == NULL) d438 11 a448 9 if (strcasecmp(ov->data.s, "arg") == 0) ctx->option_groupmode = GROUPMODE_ARG; else if (strcasecmp(ov->data.s, "envelope") == 0) ctx->option_groupmode = GROUPMODE_ENVELOPE; else if (strcasecmp(ov->data.s, "header") == 0) ctx->option_groupmode = GROUPMODE_HEADER; else { log1(ctx, ERROR, "option --groupmode, invalid mode (%s)", ov->data.s); throw(0,0,0); d462 2 a463 1 || ((ov->ndata >= 1) && (ov->data.m == NULL)) d469 25 a493 23 if ((ctx->pacl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); cpHeader = strdup(cp); if ((cp = strchr(cpHeader, ':')) == NULL) { log1(ctx, ERROR, "option --headervalue, header (%s) terminating colon missing", (ov->data.m)[i]); throw(0,0,0); } *cp = NUL; log2(ctx, DEBUG, "header[%d] = \"%s\"", i, cpHeader); cp++; while (*cp == ' ') cp++; //FIXME note this in NEWS if (*cp == NUL) { log1(ctx, ERROR, "option --headervalue, value (%s) missing", (ov->data.m)[i]); throw(0,0,0); } cpValue = strdup(cp); log2(ctx, DEBUG, " value[%d] = \"%s\"", i, cpValue); argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpHeader); argz_add(&ctx->azHeaderValuePairs, &ctx->asHeaderValuePairs, cpValue); free(cpHeader); free(cpValue); d504 3 a506 2 || (ov->ndata != 1) || (ov->data.s == NULL) d510 15 a524 13 ctx->option_mailfrom = strdup(ov->data.s); /* protect ourselfs from the substitution of backreferences. * Missing varargs would cause segfaults. Rewrite capturing * brackets to clustering syntax. Use poor man's s///g * simulator as current str library doesn't support global * substitution */ while (str_parse(ctx->option_mailfrom, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) { free(ctx->option_mailfrom); ctx->option_mailfrom = cp; } if (str_parse("<>", ctx->option_mailfrom) == -1) { log1(ctx, ERROR, "option --mailfrom, illegal regex (%s)", ctx->option_mailfrom); throw(0,0,0); d533 3 a535 2 || (ov->ndata != 1) || (ov->data.s == NULL) d539 6 a544 3 if (strlen(ov->data.s) > sizeof(ctx->uname.nodename)-1) { log1(ctx, ERROR, "option --nodename, name (%s) too long", ov->data.s); throw(0,0,0); a545 1 strcpy(ctx->uname.nodename, ov->data.s); d555 3 a557 2 || (ov->ndata != 1) || (ov->data.s == NULL) d561 37 a597 35 cp = strdup(ov->data.s); if (strcasecmp(cp, "post") == 0) ctx->option_operationmode = OPERATIONMODE_POST; else if (strcasecmp(cp, "feed") == 0) ctx->option_operationmode = OPERATIONMODE_FEED; else { if (strlen(cp) != 9) { log1(ctx, ERROR, "option --operationmode, invalid length (%s)", cp); throw(0,0,0); } if (cp[3] != '/') { log1(ctx, ERROR, "option --operationmode, missing slash (%s)", cp); throw(0,0,0); } cp[3] = NUL; ctx->option_operationmodefakestatus = &cp[0]; ctx->option_operationmodefakedsn = &cp[4]; if ( strlen(ctx->option_operationmodefakestatus) != 3 || !isdigit((int)ctx->option_operationmodefakestatus[0]) || !isdigit((int)ctx->option_operationmodefakestatus[1]) || !isdigit((int)ctx->option_operationmodefakestatus[2]) ) { log1(ctx, ERROR, "option --operationmode, invalid status code (%s)", cp); throw(0,0,0); } if ( (strlen(ctx->option_operationmodefakedsn) != 5) || !isdigit((int)ctx->option_operationmodefakedsn[0]) || (ctx->option_operationmodefakedsn[1] != '.') || !isdigit((int)ctx->option_operationmodefakedsn[2]) || (ctx->option_operationmodefakedsn[3] != '.') || !isdigit((int)ctx->option_operationmodefakedsn[4]) || (ctx->option_operationmodefakedsn[0] != ctx->option_operationmodefakestatus[0]) ) { log1(ctx, ERROR, "option --operationmode, invalid dsn code (%s)", cp); throw(0,0,0); d609 3 a611 2 || (ov->ndata != 1) || (ov->data.s == NULL) d615 15 a629 13 ctx->option_restrictheader = strdup(ov->data.s); /* protect ourselfs from the substitution of backreferences. * Missing varargs would cause segfaults. Rewrite capturing * brackets to clustering syntax. Use poor man's s///g * simulator as current str library doesn't support global * substitution */ while (str_parse(ctx->option_restrictheader, "s/(.*?)\\((?!\\?:)(.*)/$1(?:$2/", &cp) > 0) { free(ctx->option_restrictheader); ctx->option_restrictheader = cp; } if (str_parse("<>", ctx->option_restrictheader) == -1) { log1(ctx, ERROR, "option --restrictheader, illegal regex (%s)", ctx->option_restrictheader); throw(0,0,0); d638 3 a640 2 || (ov->ndata != 1) || (ov->data.s == NULL) d644 5 a648 4 if ((ctx->option_maxmessagesize = atoi(ov->data.s)) <= 0) { log1(ctx, ERROR, "option --size, number (%d) out of range", ctx->option_maxmessagesize); throw(0,0,0); } d658 3 a660 2 || (ov->ndata != 1) || (ov->data.s == NULL) d663 10 a672 8 if ((i = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutlmtp, number (%d) out of range", i); throw(0,0,0); } ctx->option_timeout_lmtp_accept = i; ctx->option_timeout_lmtp_read = i; ctx->option_timeout_lmtp_write = i; d680 3 a682 2 || (ov->ndata != 1) || (ov->data.s == NULL) d686 5 a690 4 if ((ctx->option_timeout_lmtp_accept = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutlmtpaccept, number (%d) out of range", ctx->option_timeout_lmtp_accept); throw(0,0,0); } d698 3 a700 2 || (ov->ndata != 1) || (ov->data.s == NULL) d704 5 a708 4 if ((ctx->option_timeout_lmtp_read = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutlmtpread, number (%d) out of range", ctx->option_timeout_lmtp_read); throw(0,0,0); } d716 3 a718 2 || (ov->ndata != 1) || (ov->data.s == NULL) d722 5 a726 4 if ((ctx->option_timeout_lmtp_write = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutlmtpwrite, number (%d) out of range", ctx->option_timeout_lmtp_write); throw(0,0,0); } d736 3 a738 2 || (ov->ndata != 1) || (ov->data.s == NULL) d742 9 a750 7 if ((i = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutnntp, number (%d) out of range", i); throw(0,0,0); } ctx->option_timeout_nntp_connect = i; ctx->option_timeout_nntp_read = i; ctx->option_timeout_nntp_write = i; d758 3 a760 2 || (ov->ndata != 1) || (ov->data.s == NULL) d764 5 a768 4 if ((ctx->option_timeout_nntp_connect = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutnntpconnect, number (%d) out of range", ctx->option_timeout_nntp_connect); throw(0,0,0); } d776 3 a778 2 || (ov->ndata != 1) || (ov->data.s == NULL) d782 5 a786 4 if ((ctx->option_timeout_nntp_read = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutnntpread, number (%d) out of range", ctx->option_timeout_nntp_read); throw(0,0,0); } d794 3 a796 2 || (ov->ndata != 1) || (ov->data.s == NULL) d800 5 a804 4 if ((ctx->option_timeout_nntp_write = atoi(ov->data.s)) < 0) { log1(ctx, ERROR, "option --timeoutnntpwrite, number (%d) out of range", ctx->option_timeout_nntp_write); throw(0,0,0); } d814 3 a816 2 || (ov->ndata != 1) || (ov->data.s == NULL) d820 6 a825 4 if (isdigit((int)ov->data.s[0])) { if ((sPasswd = getpwuid((uid_t)atoi(ov->data.s))) == NULL) { log1(ctx, ERROR, "option --user, uid (%s) not found", ov->data.s); throw(0,0,0); d827 5 a831 5 } else { if ((sPasswd = getpwnam(ov->data.s)) == NULL) { log1(ctx, ERROR, "option --user, name (%s) not found", ov->data.s); throw(0,0,0); d833 1 a834 1 ctx->option_uid = sPasswd->pw_uid; d842 4 a845 2 || (ov->ndata != 1) || (ov->data.f != 1) d849 4 a852 3 log1(ctx, INFO, "program version %s", lmtp2nntp_version.v_gnu); fprintf(stdout, "%s\n", lmtp2nntp_version.v_gnu); //FIXME is fprintf really the way to go? d863 2 a864 1 || ((ov->ndata >= 1) && (ov->data.m == NULL)) d870 6 a875 4 for (i = 0; i < ov->ndata; i++) { cp = (ov->data.m)[i]; log2(ctx, DEBUG, "cp = (data.m)[%d] = \"%s\"", i, cp); argz_add(&ctx->azGroupargs, &ctx->asGroupargs, cp); @ 1.36 log @moved/added --newsgroup option @ text @d112 2 @ 1.35 log @bugfix @ text @d792 22 @ 1.34 log @moved --version option @ text @d768 1 a768 1 if ((sPasswd = getpwnam(optarg)) == NULL) { @ 1.33 log @moved --user option @ text @d777 15 @ 1.32 log @moved --timeout_XXX options @ text @d32 1 d751 26 @ 1.31 log @moved --size option @ text @d612 138 @ 1.30 log @moved --restrictheader option @ text @d595 17 @ 1.29 log @bugfix @ text @d567 28 @ 1.28 log @moved --operationmode option @ text @d508 1 a508 1 if (strlen(optarg) > sizeof(ctx->uname.nodename)-1) { @ 1.27 log @moved --nodename option @ text @d516 51 @ 1.26 log @moved --mailfrom option @ text @d499 17 @ 1.25 log @moved --headervalue option @ text @d472 27 @ 1.24 log @moved --groupmode option @ text @d429 43 @ 1.23 log @use one line for a log, no matter how large @ text @d407 22 @ 1.22 log @moved --destination option @ text @d164 1 a164 2 log1(ctx, ERROR, "option --childsmax, number (%d) out of range", ctx->option_childsmax); d244 1 a244 2 log1(ctx, ERROR, "option --acl, create address (internal) failed with \"%s\"", sa_error(rc)); d248 1 a248 2 log2(ctx, ERROR, "option --acl, parsing address (%s) failed with \"%s\"", ctx->pacl[i].acl, sa_error(rc)); d268 1 a268 2 log1(ctx, ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"", sa_error(rc)); d272 1 a272 2 log1(ctx, ERROR, "option --bind, create address (internal) failed with \"%s\"", sa_error(rc)); d302 1 a302 2 log1(ctx, ERROR, "option --bind, invalid permissions \"%s\"", cpPerm); d307 1 a307 2 log2(ctx, ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"", cpPath, sa_error(rc)); d311 1 a311 2 log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", cpPath, sa_error(rc)); d316 1 a316 2 log3(ctx, ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"", cpPath, nPerm, strerror(errno)); d322 1 a322 2 log3(ctx, ERROR, "option --bind, chown (%s, %d) failed with \"%s\"", cpPath, ctx->option_uid, strerror(errno)); d331 1 a331 2 log2(ctx, ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d335 1 a335 2 log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d341 1 a341 2 log2(ctx, ERROR, "option --bind, listen (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); d358 1 a358 2 log1(ctx, ERROR, "option --client, create address (internal) failed with \"%s\"", sa_error(rc)); d362 1 a362 2 log2(ctx, ERROR, "option --client, parsing alternate IO guessing INET socket (%s) failed with \"%s\"", ov->data.s, sa_error(rc)); a388 1 log1(ctx, DEBUG, "cp = \"%s\"", cp); d390 1 a390 2 log1(ctx, ERROR, "option --destination, create address (internal) failed with \"%s\"", sa_error(rc)); d394 1 a394 2 log2(ctx, ERROR, "option --destination, parsing host address (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); d398 1 a398 2 log2(ctx, ERROR, "option --destination, creating TCP socket (%s) failed with \"%s\"", cp /*FIXME again, option vs. config */, sa_error(rc)); @ 1.21 log @moved --client option @ text @d384 42 @ 1.20 log @moved --bind option @ text @d362 22 @ 1.19 log @moved --acl option @ text @d260 102 @ 1.18 log @flush. first options moved. introduced exception handling. @ text @d162 1 d164 2 a165 1 log1(ctx, ERROR, "number (%d) out of range for option --childsmax\n", ctx->option_childsmax); a169 3 log1(ctx, ERROR, "caught class %s\n", ex.ex_class == NULL ? "N/A" : (char *)ex.ex_class ); log1(ctx, ERROR, "caught object %s\n", ex.ex_object == NULL ? "N/A" : (char *)ex.ex_object); log1(ctx, ERROR, "caught value %s\n", ex.ex_value == NULL ? "N/A" : (char *)ex.ex_value ); d180 1 d193 1 d206 1 d214 1 a215 2 char *cp; struct acl *acl; d220 1 d223 2 a224 2 log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata); if ((acl = (struct acl *)malloc(ov->ndata * sizeof(struct acl))) == NULL) throw(0,0,0); d228 26 a253 1 //ctx->option_acl[ctx->option_aclc].acl = strdup(cp); d255 1 a255 1 a258 41 #if 0 if (argz_create_sep(optarg, ',', &azACL, &asACL) != 0) CU(ERR_EXECUTION); cp = NULL; while ((cp = argz_next(azACL, asACL, cp)) != NULL) { if (ctx->option_aclc >= MAXACLS) { fprintf(stderr, "%s:Error: Too many ACL (%d) using option -a\n", ctx->progname, ctx->option_aclc); CU(ERR_EXECUTION); } ctx->option_acl[ctx->option_aclc].acl = strdup(cp); if (cp[0] == '!') { ctx->option_acl[ctx->option_aclc].not = TRUE; cpAddr = strdup(cp+1); } else { cpAddr = strdup(cp); } if ((cpPrefixLen = strrchr(cpAddr, '/')) != NULL) *cpPrefixLen++ = NUL; else cpPrefixLen = "-1"; ctx->option_acl[ctx->option_aclc].prefixlen = atoi(cpPrefixLen); if ((rc = sa_addr_create(&ctx->option_acl[ctx->option_aclc].saa)) != SA_OK) { fprintf(stderr, "%s:Error: Creating address failed for -a option (%d)\n", ctx->progname, rc); } if ((rc = sa_addr_u2a(ctx->option_acl[ctx->option_aclc].saa, "inet://%s:0", cpAddr)) != SA_OK) { fprintf(stderr, "%s:Error: Parsing host address failed for \"%s:0\" (%d)\n", ctx->progname, cpAddr, rc); CU(ERR_EXECUTION); } ctx->option_aclc++; free(cpAddr); } free(azACL); #endif @ 1.17 log @Switch from local copy of POPT to our new linked-in child OSSP popt. @ text @d31 1 d40 1 d80 24 d106 1 d108 65 a172 1 char *cp; d174 8 a181 9 printf("DEBUG: Hello, World!\n"); //case 'C': /*POD [B<-C> I] */ if (val_get(ctx->val, "option.childsmax", &ov) != VAL_OK) fprintf(stderr, "%s:Error: (internal) config did not register 'childsmax' option\n", ctx->progname); printf("DEBUG: option_childsmax %d = \"%s\"\n", ov->ndata, ov->data.s); ctx->option_childsmax = atoi(ov->data.s); if (ctx->option_childsmax <= 0) { fprintf(stderr, "%s:Error: Invalid number (%d) to option -C\n", ctx->progname, ctx->option_childsmax); return; //FIXME CU(ERR_EXECUTION); d183 92 @ 1.16 log @option works and data can be read by config @ text @a33 1 #include "lmtp2nntp_popt.h" d36 3 a38 2 #include #include @ 1.15 log @moved config to option, created a new config @ text @d80 13 @ 1.14 log @fixed nasty realloc problem. Thanks FreeBSD for MALLOC_OPTIONS=Z @ text @d1 1 d25 1 a25 1 ** FIXME lmtp2nntp_config.c: LMTP to NNTP configuration parsing d57 1 d62 1 d78 1 a78 84 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) d80 1 a80 526 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) { 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; @ 1.13 log @flag options no longer have an optarg @ text @d95 1 a95 1 union { /* option data as read from configuration */ d97 1 d99 1 d117 1 a117 2 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; d124 11 a134 1 printf("DEBUG: [%3d] \"%s\"\n", i, oc->data.m[i]); d399 1 a399 1 printf("DEBUG: flag %20s = %s should match %s\n", oc->longname, arg, cbctx); d408 1 a408 1 printf("DEBUG: single %20s = %s should match %s\n", oc->longname, arg, cbctx); a414 1 #if 0 a420 1 #endif d426 1 a426 1 printf("DEBUG: multi %20s = %s should match %s\n", oc->longname, arg, cbctx); a430 1 #if 0 d437 1 a437 1 #endif d439 3 a441 1 if ((oc->data.m = (char **)malloc( ( 1 + 1) * sizeof(char **))) == NULL) d443 1 d446 3 a448 1 if ((oc->data.m = (char **)realloc(oc->data.m, (oc->ndata + 1) * sizeof(char **))) == NULL) d450 1 d456 1 a456 1 #if 1 d460 2 a461 2 for (i=0; indata; i++) printf("DEBUG: oc->data[%3d] = %s\n", i, oc->data.m[i]); d661 2 @ 1.12 log @can now read flat example.conf through include option @ text @d345 30 a374 2 while ((cp = (char *)popt_getarg(poptCon)) != NULL) { printf("DEBUG: popt_getarg returned \"%s\"\n", cp); d404 1 d411 1 d422 1 d429 1 d442 8 d542 18 a564 19 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; a582 1 @ 1.11 log @flush @ text @a29 13 #if 0 #include #include #include #include #include #include #include #include #include #include #include #endif a31 1 #if 0 a32 3 #include "lmtp2nntp_shpat.h" #include "lmtp2nntp_daemon.h" #endif a33 1 #include "val.h" d36 2 a37 5 #include "str.h" #if 0 #include "l2.h" #include "var.h" #endif a39 2 #define L2_VERSION_HEX_REQ 0x001200 #define L2_VERSION_STR_REQ "0.1.0" a41 5 #ifdef L2_VERSION_HEX #if L2_VERSION_HEX < L2_VERSION_HEX_REQ #error "require a newer version of OSSP L2" #endif #endif a59 1 #include "sa.h" d75 1 a75 2 void die(char *); /* FIXME */ void die(char *msg) d77 2 a78 2 //printf("ERROR: %s\n", msg); exit(-1); a80 114 #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 d83 1 d123 1 a123 1 printf("DEBUG: [%3d] =<%20s>\n", i, oc->data.m[i]); d131 2 a132 2 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) d162 1 d171 1 a171 1 oc->number = o->pi; /*FIXME + 1; 0 is a reserved val in popt, so offset 1 */ d185 2 a186 1 (void)/*FIXME rc*/val_reg(oc->val, oc->longname, VAL_TYPE_PTR, oc->descrip, oc); d195 1 a195 1 o->pt = (struct popt_option *)malloc( (1 + 2) * sizeof(struct popt_option)); /*FIXME out of mem*/ d200 1 a200 1 o->pt = (struct popt_option *)realloc(o->pt, (o->pn * 2 + 2) * sizeof(struct popt_option)); /*FIXME out of mem*/ d204 2 d257 96 d355 1 a355 1 printf("DEBUG: enter stdsyntax %.8lx, \"%s\", \"%s\"\n", (long)oc, arg, cbctx); d360 1 a360 1 printf("DEBUG: flag\n"); d369 1 a369 1 printf("DEBUG: single\n"); d372 4 a375 2 if (oc->ndata >= 1 || oc->data.s != NULL) return OPTION_ERR_USE; d381 1 a381 1 printf("DEBUG: \"%s\" does match \"%s\"\n", arg, cbctx); d387 1 a387 1 //printf("DEBUG: multi\n"); d420 38 a457 2 return OPTION_OK; } d459 5 a463 3 lmtp2nntp_option_rc_t option_create(lmtp2nntp_option_t **op) { //printf("DEBUG: enter option_create(%.8lx)\n", (long)op); d465 29 a493 2 if (op == NULL) return OPTION_ERR_ARG; d495 12 a506 40 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; d508 35 a542 3 if (val_create(&((*op)->vo)) != VAL_OK) { free(*op); return OPTION_ERR_VAL; d544 2 a545 1 return OPTION_OK; d550 1 d556 28 a583 28 (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" ); d586 9 a594 18 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); a595 7 //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); d597 4 d602 1 a602 1 return OPTION_OK; @ 1.10 log @flush @ text @d107 1 a107 1 printf("ERROR: %s\n", msg); a111 42 static val_rc_t dumper(void *ctx, const char *name, int type, const char *desc, void *data) { switch (type) { case VAL_TYPE_VAL: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_VAL, desc=<%20s>, data@@%.8lx INTERNAL\n", (char *)ctx, name, desc, (long)data); break; case VAL_TYPE_PTR: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_PTR, desc=<%20s>, data@@%.8lx=%.8lx\n", (char *)ctx, name, desc, (long)data, *(long *)data); break; case VAL_TYPE_CHAR: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_CHAR, desc=<%20s>, data@@%.8lx='%c'\n", (char *)ctx, name, desc, (long)data, *(char *)data); break; case VAL_TYPE_SHORT: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_SHORT, desc=<%20s>, data@@%.8lx=%8d\n", (char *)ctx, name, desc, (long)data, *(short *)data); break; case VAL_TYPE_INT: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_INT, desc=<%20s>, data@@%.8lx=%8d\n", (char *)ctx, name, desc, (long)data, *(int *)data); break; case VAL_TYPE_LONG: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_LONG, desc=<%20s>, data@@%.8lx=%8ld\n", (char *)ctx, name, desc, (long)data, *(long *)data); break; case VAL_TYPE_FLOAT: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_FLOAT, desc=<%20s>, data@@%.8lx=%8f\n", (char *)ctx, name, desc, (long)data, *(float *)data); break; case VAL_TYPE_DOUBLE: printf("DEBUG: <%10s>, name=<%10s>, VAL_TYPE_DOUBLE, desc=<%20s>, data@@%.8lx=%8f\n", (char *)ctx, name, desc, (long)data, *(double *)data); break; default: printf("DEBUG: <%10s>, name=<%10s>, type = %.8lx, desc=<%20s>, data@@%.8lx\n", (char *)ctx, name, (long)type, desc, (long)data); } return VAL_OK; } d153 1 a153 1 printf("DEBUG: *** 1 *** file as it was just read in ***\n%s***\n", cpBuf); d193 1 a193 1 printf("DEBUG: line[%3d] = ***%s***\n", lline, cpL); d195 1 a195 1 printf("DEBUG: [%3d-%3d] = ***%s***\n", lline, pline-1, cpL); d202 1 a202 1 printf("DEBUG: no command - comment only\n"); d204 1 a204 1 printf("DEBUG: command = ***%s***\n", command); d206 1 a206 1 printf("DEBUG: no value - section\n"); d209 1 a209 1 printf("DEBUG: value = ***%s***\n", value); d226 1 a226 1 optionconfig_t *next; /* cleanup chain for destroy */ a234 1 void *pass1default; /* default for pass1 */ d237 5 a241 5 int number; /* number of this option for popt */ union { /* option data as read from configuration */ int f; /* OPT_FLAG */ char *s; /* OPT_SINGLE */ char **m; /* OPT_MULTI */ d243 1 d246 28 d295 1 a295 1 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); d303 1 a303 1 printf("DEBUG: optionconfig_t structure malloc'ed\n"); a311 1 oc->pass1default = NULL; /*FIXME*/ d314 4 d324 1 a324 1 printf("DEBUG: optionconfig_t structure created\n"); d327 1 a327 3 (void)/*FIXME rc*/val_reg(oc->val, oc->longname, type == OPT_FLAG ? VAL_TYPE_INT : VAL_TYPE_PTR, oc->descrip, NULL); d329 1 a329 1 printf("DEBUG: val_reg'ed\n"); d332 1 a332 1 printf("DEBUG: o->pi=%d, o->pn=%d\n", o->pi, o->pn); d335 1 a335 1 printf("DEBUG: malloc\n"); d340 1 a340 1 printf("DEBUG: realloc\n"); d371 1 a371 1 printf("DEBUG: popt'ed\n"); d382 1 a382 1 printf("DEBUG: linked\n"); d396 1 a396 1 static void stdsyntax(optionconfig_t *oc, char *arg, char *cbctx) d399 58 a456 1 return; d459 1 a459 1 static void includeit(optionconfig_t *oc, char *arg, char *cbctx) d461 1 a461 1 return; d466 1 a466 1 printf("DEBUG: enter option_create(%.8lx)\n", (long)op); d521 1 a521 1 printf("DEBUG: enter option_parse(%.8lx, %d, %.8lx)\n", (long)o, argc, (long)argv); d526 1 a526 1 (void)option_register(o, "childsmax", 'C', OPT_SINGLE, &stdsyntax, "[0-9]{,5}", "foo", "childsmax" ); d529 1 a529 1 (void)option_register(o, "pidfile", 'P', OPT_SINGLE, &stdsyntax, ".{,255}", "foo", "pidfile" ); d531 22 a552 22 (void)option_register(o, "acl", 'a', OPT_MULTI, &stdsyntax, "[0-9.](/[0-9]2)?", "foo", "addr[/mask]" ); (void)option_register(o, "bind", 'b', OPT_SINGLE, &stdsyntax, ".*", "foo", "addr[:port]|-|path[:perms]" ); (void)option_register(o, "client", 'c', OPT_SINGLE, &stdsyntax, ".*", "foo", "addr[:port]" ); (void)option_register(o, "destination", 'd', OPT_MULTI, &stdsyntax, ".*", "foo", "addr[:port]" ); (void)option_register(o, "groupmode", 'g', OPT_SINGLE, &stdsyntax, ".*", "foo", "groupmode" ); (void)option_register(o, "headervalue", 'h', OPT_MULTI, &stdsyntax, ".*", "foo", "header: value" ); (void)option_register(o, "include", 'i', OPT_MULTI, &includeit, ".*", "foo", "configfile" ); (void)option_register(o, "size", 's', OPT_SINGLE, &stdsyntax, ".*", "foo", "bytes" ); (void)option_register(o, "timeoutlmtpaccept", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "sec" ); (void)option_register(o, "timeoutlmtpread", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "sec" ); (void)option_register(o, "timeoutlmtpwrite", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "sec" ); (void)option_register(o, "timeoutnntpconnect", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "sec" ); (void)option_register(o, "timeoutnntpread", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "sec" ); (void)option_register(o, "timeoutnntpwrite", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "sec" ); (void)option_register(o, "mailfrom", 'm', OPT_SINGLE, &stdsyntax, ".*", "foo", "regex" ); (void)option_register(o, "nodename", 'n', OPT_SINGLE, &stdsyntax, ".*", "foo", "nodename" ); (void)option_register(o, "operationmode", 'o', OPT_SINGLE, &stdsyntax, ".*", "foo", "post|feed" ); (void)option_register(o, "l2spec", 'l', OPT_SINGLE, &stdsyntax, ".*", "foo", "spec" ); (void)option_register(o, "uid", 'u', OPT_SINGLE, &stdsyntax, ".*", "foo", "number|name" ); (void)option_register(o, "restrictheader", 'r', OPT_MULTI, &stdsyntax, ".*", "foo", "regex" ); (void)option_register(o, "newsgroup", NUL, OPT_MULTI, &stdsyntax, ".*", "foo", "newsgroup"); d562 1 a562 1 printf("DEBUG: argc=%d\n", argc); d569 5 a573 6 if (ocp->type == OPT_FLAG) ocp->cb(ocp, "ohne", ocp->cbctx); else ocp->cb(ocp, cp = 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); d575 2 a576 2 printf("DEBUG: current popt error is \"%s\"(%d)\n", popt_strerror(i), i); printf("DEBUG: ----\n"); d578 1 a578 1 printf("DEBUG: popt_getarg returned \"%s\"\n", cp); d580 1 a580 1 printf("DEBUG: current popt error is \"%s\"(%d)\n", popt_strerror(i), i); d583 1 d589 3 d595 14 a610 1 @ 1.9 log @flush weekly work @ text @d116 1 a116 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_VAL, desc=<%20s>, data@@%.8lx INTERNAL\n", d120 1 a120 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_PTR, desc=<%20s>, data@@%.8lx=%.8lx\n", d124 1 a124 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_CHAR, desc=<%20s>, data@@%.8lx='%c'\n", d128 1 a128 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_SHORT, desc=<%20s>, data@@%.8lx=%8d\n", d132 1 a132 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_INT, desc=<%20s>, data@@%.8lx=%8d\n", d136 1 a136 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_LONG, desc=<%20s>, data@@%.8lx=%8ld\n", d140 1 a140 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_FLOAT, desc=<%20s>, data@@%.8lx=%8f\n", d144 1 a144 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, VAL_TYPE_DOUBLE, desc=<%20s>, data@@%.8lx=%8f\n", d148 1 a148 1 fprintf(stderr, "DEBUG: <%10s>, name=<%10s>, type = %.8lx, desc=<%20s>, data@@%.8lx\n", a162 29 popt_context poptCon; /* context for parsing command-line options */ lmtp2nntp_config_t *ctx; char *cpBuf; struct popt_option poptTable[] = { { "childsmax", 'C', POPT_ARG_STRING, NULL, 'C', "foo", "childsmax" }, { "daemonize", 'D', POPT_ARG_NONE, NULL, 'D', "foo", NULL }, { "kill", 'K', POPT_ARG_NONE, NULL, 'K', "foo", NULL }, { "pidfile", 'P', POPT_ARG_STRING, NULL, 'P', "foo", "pidfile" }, { "veryverbose", 'V', POPT_ARG_NONE, NULL, 'V', "foo", NULL }, { "acl", 'a', POPT_ARG_STRING, NULL, 'a', "foo", "addr[/mask]" }, { "bind", 'b', POPT_ARG_STRING, NULL, 'b', "foo", "addr[:port]|-|path[:perms]" }, { "client", 'c', POPT_ARG_STRING, NULL, 'c', "foo", "addr[:port]" }, { "destination", 'd', POPT_ARG_STRING, NULL, 'd', "foo", "addr[:port]" }, { "groupmode", 'g', POPT_ARG_STRING, NULL, 'g', "foo", "groupmode" }, { "headervalue", 'h', POPT_ARG_STRING, NULL, 'h', "foo", "header: value" }, { "include", 'i', POPT_ARG_STRING, NULL, 'i', "foo", "configfile" }, { "size", 's', POPT_ARG_STRING, NULL, 's', "foo", "bytes" }, { "timeout", 't', POPT_ARG_STRING, NULL, 't', "foo", "name=sec" }, { "mailfrom", 'm', POPT_ARG_STRING, NULL, 'm', "foo", "regex" }, { "nodename", 'n', POPT_ARG_STRING, NULL, 'n', "foo", "nodename" }, { "operationmode", 'o', POPT_ARG_STRING, NULL, 'o', "foo", "post|feed" }, { "l2spec", 'l', POPT_ARG_STRING, NULL, 'l', "foo", "spec" }, { "uid", 'u', POPT_ARG_STRING, NULL, 'u', "foo", "number|name" }, { "restrictheader", 'r', POPT_ARG_STRING, NULL, 'r', "foo", "regex" }, { "newsgroup", NUL, POPT_ARG_STRING |POPT_ARGFLAG_DOC_HIDDEN, NULL, 1, NULL, NULL }, POPT_AUTOHELP { NULL, 0, 0, NULL, 0 } }; a166 125 { int testint = 10; int testintout = 100; int testint2 = 20; int testintout2 = 200; val_rc_t rc; val_t *v, *v2, *v3; if ((rc = val_create(&v)) != VAL_OK) die("val_create"); printf("DEBUG: testint = %d, testintout = %d\n", testint, testintout); if ((rc = val_reg(v, "foo", VAL_TYPE_INT, "foo variable", (void *)&testint)) != VAL_OK) die("val_reg"); testint++; if ((rc = val_get(v, "foo", &testintout)) != VAL_OK) die("val_get"); printf("DEBUG: testint = %d, testintout = %d\n", testint, testintout); if ((rc = val_set(v, "foo", 2)) != VAL_OK) die("val_set"); if ((rc = val_get(v, "foo", &testintout)) != VAL_OK) die("val_get"); printf("DEBUG: testint = %d, testintout = %d\n", testint, testintout); if ((rc = val_create(&v2)) != VAL_OK) die("val_create 2"); if ((rc = val_reg(v, "bar", VAL_TYPE_VAL, "bar variable", (void *)&v2)) != VAL_OK) die("val_reg 2"); val_reg(v, "bar", VAL_TYPE_VAL, "bar variable", NULL); val_set(v, "bar", v2); if ((rc = val_get(v, "bar", &v3)) != VAL_OK) die("val_get v3"); if ((rc = val_reg(v2, "quux", VAL_TYPE_INT, "quux variable", (void *)&testint2)) != VAL_OK) die("val_reg 2b"); testint2++; if ((rc = val_get(v2, "quux", &testintout2)) != VAL_OK) die("val_get 2c"); printf("DEBUG: testint2 = %d, testintout2 = %d\n", testint2, testintout2); if ((rc = val_get(v, "bar.quux", &testintout2)) != VAL_OK) { fprintf(stderr, "rc=%d\n", rc); die("val_get 2d"); } printf("DEBUG: testint2 = %d, testintout2 = %d\n", testint2, testintout2); printf("DEBUG: testint at address %lx\n", (long)&testint); printf("DEBUG: testintout at address %lx\n", (long)&testintout); printf("DEBUG: testint2 at address %lx\n", (long)&testint2); printf("DEBUG: testint2out at address %lx\n", (long)&testintout2); if ((rc = val_reg(v, "bar.ptr", VAL_TYPE_PTR, "bar ptr (&testint)", NULL)) != VAL_OK) die("val_ret for bar.ptr using inline data"); if ((rc = val_set(v, "bar.ptr", &testint)) != VAL_OK) die("val_set for bar.ptr using inline data"); if ((rc = val_reg(v, "bar.char", VAL_TYPE_CHAR, "bar character (!)", NULL)) != VAL_OK) die("val_ret for bar.char using inline data"); if ((rc = val_set(v, "bar.char", '!')) != VAL_OK) die("val_set for bar.char using inline data"); if ((rc = val_reg(v, "bar.short", VAL_TYPE_SHORT, "bar short (555)", NULL)) != VAL_OK) die("val_ret for bar.short using inline data"); if ((rc = val_set(v, "bar.short", 555)) != VAL_OK) die("val_set for bar.short using inline data"); if ((rc = val_reg(v, "bar.int", VAL_TYPE_INT, "bar integer (76543)", NULL)) != VAL_OK) die("val_ret for bar.int using inline data"); if ((rc = val_set(v, "bar.int", 76543)) != VAL_OK) die("val_set for bar.int using inline data"); if ((rc = val_reg(v, "bar.long", VAL_TYPE_LONG, "bar long (2097152)", NULL)) != VAL_OK) die("val_ret for bar.long using inline data"); if ((rc = val_set(v, "bar.long", 2097152)) != VAL_OK) die("val_set for bar.long using inline data"); if ((rc = val_reg(v, "bar.float", VAL_TYPE_FLOAT, "bar float (1.955830)", NULL)) != VAL_OK) die("val_ret for bar.float using inline data"); if ((rc = val_set(v, "bar.float", 1.95583)) != VAL_OK) die("val_set for bar.float using inline data"); if ((rc = val_reg(v, "bar.double", VAL_TYPE_DOUBLE, "bar double (3.1415+)", NULL)) != VAL_OK) die("val_ret for bar.double using inline data"); if ((rc = val_set(v, "bar.double", 3.14159265358979)) != VAL_OK) die("val_set for bar.double using inline data"); OK val_apply(v, "", 9, dumper, "v" ); OK val_apply(v2, "", 9, dumper, "v2"); OK val_apply(v, "", 0, dumper, "v" ); OK val_apply(v, "bar", 1, dumper, "v" ); OK val_apply(v2, "", 0, dumper, "v" ); OK val_apply(v, "", 1, dumper, "v" ); OK val_apply(v, "foo", 0, dumper, "v" ); OK val_apply(v2, "char", 2, dumper, "v" ); OK val_apply(v, "bar.char", 2, dumper, "v" ); if ((rc = val_destroy(v2)) != VAL_OK) die("val_destroy 2"); if ((rc = val_destroy(v)) != VAL_OK) die("val_destroy"); return; } { char c; char *cp; poptCon = popt_getcontext(NULL, argc, (const char **)argv, poptTable, 0); popt_setotheroptionhelp(poptCon, "[OPTIONS]* [newsgroup ...]"); printf("DEBUG: argc=%d\n", argc); if (argc < 2) { popt_printusage(poptCon, stderr, 0); exit(1); } while ((c = popt_getnextopt(poptCon)) >= 0) { printf("DEBUG: popt_getnextopt returned %d='%c'\n", (int)c, c); } while ((cp = popt_getarg(poptCon)) != NULL) { printf("DEBUG: popt_getarg returned \"%s\"\n", cp); } printf("DEBUG: popt_getnextopt ended with \"%s\"(%d)\n", popt_strerror((int)c), (int)c); popt_freecontext(poptCon); return; } a266 10 typedef enum { OPT_FLAG, OPT_SINGLE, OPT_MULTI } optiontype_t; typedef void (*optionloop_cb_t)(void); struct optionconfig_s; typedef struct optionconfig_s optionconfig_t; d288 17 a304 1 static void stdsyntax(void) d306 101 a406 1 return; d409 1 a409 1 static void includeit(void) d411 1 d415 1 a415 1 static void option_register(lmtp2nntp_option_t *o, char *longname, char shortname, optiontype_t type, optionloop_cb_t cb, char *cbctx, char *descrip, char *argdescrip) d422 2 d461 2 d464 4 d477 2 d482 33 a514 26 option_register(o, "childsmax", 'C', OPT_SINGLE, stdsyntax, "[0-9]{,5}", "foo", "childsmax" ); option_register(o, "daemonize", 'D', OPT_FLAG, NULL, NULL, "foo", NULL ); option_register(o, "kill", 'K', OPT_FLAG, NULL, NULL, "foo", NULL ); option_register(o, "pidfile", 'P', OPT_SINGLE, stdsyntax, ".{,255}", "foo", "pidfile" ); option_register(o, "veryverbose", 'V', OPT_FLAG, NULL, NULL, "foo", NULL ); option_register(o, "acl", 'a', OPT_MULTI, stdsyntax, "[0-9.](/[0-9]2)?", "foo", "addr[/mask]" ); option_register(o, "bind", 'b', OPT_SINGLE, stdsyntax, ".*", "foo", "addr[:port]|-|path[:perms]" ); option_register(o, "client", 'c', OPT_SINGLE, stdsyntax, ".*", "foo", "addr[:port]" ); option_register(o, "destination", 'd', OPT_MULTI, stdsyntax, ".*", "foo", "addr[:port]" ); option_register(o, "groupmode", 'g', OPT_SINGLE, stdsyntax, ".*", "foo", "groupmode" ); option_register(o, "headervalue", 'h', OPT_MULTI, stdsyntax, ".*", "foo", "header: value" ); option_register(o, "include", 'i', OPT_MULTI, includeit, ".*", "foo", "configfile" ); option_register(o, "size", 's', OPT_SINGLE, stdsyntax, ".*", "foo", "bytes" ); option_register(o, "timeoutlmtpaccept", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "sec" ); option_register(o, "timeoutlmtpread", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "sec" ); option_register(o, "timeoutlmtpwrite", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "sec" ); option_register(o, "timeoutnntpconnect", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "sec" ); option_register(o, "timeoutnntpread", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "sec" ); option_register(o, "timeoutnntpwrite", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "sec" ); option_register(o, "mailfrom", 'm', OPT_SINGLE, stdsyntax, ".*", "foo", "regex" ); option_register(o, "nodename", 'n', OPT_SINGLE, stdsyntax, ".*", "foo", "nodename" ); option_register(o, "operationmode", 'o', OPT_SINGLE, stdsyntax, ".*", "foo", "post|feed" ); option_register(o, "l2spec", 'l', OPT_SINGLE, stdsyntax, ".*", "foo", "spec" ); option_register(o, "uid", 'u', OPT_SINGLE, stdsyntax, ".*", "foo", "number|name" ); option_register(o, "restrictheader", 'r', OPT_MULTI, stdsyntax, ".*", "foo", "regex" ); option_register(o, "newsgroup", NUL, OPT_MULTI, stdsyntax, ".*", "foo", "newsgroup"); d516 24 @ 1.8 log @switch from included to linked-in OSSP val variant @ text @d24 1 a24 1 ** lmtp2nntp.c: LMTP to NNTP configuration parsing d30 13 a42 11 // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include // #include d45 5 a49 3 // #include "lmtp2nntp_argz.h" // #include "lmtp2nntp_shpat.h" // #include "lmtp2nntp_daemon.h" d55 4 a58 2 // #include "l2.h" // #include "var.h" d104 1 a104 1 void die(char *); //FIXME d111 1 d155 6 a225 1 #if 0 a227 1 #endif d280 9 a288 9 // OK val_apply(v, "", 9, dumper, "v" ); // OK val_apply(v2, "", 9, dumper, "v2"); // OK val_apply(v, "", 0, dumper, "v" ); // OK val_apply(v, "bar", 1, dumper, "v" ); // OK val_apply(v2, "", 0, dumper, "v" ); // OK val_apply(v, "", 1, dumper, "v" ); // OK val_apply(v, "foo", 0, dumper, "v" ); // OK val_apply(v2, "char", 2, dumper, "v" ); // OK val_apply(v, "bar.char", 2, dumper, "v" ); a331 21 /* Braindump fuer var ich brauche eine struktur, aus der man ersehen kann, welche variablen es gibt. { struct "system.uname.sysname", varstring, struct "system.uname.nodename", struct "system.uname.release", struct "system.uname.version", struct "system.uname.machine", <<< ctx->progname = strdup(argv[0]); <<< foo = ctx->progname; >>> rc = varreg("main.progname", &ctx->progname); >>> rc = varset("main.progname", strdup(argv[0])); //equivalent to ctx->progname = strdup(argv[0]); >>> rc = varget("main.progname", &foo); //equivalent to foo = ctx->progname } */ d349 1 a349 1 //FIXME printf("DEBUG: *** 1 *** file as it was just read in ***\n%s***\n", cpBuf); d389 1 a389 1 ;//printf("DEBUG: line[%3d] = ***%s***\n", lline, cpL); d391 1 a391 1 ;//printf("DEBUG: [%3d-%3d] = ***%s***\n", lline, pline-1, cpL); d398 1 a398 1 ;//printf("DEBUG: no command - comment only\n"); d404 1 a404 1 ;//while(isspace((int)*value)) value++; d419 32 d452 109 @ 1.7 log @commit for protocol reasons @ text @d47 1 a47 1 #include "lmtp2nntp_val.h" @ 1.6 log @val now supports OO-style variable names. lh now supports iteration through all elements and applying a callback to each. lmtp2nntp_config.c currently has sample code for lib val embedded, including a data dumper. @ text @d109 2 a110 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_VAL, desc=<%20s>, data@@%.8lx INTERNAL\n", (char *)ctx, desc, (long)data); d113 2 a114 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_PTR, desc=<%20s>, data@@%.8lx=%.8lx\n", (char *)ctx, desc, (long)data, *(long *)data); d117 2 a118 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_CHAR, desc=<%20s>, data@@%.8lx='%c'\n", (char *)ctx, desc, (long)data, *(char *)data); d121 2 a122 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_SHORT, desc=<%20s>, data@@%.8lx=%8d\n", (char *)ctx, desc, (long)data, *(short *)data); d125 2 a126 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_INT, desc=<%20s>, data@@%.8lx=%8d\n", (char *)ctx, desc, (long)data, *(int *)data); d129 2 a130 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_LONG, desc=<%20s>, data@@%.8lx=%8d\n", (char *)ctx, desc, (long)data, *(long *)data); d133 2 a134 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_FLOAT, desc=<%20s>, data@@%.8lx=%8f\n", (char *)ctx, desc, (long)data, *(float *)data); d137 2 a138 2 fprintf(stderr, "DEBUG: <%10s> VAL_TYPE_DOUBLE, desc=<%20s>, data@@%.8lx=%8f\n", (char *)ctx, desc, (long)data, *(double *)data); d141 2 a142 2 fprintf(stderr, "DEBUG: <%10s> type = %.8lx, desc=<%20s>, data@@%.8lx\n", (char *)ctx, type, desc, (long)data); d269 9 a277 2 val_apply(v, dumper, "v" ); val_apply(v2, dumper, "v2"); @ 1.5 log @map renamed to val and basic functionality successfully verified @ text @d101 1 a101 1 printf("ERROR: %s", msg); d105 43 d186 2 d189 1 a189 1 val_t *v; d196 1 a196 1 if ((rc = val_reg(v, "foo.bar", VAL_TYPE_INT, (void *)&testint)) != VAL_OK) d200 1 a200 1 if ((rc = val_get(v, "foo.bar", &testintout)) != VAL_OK) d204 1 a204 1 if ((rc = val_set(v, "foo.bar", 2)) != VAL_OK) d206 1 a206 1 if ((rc = val_get(v, "foo.bar", &testintout)) != VAL_OK) d209 65 @ 1.4 log @map renamed to val and basic functionality successfully verified @ text @d151 1 a151 1 if ((rc = val_reg(v, "foo", VAL_TYPE_INT, (void *)&testint)) != VAL_OK) d155 1 a155 1 if ((rc = val_get(v, "foo", &testintout)) != VAL_OK) d159 1 a159 1 if ((rc = val_set(v, "foo", 2)) != VAL_OK) d161 1 a161 1 if ((rc = val_get(v, "foo", &testintout)) != VAL_OK) @ 1.3 log @first steps toward popt @ text @d47 1 d141 31 d193 31 @ 1.2 log @replaced dotconf library with own code and str_token @ text @d46 1 a46 1 // #include "lmtp2nntp_popt.h" d77 1 d104 1 a104 1 void dotconftest(void) d106 28 a133 36 #if 0 static const configoption_t options[] = { { "", ARG_NONE, foo, NULL, CTX_ALL }, { "childsmax", ARG_STR, foo, NULL, CTX_DAEMON }, { "daemonize", ARG_STR, foo, NULL, CTX_DAEMON }, { "pidfile", ARG_STR, foo, NULL, CTX_DAEMON }, { "acl", ARG_STR, foo, NULL, CTX_DAEMON }, { "bind", ARG_STR, foo, NULL, CTX_DAEMON }, { "", ARG_NONE, foo, NULL, CTX_DAEMON }, { "", ARG_NONE, foo, NULL, CTX_ALL }, { "timeoutaccept", ARG_STR, foo, NULL, CTX_SERVER }, { "timeoutread", ARG_STR, foo, NULL, CTX_SERVER }, { "timeoutwrite", ARG_STR, foo, NULL, CTX_SERVER }, { "size", ARG_STR, foo, NULL, CTX_SERVER }, { "mailfrom", ARG_STR, foo, NULL, CTX_SERVER }, { "nodename", ARG_STR, foo, NULL, CTX_SERVER }, { "", ARG_NONE, foo, NULL, CTX_SERVER }, { "", ARG_NONE, foo, NULL, CTX_ALL }, { "client", ARG_STR, foo, NULL, CTX_CLIENT }, { "destination", ARG_STR, foo, NULL, CTX_CLIENT }, { "operationmode", ARG_STR, foo, NULL, CTX_CLIENT }, { "timeoutconnect", ARG_STR, foo, NULL, CTX_CLIENT }, { "timeoutread", ARG_STR, foo, NULL, CTX_CLIENT }, { "timeoutwrite", ARG_STR, foo, NULL, CTX_CLIENT }, { "", ARG_NONE, foo, NULL, CTX_CLIENT }, { "", ARG_NONE, foo, NULL, CTX_ALL }, { "groupmode", ARG_STR, foo, NULL, CTX_GATEWAY }, { "l2spec", ARG_STR, foo, NULL, CTX_GATEWAY }, { "uid", ARG_STR, foo, NULL, CTX_GATEWAY }, { "newsgroup", ARG_STR, foo, NULL, CTX_GATEWAY }, { "", ARG_NONE, foo, NULL, CTX_GATEWAY }, { "", ARG_NONE, foo, NULL, CTX_ALL }, { "headervalue", ARG_STR, foo, NULL, CTX_MESSAGE }, { "restrictheader", ARG_STR, foo, NULL, CTX_MESSAGE }, { "", ARG_NONE, foo, NULL, CTX_MESSAGE }, LAST_OPTION d135 7 a141 1 #endif d143 18 a160 2 const char *filename = "example.conf"; char *cpBuf; d163 1 d182 10 a191 9 char *cpI; /* pointer to next character to be read */ char *cpO; /* pointer to next character to be written when 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 */ d197 1 a197 3 p = NUL; /* prefill previous character with fake value to avoid false line continuation detection when a newline is seen as the first character in the buffer */ d219 1 a219 1 printf("DEBUG: line[%3d] = ***%s***\n", lline, cpL); d221 1 a221 1 printf("DEBUG: [%3d-%3d] = ***%s***\n", lline, pline-1, cpL); d224 1 a224 1 char *token; d227 2 a228 2 if ((token = str_token(&cp, " ", "\"'", "#", STR_STRIPQUOTES|STR_BACKSLASHESC)) == NULL) printf("DEBUG: no token - comment only\n"); d230 2 a231 2 printf("DEBUG: token = ***%s***\n", token); if ((value = str_token(&cp, "", "\"'", "#", STR_STRIPQUOTES|STR_BACKSLASHESC)) == NULL) d233 2 a234 1 else d236 1 @ 1.1 log @configfile example with sections and evaluation of code to parse it @ text @d29 1 a46 1 #include "lmtp2nntp_dotconf.h" d49 1 a49 1 // #include "str.h" d96 2 a97 23 const char *foo(command_t *, context_t *); int bar(configfile_t *, int, long, const char *); const char *quux(command_t *, unsigned long); const char *foo(command_t *cmd, context_t *_ctx) { int *foodata = (int *)_ctx; int i; printf("DEBUG: callbck %s:%ld: %s:", cmd->configfile->filename, cmd->configfile->line, cmd->name); for (i = 0; i < cmd->arg_count; i++) ;//printf("[%d=***%s***] ", i, cmd->data.list[i]); printf("---%lx---%d---", foodata, (*foodata)++); printf("\n"); return NULL; } int bar(configfile_t *configfile, int type, long dc_errno, const char *msg) { printf("DEBUG: handler type=%d, dc_errno=%ld, msg=***%s***\n", type, dc_errno, msg); return 0; /* 0=continue, 1=abort */ } const char *quux(command_t *cmd, unsigned long mask) d99 2 a100 6 printf("DEBUG: checker %s:%ld: %s: ", cmd->configfile->filename, cmd->configfile->line, cmd->name); printf("[mask=%lx]", mask); printf("\n"); if ((strcmp(cmd->name, "client") == 0) && (mask = 4)) return "Nasenbaer!"; return NULL; a102 10 enum configcontext { CTX_DAEMON = 1<<0, CTX_SERVER = 1<<1, CTX_CLIENT = 1<<2, CTX_GATEWAY = 1<<3, CTX_MESSAGE = 1<<4 }; d105 1 a105 2 configfile_t *configfile; static int foodata; d142 1 d144 2 a145 2 foodata = 1000; printf("---%lx---%d---", &foodata, foodata); d147 15 a161 4 configfile = dotconf_create("example.conf", options, &foodata, CASE_INSENSITIVE); if (!configfile) { fprintf(stderr, "Error opening config file\n"); return; d163 1 a163 2 configfile->errorhandler = (dotconf_errorhandler_t)bar; configfile->contextchecker = (dotconf_contextchecker_t)quux; d165 66 a230 4 if (dotconf_command_loop(configfile) == 0) fprintf(stderr, "Error reading config file\n"); dotconf_cleanup(configfile); @