/* * Copyright (c) 2006 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-7.c,v 1.2 2006/12/24 00:20:24 ca Exp $") #if SM_LIBCONF_ALONE #include #include #include #include "sm-conf.h" #else /* SM_LIBCONF_ALONE */ #include "sm/io.h" #include "sm/string.h" #include "sm/net.h" #include "sm/units.h" #include "sm/sm-conf.h" #define SM_CONF_BYTE_DEF 1 #define SM_CONF_KBYTE_DEF 1 #include "sm/sm-conf-byte.h" #include "sm/sm-conf-prt.h" #include #endif /* SM_LIBCONF_ALONE */ /* ** Just a test program to play around with libconf. ** testing inheritance */ #define SSSE_CFL_STARTTLS 0x00800000u /* offer STARTTLS */ #define SSSE_CFL_AUTH 0x01000000u /* offer AUTH */ #define SSSE_CFL_DELAY_CHKS 0x00000002u /* delay checks */ /* server features (per session) */ struct ss_srv_feat_S { char *sssf_name; uint32_t sssf_flags; }; typedef struct ss_srv_feat_S ss_srv_feat_T, *ss_srv_feat_P; typedef struct ss_cnf_S ss_cnf_T, *ss_cnf_P; struct ss_cnf_S { uint32_t ss_cnf_cflags; ss_srv_feat_T ss_cnf_srv_feat; }; sm_conf_definition_T const ss_se_flag_names[] = { { SM_CONF_DEF_MAGIC, "starttls", sm_conf_type_choice_value, SSSE_CFL_STARTTLS, 0, NULL, 0, NULL, NULL, NULL, "offer STARTTLS" }, { SM_CONF_DEF_MAGIC, "auth", sm_conf_type_choice_value, SSSE_CFL_AUTH, 0, NULL, 0, NULL, NULL, NULL, "offer AUTH" }, { SM_CONF_DEF_MAGIC, "delay_checks", sm_conf_type_choice_value, SSSE_CFL_DELAY_CHKS, 0, NULL, 0, NULL, NULL, NULL, "delay returning results from access check until RCPT stage" }, { SM_CONF_DEF_MAGIC, NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL } }; sm_conf_definition_T ss_srv_feat_defs[] = { { SM_CONF_DEF_MAGIC, "name", sm_conf_type_section_title, offsetof(ss_srv_feat_T, sssf_name), 0, NULL, 0 /*SM_CONF_FLAG_STRICTLY_REQUIRED*/, NULL, NULL, NULL, NULL }, { SM_CONF_DEF_MAGIC, "flags", sm_conf_type_choice, offsetof(ss_srv_feat_T, sssf_flags), sizeof(uint32_t), NULL, SM_CONF_FLAG_STRICTLY_REQUIRED|SM_CONF_FLAG_MULTIPLE| SM_CONF_FLAG_DEFAULT_FROM_ENVIRONMENT| SM_CONF_FLAG_SECTION_DEFAULT_FROM_ANONYMOUS, ss_se_flag_names, NULL, NULL, "flags to influence behavior per session" }, { SM_CONF_DEF_MAGIC, NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL } }; sm_conf_definition_T ss_defs[] = { { SM_CONF_DEF_MAGIC, "server_features", sm_conf_type_section, offsetof(ss_cnf_T, ss_cnf_srv_feat), sizeof(ss_srv_feat_T), NULL, SM_CONF_FLAG_MULTIPLE|SM_CONF_FLAG_SECTION_DEFAULT_FROM_ANONYMOUS, ss_srv_feat_defs, NULL, NULL, "server feature declarations" }, { SM_CONF_DEF_MAGIC, "flags", sm_conf_type_choice, offsetof(ss_cnf_T, ss_cnf_cflags), sizeof(uint32_t), NULL, SM_CONF_FLAG_MULTIPLE|SM_CONF_FLAG_NUMERIC|SM_CONF_FLAG_SECTION_DEFAULT_FROM_ANONYMOUS, ss_se_flag_names, NULL, NULL, "global flags to influence behavior" }, { SM_CONF_DEF_MAGIC, NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL } }; static ss_cnf_T s; static int process(char const *name, FILE *fp, const char *ssname) { sm_conf_T *stream; /* uint u,n; */ int err; char buf[SM_CONF_ERROR_BUFFER_SIZE]; char const *e = NULL; 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; } if ((err = sm_conf_scan(stream, ss_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; } (void) sm_conf_prt_conf(ss_defs, &s, smioerr); /* n = s.ss_cnf_srv_feats.sssfs_n; fprintf(stderr, "n=%u\n", n); for (u = 0; u < n; u++) { fprintf(stderr, "name[%u]=%s\n", u, s.ss_cnf_srv_feats.sssfs_feat[u].sssf_name); fprintf(stderr, "flags[%u]=%#010x\n", u, s.ss_cnf_srv_feats.sssfs_feat[u].sssf_flags); } */ #if 0 sm_conf_destroy(stream); #endif /* 0 */ return 0; } int main(int ac, char **av) { int ai, c, ret, done; char *ssname; done = 0; ssname = NULL; while ((c = getopt(ac, av, "f:N:")) != -1) { switch (c) { case 'f': ret = process(optarg, NULL, ssname); if (ret != 0) return ret; done = 1; break; case 'N': ssname = strdup(optarg); if (ssname == NULL) return ENOMEM; break; } } ac -= optind; av += optind; if (ac == 0) return process("*stdin*", stdin, ssname); for (ai = 0; ai < ac; ai++) { int ret = process(av[ai], NULL, ssname); if (ret != 0) return ret; } return 0; }