/*
* 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-3.c,v 1.7 2006/12/24 00:20:24 ca Exp $")
#if SM_LIBCONF_ALONE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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 <stdio.h>
#endif /* SM_LIBCONF_ALONE */
/*
** Just a test program to play around with libconf.
** testing an array
*/
#define SSSE_CFL_STARTTLS 0x00800000u /* offer STARTTLS */
#define SSSE_CFL_AUTH 0x01000000u /* offer AUTH */
#define SSSE_CFL_DELAY_CHKS 0x00000002u /* delay checks */
#define SM_SRV_FEAT_MAGIC SM_MAGIC('S', 'R', 'V', 'F')
#define SM_CNF_MAGIC SM_MAGIC('S', 'C', 'N', 'F')
/* session features */
struct ss_srv_feat_S {
/*
how to do this? it's allocated by libconf...
sm_magic_T sm_magic;
*/
char *sssf_name;
uint32_t sssf_flags;
uint32_t sssf_max_ta;
#if SM_LIBCONF_ISSET
uchar sssf_isset_name;
uchar sssf_isset_flags;
uchar sssf_max_ta_isset;
#endif
};
typedef struct ss_srv_feat_S ss_srv_feat_T, *ss_srv_feat_P;
/* array of session features */
struct ss_srv_feats_S {
ss_srv_feat_T *sssfs_feat;
uint sssfs_n;
};
typedef struct ss_srv_feats_S ss_srv_feats_T, *ss_srv_feats_P;
typedef struct ss_cnf_S ss_cnf_T, *ss_cnf_P;
struct ss_cnf_S
{
sm_magic_T sm_magic;
uint32_t ss_cnf_cflags;
uint32_t ss_cnf_max_ta;
ss_srv_feats_T ss_cnf_srv_feats;
#if SM_LIBCONF_ISSET
uchar sssf_isset_cflags;
uchar ss_cnf_max_ta_isset;
#endif
};
sm_conf_definition_T const ss_se_flag_names[] = {
{ SM_CONF_DEF_MAGIC, "u|", sm_conf_type_u32_suffix, 1,
1, NULL, 0, NULL, NULL, NULL, "" },
{ SM_CONF_DEF_MAGIC, "|", sm_conf_type_u32_suffix, 1,
1, NULL, 0, NULL, NULL, NULL, "" },
{ SM_CONF_DEF_MAGIC, "u", sm_conf_type_u32_suffix, 1,
1, NULL, 0, NULL, NULL, NULL, "" },
{ SM_CONF_DEF_MAGIC,
"starttls", sm_conf_type_choice_value,
SSSE_CFL_STARTTLS,
0, "starttls", 0, NULL, NULL, NULL,
"offer STARTTLS" },
{ SM_CONF_DEF_MAGIC,
"auth", sm_conf_type_choice_value,
SSSE_CFL_AUTH,
0, "auth", 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
#if SM_LIBCONF_ISSET
, offsetof(ss_srv_feat_T, sssf_isset_name)
#endif
},
{ SM_CONF_DEF_MAGIC, "flags", sm_conf_type_choice,
offsetof(ss_srv_feat_T, sssf_flags), sizeof(uint32_t),
SM_XSTR(SSSE_CFL_STARTTLS) "|" SM_XSTR(SSSE_CFL_AUTH)
/* "0x00800000|0x01000000" "{starttls,auth}"*/
/*NULL */
,
SM_CONF_FLAG_MULTIPLE|SM_CONF_FLAG_OR|SM_CONF_FLAG_PLURAL|
SM_CONF_FLAG_NUMERIC|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"
#if SM_LIBCONF_ISSET
, offsetof(ss_srv_feat_T, sssf_isset_flags)
#endif
},
{ SM_CONF_DEF_MAGIC, "max_ta", sm_conf_type_u32,
offsetof(ss_srv_feat_T, sssf_max_ta), sizeof(uint32_t),
NULL, SM_CONF_FLAG_DEFAULT_FROM_ENVIRONMENT|
SM_CONF_FLAG_SECTION_DEFAULT_FROM_ANONYMOUS,
NULL, NULL, NULL,
"max ta"
#if SM_LIBCONF_ISSET
, offsetof(ss_srv_feat_T, sssf_max_ta_isset)
#endif
},
{ SM_CONF_DEF_MAGIC, NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL }
};
sm_conf_definition_T ss_srv_feat_definitions[] = {
{ SM_CONF_DEF_MAGIC, "", sm_conf_type_section,
offsetof(ss_cnf_T, ss_cnf_srv_feats.sssfs_feat), sizeof(ss_srv_feat_T),
NULL, /*SM_CONF_FLAG_SECTION_MUST_BE_NAMED|*/SM_CONF_FLAG_DEFAULT_FROM_ENVIRONMENT,
ss_srv_feat_defs,
NULL, NULL, "session features" },
{ SM_CONF_DEF_MAGIC, "n", sm_conf_type_array_n,
offsetof(ss_cnf_T, ss_cnf_srv_feats.sssfs_n), sizeof(uint),
NULL, 0,
ss_srv_feat_defs,
NULL, NULL,
"number of session features (implicit)" },
{ SM_CONF_DEF_MAGIC, NULL, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL }
};
sm_conf_definition_T ss_defs[] = {
{ SM_CONF_DEF_MAGIC, "session_features", sm_conf_type_array,
0, /* offset */
0, /* size (# of elements) */
NULL, /* default */
SM_CONF_FLAG_MULTIPLE|SM_CONF_FLAG_DEFAULT_FROM_ENVIRONMENT|SM_CONF_FLAG_SECTION_DEFAULT_FROM_ANONYMOUS,
ss_srv_feat_definitions,
NULL, NULL,
"session feature declarations" },
{ SM_CONF_DEF_MAGIC, "flags", sm_conf_type_choice,
offsetof(ss_cnf_T, ss_cnf_cflags), sizeof(uint32_t),
SM_XSTR(SSSE_CFL_STARTTLS) "|" SM_XSTR(SSSE_CFL_AUTH),
SM_CONF_FLAG_MULTIPLE|SM_CONF_FLAG_OR|SM_CONF_FLAG_PLURAL|SM_CONF_FLAG_NUMERIC,
ss_se_flag_names,
NULL, NULL,
"global flags to influence behavior"
#if SM_LIBCONF_ISSET
, offsetof(ss_cnf_T, sssf_isset_cflags)
#endif
#if SM_LIBCONF_MAGIC
, SM_CNF_MAGIC
#endif
},
{ SM_CONF_DEF_MAGIC, "max_ta", sm_conf_type_u32,
offsetof(ss_cnf_T, ss_cnf_max_ta), sizeof(uint32_t),
"99", 0,
NULL, NULL, NULL,
"global max ta"
#if SM_LIBCONF_ISSET
, offsetof(ss_cnf_T, ss_cnf_max_ta_isset)
#endif
#if SM_LIBCONF_MAGIC
, SM_CNF_MAGIC
#endif
},
{ 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;
s.sm_magic = SM_CNF_MAGIC;
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;
#if SM_LIBCONF_ISSET
fprintf(stderr, "isset_cflags=%hd\n", s.sssf_isset_cflags);
#endif
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]=0x%08x\n", u,
s.ss_cnf_srv_feats.sssfs_feat[u].sssf_flags);
fprintf(stderr, "isset_flags[%u]=%hd\n", u,
s.ss_cnf_srv_feats.sssfs_feat[u].sssf_isset_flags);
fprintf(stderr, "isset_name[%u]=%hd\n", u,
s.ss_cnf_srv_feats.sssfs_feat[u].sssf_isset_name);
fprintf(stderr, "isset_max_ta[%u]=%hd\n", u,
s.ss_cnf_srv_feats.sssfs_feat[u].sssf_max_ta_isset);
}
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1