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