xref: /netbsd-src/external/ibm-public/postfix/dist/src/postconf/postconf_main.c (revision c48c605c14fd8622b523d1d6a3f0c0bad133ea89)
1 /*	$NetBSD: postconf_main.c,v 1.4 2023/12/23 20:30:44 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	postconf_main 3
6 /* SUMMARY
7 /*	basic support for main.cf
8 /* SYNOPSIS
9 /*	#include <postconf.h>
10 /*
11 /*	void	pcf_read_parameters()
12 /*
13 /*	void	pcf_show_parameters(fp, mode, param_class, names)
14 /*	VSTREAM	*fp;
15 /*	int	mode;
16 /*	int	param_class;
17 /*	char	**names;
18 /* DESCRIPTION
19 /*	pcf_read_parameters() reads parameters from main.cf.
20 /*
21 /*	pcf_set_parameters() takes an array of \fIname=value\fR
22 /*	pairs and overrides settings read with pcf_read_parameters().
23 /*
24 /*	pcf_show_parameters() writes main.cf parameters to the
25 /*	specified output stream.
26 /*
27 /*	Arguments:
28 /* .IP fp
29 /*	Output stream.
30 /* .IP mode
31 /*	Bit-wise OR of zero or more of the following:
32 /* .RS
33 /* .IP PCF_FOLD_LINE
34 /*	Fold long lines.
35 /* .IP PCF_SHOW_DEFS
36 /*	Output default parameter values.
37 /* .IP PCF_SHOW_NONDEF
38 /*	Output explicit settings only.
39 /* .IP PCF_HIDE_NAME
40 /*	Output parameter values without the "name =" prefix.
41 /* .IP PCF_SHOW_EVAL
42 /*	Expand $name in parameter values.
43 /* .RE
44 /* .IP param_class
45 /*	Bit-wise OR of one or more of the following:
46 /* .RS
47 /* .IP PCF_PARAM_FLAG_BUILTIN
48 /*	Show built-in parameters.
49 /* .IP PCF_PARAM_FLAG_SERVICE
50 /*	Show service-defined parameters.
51 /* .IP PCF_PARAM_FLAG_USER
52 /*	Show user-defined parameters.
53 /* .RE
54 /* .IP names
55 /*	List of zero or more parameter names. If the list is empty,
56 /*	output all parameters.
57 /* DIAGNOSTICS
58 /*	Problems are reported to the standard error stream.
59 /* LICENSE
60 /* .ad
61 /* .fi
62 /*	The Secure Mailer license must be distributed with this software.
63 /* AUTHOR(S)
64 /*	Wietse Venema
65 /*	IBM T.J. Watson Research
66 /*	P.O. Box 704
67 /*	Yorktown Heights, NY 10598, USA
68 /*
69 /*	Wietse Venema
70 /*	Google, Inc.
71 /*	111 8th Avenue
72 /*	New York, NY 10011, USA
73 /*--*/
74 
75 /* System library. */
76 
77 #include <sys_defs.h>
78 #include <stdarg.h>
79 #include <stdlib.h>
80 #include <string.h>
81 
82 /* Utility library. */
83 
84 #include <msg.h>
85 #include <mymalloc.h>
86 #include <vstream.h>
87 #include <vstring.h>
88 #include <readlline.h>
89 #include <dict.h>
90 #include <stringops.h>
91 #include <htable.h>
92 #include <mac_expand.h>
93 
94 /* Global library. */
95 
96 #include <mail_params.h>
97 #include <mail_conf.h>
98 
99 /* Application-specific. */
100 
101 #include <postconf.h>
102 
103 #define STR(x) vstring_str(x)
104 
105 /* pcf_read_parameters - read parameter info from file */
106 
pcf_read_parameters(void)107 void    pcf_read_parameters(void)
108 {
109     const char *path;
110 
111     /*
112      * A direct rip-off of mail_conf_read(). XXX Avoid code duplication by
113      * better code decomposition.
114      */
115     path = pcf_get_main_path();
116     if (dict_load_file_xt(CONFIG_DICT, path) == 0)
117 	msg_fatal("open %s: %m", path);
118 }
119 
120 /* pcf_set_parameters - add or override name=value pairs */
121 
pcf_set_parameters(char ** name_val_array)122 void    pcf_set_parameters(char **name_val_array)
123 {
124     char   *name, *value, *junk;
125     const char *err;
126     char  **cpp;
127 
128     for (cpp = name_val_array; *cpp; cpp++) {
129 	junk = mystrdup(*cpp);
130 	if ((err = split_nameval(junk, &name, &value)) != 0)
131 	    msg_fatal("invalid parameter override: %s: %s", *cpp, err);
132 	mail_conf_update(name, value);
133 	myfree(junk);
134     }
135 }
136 
137 /* pcf_print_parameter - show specific parameter */
138 
pcf_print_parameter(VSTREAM * fp,int mode,const char * name,PCF_PARAM_NODE * node)139 static void pcf_print_parameter(VSTREAM *fp, int mode, const char *name,
140 				        PCF_PARAM_NODE *node)
141 {
142     static VSTRING *exp_buf = 0;
143     const char *value;
144 
145     if (exp_buf == 0)
146 	exp_buf = vstring_alloc(100);
147 
148     /*
149      * Use the default or actual value.
150      */
151     value = pcf_lookup_parameter_value(mode, name, (PCF_MASTER_ENT *) 0, node);
152 
153     /*
154      * Optionally expand $name in the parameter value. Print the result with
155      * or without the name= prefix.
156      */
157     if (value != 0) {
158 	if (mode & PCF_HIDE_VALUE) {
159 	    pcf_print_line(fp, mode, "%s\n", name);
160 	} else {
161 	    if ((mode & PCF_SHOW_EVAL) != 0 && PCF_RAW_PARAMETER(node) == 0)
162 		value = pcf_expand_parameter_value(exp_buf, mode, value,
163 						   (PCF_MASTER_ENT *) 0);
164 	    if ((mode & PCF_HIDE_NAME) == 0) {
165 		pcf_print_line(fp, mode, "%s = %s\n", name, value);
166 	    } else {
167 		pcf_print_line(fp, mode, "%s\n", value);
168 	    }
169 	}
170 	if (msg_verbose)
171 	    vstream_fflush(fp);
172     }
173 }
174 
175 /* pcf_comp_names - qsort helper */
176 
pcf_comp_names(const void * a,const void * b)177 static int pcf_comp_names(const void *a, const void *b)
178 {
179     PCF_PARAM_INFO **ap = (PCF_PARAM_INFO **) a;
180     PCF_PARAM_INFO **bp = (PCF_PARAM_INFO **) b;
181 
182     return (strcmp(PCF_PARAM_INFO_NAME(ap[0]),
183 		   PCF_PARAM_INFO_NAME(bp[0])));
184 }
185 
186 /* pcf_show_parameters - show parameter info */
187 
pcf_show_parameters(VSTREAM * fp,int mode,int param_class,char ** names)188 void    pcf_show_parameters(VSTREAM *fp, int mode, int param_class, char **names)
189 {
190     PCF_PARAM_INFO **list;
191     PCF_PARAM_INFO **ht;
192     char  **namep;
193     PCF_PARAM_NODE *node;
194 
195     /*
196      * Show all parameters.
197      */
198     if (*names == 0) {
199 	list = PCF_PARAM_TABLE_LIST(pcf_param_table);
200 	qsort((void *) list, pcf_param_table->used, sizeof(*list),
201 	      pcf_comp_names);
202 	for (ht = list; *ht; ht++)
203 	    if (param_class & PCF_PARAM_INFO_NODE(*ht)->flags)
204 		pcf_print_parameter(fp, mode, PCF_PARAM_INFO_NAME(*ht),
205 				    PCF_PARAM_INFO_NODE(*ht));
206 	myfree((void *) list);
207 	return;
208     }
209 
210     /*
211      * Show named parameters.
212      */
213     for (namep = names; *namep; namep++) {
214 	if ((node = PCF_PARAM_TABLE_FIND(pcf_param_table, *namep)) == 0) {
215 	    msg_warn("%s: unknown parameter", *namep);
216 	} else {
217 	    pcf_print_parameter(fp, mode, *namep, node);
218 	}
219     }
220 }
221