/*
* 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: t-conf-0.c,v 1.14 2005/07/11 02:42:02 ca Exp $")
#include "sm/error.h"
#include "sm/sysexits.h"
#include "sm/memops.h"
#include "sm/string.h"
#include "sm/net.h"
#include "sm/maps.h"
#include "sm/mapc.h"
#include "sm/map.h"
#include "sm/mapconf.h"
#include "map.h"
#include "sm/sm-conf.h"
#include <stdio.h>
#include "sm/mapcnf.h"
#define SM_MAPCNFDEF 1
#include "sm/mapcnfdef.h"
/*
** test program: maps and libconf.
*/
static sm_ret_T
mapsetup(map_decl_P mapdef, sm_maps_P *pmaps)
{
sm_ret_T ret;
SM_REQUIRE(mapdef != NULL);
SM_REQUIRE(pmaps != NULL);
*pmaps = NULL;
ret = sm_maps_init(pmaps);
if (*pmaps == NULL)
return -1;
if (sm_is_err(ret))
goto error;
ret = sm_maps_create(*pmaps);
if (sm_is_err(ret))
goto error;
ret = sm_mapconfopen(mapdef, *pmaps, NULL);
return ret;
error:
return ret;
}
static sm_ret_T
maplookup(FILE *fp, sm_maps_P maps, const char *mapname, const char *lookup, sm_str_P detail, uchar delim, uint32_t flags)
{
sm_ret_T ret;
sm_map_P map;
sm_cstr_P mname;
sm_str_P lhs, rhs;
char *s;
SM_REQUIRE(fp != NULL);
SM_REQUIRE(maps != NULL);
SM_REQUIRE(mapname != NULL);
SM_REQUIRE(lookup != NULL);
lhs = rhs = NULL;
map = NULL;
mname = sm_cstr_scpyn0((const uchar *)mapname, strlen(mapname));
if (mname == NULL)
goto error;
ret = sm_mapname_find(maps, mname, &map);
if (ret != SM_SUCCESS)
goto error;
if (map == NULL)
goto error;
lhs = sm_str_new(NULL, 256, 1024);
if (lhs == NULL)
goto error;
rhs = sm_str_new(NULL, 256, 1024);
if (rhs == NULL)
goto error;
/* perform some operations ... */
sm_str_clr(rhs);
sm_str_clr(lhs);
ret = sm_str_scat(lhs, lookup);
if (sm_is_err(ret))
goto error;
if (detail != NULL)
ret = sm_map_lookup_addr(map, lhs, detail, NULL, NULL, delim,
flags, rhs);
else
ret = sm_map_lookup(map, SMMAP_FL_NONE, lhs, rhs);
if (sm_is_err(ret))
{
if (ret == sm_error_perm(SM_EM_MAP, SM_E_NOTFOUND))
fprintf(fp, "notfound\n");
goto error;
}
s = (char *) sm_str_getdata(rhs);
if (s != NULL)
fprintf(fp, "result=\"%s\"\n", s);
return ret;
error:
return -1;
}
static int
mapprtcnf(FILE *fp, map_decl_P mapdef)
{
mapspec_P md_maps;
uint n, i;
if (mapdef == NULL)
{
fprintf(fp, "map == NULL\n");
return -1;
}
for (n = 0; n < mapdef->mapdecl_n; n++)
{
md_maps = mapdef->mapdecl_maps + n;
if (md_maps == NULL)
{
fprintf(fp, "mapdef[%d] == NULL\n", n);
continue;
}
#if 0
fprintf(fp, "map = %p\n", md_maps);
#endif
fprintf(fp, "map = %u\n", n);
fprintf(fp, "kind= %d\n", md_maps->mst_kind);
fprintf(fp, "type= %s\n", md_maps->mst_type);
fprintf(fp, "name= %s\n", md_maps->mst_name);
switch (md_maps->mst_kind)
{
case MST_HASH:
fprintf(fp, "file= %s\n",
md_maps->mst_hash.mst_hash_fn);
break;
case MST_SOCKET:
fprintf(fp, "mapname= %s\n",
md_maps->mst_socket.mst_socket_mapname);
if (md_maps->mst_socket.mst_socket_path != NULL)
{
fprintf(fp, "path= %s\n",
md_maps->mst_socket.mst_socket_path);
}
else
{
fprintf(fp, "ipv4= %x\n",
(int) htonl(md_maps->mst_socket.mst_socket_ipv4));
fprintf(fp, "port= %d\n",
md_maps->mst_socket.mst_socket_port);
}
break;
case MST_SEQUENCE:
for (i = 0; md_maps->mst_seq.mst_seq_maps[i] != NULL; i++)
{
fprintf(fp, "maps[%u]= %s\n", i,
md_maps->mst_seq.mst_seq_maps[i]);
}
break;
default:
break;
}
fprintf(fp, "\n");
}
return 0;
}
static int
process(char const *name, FILE *fp, int show, const char *mapname, const char *lookup, sm_str_P detail, uchar delim, uint32_t flags)
{
sm_conf_T *stream;
int err;
sm_ret_T ret;
#if 0
char const *service_name;
size_t service_name_n;
sm_conf_iterator_T service_iter;
#endif /* 0 */
char const *e = NULL;
sm_maps_P maps;
map_decl_T s;
char buf[SM_CONF_ERROR_BUFFER_SIZE];
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)
{
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;
}
sm_memzero(&s, sizeof(s));
if ((err = sm_conf_scan(stream, maps_spec_defs, 0, &s)) != 0)
{
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;
}
if (lookup == NULL || mapname == NULL)
mapprtcnf(stdout, &s);
else
{
maps = NULL;
ret = mapsetup(&s, &maps);
if (sm_is_err(ret))
goto error;
if (maps == NULL)
goto error;
ret = maplookup(stdout, maps, mapname, lookup, detail, delim,
flags);
if (sm_is_err(ret))
goto error;
}
#if 0
sm_conf_destroy(stream);
#endif /* 0 */
return 0;
error:
return -1;
}
static void
usage(char *prg)
{
fprintf(stderr,
"%s: usage: %s [options] configfile\n"
"options:\n"
" -l key lookup key\n"
" -m map lookup key in map\n"
"Note: -l and -m must be used together\n"
"Default: only parse and print configfile\n"
, prg, prg
);
}
int
main(int argc, char **argv)
{
int ai, c, ret;
uchar delim;
uint32_t flags;
char *lookup, *mapname;
sm_str_P detail;
lookup = mapname = NULL;
detail = NULL;
delim = '+';
flags = 0;
while ((c = getopt(argc, argv, "?D:d:F:f:hl:m:")) != -1)
{
switch (c)
{
case 'D':
detail = sm_str_scpy0(NULL, optarg, 64);
break;
case 'd':
delim = (uchar) optarg[0];
break;
case 'F':
flags = strtoul(optarg, NULL, 0);
break;
case 'f':
ret = process(optarg, NULL, 0, mapname, lookup,
detail, delim, flags);
if (ret != 0)
return ret;
break;
case 'l':
lookup = strdup(optarg);
if (lookup == NULL)
return EX_OSERR;
break;
case 'm':
mapname = strdup(optarg);
if (mapname == NULL)
return EX_OSERR;
break;
case '?':
case 'h':
default:
usage(argv[0]);
exit(EX_USAGE);
}
}
argc -= optind;
argv += optind;
if (argc == 0)
return process("*stdin*", stdin, 1, mapname, lookup,
detail, delim, flags);
for (ai = 0; ai < argc; ai++)
{
int ret;
ret = process(argv[ai], NULL, 1, mapname, lookup,
detail, delim, flags);
if (ret != 0)
return ret;
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1