1/*	$NetBSD: postconf_node.c,v 1.2 2017/02/14 01:16:46 christos Exp $	*/
2
3/*++
4/* NAME
5/*	postconf_node 3
6/* SUMMARY
7/*	low-level parameter node support
8/* SYNOPSIS
9/*	#include <postconf.h>
10/*
11/*	PCF_PARAM_TABLE *PCF_PARAM_TABLE_CREATE(size)
12/*	ssize_t	size;
13/*
14/*	PCF_PARAM_INFO **PCF_PARAM_TABLE_LIST(table)
15/*	PCF_PARAM_TABLE *table;
16/*
17/*	const char *PCF_PARAM_INFO_NAME(info)
18/*	PCF_PARAM_INFO *info;
19/*
20/*	PCF_PARAM_NODE *PCF_PARAM_INFO_NODE(info)
21/*	PCF_PARAM_INFO *info;
22/*
23/*	PCF_PARAM_NODE *PCF_PARAM_TABLE_FIND(table, name)
24/*	PCF_PARAM_TABLE *table;
25/*	const char *name;
26/*
27/*	PCF_PARAM_INFO *PCF_PARAM_TABLE_LOCATE(table, name)
28/*	PCF_PARAM_TABLE *table;
29/*	const char *name;
30/*
31/*	PCF_PARAM_INFO *PCF_PARAM_TABLE_ENTER(table, name, flags,
32/*						param_data, convert_fn)
33/*	PCF_PARAM_TABLE *table;
34/*	const char *name;
35/*	int	flags;
36/*	void	*param_data;
37/*	const char *(*convert_fn)(void *);
38/*
39/*	PCF_PARAM_NODE *pcf_make_param_node(flags, param_data, convert_fn)
40/*	int	flags;
41/*	void	*param_data;
42/*	const char *(*convert_fn) (void *);
43/*
44/*	const char *pcf_convert_param_node(mode, name, node)
45/*	int	mode;
46/*	const char *name;
47/*	PCF_PARAM_NODE *node;
48/*
49/*	VSTRING *pcf_param_string_buf;
50/*
51/*	PCF_RAW_PARAMETER(node)
52/*	const PCF_PARAM_NODE *node;
53/* DESCRIPTION
54/*	This module maintains data structures (PCF_PARAM_NODE) with
55/*	information about known-legitimate parameters.  These data
56/*	structures are stored in a hash table.
57/*
58/*	The PCF_PARAM_MUMBLE() macros are wrappers around the
59/*	htable(3) module. Their sole purpose is to encapsulate all
60/*	the pointer casting from and to (PCF_PARAM_NODE *). Apart
61/*	from that, the macros have no features worth discussing.
62/*
63/*	pcf_make_param_node() creates a node for the global parameter
64/*	table. This node provides a parameter default value, and a
65/*	function that converts the default value to string.
66/*
67/*	pcf_convert_param_node() produces a string representation
68/*	for a global parameter default value.
69/*
70/*	PCF_RAW_PARAMETER() returns non-zero if the specified
71/*	parameter node represents a "raw parameter". The value of
72/*	such parameters must not be scanned for macro names.  Some
73/*	"raw parameter" values contain "$" without macros, such as
74/*	the smtpd_expansion_filter "safe character" set; and some
75/*	contain $name from a private name space, such as forward_path.
76/*	Some "raw parameter" values in postscreen(8) are safe to
77/*	expand by one level.  Support for that may be added later.
78/*
79/*	pcf_param_string_buf is a buffer that is initialized on the
80/*	fly and that parameter-to-string conversion functions may
81/*	use for temporary result storage.
82/*
83/*	Arguments:
84/* .IP size
85/*	The initial size of the hash table.
86/* .IP table
87/*	A hash table for storage of "valid parameter" information.
88/* .IP info
89/*	A data structure with a name component and a PCF_PARAM_NODE
90/*	component. Use PCF_PARAM_INFO_NAME() and PCF_PARAM_INFO_NODE()
91/*	to access these components.
92/* .IP name
93/*	The name of a "valid parameter".
94/* .IP flags
95/*	PCF_PARAM_FLAG_RAW for a "raw parameter", PCF_PARAM_FLAG_NONE
96/*	otherwise. See the PCF_RAW_PARAMETER() discussion above for
97/*	discussion of "raw parameter" values.
98/* .IP param_data
99/*	Information about the parameter value.  Specify PCF_PARAM_NO_DATA
100/*	if this is not applicable.
101/* .IP convert_fn
102/*	The function that will be invoked to produce a string
103/*	representation of the information in param_data. The function
104/*	receives the param_data value as argument.
105/* .IP mode
106/*	For now, the PCF_SHOW_DEFS flag is required.
107/* .IP name
108/*	The name of the parameter whose value is requested.  This
109/*	is used for diagnostics.
110/* .IP node
111/*	The (flags, param_data, convert_fn) information that needs
112/*	to be converted to a string representation of the default
113/*	value.
114/* DIAGNOSTICS
115/*	Problems are reported to the standard error stream.
116/* LICENSE
117/* .ad
118/* .fi
119/*	The Secure Mailer license must be distributed with this software.
120/* AUTHOR(S)
121/*	Wietse Venema
122/*	IBM T.J. Watson Research
123/*	P.O. Box 704
124/*	Yorktown Heights, NY 10598, USA
125/*--*/
126
127
128/* System library. */
129
130#include <sys_defs.h>
131
132/* Utility library. */
133
134#include <msg.h>
135#include <mymalloc.h>
136#include <vstring.h>
137
138/* Application-specific. */
139
140#include <postconf.h>
141
142VSTRING *pcf_param_string_buf;
143
144/* pcf_make_param_node - make node for global parameter table */
145
146PCF_PARAM_NODE *pcf_make_param_node(int flags, void *param_data,
147				         const char *(*convert_fn) (void *))
148{
149    PCF_PARAM_NODE *node;
150
151    node = (PCF_PARAM_NODE *) mymalloc(sizeof(*node));
152    node->flags = flags;
153    node->param_data = param_data;
154    node->convert_fn = convert_fn;
155    return (node);
156}
157
158/* pcf_convert_param_node - get default parameter value */
159
160const char *pcf_convert_param_node(int mode, const char *name, PCF_PARAM_NODE *node)
161{
162    const char *myname = "pcf_convert_param_node";
163    const char *value;
164
165    /*
166     * One-off initialization.
167     */
168    if (pcf_param_string_buf == 0)
169	pcf_param_string_buf = vstring_alloc(100);
170
171    /*
172     * Sanity check. A null value indicates that a parameter does not have
173     * the requested value. At this time, the only requested value can be the
174     * default value, and a null pointer value makes no sense here.
175     */
176    if ((mode & PCF_SHOW_DEFS) == 0)
177	msg_panic("%s: request for non-default value of parameter %s",
178		  myname, name);
179    if ((value = node->convert_fn(node->param_data)) == 0)
180	msg_panic("%s: parameter %s has null pointer default value",
181		  myname, name);
182
183    /*
184     * Return the parameter default value.
185     */
186    return (value);
187}
188