/*
* 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.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: mtinit.c,v 1.19 2006/11/10 03:46:11 ca Exp $")
#include "sm/error.h"
#include "sm/assert.h"
#include "sm/ctype.h"
#include "sm/io.h"
#include "sm/net.h"
#include "sm/misc.h"
#include "sm/smardef.h"
#include "sm/confsetpath.h"
#include "smar.h"
#include "log.h"
/*
** SMAR_MT_INIT -- initialize "mailertable". This is a hack.
**
** Parameters:
** smar_ctx -- SMAR context
**
** Returns:
** usual sm_error code
*/
sm_ret_T
smar_mt_init(smar_ctx_P smar_ctx)
{
sm_ret_T ret;
sm_file_T *fp;
int c, i, hl;
const char *mpath;
char hn[256], *hna;
char ipv4[128], *ipv4a, *addr, *eos;
sm_str_T key, data;
char confdir[PATH_MAX];
SM_IS_SMAR_CTX(smar_ctx);
ret = sm_dirname(smar_ctx->smar_cnf.smar_cnf_conffile, confdir,
sizeof(confdir));
if (sm_is_err(ret)) goto error;
SM_GEN_MAP_PATH(mpath, smar_ctx->smar_cnf.smar_cnf_mt_path, confdir,
smar_ctx->smar_cnf.smar_cnf_mt_fn, SMAR_MT_NAME, error);
fp = NULL;
ret = sm_io_open(SmStStdio, mpath, SM_IO_RDONLY, &fp, SM_IO_WHAT_END);
if (sm_is_err(ret)) goto error;
while (!sm_eof(fp))
{
i = 0;
/* read hostname/domain literal */
if (SMAR_MT_FULL_LOOKUP(smar_ctx))
{
/* note: this isn't correct: it could be a quoted space... */
while ((c = sm_io_getc(fp)) != SM_IO_EOF && !ISSPACE(c))
{
hn[i++] = (char) c;
if (i >= (int) sizeof(hn))
goto syntax;
}
}
else
{
while ((c = sm_io_getc(fp)) != SM_IO_EOF &&
(ISALNUM(c) || c == '.' || c == '-'
|| (c == '[' && i == 0) || (c == ']' && i > 0)))
{
hn[i++] = (char) c;
if (i >= (int) sizeof(hn))
goto syntax;
}
}
if (c == SM_IO_EOF && i == 0)
break;
if (c == SM_IO_EOF || !ISSPACE(c)) goto syntax;
hn[i++] = '\0';
hna = (char *) sm_malloc(i + 1);
if (hna == NULL) goto enomem;
strlcpy(hna, hn, i);
hl = i - 1;
/* skip over whitespace */
while ((c = sm_io_getc(fp)) != SM_IO_EOF && ISSPACE(c))
;
if (c != SM_IO_EOF)
sm_io_ungetc(fp, c);
/* read RHS and check syntax */
i = 0;
while ((c = sm_io_getc(fp)) != SM_IO_EOF &&
(ISALNUM(c) ||
c == '.' || c == '-' || c == '[' || c == ']' ||
c == ':' ||
c == SMAR_RHS_SEP_C || c == SMAR_RHS_PORT_C ||
c == SMAR_RHS_PROT_C
))
{
ipv4[i++] = (char) c;
if (i >= (int) sizeof(ipv4))
goto syntax;
}
ipv4[i++] = '\0';
if (c == SM_IO_EOF || !ISSPACE(c)) {
sm_log_write(smar_ctx->smar_lctx,
AR_LCAT_INIT, AR_LMOD_CONFIG,
SM_LOG_ERROR, 0,
"sev=ERROR, func=smar_mt_init, syntax_error_rhs=\"%.256s\"",
ipv4);
goto syntax;
}
ipv4a = (char *) sm_malloc(i);
if (ipv4a == NULL) goto enomem;
strlcpy(ipv4a, ipv4, i);
eos = ipv4a + i;
for (addr = ipv4a; *addr != '\0' && addr < eos; ++addr)
{
if (*addr == '[') {
ret = sm_inet_a2ipv4(addr, NULL, NULL);
if (sm_is_err(ret)) {
sm_log_write(smar_ctx->smar_lctx,
AR_LCAT_INIT, AR_LMOD_CONFIG,
SM_LOG_ERROR, 0,
"sev=ERROR, func=smar_mt_init, not_an_IPv4_address=\"%.256s\", input=%.256s",
addr, ipv4a);
ret = sm_error_perm(SM_EM_AR, errno);
goto error;
}
}
/* skip to end of address */
while (*addr != '\0' && *addr != SMAR_RHS_SEP_C &&
addr < eos)
++addr;
if (*addr == '\0')
break;
}
sm_str_assign(key, NULL, (uchar *)hna, hl, hl + 2);
sm_str_assign(data, NULL, (uchar *)ipv4a, i, i + 2);
ret = sm_map_add(smar_ctx->smar_mt_map, &key, &data, SMMAP_AFL_UNIQUE);
if (sm_is_err(ret)) goto error;
}
sm_io_close(fp, SM_IO_CF_NONE);
return SM_SUCCESS;
enomem:
ret = sm_error_temp(SM_EM_AR, ENOMEM);
goto error;
syntax:
ret = sm_error_perm(SM_EM_AR, SM_E_SYNTAX);
error:
if (fp != NULL)
sm_io_close(fp, SM_IO_CF_NONE);
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1