/*
* Copyright (c) 2004-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: sm-conf-prtdef.c,v 1.12 2007/06/10 16:03:55 ca Exp $")
#include "sm/string.h"
#include "sm/sm-conf.h"
#include "sm/sm-conf-prt.h"
#include "sm-conf-type.h"
#include "sm/io.h"
#include "sm/util.h"
#include "prtcnf.h"
/* show configuration definition */
/*
** SM_CONF_PRT_DEF -- print defaults for one node
**
** Parameters:
** def -- configuration definition.
** flags -- flags
** fp -- file for output
** indent -- current indentation
** text -- if not NULL: print this if something is printed
** in this invocation
**
** Returns:
** 0: didn't print anything
** >0: something has been printed
**
** Note: this doesn't deal with all types! FIXME!
*/
static int
sm_conf_prt_def(const sm_conf_definition_T *def, uint flags, sm_file_T *fp, int indent, sm_str_P text)
{
const sm_conf_type_T *scdtype;
int ret;
sm_file_T *sfp;
sm_file_T text_file;
SM_IS_CONF_DEF(def);
scdtype = def->scd_type;
if (scdtype == NULL)
return 0;
ret = 0;
sfp = NULL;
#define PRT_COMMENT(fp) \
do \
{ \
if (def->scd_description != NULL && \
*(def->scd_description) != '\0') \
{ \
prt_fmtted((fp), indent, "# ", def->scd_description); \
} \
} while (0)
#define PRT_TEXT \
do \
{ \
if (text != NULL && sm_str_getlen(text) > 0) \
{ \
sm_io_fprintf(fp, "%S", text); \
sm_str_clr(text); \
} \
} while (0)
#define TEXT2FP \
do \
{ \
if (text != NULL) \
{ \
/* currently doesn't fail; check?? */ \
(void) sm_str2file(text, &text_file); \
sfp = &text_file; \
} \
else \
{ \
PRT_TEXT; \
sfp = fp; \
} \
} while (0)
if (SM_IS_FLAG(def->scd_flags, SM_CONF_FLAG_DPRCD))
return 0;
if (scdtype == sm_conf_type_section)
{
int r;
TEXT2FP;
PRT_COMMENT(sfp);
sm_io_fprintf(sfp, "\n%*s%s {\n"
, indent, ""
, def->scd_name);
r = sm_conf_prt_defs(def->scd_contents, flags, fp, indent + 2,
text);
if (r > 0)
{
sm_io_fprintf(fp, "%*s}\n"
, indent, "");
ret += r;
}
/*
** This doesn't work for nested sections!
** we "just" need to get back to the old text
*/
if (text != NULL)
sm_str_clr(text);
}
else if (scdtype == sm_conf_type_string && def->scd_default != NULL)
{
PRT_TEXT;
PRT_COMMENT(fp);
sm_io_fprintf(fp, "%*s%s=\"%s\";\n"
, indent, ""
, def->scd_name
, def->scd_default);
ret = 1;
}
else if (scdtype == sm_conf_type_union)
{
const sm_conf_definition_T *union_def;
union_def = def->scd_contents;
if (union_def != NULL
&& union_def->scd_type == sm_conf_type_union_type)
{
int choice_type;
bool found;
ptrdiff_t offtype;
const sm_conf_definition_T *union_choice_def;
offtype = union_def->scd_offset;
/* fixme: how to find the right size for the type?? */
choice_type = 0; /* default???? */
#if 0
if (def->scd_default != NULL)
/* scan default, assign it to choice_type?? */;
#endif
found = false;
union_choice_def = union_def + 1;
while (union_choice_def != NULL
&& union_choice_def->sm_magic
== SM_CONF_DEF_MAGIC
&& union_choice_def->scd_name != NULL
&& union_choice_def->scd_type
== sm_conf_type_union_choice
&& !found
)
{
if ((int) union_choice_def->scd_offset
== choice_type)
found = true;
else
++union_choice_def;
}
if (found)
{
int r;
PRT_TEXT;
PRT_COMMENT(fp);
sm_io_fprintf(fp, "%*s%s {\n"
, indent, ""
, def->scd_name);
r = sm_conf_prt_defs(
union_choice_def->scd_contents, flags,
fp, indent + 2, text);
sm_io_fprintf(fp, "%*s}\n"
, indent, "");
if (r > 0)
ret += r;
}
}
}
else if (scdtype == sm_conf_type_choice &&
SM_IS_FLAG(flags, SMC_FLD_FLAGS))
{
/*
** When can we actually print this?
** Only if the section doesn't contain a required selection,
** otherwise the created output is not a valid conf file.
*/
uint32_t u;
u = 0xffffffff;
/* scan def->scd_default? */
if (u != 0 &&
(def->scd_flags & SM_CONF_FLAG_MULTIPLE) != 0)
{
PRT_TEXT;
PRT_COMMENT(fp);
sm_io_fprintf(fp, "%*s# %s={ # possible values:\n"
, indent, ""
, def->scd_name);
(void) sm_conf_sub2valbit(def->scd_contents,
NULL, u, "# flag: ", "\n",
indent + 2, fp);
sm_io_fprintf(fp, "%*s# }\n", indent, "");
ret = 1;
}
else if (u != 0 &&
(def->scd_flags & SM_CONF_FLAG_OR) != 0)
{
PRT_TEXT;
PRT_COMMENT(fp);
sm_io_fprintf(fp, "%*s# %s= # select one of:\n"
, indent, ""
, def->scd_name);
(void) sm_conf_sub2valbit(def->scd_contents,
NULL, u, "# flag:", "\n",
indent + 2, fp);
ret = 1;
}
else if (u != 0)
{
PRT_TEXT;
PRT_COMMENT(fp);
sm_io_fprintf(fp, "%*s# %s=\n"
, indent, ""
, def->scd_name);
(void) sm_conf_sub2valeq(def->scd_contents,
NULL, u, fp);
sm_io_fprintf(fp, "\n");
ret = 1;
}
}
else if (def->scd_default != NULL)
{
PRT_TEXT;
PRT_COMMENT(fp);
sm_io_fprintf(fp, "%*s%s=%s;\n"
, indent, ""
, def->scd_name
, def->scd_default);
ret = 1;
}
else
{
TEXT2FP;
PRT_COMMENT(sfp);
sm_io_fprintf(sfp, "%*s# %s %s not set by default\n"
, indent, ""
, def->scd_name
, ((def->scd_flags & SM_CONF_FLAG_PLURAL) != 0)
? "are" : "is"
);
}
return ret;
}
/*
** SM_CONF_PRT_DEFS -- print default values of configuration definition
**
** Parameters:
** def -- configuration definition.
** fp -- file for output
** indent -- current indentation
** text -- if not NULL: print this if something is printed
** in this invocation
**
** Returns:
** SM_SUCCESS
*/
int
sm_conf_prt_defs(const sm_conf_definition_T *defs, uint flags, sm_file_T *fp, int indent, sm_str_P text)
{
const sm_conf_definition_T *def;
int r, ret;
ret = 0;
while ((def = defs++) != NULL && def->scd_name != NULL)
{
SM_IS_CONF_DEF(def);
r = sm_conf_prt_def(def, flags, fp, indent, text);
if (r > 0)
ret += r;
}
return ret;
}
/*
** SM_CONF_PRT_DFLT -- print default values of configuration definition
** (wrapper for sm_conf_prt_defs())
**
** Parameters:
** def -- configuration definition.
** fp -- file for output
**
** Returns:
** SM_SUCCESS or ENOMEM
*/
sm_ret_T
sm_conf_prt_dflt(const sm_conf_definition_T *defs, uint flags, sm_file_T *fp)
{
int ret;
sm_str_P sect_text;
sect_text = sm_str_new(NULL, 256, 8 * 1024);
if (sect_text == NULL)
return sm_err_temp(ENOMEM);
ret = sm_conf_prt_defs(defs, flags, fp, 0, sect_text);
SM_STR_FREE(sect_text);
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1