OSSP CVS Repository

ossp - ossp-pkg/lmtp2nntp/lmtp2nntp_config.c 1.18
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/lmtp2nntp/lmtp2nntp_config.c 1.18

/*
**  Copyright (c) 2001-2002 The OSSP Project <http://www.ossp.org/>
**  Copyright (c) 2001-2002 Cable & Wireless Deutschland <http://www.cw.com/de/>
**
**  This file is part of OSSP lmtp2nntp, an LMTP speaking local
**  mailer which forwards mails as Usenet news articles via NNTP.
**  It can be found at http://www.ossp.org/pkg/lmtp2nntp/.
**
**  This program is free software; you can redistribute it and/or
**  modify it under the terms of the GNU General Public  License
**  as published by the Free Software Foundation; either version
**  2.0 of the License, or (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**  General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this file; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
**  USA, or contact the OSSP project <ossp@ossp.org>.
**
**  lmtp2nntp_config.c: config handling
*/

#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>

/* third party (included) */
#include "lmtp2nntp_argz.h"

/* third party (linked in) */
#include "str.h"
#include "val.h"
#include "popt.h"
#include "l2.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(DMALLOC)
#include "dmalloc.h"
#endif
#include "lmtp2nntp_option.h"
#include "lmtp2nntp_config.h"
#include "lmtp2nntp_lmtp.h"
#include "lmtp2nntp_nntp.h"
#include "lmtp2nntp_msg.h"
#include "fixme.h"
#define _LMTP2NNTP_VERSION_C_AS_HEADER_
#include "lmtp2nntp_version.c"
#undef  _LMTP2NNTP_VERSION_C_AS_HEADER_

#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 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;
}

void config_context(lmtp2nntp_t *ctx)
{
    ex_t ex;
    optionval_t *ov;
    //char *cp;
    int 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(ERR_EXECUTION);
    }
    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(ERR_EXECUTION);
    }
    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(ERR_EXECUTION);
    }
    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(ERR_EXECUTION);
    }
    if (l2_env_formatter(ctx->l2_env, 'm', formatter_errno, NULL) != L2_OK) {
        fprintf(stderr, "%s:Error: logging failed to register errno formatter\n", ctx->progname);
        CU(ERR_EXECUTION);
    }
    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(ERR_EXECUTION);
    }
    if (ov->data.s != NULL) {
        if ((rc = l2_spec(&ctx->l2, ctx->l2_env, ov->data.s)) != L2_OK) {
            fprintf(stderr, "%s:Error: logging failed to create stream\n", ctx->progname);
            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);
            CU(ERR_EXECUTION);
        }
        if (l2_channel_open(ctx->l2) != L2_OK) {
            fprintf(stderr, "%s:Error: logging failed to open channel stream\n", ctx->progname);
            CU(ERR_EXECUTION);
        }
    }
    /* from this point on logging is up and running and fprintf(stderr, ...)
     * should not be used in the remainder of the program flow.
     */
    log1(ctx, NOTICE, "startup, version %s", lmtp2nntp_version.v_gnu);

    /* --childsmax SINGLE */
    try {
        if (   (val_get(ctx->val, "option.childsmax", &ov) != VAL_OK)
            || (ov->ndata != 1)
            || (ov->data.s == NULL)
              ) throw(0,0,0);
        log1(ctx, TRACE, "--childsmax = \"%s\"", ov->data.s);
        if ((ctx->option_childsmax = atoi(ov->data.s)) <= 0) {
            log1(ctx, ERROR, "number (%d) out of range for option --childsmax\n", ctx->option_childsmax);
            throw(0,0,0);
        }
    }
    catch (ex) {
        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 );
        rethrow;
    }

    /* --daemonize FLAG */
    try {
        if (   (val_get(ctx->val, "option.daemonize", &ov) != VAL_OK)
            || (ov->ndata != 1)
            || (ov->data.f != 1)
              ) throw(0,0,0);
        log1(ctx, TRACE, "--daemonize = %d", ov->data.f);
        ctx->option_daemon = TRUE;
    }
    catch (ex)
        rethrow;

    /* --kill FLAG */
    try {
        if (   (val_get(ctx->val, "option.kill", &ov) != VAL_OK)
            || (ov->ndata != 1)
            || (ov->data.f != 1)
              ) throw(0,0,0);
        log1(ctx, TRACE, "--kill = %d", ov->data.f);
        ctx->option_killflag = TRUE;
    }
    catch (ex)
        rethrow;

    /* --pidfile SINGLE */
    try {
        if (   (val_get(ctx->val, "option.pidfile", &ov) != VAL_OK)
            || (ov->ndata != 1)
            || (ov->data.s == NULL)
              ) throw(0,0,0);
        log1(ctx, TRACE, "--pidfile = \"%s\"", ov->data.s);
        ctx->option_pidfile = ov->data.s;
    }
    catch (ex)
        rethrow;

    /* --acl MULTI */
    try {
        int i;
        char *cp;
        struct acl *acl;

        if (   (val_get(ctx->val, "option.acl", &ov) != VAL_OK)
            || ((ov->ndata >= 1) && (ov->data.m == NULL))
              ) throw(0,0,0);
        for (i = 0; i < ov->ndata; i++)
            log2(ctx, TRACE, "--acl[%d] = \"%s\"", i, (ov->data.m)[i]);
        log1(ctx, DEBUG, "ov->ndata = %d", ov->ndata);
        if ((acl = (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);
            //ctx->option_acl[ctx->option_aclc].acl = strdup(cp);
        }

    }
    catch (ex)
        rethrow;
#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


CUS:
    return;
}

CVSTrac 2.0.1