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