/*
* Copyright (c) 2004, 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#define SM_QMGRCNFDEF 1
#include "sm/generic.h"
SM_RCSID("@(#)$Id: qmgr_conf.c,v 1.26 2007/04/24 03:07:51 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/sysexits.h"
#include "sm/string.h"
#include "sm/io.h"
#include "sm/sm-conf.h"
#include "sm/sm-conf-prt.h"
#define SM_LOG_IDENT "qmgr"
#define SM_CONF_LOG_DEF 1
#define SM_CONF_TIME_DEF 1
#define SM_CONF_BYTE_DEF 1
#define SM_CONF_KBYTE_DEF 1
#include "sm/qmgr-int.h"
#include "sm/qmgrcnf.h"
#include "sm/qmgrcnfdef.h"
#include "qmgr.h"
/*
** QM_READ_CNF -- Read configuration file
**
** Parameters:
** qmgr_ctx -- QMGR context
** fn -- filename of configuration file
** psmc -- (pointer to) configuration context (output)
**
** Returns:
** 0 on success, everything else is an error
*/
sm_ret_T
qm_read_cnf(qmgr_ctx_P qmgr_ctx, const char *fn, sm_conf_T **psmc)
{
int err;
sm_ret_T ret;
int i;
uint u;
#if 0
sm_conf_iterator_T qm_cnf_iter;
char const *qm_cnf_name;
size_t qm_cnf_name_n;
#endif /* 0 */
sm_conf_T *smc;
FILE *fp;
fp = NULL;
smc = sm_conf_new(fn);
if (smc == NULL)
{
err = errno;
sm_io_fprintf(smioerr, "%s: sm_conf_new=NULL, errno=%d\n",
fn, err);
ret = sm_error_temp(SM_EM_Q_CONF, ENOMEM);
return ret;
}
err = sm_conf_read_FILE(smc, fn, fp);
if (err != 0)
{
sm_prt_conferr(fn, smc, err, smioerr);
ret = err;
goto error;
}
err = sm_conf_scan(smc, qmgr_global_defs, SM_CONF_FLAG_ALLOW_ANY,
&qmgr_ctx->qmgr_cnf);
if (err != 0)
{
sm_prt_conferr(fn, smc, err, smioerr);
ret = err;
goto error;
}
if (qmgr_ctx->qmgr_cnf.q_cnf_hostname != NULL)
{
size_t l;
l = strlen(qmgr_ctx->qmgr_cnf.q_cnf_hostname) + 1;
qmgr_ctx->qmgr_hostname = sm_str_scpyn0(NULL,
qmgr_ctx->qmgr_cnf.q_cnf_hostname, l, l);
if (qmgr_ctx->qmgr_hostname == NULL)
{
ret = sm_error_temp(SM_EM_Q_CONF, ENOMEM);
goto error;
}
}
#if 0
err = sm_conf_scan_next(smc, "qmgr.log",
qmgr_defs, 0, &conf_name, &conf_name_n,
&s, &conf_iter);
#endif /* 0 */
i = qmgr_ctx->qmgr_cnf.q_cnf_log.sm_logspc_facility;
/*
** HACK! it should check whether log is in config file
** however it's not clear how to do that...
** this only works because facility 0 is KERN.
*/
if (i != 0)
{
ret = sm_log_opensyslog(
qmgr_ctx->qmgr_cnf.q_cnf_log.sm_logspc_ident,
qmgr_ctx->qmgr_cnf.q_cnf_log.sm_logspc_opt, i);
if (sm_is_err(ret))
goto error;
ret = sm_log_setfp_fd(qmgr_ctx->qmgr_lctx, NULL, INVALID_FD);
if (sm_is_err(ret))
goto error;
}
/*
** Transfer values from config file to
** "global" variables; the configuration
** context isn't passed to every function.
*/
#if QMGR_DEBUG
for (u = 0; u < SM_ARRAY_SIZE(qm_debug); u++)
qm_debug[u] = qmgr_ctx->qmgr_cnf.q_cnf_debug;
#endif
#if RCBCOMM_DEBUG
rcbcomm_debug = qmgr_ctx->qmgr_cnf.q_cnf_debug;
#endif
if (psmc != NULL)
*psmc = smc;
return SM_SUCCESS;
error:
if (smc != NULL)
{
sm_conf_destroy(smc);
smc = NULL;
}
return ret;
}
#if STANDALONE
static int
process(char const *name, FILE *fp)
{
sm_conf_T *stream;
int err;
qmgr_cnf_T s;
sm_conf_iterator_T qm_cnf_iter;
char const *qm_cnf_name;
size_t qm_cnf_name_n;
if (((stream = sm_conf_new(name ? name : "*stdin*"))) == NULL)
{
fprintf(stderr, "error -- sm_conf_new() returns NULL!\n");
return 1;
}
if ((err = sm_conf_read_FILE(stream, name, fp)) != 0)
{
char buf[200];
char const *e = NULL;
fprintf(stderr, "%s: %s\n",
name ? name : "*stdin*",
sm_conf_strerror(err, buf, sizeof buf));
while ((e = sm_conf_syntax_error(stream, e)) != NULL)
fprintf(stderr, "%s\n", e);
sm_conf_destroy(stream);
return 2;
}
qm_cnf_iter = NULL;
while ((err = sm_conf_scan_next(stream, "qmgr",
mcp_defs, 0, &qm_cnf_name, &qm_cnf_name_n,
&s, &qm_cnf_iter)) == 0)
{
print_structure(&s, qm_cnf_name, qm_cnf_name_n);
}
if (err != 0 && err != SM_CONF_ERR_NOT_FOUND)
{
char buf[200];
char const *e = NULL;
fprintf(stderr, "(while scanning) %s: %s\n",
name ? name : "*stdin*",
sm_conf_strerror(err, buf, sizeof buf));
while ((e = sm_conf_syntax_error(stream, e)) != NULL)
fprintf(stderr, "%s\n", e);
sm_conf_destroy(stream);
return 3;
}
sm_conf_destroy(stream);
return 0;
}
int
main(int ac, char **av)
{
int ret;
int ai;
ret = 0; /* make compiler happy */
if (ac == 1)
ret = process("*stdin*", stdin);
else
{
for (ai = 1; ai < ac; ai++)
{
ret = process(av[ai], NULL);
if (ret != 0)
break;
}
}
return ret;
}
#endif /* STANDALONE */
syntax highlighted by Code2HTML, v. 0.9.1