b2a3c7370ba836350c7a6157b0ada5c6ebc6ae99
[users/heiko/exim.git] / src / src / readconf.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2016 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Functions for reading the configuration file, and for displaying
9 overall configuration values. Thanks to Brian Candler for the original
10 implementation of the conditional .ifdef etc. */
11
12 #include "exim.h"
13
14 extern char **environ;
15
16 static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
17 static void save_config_line(const uschar* line);
18 static void save_config_position(const uschar *file, int line);
19 static void print_config(BOOL admin, BOOL terse);
20 static void readconf_options_auths(void);
21
22
23 #define CSTATE_STACK_SIZE 10
24
25
26 /* Structure for chain (stack) of .included files */
27
28 typedef struct config_file_item {
29   struct config_file_item *next;
30   uschar *filename;
31   FILE *file;
32   int lineno;
33 } config_file_item;
34
35 /* Structure for chain of configuration lines (-bP config) */
36
37 typedef struct config_line_item {
38   struct config_line_item *next;
39   uschar *line;
40 } config_line_item;
41
42 static config_line_item* config_lines;
43
44 /* Structure of table of conditional words and their state transitions */
45
46 typedef struct cond_item {
47   uschar *name;
48   int    namelen;
49   int    action1;
50   int    action2;
51   int    pushpop;
52 } cond_item;
53
54 /* Structure of table of syslog facility names and values */
55
56 typedef struct syslog_fac_item {
57   uschar *name;
58   int    value;
59 } syslog_fac_item;
60
61 /* constants */
62 static const char * const hidden = "<value not displayable>";
63
64 /* Static variables */
65
66 static config_file_item *config_file_stack = NULL;  /* For includes */
67
68 static uschar *syslog_facility_str  = NULL;
69 static uschar next_section[24];
70 static uschar time_buffer[24];
71
72 /* State variables for conditional loading (.ifdef / .else / .endif) */
73
74 static int cstate = 0;
75 static int cstate_stack_ptr = -1;
76 static int cstate_stack[CSTATE_STACK_SIZE];
77
78 /* Table of state transitions for handling conditional inclusions. There are
79 four possible state transitions:
80
81   .ifdef true
82   .ifdef false
83   .elifdef true  (or .else)
84   .elifdef false
85
86 .endif just causes the previous cstate to be popped off the stack */
87
88 static int next_cstate[3][4] =
89   {
90   /* State 0: reading from file, or reading until next .else or .endif */
91   { 0, 1, 2, 2 },
92   /* State 1: condition failed, skipping until next .else or .endif */
93   { 2, 2, 0, 1 },
94   /* State 2: skipping until .endif */
95   { 2, 2, 2, 2 },
96   };
97
98 /* Table of conditionals and the states to set. For each name, there are four
99 values: the length of the name (to save computing it each time), the state to
100 set if a macro was found in the line, the state to set if a macro was not found
101 in the line, and a stack manipulation setting which is:
102
103   -1   pull state value off the stack
104    0   don't alter the stack
105   +1   push value onto stack, before setting new state
106 */
107
108 static cond_item cond_list[] = {
109   { US"ifdef",    5, 0, 1,  1 },
110   { US"ifndef",   6, 1, 0,  1 },
111   { US"elifdef",  7, 2, 3,  0 },
112   { US"elifndef", 8, 3, 2,  0 },
113   { US"else",     4, 2, 2,  0 },
114   { US"endif",    5, 0, 0, -1 }
115 };
116
117 static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
118
119 /* Table of syslog facility names and their values */
120
121 static syslog_fac_item syslog_list[] = {
122   { US"mail",   LOG_MAIL },
123   { US"user",   LOG_USER },
124   { US"news",   LOG_NEWS },
125   { US"uucp",   LOG_UUCP },
126   { US"local0", LOG_LOCAL0 },
127   { US"local1", LOG_LOCAL1 },
128   { US"local2", LOG_LOCAL2 },
129   { US"local3", LOG_LOCAL3 },
130   { US"local4", LOG_LOCAL4 },
131   { US"local5", LOG_LOCAL5 },
132   { US"local6", LOG_LOCAL6 },
133   { US"local7", LOG_LOCAL7 },
134   { US"daemon", LOG_DAEMON }
135 };
136
137 static int syslog_list_size = sizeof(syslog_list)/sizeof(syslog_fac_item);
138
139
140
141
142 /*************************************************
143 *           Main configuration options           *
144 *************************************************/
145
146 /* The list of options that can be set in the main configuration file. This
147 must be in alphabetic order because it is searched by binary chop. */
148
149 static optionlist optionlist_config[] = {
150   { "*set_exim_group",          opt_bool|opt_hidden, &exim_gid_set },
151   { "*set_exim_user",           opt_bool|opt_hidden, &exim_uid_set },
152   { "*set_system_filter_group", opt_bool|opt_hidden, &system_filter_gid_set },
153   { "*set_system_filter_user",  opt_bool|opt_hidden, &system_filter_uid_set },
154   { "accept_8bitmime",          opt_bool,        &accept_8bitmime },
155   { "acl_not_smtp",             opt_stringptr,   &acl_not_smtp },
156 #ifdef WITH_CONTENT_SCAN
157   { "acl_not_smtp_mime",        opt_stringptr,   &acl_not_smtp_mime },
158 #endif
159   { "acl_not_smtp_start",       opt_stringptr,   &acl_not_smtp_start },
160   { "acl_smtp_auth",            opt_stringptr,   &acl_smtp_auth },
161   { "acl_smtp_connect",         opt_stringptr,   &acl_smtp_connect },
162   { "acl_smtp_data",            opt_stringptr,   &acl_smtp_data },
163 #ifndef DISABLE_PRDR
164   { "acl_smtp_data_prdr",       opt_stringptr,   &acl_smtp_data_prdr },
165 #endif
166 #ifndef DISABLE_DKIM
167   { "acl_smtp_dkim",            opt_stringptr,   &acl_smtp_dkim },
168 #endif
169   { "acl_smtp_etrn",            opt_stringptr,   &acl_smtp_etrn },
170   { "acl_smtp_expn",            opt_stringptr,   &acl_smtp_expn },
171   { "acl_smtp_helo",            opt_stringptr,   &acl_smtp_helo },
172   { "acl_smtp_mail",            opt_stringptr,   &acl_smtp_mail },
173   { "acl_smtp_mailauth",        opt_stringptr,   &acl_smtp_mailauth },
174 #ifdef WITH_CONTENT_SCAN
175   { "acl_smtp_mime",            opt_stringptr,   &acl_smtp_mime },
176 #endif
177   { "acl_smtp_notquit",         opt_stringptr,   &acl_smtp_notquit },
178   { "acl_smtp_predata",         opt_stringptr,   &acl_smtp_predata },
179   { "acl_smtp_quit",            opt_stringptr,   &acl_smtp_quit },
180   { "acl_smtp_rcpt",            opt_stringptr,   &acl_smtp_rcpt },
181 #ifdef SUPPORT_TLS
182   { "acl_smtp_starttls",        opt_stringptr,   &acl_smtp_starttls },
183 #endif
184   { "acl_smtp_vrfy",            opt_stringptr,   &acl_smtp_vrfy },
185   { "add_environment",          opt_stringptr,   &add_environment },
186   { "admin_groups",             opt_gidlist,     &admin_groups },
187   { "allow_domain_literals",    opt_bool,        &allow_domain_literals },
188   { "allow_mx_to_ip",           opt_bool,        &allow_mx_to_ip },
189   { "allow_utf8_domains",       opt_bool,        &allow_utf8_domains },
190   { "auth_advertise_hosts",     opt_stringptr,   &auth_advertise_hosts },
191   { "auto_thaw",                opt_time,        &auto_thaw },
192 #ifdef WITH_CONTENT_SCAN
193   { "av_scanner",               opt_stringptr,   &av_scanner },
194 #endif
195   { "bi_command",               opt_stringptr,   &bi_command },
196 #ifdef EXPERIMENTAL_BRIGHTMAIL
197   { "bmi_config_file",          opt_stringptr,   &bmi_config_file },
198 #endif
199   { "bounce_message_file",      opt_stringptr,   &bounce_message_file },
200   { "bounce_message_text",      opt_stringptr,   &bounce_message_text },
201   { "bounce_return_body",       opt_bool,        &bounce_return_body },
202   { "bounce_return_linesize_limit", opt_mkint,   &bounce_return_linesize_limit },
203   { "bounce_return_message",    opt_bool,        &bounce_return_message },
204   { "bounce_return_size_limit", opt_mkint,       &bounce_return_size_limit },
205   { "bounce_sender_authentication",opt_stringptr,&bounce_sender_authentication },
206   { "callout_domain_negative_expire", opt_time,  &callout_cache_domain_negative_expire },
207   { "callout_domain_positive_expire", opt_time,  &callout_cache_domain_positive_expire },
208   { "callout_negative_expire",  opt_time,        &callout_cache_negative_expire },
209   { "callout_positive_expire",  opt_time,        &callout_cache_positive_expire },
210   { "callout_random_local_part",opt_stringptr,   &callout_random_local_part },
211   { "check_log_inodes",         opt_int,         &check_log_inodes },
212   { "check_log_space",          opt_Kint,        &check_log_space },
213   { "check_rfc2047_length",     opt_bool,        &check_rfc2047_length },
214   { "check_spool_inodes",       opt_int,         &check_spool_inodes },
215   { "check_spool_space",        opt_Kint,        &check_spool_space },
216   { "chunking_advertise_hosts", opt_stringptr,   &chunking_advertise_hosts },
217   { "daemon_smtp_port",         opt_stringptr|opt_hidden, &daemon_smtp_port },
218   { "daemon_smtp_ports",        opt_stringptr,   &daemon_smtp_port },
219   { "daemon_startup_retries",   opt_int,         &daemon_startup_retries },
220   { "daemon_startup_sleep",     opt_time,        &daemon_startup_sleep },
221 #ifdef EXPERIMENTAL_DCC
222   { "dcc_direct_add_header",    opt_bool,        &dcc_direct_add_header },
223   { "dccifd_address",           opt_stringptr,   &dccifd_address },
224   { "dccifd_options",           opt_stringptr,   &dccifd_options },
225 #endif
226   { "delay_warning",            opt_timelist,    &delay_warning },
227   { "delay_warning_condition",  opt_stringptr,   &delay_warning_condition },
228   { "deliver_drop_privilege",   opt_bool,        &deliver_drop_privilege },
229   { "deliver_queue_load_max",   opt_fixed,       &deliver_queue_load_max },
230   { "delivery_date_remove",     opt_bool,        &delivery_date_remove },
231 #ifdef ENABLE_DISABLE_FSYNC
232   { "disable_fsync",            opt_bool,        &disable_fsync },
233 #endif
234   { "disable_ipv6",             opt_bool,        &disable_ipv6 },
235 #ifndef DISABLE_DKIM
236   { "dkim_verify_signers",      opt_stringptr,   &dkim_verify_signers },
237 #endif
238 #ifdef EXPERIMENTAL_DMARC
239   { "dmarc_forensic_sender",    opt_stringptr,   &dmarc_forensic_sender },
240   { "dmarc_history_file",       opt_stringptr,   &dmarc_history_file },
241   { "dmarc_tld_file",           opt_stringptr,   &dmarc_tld_file },
242 #endif
243   { "dns_again_means_nonexist", opt_stringptr,   &dns_again_means_nonexist },
244   { "dns_check_names_pattern",  opt_stringptr,   &check_dns_names_pattern },
245   { "dns_csa_search_limit",     opt_int,         &dns_csa_search_limit },
246   { "dns_csa_use_reverse",      opt_bool,        &dns_csa_use_reverse },
247   { "dns_dnssec_ok",            opt_int,         &dns_dnssec_ok },
248   { "dns_ipv4_lookup",          opt_stringptr,   &dns_ipv4_lookup },
249   { "dns_retrans",              opt_time,        &dns_retrans },
250   { "dns_retry",                opt_int,         &dns_retry },
251   { "dns_trust_aa",             opt_stringptr,   &dns_trust_aa },
252   { "dns_use_edns0",            opt_int,         &dns_use_edns0 },
253  /* This option is now a no-op, retained for compability */
254   { "drop_cr",                  opt_bool,        &drop_cr },
255 /*********************************************************/
256   { "dsn_advertise_hosts",      opt_stringptr,   &dsn_advertise_hosts },
257   { "dsn_from",                 opt_stringptr,   &dsn_from },
258   { "envelope_to_remove",       opt_bool,        &envelope_to_remove },
259   { "errors_copy",              opt_stringptr,   &errors_copy },
260   { "errors_reply_to",          opt_stringptr,   &errors_reply_to },
261 #ifndef DISABLE_EVENT
262   { "event_action",             opt_stringptr,   &event_action },
263 #endif
264   { "exim_group",               opt_gid,         &exim_gid },
265   { "exim_path",                opt_stringptr,   &exim_path },
266   { "exim_user",                opt_uid,         &exim_uid },
267   { "extra_local_interfaces",   opt_stringptr,   &extra_local_interfaces },
268   { "extract_addresses_remove_arguments", opt_bool, &extract_addresses_remove_arguments },
269   { "finduser_retries",         opt_int,         &finduser_retries },
270   { "freeze_tell",              opt_stringptr,   &freeze_tell },
271   { "gecos_name",               opt_stringptr,   &gecos_name },
272   { "gecos_pattern",            opt_stringptr,   &gecos_pattern },
273 #ifdef SUPPORT_TLS
274   { "gnutls_allow_auto_pkcs11", opt_bool,        &gnutls_allow_auto_pkcs11 },
275   { "gnutls_compat_mode",       opt_bool,        &gnutls_compat_mode },
276 #endif
277   { "header_line_maxsize",      opt_int,         &header_line_maxsize },
278   { "header_maxsize",           opt_int,         &header_maxsize },
279   { "headers_charset",          opt_stringptr,   &headers_charset },
280   { "helo_accept_junk_hosts",   opt_stringptr,   &helo_accept_junk_hosts },
281   { "helo_allow_chars",         opt_stringptr,   &helo_allow_chars },
282   { "helo_lookup_domains",      opt_stringptr,   &helo_lookup_domains },
283   { "helo_try_verify_hosts",    opt_stringptr,   &helo_try_verify_hosts },
284   { "helo_verify_hosts",        opt_stringptr,   &helo_verify_hosts },
285   { "hold_domains",             opt_stringptr,   &hold_domains },
286   { "host_lookup",              opt_stringptr,   &host_lookup },
287   { "host_lookup_order",        opt_stringptr,   &host_lookup_order },
288   { "host_reject_connection",   opt_stringptr,   &host_reject_connection },
289   { "hosts_connection_nolog",   opt_stringptr,   &hosts_connection_nolog },
290 #ifdef SUPPORT_PROXY
291   { "hosts_proxy",              opt_stringptr,   &hosts_proxy },
292 #endif
293   { "hosts_treat_as_local",     opt_stringptr,   &hosts_treat_as_local },
294 #ifdef LOOKUP_IBASE
295   { "ibase_servers",            opt_stringptr,   &ibase_servers },
296 #endif
297   { "ignore_bounce_errors_after", opt_time,      &ignore_bounce_errors_after },
298   { "ignore_fromline_hosts",    opt_stringptr,   &ignore_fromline_hosts },
299   { "ignore_fromline_local",    opt_bool,        &ignore_fromline_local },
300   { "keep_environment",         opt_stringptr,   &keep_environment },
301   { "keep_malformed",           opt_time,        &keep_malformed },
302 #ifdef LOOKUP_LDAP
303   { "ldap_ca_cert_dir",         opt_stringptr,   &eldap_ca_cert_dir },
304   { "ldap_ca_cert_file",        opt_stringptr,   &eldap_ca_cert_file },
305   { "ldap_cert_file",           opt_stringptr,   &eldap_cert_file },
306   { "ldap_cert_key",            opt_stringptr,   &eldap_cert_key },
307   { "ldap_cipher_suite",        opt_stringptr,   &eldap_cipher_suite },
308   { "ldap_default_servers",     opt_stringptr,   &eldap_default_servers },
309   { "ldap_require_cert",        opt_stringptr,   &eldap_require_cert },
310   { "ldap_start_tls",           opt_bool,        &eldap_start_tls },
311   { "ldap_version",             opt_int,         &eldap_version },
312 #endif
313   { "local_from_check",         opt_bool,        &local_from_check },
314   { "local_from_prefix",        opt_stringptr,   &local_from_prefix },
315   { "local_from_suffix",        opt_stringptr,   &local_from_suffix },
316   { "local_interfaces",         opt_stringptr,   &local_interfaces },
317   { "local_scan_timeout",       opt_time,        &local_scan_timeout },
318   { "local_sender_retain",      opt_bool,        &local_sender_retain },
319   { "localhost_number",         opt_stringptr,   &host_number_string },
320   { "log_file_path",            opt_stringptr,   &log_file_path },
321   { "log_selector",             opt_stringptr,   &log_selector_string },
322   { "log_timezone",             opt_bool,        &log_timezone },
323   { "lookup_open_max",          opt_int,         &lookup_open_max },
324   { "max_username_length",      opt_int,         &max_username_length },
325   { "message_body_newlines",    opt_bool,        &message_body_newlines },
326   { "message_body_visible",     opt_mkint,       &message_body_visible },
327   { "message_id_header_domain", opt_stringptr,   &message_id_domain },
328   { "message_id_header_text",   opt_stringptr,   &message_id_text },
329   { "message_logs",             opt_bool,        &message_logs },
330   { "message_size_limit",       opt_stringptr,   &message_size_limit },
331 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
332   { "move_frozen_messages",     opt_bool,        &move_frozen_messages },
333 #endif
334   { "mua_wrapper",              opt_bool,        &mua_wrapper },
335 #ifdef LOOKUP_MYSQL
336   { "mysql_servers",            opt_stringptr,   &mysql_servers },
337 #endif
338   { "never_users",              opt_uidlist,     &never_users },
339 #ifdef SUPPORT_TLS
340   { "openssl_options",          opt_stringptr,   &openssl_options },
341 #endif
342 #ifdef LOOKUP_ORACLE
343   { "oracle_servers",           opt_stringptr,   &oracle_servers },
344 #endif
345   { "percent_hack_domains",     opt_stringptr,   &percent_hack_domains },
346 #ifdef EXIM_PERL
347   { "perl_at_start",            opt_bool,        &opt_perl_at_start },
348   { "perl_startup",             opt_stringptr,   &opt_perl_startup },
349   { "perl_taintmode",           opt_bool,        &opt_perl_taintmode },
350 #endif
351 #ifdef LOOKUP_PGSQL
352   { "pgsql_servers",            opt_stringptr,   &pgsql_servers },
353 #endif
354   { "pid_file_path",            opt_stringptr,   &pid_file_path },
355   { "pipelining_advertise_hosts", opt_stringptr, &pipelining_advertise_hosts },
356 #ifndef DISABLE_PRDR
357   { "prdr_enable",              opt_bool,        &prdr_enable },
358 #endif
359   { "preserve_message_logs",    opt_bool,        &preserve_message_logs },
360   { "primary_hostname",         opt_stringptr,   &primary_hostname },
361   { "print_topbitchars",        opt_bool,        &print_topbitchars },
362   { "process_log_path",         opt_stringptr,   &process_log_path },
363   { "prod_requires_admin",      opt_bool,        &prod_requires_admin },
364   { "qualify_domain",           opt_stringptr,   &qualify_domain_sender },
365   { "qualify_recipient",        opt_stringptr,   &qualify_domain_recipient },
366   { "queue_domains",            opt_stringptr,   &queue_domains },
367   { "queue_list_requires_admin",opt_bool,        &queue_list_requires_admin },
368   { "queue_only",               opt_bool,        &queue_only },
369   { "queue_only_file",          opt_stringptr,   &queue_only_file },
370   { "queue_only_load",          opt_fixed,       &queue_only_load },
371   { "queue_only_load_latch",    opt_bool,        &queue_only_load_latch },
372   { "queue_only_override",      opt_bool,        &queue_only_override },
373   { "queue_run_in_order",       opt_bool,        &queue_run_in_order },
374   { "queue_run_max",            opt_stringptr,   &queue_run_max },
375   { "queue_smtp_domains",       opt_stringptr,   &queue_smtp_domains },
376   { "receive_timeout",          opt_time,        &receive_timeout },
377   { "received_header_text",     opt_stringptr,   &received_header_text },
378   { "received_headers_max",     opt_int,         &received_headers_max },
379   { "recipient_unqualified_hosts", opt_stringptr, &recipient_unqualified_hosts },
380   { "recipients_max",           opt_int,         &recipients_max },
381   { "recipients_max_reject",    opt_bool,        &recipients_max_reject },
382 #ifdef LOOKUP_REDIS
383   { "redis_servers",            opt_stringptr,   &redis_servers },
384 #endif
385   { "remote_max_parallel",      opt_int,         &remote_max_parallel },
386   { "remote_sort_domains",      opt_stringptr,   &remote_sort_domains },
387   { "retry_data_expire",        opt_time,        &retry_data_expire },
388   { "retry_interval_max",       opt_time,        &retry_interval_max },
389   { "return_path_remove",       opt_bool,        &return_path_remove },
390   { "return_size_limit",        opt_mkint|opt_hidden, &bounce_return_size_limit },
391   { "rfc1413_hosts",            opt_stringptr,   &rfc1413_hosts },
392   { "rfc1413_query_timeout",    opt_time,        &rfc1413_query_timeout },
393   { "sender_unqualified_hosts", opt_stringptr,   &sender_unqualified_hosts },
394   { "slow_lookup_log",          opt_int,         &slow_lookup_log },
395   { "smtp_accept_keepalive",    opt_bool,        &smtp_accept_keepalive },
396   { "smtp_accept_max",          opt_int,         &smtp_accept_max },
397   { "smtp_accept_max_nonmail",  opt_int,         &smtp_accept_max_nonmail },
398   { "smtp_accept_max_nonmail_hosts", opt_stringptr, &smtp_accept_max_nonmail_hosts },
399   { "smtp_accept_max_per_connection", opt_int,   &smtp_accept_max_per_connection },
400   { "smtp_accept_max_per_host", opt_stringptr,   &smtp_accept_max_per_host },
401   { "smtp_accept_queue",        opt_int,         &smtp_accept_queue },
402   { "smtp_accept_queue_per_connection", opt_int, &smtp_accept_queue_per_connection },
403   { "smtp_accept_reserve",      opt_int,         &smtp_accept_reserve },
404   { "smtp_active_hostname",     opt_stringptr,   &raw_active_hostname },
405   { "smtp_banner",              opt_stringptr,   &smtp_banner },
406   { "smtp_check_spool_space",   opt_bool,        &smtp_check_spool_space },
407   { "smtp_connect_backlog",     opt_int,         &smtp_connect_backlog },
408   { "smtp_enforce_sync",        opt_bool,        &smtp_enforce_sync },
409   { "smtp_etrn_command",        opt_stringptr,   &smtp_etrn_command },
410   { "smtp_etrn_serialize",      opt_bool,        &smtp_etrn_serialize },
411   { "smtp_load_reserve",        opt_fixed,       &smtp_load_reserve },
412   { "smtp_max_synprot_errors",  opt_int,         &smtp_max_synprot_errors },
413   { "smtp_max_unknown_commands",opt_int,         &smtp_max_unknown_commands },
414   { "smtp_ratelimit_hosts",     opt_stringptr,   &smtp_ratelimit_hosts },
415   { "smtp_ratelimit_mail",      opt_stringptr,   &smtp_ratelimit_mail },
416   { "smtp_ratelimit_rcpt",      opt_stringptr,   &smtp_ratelimit_rcpt },
417   { "smtp_receive_timeout",     opt_func,        &fn_smtp_receive_timeout },
418   { "smtp_reserve_hosts",       opt_stringptr,   &smtp_reserve_hosts },
419   { "smtp_return_error_details",opt_bool,        &smtp_return_error_details },
420 #ifdef SUPPORT_I18N
421   { "smtputf8_advertise_hosts", opt_stringptr,   &smtputf8_advertise_hosts },
422 #endif
423 #ifdef WITH_CONTENT_SCAN
424   { "spamd_address",            opt_stringptr,   &spamd_address },
425 #endif
426 #ifdef EXPERIMENTAL_SPF
427   { "spf_guess",                opt_stringptr,   &spf_guess },
428 #endif
429   { "split_spool_directory",    opt_bool,        &split_spool_directory },
430   { "spool_directory",          opt_stringptr,   &spool_directory },
431 #ifdef LOOKUP_SQLITE
432   { "sqlite_lock_timeout",      opt_int,         &sqlite_lock_timeout },
433 #endif
434 #ifdef EXPERIMENTAL_SRS
435   { "srs_config",               opt_stringptr,   &srs_config },
436   { "srs_hashlength",           opt_int,         &srs_hashlength },
437   { "srs_hashmin",              opt_int,         &srs_hashmin },
438   { "srs_maxage",               opt_int,         &srs_maxage },
439   { "srs_secrets",              opt_stringptr,   &srs_secrets },
440   { "srs_usehash",              opt_bool,        &srs_usehash },
441   { "srs_usetimestamp",         opt_bool,        &srs_usetimestamp },
442 #endif
443   { "strict_acl_vars",          opt_bool,        &strict_acl_vars },
444   { "strip_excess_angle_brackets", opt_bool,     &strip_excess_angle_brackets },
445   { "strip_trailing_dot",       opt_bool,        &strip_trailing_dot },
446   { "syslog_duplication",       opt_bool,        &syslog_duplication },
447   { "syslog_facility",          opt_stringptr,   &syslog_facility_str },
448   { "syslog_pid",               opt_bool,        &syslog_pid },
449   { "syslog_processname",       opt_stringptr,   &syslog_processname },
450   { "syslog_timestamp",         opt_bool,        &syslog_timestamp },
451   { "system_filter",            opt_stringptr,   &system_filter },
452   { "system_filter_directory_transport", opt_stringptr,&system_filter_directory_transport },
453   { "system_filter_file_transport",opt_stringptr,&system_filter_file_transport },
454   { "system_filter_group",      opt_gid,         &system_filter_gid },
455   { "system_filter_pipe_transport",opt_stringptr,&system_filter_pipe_transport },
456   { "system_filter_reply_transport",opt_stringptr,&system_filter_reply_transport },
457   { "system_filter_user",       opt_uid,         &system_filter_uid },
458   { "tcp_nodelay",              opt_bool,        &tcp_nodelay },
459 #ifdef USE_TCP_WRAPPERS
460   { "tcp_wrappers_daemon_name", opt_stringptr,   &tcp_wrappers_daemon_name },
461 #endif
462   { "timeout_frozen_after",     opt_time,        &timeout_frozen_after },
463   { "timezone",                 opt_stringptr,   &timezone_string },
464   { "tls_advertise_hosts",      opt_stringptr,   &tls_advertise_hosts },
465 #ifdef SUPPORT_TLS
466   { "tls_certificate",          opt_stringptr,   &tls_certificate },
467   { "tls_crl",                  opt_stringptr,   &tls_crl },
468   { "tls_dh_max_bits",          opt_int,         &tls_dh_max_bits },
469   { "tls_dhparam",              opt_stringptr,   &tls_dhparam },
470   { "tls_eccurve",              opt_stringptr,   &tls_eccurve },
471 # ifndef DISABLE_OCSP
472   { "tls_ocsp_file",            opt_stringptr,   &tls_ocsp_file },
473 # endif
474   { "tls_on_connect_ports",     opt_stringptr,   &tls_in.on_connect_ports },
475   { "tls_privatekey",           opt_stringptr,   &tls_privatekey },
476   { "tls_remember_esmtp",       opt_bool,        &tls_remember_esmtp },
477   { "tls_require_ciphers",      opt_stringptr,   &tls_require_ciphers },
478   { "tls_try_verify_hosts",     opt_stringptr,   &tls_try_verify_hosts },
479   { "tls_verify_certificates",  opt_stringptr,   &tls_verify_certificates },
480   { "tls_verify_hosts",         opt_stringptr,   &tls_verify_hosts },
481 #endif
482   { "trusted_groups",           opt_gidlist,     &trusted_groups },
483   { "trusted_users",            opt_uidlist,     &trusted_users },
484   { "unknown_login",            opt_stringptr,   &unknown_login },
485   { "unknown_username",         opt_stringptr,   &unknown_username },
486   { "untrusted_set_sender",     opt_stringptr,   &untrusted_set_sender },
487   { "uucp_from_pattern",        opt_stringptr,   &uucp_from_pattern },
488   { "uucp_from_sender",         opt_stringptr,   &uucp_from_sender },
489   { "warn_message_file",        opt_stringptr,   &warn_message_file },
490   { "write_rejectlog",          opt_bool,        &write_rejectlog }
491 };
492
493 static int optionlist_config_size = nelem(optionlist_config);
494
495
496
497 /*************************************************
498 *         Find the name of an option             *
499 *************************************************/
500
501 /* This function is to aid debugging. Various functions take arguments that are
502 pointer variables in the options table or in option tables for various drivers.
503 For debugging output, it is useful to be able to find the name of the option
504 which is currently being processed. This function finds it, if it exists, by
505 searching the table(s).
506
507 Arguments:   a value that is presumed to be in the table above
508 Returns:     the option name, or an empty string
509 */
510
511 uschar *
512 readconf_find_option(void *p)
513 {
514 int i;
515 router_instance *r;
516 transport_instance *t;
517
518 for (i = 0; i < nelem(optionlist_config); i++)
519   if (p == optionlist_config[i].value) return US optionlist_config[i].name;
520
521 for (r = routers; r; r = r->next)
522   {
523   router_info *ri = r->info;
524   for (i = 0; i < *ri->options_count; i++)
525     {
526     if ((ri->options[i].type & opt_mask) != opt_stringptr) continue;
527     if (p == (char *)(r->options_block) + (long int)(ri->options[i].value))
528       return US ri->options[i].name;
529     }
530   }
531
532 for (t = transports; t; t = t->next)
533   {
534   transport_info *ti = t->info;
535   for (i = 0; i < *ti->options_count; i++)
536     {
537     optionlist * op = &ti->options[i];
538     if ((op->type & opt_mask) != opt_stringptr) continue;
539     if (p == (  op->type & opt_public
540              ? (char *)t
541              : (char *)t->options_block
542              )
543              + (long int)op->value)
544         return US op->name;
545     }
546   }
547
548 return US"";
549 }
550
551
552
553
554 /*************************************************
555 *       Deal with an assignment to a macro       *
556 *************************************************/
557
558 /* We have a new definition. The macro_item structure includes a final vector
559 called "name" which is one byte long. Thus, adding "namelen" gives us enough
560 room to store the "name" string.
561 If a builtin macro we place at head of list, else tail.  This lets us lazy-create
562 builtins. */
563
564 macro_item *
565 macro_create(const uschar * name, const uschar * val,
566   BOOL command_line, BOOL builtin)
567 {
568 unsigned namelen = Ustrlen(name);
569 macro_item * m = store_get(sizeof(macro_item) + namelen);
570
571 /* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val) */
572 if (!macros)
573   {
574   macros = m;
575   mlast = m;
576   m->next = NULL;
577   }
578 else if (builtin)
579   {
580   m->next = macros;
581   macros = m;
582   }
583 else
584   {
585   mlast->next = m;
586   mlast = m;
587   m->next = NULL;
588   }
589 m->command_line = command_line;
590 m->namelen = namelen;
591 m->replacement = string_copy(val);
592 Ustrcpy(m->name, name);
593 return m;
594 }
595
596
597 /* This function is called when a line that starts with an upper case letter is
598 encountered. The argument "line" should contain a complete logical line, and
599 start with the first letter of the macro name. The macro name and the
600 replacement text are extracted and stored. Redefinition of existing,
601 non-command line, macros is permitted using '==' instead of '='.
602
603 Arguments:
604   s            points to the start of the logical line
605
606 Returns:       nothing
607 */
608
609 static void
610 read_macro_assignment(uschar *s)
611 {
612 uschar name[64];
613 int namelen = 0;
614 BOOL redef = FALSE;
615 macro_item *m;
616
617 while (isalnum(*s) || *s == '_')
618   {
619   if (namelen >= sizeof(name) - 1)
620     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
621       "macro name too long (maximum is " SIZE_T_FMT " characters)", sizeof(name) - 1);
622   name[namelen++] = *s++;
623   }
624 name[namelen] = 0;
625
626 while (isspace(*s)) s++;
627 if (*s++ != '=')
628   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "malformed macro definition");
629
630 if (*s == '=')
631   {
632   redef = TRUE;
633   s++;
634   }
635 while (isspace(*s)) s++;
636
637 /* If an existing macro of the same name was defined on the command line, we
638 just skip this definition. It's an error to attempt to redefine a macro without
639 redef set to TRUE, or to redefine a macro when it hasn't been defined earlier.
640 It is also an error to define a macro whose name begins with the name of a
641 previously defined macro.  This is the requirement that make using a tree
642 for macros hard; we must check all macros for the substring.  Perhaps a
643 sorted list, and a bsearch, would work?
644 Note: it is documented that the other way round works. */
645
646 for (m = macros; m; m = m->next)
647   {
648   if (Ustrcmp(m->name, name) == 0)
649     {
650     if (!m->command_line && !redef)
651       log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "macro \"%s\" is already "
652        "defined (use \"==\" if you want to redefine it", name);
653     break;
654     }
655
656   if (m->namelen < namelen && Ustrstr(name, m->name) != NULL)
657     log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
658       "a macro because previously defined macro \"%s\" is a substring",
659       name, m->name);
660
661   /* We cannot have this test, because it is documented that a substring
662   macro is permitted (there is even an example).
663   *
664   * if (m->namelen > namelen && Ustrstr(m->name, name) != NULL)
665   *   log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
666   *     "a macro because it is a substring of previously defined macro \"%s\"",
667   *     name, m->name);
668   */
669   }
670
671 /* Check for an overriding command-line definition. */
672
673 if (m && m->command_line) return;
674
675 /* Redefinition must refer to an existing macro. */
676
677 if (redef)
678   if (m)
679     m->replacement = string_copy(s);
680   else
681     log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "can't redefine an undefined macro "
682       "\"%s\"", name);
683
684 /* We have a new definition. */
685 else
686   (void) macro_create(name, s, FALSE, FALSE);
687 }
688
689
690
691
692
693 /*************************************************/
694 /* Create compile-time feature macros */
695 static void
696 readconf_features(void)
697 {
698 /* Probably we could work out a static initialiser for wherever
699 macros are stored, but this will do for now. Some names are awkward
700 due to conflicts with other common macros. */
701
702 #ifdef SUPPORT_CRYPTEQ
703   macro_create(US"_HAVE_CRYPTEQ", US"y", FALSE, TRUE);
704 #endif
705 #if HAVE_ICONV
706   macro_create(US"_HAVE_ICONV", US"y", FALSE, TRUE);
707 #endif
708 #if HAVE_IPV6
709   macro_create(US"_HAVE_IPV6", US"y", FALSE, TRUE);
710 #endif
711 #ifdef HAVE_SETCLASSRESOURCES
712   macro_create(US"_HAVE_SETCLASSRESOURCES", US"y", FALSE, TRUE);
713 #endif
714 #ifdef SUPPORT_PAM
715   macro_create(US"_HAVE_PAM", US"y", FALSE, TRUE);
716 #endif
717 #ifdef EXIM_PERL
718   macro_create(US"_HAVE_PERL", US"y", FALSE, TRUE);
719 #endif
720 #ifdef EXPAND_DLFUNC
721   macro_create(US"_HAVE_DLFUNC", US"y", FALSE, TRUE);
722 #endif
723 #ifdef USE_TCP_WRAPPERS
724   macro_create(US"_HAVE_TCPWRAPPERS", US"y", FALSE, TRUE);
725 #endif
726 #ifdef SUPPORT_TLS
727   macro_create(US"_HAVE_TLS", US"y", FALSE, TRUE);
728 # ifdef USE_GNUTLS
729   macro_create(US"_HAVE_GNUTLS", US"y", FALSE, TRUE);
730 # else
731   macro_create(US"_HAVE_OPENSSL", US"y", FALSE, TRUE);
732 # endif
733 #endif
734 #ifdef SUPPORT_TRANSLATE_IP_ADDRESS
735   macro_create(US"_HAVE_TRANSLATE_IP_ADDRESS", US"y", FALSE, TRUE);
736 #endif
737 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
738   macro_create(US"_HAVE_MOVE_FROZEN_MESSAGES", US"y", FALSE, TRUE);
739 #endif
740 #ifdef WITH_CONTENT_SCAN
741   macro_create(US"_HAVE_CONTENT_SCANNING", US"y", FALSE, TRUE);
742 #endif
743 #ifndef DISABLE_DKIM
744   macro_create(US"_HAVE_DKIM", US"y", FALSE, TRUE);
745 #endif
746 #ifndef DISABLE_DNSSEC
747   macro_create(US"_HAVE_DNSSEC", US"y", FALSE, TRUE);
748 #endif
749 #ifndef DISABLE_EVENT
750   macro_create(US"_HAVE_EVENT", US"y", FALSE, TRUE);
751 #endif
752 #ifdef SUPPORT_I18N
753   macro_create(US"_HAVE_I18N", US"y", FALSE, TRUE);
754 #endif
755 #ifndef DISABLE_OCSP
756   macro_create(US"_HAVE_OCSP", US"y", FALSE, TRUE);
757 #endif
758 #ifndef DISABLE_PRDR
759   macro_create(US"_HAVE_PRDR", US"y", FALSE, TRUE);
760 #endif
761 #ifdef SUPPORT_PROXY
762   macro_create(US"_HAVE_PROXY", US"y", FALSE, TRUE);
763 #endif
764 #ifdef SUPPORT_SOCKS
765   macro_create(US"_HAVE_SOCKS", US"y", FALSE, TRUE);
766 #endif
767 #ifdef TCP_FASTOPEN
768   macro_create(US"_HAVE_TCP_FASTOPEN", US"y", FALSE, TRUE);
769 #endif
770 #ifdef EXPERIMENTAL_LMDB
771   macro_create(US"_HAVE_LMDB", US"y", FALSE, TRUE);
772 #endif
773 #ifdef EXPERIMENTAL_SPF
774   macro_create(US"_HAVE_SPF", US"y", FALSE, TRUE);
775 #endif
776 #ifdef EXPERIMENTAL_SRS
777   macro_create(US"_HAVE_SRS", US"y", FALSE, TRUE);
778 #endif
779 #ifdef EXPERIMENTAL_BRIGHTMAIL
780   macro_create(US"_HAVE_BRIGHTMAIL", US"y", FALSE, TRUE);
781 #endif
782 #ifdef EXPERIMENTAL_DANE
783   macro_create(US"_HAVE_DANE", US"y", FALSE, TRUE);
784 #endif
785 #ifdef EXPERIMENTAL_DCC
786   macro_create(US"_HAVE_DCC", US"y", FALSE, TRUE);
787 #endif
788 #ifdef EXPERIMENTAL_DMARC
789   macro_create(US"_HAVE_DMARC", US"y", FALSE, TRUE);
790 #endif
791 #ifdef EXPERIMENTAL_DSN_INFO
792   macro_create(US"_HAVE_DSN_INFO", US"y", FALSE, TRUE);
793 #endif
794
795 #ifdef LOOKUP_LSEARCH
796   macro_create(US"_HAVE_LOOKUP_LSEARCH", US"y", FALSE, TRUE);
797 #endif
798 #ifdef LOOKUP_CDB
799   macro_create(US"_HAVE_LOOKUP_CDB", US"y", FALSE, TRUE);
800 #endif
801 #ifdef LOOKUP_DBM
802   macro_create(US"_HAVE_LOOKUP_DBM", US"y", FALSE, TRUE);
803 #endif
804 #ifdef LOOKUP_DNSDB
805   macro_create(US"_HAVE_LOOKUP_DNSDB", US"y", FALSE, TRUE);
806 #endif
807 #ifdef LOOKUP_DSEARCH
808   macro_create(US"_HAVE_LOOKUP_DSEARCH", US"y", FALSE, TRUE);
809 #endif
810 #ifdef LOOKUP_IBASE
811   macro_create(US"_HAVE_LOOKUP_IBASE", US"y", FALSE, TRUE);
812 #endif
813 #ifdef LOOKUP_LDAP
814   macro_create(US"_HAVE_LOOKUP_LDAP", US"y", FALSE, TRUE);
815 #endif
816 #ifdef EXPERIMENTAL_LMDB
817   macro_create(US"_HAVE_LOOKUP_LMDB", US"y", FALSE, TRUE);
818 #endif
819 #ifdef LOOKUP_MYSQL
820   macro_create(US"_HAVE_LOOKUP_MYSQL", US"y", FALSE, TRUE);
821 #endif
822 #ifdef LOOKUP_NIS
823   macro_create(US"_HAVE_LOOKUP_NIS", US"y", FALSE, TRUE);
824 #endif
825 #ifdef LOOKUP_NISPLUS
826   macro_create(US"_HAVE_LOOKUP_NISPLUS", US"y", FALSE, TRUE);
827 #endif
828 #ifdef LOOKUP_ORACLE
829   macro_create(US"_HAVE_LOOKUP_ORACLE", US"y", FALSE, TRUE);
830 #endif
831 #ifdef LOOKUP_PASSWD
832   macro_create(US"_HAVE_LOOKUP_PASSWD", US"y", FALSE, TRUE);
833 #endif
834 #ifdef LOOKUP_PGSQL
835   macro_create(US"_HAVE_LOOKUP_PGSQL", US"y", FALSE, TRUE);
836 #endif
837 #ifdef LOOKUP_REDIS
838   macro_create(US"_HAVE_LOOKUP_REDIS", US"y", FALSE, TRUE);
839 #endif
840 #ifdef LOOKUP_SQLITE
841   macro_create(US"_HAVE_LOOKUP_SQLITE", US"y", FALSE, TRUE);
842 #endif
843 #ifdef LOOKUP_TESTDB
844   macro_create(US"_HAVE_LOOKUP_TESTDB", US"y", FALSE, TRUE);
845 #endif
846 #ifdef LOOKUP_WHOSON
847   macro_create(US"_HAVE_LOOKUP_WHOSON", US"y", FALSE, TRUE);
848 #endif
849
850 #ifdef TRANSPORT_APPENDFILE
851 # ifdef SUPPORT_MAILDIR
852   macro_create(US"_HAVE_TRANSPORT_APPEND_MAILDR", US"y", FALSE, TRUE);
853 # endif
854 # ifdef SUPPORT_MAILSTORE
855   macro_create(US"_HAVE_TRANSPORT_APPEND_MAILSTORE", US"y", FALSE, TRUE);
856 # endif
857 # ifdef SUPPORT_MBX
858   macro_create(US"_HAVE_TRANSPORT_APPEND_MBX", US"y", FALSE, TRUE);
859 # endif
860 #endif
861 }
862
863
864 void
865 readconf_options_from_list(optionlist * opts, unsigned nopt, const uschar * section, uschar * group)
866 {
867 int i;
868 const uschar * s;
869
870 /* The 'previously-defined-substring' rule for macros in config file
871 lines is done so for these builtin macros: we know that the table
872 we source from is in strict alpha order, hence the builtins portion
873 of the macros list is in reverse-alpha (we prepend them) - so longer
874 macros that have substrings are always discovered first during
875 expansion. */
876
877 for (i = 0; i < nopt; i++)  if (*(s = opts[i].name) && *s != '*')
878   if (group)
879     macro_create(string_sprintf("_OPT_%T_%T_%T", section, group, s), US"y", FALSE, TRUE);
880   else
881     macro_create(string_sprintf("_OPT_%T_%T", section, s), US"y", FALSE, TRUE);
882 }
883
884
885 static void
886 readconf_options(void)
887 {
888 readconf_options_from_list(optionlist_config, nelem(optionlist_config), US"MAIN", NULL);
889 readconf_options_routers();
890 readconf_options_transports();
891 readconf_options_auths();
892 }
893
894 static void
895 macros_create_builtin(void)
896 {
897 readconf_features();
898 readconf_options();
899 macros_builtin_created = TRUE;
900 }
901
902
903 /*************************************************
904 *            Read configuration line             *
905 *************************************************/
906
907 /* A logical line of text is read from the configuration file into the big
908 buffer, taking account of macros, .includes, and continuations. The size of
909 big_buffer is increased if necessary. The count of configuration lines is
910 maintained. Physical input lines starting with # (ignoring leading white space,
911 and after macro replacement) and empty logical lines are always ignored.
912 Leading and trailing spaces are removed.
913
914 If we hit a line of the form "begin xxxx", the xxxx is placed in the
915 next_section vector, and the function returns NULL, indicating the end of a
916 configuration section. On end-of-file, NULL is returned with next_section
917 empty.
918
919 Arguments:      none
920
921 Returns:        a pointer to the first non-blank in the line,
922                 or NULL if eof or end of section is reached
923 */
924
925 static uschar *
926 get_config_line(void)
927 {
928 int startoffset = 0;         /* To first non-blank char in logical line */
929 int len = 0;                 /* Of logical line so far */
930 int newlen;
931 uschar *s, *ss;
932 macro_item *m;
933 BOOL macro_found;
934
935 /* Loop for handling continuation lines, skipping comments, and dealing with
936 .include files. */
937
938 for (;;)
939   {
940   if (Ufgets(big_buffer+len, big_buffer_size-len, config_file) == NULL)
941     {
942     if (config_file_stack != NULL)    /* EOF inside .include */
943       {
944       (void)fclose(config_file);
945       config_file = config_file_stack->file;
946       config_filename = config_file_stack->filename;
947       config_lineno = config_file_stack->lineno;
948       config_file_stack = config_file_stack->next;
949       if (config_lines)
950         save_config_position(config_filename, config_lineno);
951       continue;
952       }
953
954     /* EOF at top level */
955
956     if (cstate_stack_ptr >= 0)
957       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
958         "Unexpected end of configuration file: .endif missing");
959
960     if (len != 0) break;        /* EOF after continuation */
961     next_section[0] = 0;        /* EOF at start of logical line */
962     return NULL;
963     }
964
965   config_lineno++;
966   newlen = len + Ustrlen(big_buffer + len);
967
968   if (config_lines && config_lineno == 1)
969     save_config_position(config_filename, config_lineno);
970
971   /* Handle pathologically long physical lines - yes, it did happen - by
972   extending big_buffer at this point. The code also copes with very long
973   logical lines. */
974
975   while (newlen == big_buffer_size - 1 && big_buffer[newlen - 1] != '\n')
976     {
977     uschar *newbuffer;
978     big_buffer_size += BIG_BUFFER_SIZE;
979     newbuffer = store_malloc(big_buffer_size);
980
981     /* This use of strcpy is OK because we know that the string in the old
982     buffer is shorter than the new buffer. */
983
984     Ustrcpy(newbuffer, big_buffer);
985     store_free(big_buffer);
986     big_buffer = newbuffer;
987     if (Ufgets(big_buffer+newlen, big_buffer_size-newlen, config_file) == NULL)
988       break;
989     newlen += Ustrlen(big_buffer + newlen);
990     }
991
992   /* Find the true start of the physical line - leading spaces are always
993   ignored. */
994
995   ss = big_buffer + len;
996   while (isspace(*ss)) ss++;
997
998   /* Process the physical line for macros. If this is the start of the logical
999   line, skip over initial text at the start of the line if it starts with an
1000   upper case character followed by a sequence of name characters and an equals
1001   sign, because that is the definition of a new macro, and we don't do
1002   replacement therein. */
1003
1004   s = ss;
1005   if (len == 0 && isupper(*s))
1006     {
1007     while (isalnum(*s) || *s == '_') s++;
1008     while (isspace(*s)) s++;
1009     if (*s != '=') s = ss;          /* Not a macro definition */
1010     }
1011
1012   /* If the builtin macros are not yet defined, and the line contains an
1013   underscrore followed by an one of the three possible chars used by
1014   builtins, create them. */
1015
1016   if (!macros_builtin_created)
1017     {
1018     const uschar * t, * p;
1019     uschar c;
1020     for (t = s; (p = CUstrchr(t, '_')); t = p+1)
1021       if (c = p[1], c == 'O' || c == 'D' || c == 'H')
1022         {
1023 /* fprintf(stderr, "%s: builtins create triggered by '%s'\n", __FUNCTION__, s); */
1024         macros_create_builtin();
1025         break;
1026         }
1027     }
1028
1029   /* For each defined macro, scan the line (from after XXX= if present),
1030   replacing all occurrences of the macro. */
1031
1032   macro_found = FALSE;
1033   for (m = macros; m; m = m->next)
1034     {
1035     uschar *p, *pp;
1036     uschar *t = s;
1037
1038     while ((p = Ustrstr(t, m->name)) != NULL)
1039       {
1040       int moveby;
1041       int replen = Ustrlen(m->replacement);
1042
1043 /* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, t) */
1044       /* Expand the buffer if necessary */
1045
1046       while (newlen - m->namelen + replen + 1 > big_buffer_size)
1047         {
1048         int newsize = big_buffer_size + BIG_BUFFER_SIZE;
1049         uschar *newbuffer = store_malloc(newsize);
1050         memcpy(newbuffer, big_buffer, newlen + 1);
1051         p = newbuffer  + (p - big_buffer);
1052         s = newbuffer  + (s - big_buffer);
1053         ss = newbuffer + (ss - big_buffer);
1054         t = newbuffer  + (t - big_buffer);
1055         big_buffer_size = newsize;
1056         store_free(big_buffer);
1057         big_buffer = newbuffer;
1058         }
1059
1060       /* Shuffle the remaining characters up or down in the buffer before
1061       copying in the replacement text. Don't rescan the replacement for this
1062       same macro. */
1063
1064       pp = p + m->namelen;
1065       if ((moveby = replen - m->namelen) != 0)
1066         {
1067         memmove(p + replen, pp, (big_buffer + newlen) - pp + 1);
1068         newlen += moveby;
1069         }
1070       Ustrncpy(p, m->replacement, replen);
1071       t = p + replen;
1072       macro_found = TRUE;
1073       }
1074     }
1075
1076   /* An empty macro replacement at the start of a line could mean that ss no
1077   longer points to the first non-blank character. */
1078
1079   while (isspace(*ss)) ss++;
1080
1081   /* Check for comment lines - these are physical lines. */
1082
1083   if (*ss == '#') continue;
1084
1085   /* Handle conditionals, which are also applied to physical lines. Conditions
1086   are of the form ".ifdef ANYTEXT" and are treated as true if any macro
1087   expansion occured on the rest of the line. A preliminary test for the leading
1088   '.' saves effort on most lines. */
1089
1090   if (*ss == '.')
1091     {
1092     int i;
1093
1094     /* Search the list of conditional directives */
1095
1096     for (i = 0; i < cond_list_size; i++)
1097       {
1098       int n;
1099       cond_item *c = cond_list+i;
1100       if (Ustrncmp(ss+1, c->name, c->namelen) != 0) continue;
1101
1102       /* The following character must be white space or end of string */
1103
1104       n = ss[1 + c->namelen];
1105       if (n != ' ' && n != 't' && n != '\n' && n != 0) break;
1106
1107       /* .ifdef and .ifndef push the current state onto the stack, then set
1108       a new one from the table. Stack overflow is an error */
1109
1110       if (c->pushpop > 0)
1111         {
1112         if (cstate_stack_ptr >= CSTATE_STACK_SIZE - 1)
1113           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1114             ".%s nested too deeply", c->name);
1115         cstate_stack[++cstate_stack_ptr] = cstate;
1116         cstate = next_cstate[cstate][macro_found? c->action1 : c->action2];
1117         }
1118
1119       /* For any of the others, stack underflow is an error. The next state
1120       comes either from the stack (.endif) or from the table. */
1121
1122       else
1123         {
1124         if (cstate_stack_ptr < 0)
1125           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1126             ".%s without matching .ifdef", c->name);
1127         cstate = (c->pushpop < 0)? cstate_stack[cstate_stack_ptr--] :
1128           next_cstate[cstate][macro_found? c->action1 : c->action2];
1129         }
1130
1131       /* Having dealt with a directive, break the loop */
1132
1133       break;
1134       }
1135
1136     /* If we have handled a conditional directive, continue with the next
1137     physical line. Otherwise, fall through. */
1138
1139     if (i < cond_list_size) continue;
1140     }
1141
1142   /* If the conditional state is not 0 (actively using these lines), ignore
1143   this input line. */
1144
1145   if (cstate != 0) continue;  /* Conditional skip */
1146
1147   /* Handle .include lines - these are also physical lines. */
1148
1149   if (Ustrncmp(ss, ".include", 8) == 0 &&
1150        (isspace(ss[8]) ||
1151          (Ustrncmp(ss+8, "_if_exists", 10) == 0 && isspace(ss[18]))))
1152     {
1153     uschar *t;
1154     int include_if_exists = isspace(ss[8])? 0 : 10;
1155     config_file_item *save;
1156     struct stat statbuf;
1157
1158     ss += 9 + include_if_exists;
1159     while (isspace(*ss)) ss++;
1160     t = ss + Ustrlen(ss);
1161     while (t > ss && isspace(t[-1])) t--;
1162     if (*ss == '\"' && t[-1] == '\"')
1163       {
1164       ss++;
1165       t--;
1166       }
1167     *t = 0;
1168
1169     if (*ss != '/')
1170       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, ".include specifies a non-"
1171         "absolute path \"%s\"", ss);
1172
1173     if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
1174
1175     if (config_lines)
1176       save_config_position(config_filename, config_lineno);
1177     save = store_get(sizeof(config_file_item));
1178     save->next = config_file_stack;
1179     config_file_stack = save;
1180     save->file = config_file;
1181     save->filename = config_filename;
1182     save->lineno = config_lineno;
1183
1184     if (!(config_file = Ufopen(ss, "rb")))
1185       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to open included "
1186         "configuration file %s", ss);
1187
1188     config_filename = string_copy(ss);
1189     config_lineno = 0;
1190     continue;
1191     }
1192
1193   /* If this is the start of the logical line, remember where the non-blank
1194   data starts. Otherwise shuffle down continuation lines to remove leading
1195   white space. */
1196
1197   if (len == 0)
1198     startoffset = ss - big_buffer;
1199   else
1200     {
1201     s = big_buffer + len;
1202     if (ss > s)
1203       {
1204       memmove(s, ss, (newlen - len) -  (ss - s) + 1);
1205       newlen -= ss - s;
1206       }
1207     }
1208
1209   /* Accept the new addition to the line. Remove trailing white space. */
1210
1211   len = newlen;
1212   while (len > 0 && isspace(big_buffer[len-1])) len--;
1213   big_buffer[len] = 0;
1214
1215   /* We are done if the line does not end in backslash and contains some data.
1216   Empty logical lines are ignored. For continuations, remove the backslash and
1217   go round the loop to read the continuation line. */
1218
1219   if (len > 0)
1220     {
1221     if (big_buffer[len-1] != '\\') break;   /* End of logical line */
1222     big_buffer[--len] = 0;                  /* Remove backslash */
1223     }
1224   }     /* Loop for reading multiple physical lines */
1225
1226 /* We now have a logical line. Test for the end of a configuration section (or,
1227 more accurately, for the start of the next section). Place the name of the next
1228 section in next_section, and return NULL. If the name given is longer than
1229 next_section, truncate it. It will be unrecognized later, because all the known
1230 section names do fit. Leave space for pluralizing. */
1231
1232 s = big_buffer + startoffset;            /* First non-space character */
1233
1234 if (config_lines)
1235   save_config_line(s);
1236
1237 if (strncmpic(s, US"begin ", 6) == 0)
1238   {
1239   s += 6;
1240   while (isspace(*s)) s++;
1241   if (big_buffer + len - s > sizeof(next_section) - 2)
1242     s[sizeof(next_section) - 2] = 0;
1243   Ustrcpy(next_section, s);
1244   return NULL;
1245   }
1246
1247 /* Return the first non-blank character. */
1248
1249 return s;
1250 }
1251
1252
1253
1254 /*************************************************
1255 *             Read a name                        *
1256 *************************************************/
1257
1258 /* The yield is the pointer to the next uschar. Names longer than the
1259 output space are silently truncated. This function is also used from acl.c when
1260 parsing ACLs.
1261
1262 Arguments:
1263   name      where to put the name
1264   len       length of name
1265   s         input pointer
1266
1267 Returns:    new input pointer
1268 */
1269
1270 uschar *
1271 readconf_readname(uschar *name, int len, uschar *s)
1272 {
1273 int p = 0;
1274 while (isspace(*s)) s++;
1275 if (isalpha(*s))
1276   {
1277   while (isalnum(*s) || *s == '_')
1278     {
1279     if (p < len-1) name[p++] = *s;
1280     s++;
1281     }
1282   }
1283 name[p] = 0;
1284 while (isspace(*s)) s++;
1285 return s;
1286 }
1287
1288
1289
1290
1291 /*************************************************
1292 *          Read a time value                     *
1293 *************************************************/
1294
1295 /* This function is also called from outside, to read argument
1296 time values. The format of a time value is:
1297
1298   [<n>w][<n>d][<n>h][<n>m][<n>s]
1299
1300 as long as at least one is present. If a format error is encountered,
1301 return a negative value. The value must be terminated by the given
1302 terminator.
1303
1304 Arguments:
1305   s             input pointer
1306   terminator    required terminating character
1307   return_msec   if TRUE, allow fractional seconds and return milliseconds
1308
1309 Returns:        the time value, or -1 on syntax error
1310                 value is seconds if return_msec is FALSE
1311                 value is milliseconds if return_msec is TRUE
1312 */
1313
1314 int
1315 readconf_readtime(const uschar *s, int terminator, BOOL return_msec)
1316 {
1317 int yield = 0;
1318 for (;;)
1319   {
1320   int value, count;
1321   double fraction;
1322
1323   if (!isdigit(*s)) return -1;
1324   (void)sscanf(CCS s, "%d%n", &value, &count);
1325   s += count;
1326
1327   switch (*s)
1328     {
1329     case 'w': value *= 7;
1330     case 'd': value *= 24;
1331     case 'h': value *= 60;
1332     case 'm': value *= 60;
1333     case 's': s++;
1334     break;
1335
1336     case '.':
1337     if (!return_msec) return -1;
1338     (void)sscanf(CCS s, "%lf%n", &fraction, &count);
1339     s += count;
1340     if (*s++ != 's') return -1;
1341     yield += (int)(fraction * 1000.0);
1342     break;
1343
1344     default: return -1;
1345     }
1346
1347   if (return_msec) value *= 1000;
1348   yield += value;
1349   if (*s == terminator) return yield;
1350   }
1351 /* Control never reaches here. */
1352 }
1353
1354
1355
1356 /*************************************************
1357 *          Read a fixed point value              *
1358 *************************************************/
1359
1360 /* The value is returned *1000
1361
1362 Arguments:
1363   s           input pointer
1364   terminator  required terminator
1365
1366 Returns:      the value, or -1 on error
1367 */
1368
1369 static int
1370 readconf_readfixed(const uschar *s, int terminator)
1371 {
1372 int yield = 0;
1373 int value, count;
1374 if (!isdigit(*s)) return -1;
1375 (void)sscanf(CS  s, "%d%n", &value, &count);
1376 s += count;
1377 yield = value * 1000;
1378 if (*s == '.')
1379   {
1380   int m = 100;
1381   while (isdigit((*(++s))))
1382     {
1383     yield += (*s - '0') * m;
1384     m /= 10;
1385     }
1386   }
1387
1388 return (*s == terminator)? yield : (-1);
1389 }
1390
1391
1392
1393 /*************************************************
1394 *            Find option in list                 *
1395 *************************************************/
1396
1397 /* The lists are always in order, so binary chop can be used.
1398
1399 Arguments:
1400   name      the option name to search for
1401   ol        the first entry in the option list
1402   last      one more than the offset of the last entry in the option list
1403
1404 Returns:    pointer to an option entry, or NULL if not found
1405 */
1406
1407 static optionlist *
1408 find_option(uschar *name, optionlist *ol, int last)
1409 {
1410 int first = 0;
1411 while (last > first)
1412   {
1413   int middle = (first + last)/2;
1414   int c = Ustrcmp(name, ol[middle].name);
1415
1416   if (c == 0) return ol + middle;
1417   else if (c > 0) first = middle + 1;
1418   else last = middle;
1419   }
1420 return NULL;
1421 }
1422
1423
1424
1425 /*************************************************
1426 *      Find a set flag in option list            *
1427 *************************************************/
1428
1429 /* Because some versions of Unix make no restrictions on the values of uids and
1430 gids (even negative ones), we cannot represent "unset" by a special value.
1431 There is therefore a separate boolean variable for each one indicating whether
1432 a value is set or not. This function returns a pointer to the boolean, given
1433 the original option name. It is a major disaster if the flag cannot be found.
1434
1435 Arguments:
1436   name          the name of the uid or gid option
1437   oltop         points to the start of the relevant option list
1438   last          one more than the offset of the last item in the option list
1439   data_block    NULL when reading main options => data values in the option
1440                   list are absolute addresses; otherwise they are byte offsets
1441                   in data_block (used for driver options)
1442
1443 Returns:        a pointer to the boolean flag.
1444 */
1445
1446 static BOOL *
1447 get_set_flag(uschar *name, optionlist *oltop, int last, void *data_block)
1448 {
1449 optionlist *ol;
1450 uschar name2[64];
1451 sprintf(CS name2, "*set_%.50s", name);
1452 ol = find_option(name2, oltop, last);
1453 if (ol == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1454   "Exim internal error: missing set flag for %s", name);
1455 return (data_block == NULL)? (BOOL *)(ol->value) :
1456   (BOOL *)((uschar *)data_block + (long int)(ol->value));
1457 }
1458
1459
1460
1461
1462 /*************************************************
1463 *    Output extra characters message and die     *
1464 *************************************************/
1465
1466 /* Called when an option line has junk on the end. Sometimes this is because
1467 the sysadmin thinks comments are permitted.
1468
1469 Arguments:
1470   s          points to the extra characters
1471   t1..t3     strings to insert in the log message
1472
1473 Returns:     doesn't return; dies
1474 */
1475
1476 static void
1477 extra_chars_error(const uschar *s, const uschar *t1, const uschar *t2, const uschar *t3)
1478 {
1479 uschar *comment = US"";
1480 if (*s == '#') comment = US" (# is comment only at line start)";
1481 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1482   "extra characters follow %s%s%s%s", t1, t2, t3, comment);
1483 }
1484
1485
1486
1487 /*************************************************
1488 *              Read rewrite information          *
1489 *************************************************/
1490
1491 /* Each line of rewrite information contains:
1492
1493 .  A complete address in the form user@domain, possibly with
1494    leading * for each part; or alternatively, a regex.
1495
1496 .  A replacement string (which will be expanded).
1497
1498 .  An optional sequence of one-letter flags, indicating which
1499    headers etc. to apply this rule to.
1500
1501 All this is decoded and placed into a control block. The OR of the flags is
1502 maintained in a common word.
1503
1504 Arguments:
1505   p           points to the string that makes up the rule
1506   existflags  points to the overall flag word
1507   isglobal    TRUE if reading global rewrite rules
1508
1509 Returns:      the control block for the parsed rule.
1510 */
1511
1512 static rewrite_rule *
1513 readconf_one_rewrite(const uschar *p, int *existflags, BOOL isglobal)
1514 {
1515 rewrite_rule *next = store_get(sizeof(rewrite_rule));
1516
1517 next->next = NULL;
1518 next->key = string_dequote(&p);
1519
1520 while (isspace(*p)) p++;
1521 if (*p == 0)
1522   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1523     "missing rewrite replacement string");
1524
1525 next->flags = 0;
1526 next->replacement = string_dequote(&p);
1527
1528 while (*p != 0) switch (*p++)
1529   {
1530   case ' ': case '\t': break;
1531
1532   case 'q': next->flags |= rewrite_quit; break;
1533   case 'w': next->flags |= rewrite_whole; break;
1534
1535   case 'h': next->flags |= rewrite_all_headers; break;
1536   case 's': next->flags |= rewrite_sender; break;
1537   case 'f': next->flags |= rewrite_from; break;
1538   case 't': next->flags |= rewrite_to;   break;
1539   case 'c': next->flags |= rewrite_cc;   break;
1540   case 'b': next->flags |= rewrite_bcc;  break;
1541   case 'r': next->flags |= rewrite_replyto; break;
1542
1543   case 'E': next->flags |= rewrite_all_envelope; break;
1544   case 'F': next->flags |= rewrite_envfrom; break;
1545   case 'T': next->flags |= rewrite_envto; break;
1546
1547   case 'Q': next->flags |= rewrite_qualify; break;
1548   case 'R': next->flags |= rewrite_repeat; break;
1549
1550   case 'S':
1551   next->flags |= rewrite_smtp;
1552   if (next->key[0] != '^' && Ustrncmp(next->key, "\\N^", 3) != 0)
1553     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1554       "rewrite rule has the S flag but is not a regular expression");
1555   break;
1556
1557   default:
1558   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1559     "unknown rewrite flag character '%c' "
1560     "(could be missing quotes round replacement item)", p[-1]);
1561   break;
1562   }
1563
1564 /* If no action flags are set, set all the "normal" rewrites. */
1565
1566 if ((next->flags & (rewrite_all | rewrite_smtp)) == 0)
1567   next->flags |= isglobal? rewrite_all : rewrite_all_headers;
1568
1569 /* Remember which exist, for optimization, and return the rule */
1570
1571 *existflags |= next->flags;
1572 return next;
1573 }
1574
1575
1576
1577
1578 /*************************************************
1579 *          Read global rewrite information       *
1580 *************************************************/
1581
1582 /* Each line is a single rewrite rule; it is parsed into a control block
1583 by readconf_one_rewrite(), and its flags are ORed into the global flag
1584 word rewrite_existflags. */
1585
1586 void
1587 readconf_rewrites(void)
1588 {
1589 rewrite_rule **chain = &global_rewrite_rules;
1590 uschar *p;
1591
1592 while ((p = get_config_line()) != NULL)
1593   {
1594   rewrite_rule *next = readconf_one_rewrite(p, &rewrite_existflags, TRUE);
1595   *chain = next;
1596   chain = &(next->next);
1597   }
1598 }
1599
1600
1601
1602 /*************************************************
1603 *               Read a string                    *
1604 *************************************************/
1605
1606 /* Strings are read into the normal store pool. As long we aren't too
1607 near the end of the current block, the string will just use what is necessary
1608 on the top of the stacking pool, because string_cat() uses the extension
1609 mechanism.
1610
1611 Argument:
1612   s         the rest of the input line
1613   name      the option name (for errors)
1614
1615 Returns:    pointer to the string
1616 */
1617
1618 static uschar *
1619 read_string(const uschar *s, const uschar *name)
1620 {
1621 uschar *yield;
1622 const uschar *ss;
1623
1624 if (*s != '\"') return string_copy(s);
1625
1626 ss = s;
1627 yield = string_dequote(&s);
1628
1629 if (s == ss+1 || s[-1] != '\"')
1630   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1631     "missing quote at end of string value for %s", name);
1632
1633 if (*s != 0) extra_chars_error(s, US"string value for ", name, US"");
1634
1635 return yield;
1636 }
1637
1638
1639 /*************************************************
1640 *            Custom-handler options              *
1641 *************************************************/
1642 static void
1643 fn_smtp_receive_timeout(const uschar * name, const uschar * str)
1644 {
1645 if (*str == '$')
1646   smtp_receive_timeout_s = string_copy(str);
1647 else
1648   {
1649   /* "smtp_receive_timeout",     opt_time,        &smtp_receive_timeout */
1650   smtp_receive_timeout = readconf_readtime(str, 0, FALSE);
1651   if (smtp_receive_timeout < 0)
1652     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
1653       name);
1654   }
1655 }
1656
1657 /*************************************************
1658 *            Handle option line                  *
1659 *************************************************/
1660
1661 /* This function is called from several places to process a line containing the
1662 setting of an option. The first argument is the line to be decoded; it has been
1663 checked not to be empty and not to start with '#'. Trailing newlines and white
1664 space have been removed. The second argument is a pointer to the list of
1665 variable names that are to be recognized, together with their types and
1666 locations, and the third argument gives the number of entries in the list.
1667
1668 The fourth argument is a pointer to a data block. If it is NULL, then the data
1669 values in the options list are absolute addresses. Otherwise, they are byte
1670 offsets in the data block.
1671
1672 String option data may continue onto several lines; this function reads further
1673 data from config_file if necessary.
1674
1675 The yield of this function is normally zero. If a string continues onto
1676 multiple lines, then the data value is permitted to be followed by a comma
1677 or a semicolon (for use in drivers) and the yield is that character.
1678
1679 Arguments:
1680   buffer        contains the configuration line to be handled
1681   oltop         points to the start of the relevant option list
1682   last          one more than the offset of the last item in the option list
1683   data_block    NULL when reading main options => data values in the option
1684                   list are absolute addresses; otherwise they are byte offsets
1685                   in data_block when they have opt_public set; otherwise
1686                   they are byte offsets in data_block->options_block.
1687   unknown_txt   format string to use in panic message for unknown option;
1688                   must contain %s for option name
1689                 if given as NULL, don't panic on unknown option
1690
1691 Returns:        TRUE if an option was read successfully,
1692                 FALSE false for an unknown option if unknown_txt == NULL,
1693                   otherwise panic and die on an unknown option
1694 */
1695
1696 static BOOL
1697 readconf_handle_option(uschar *buffer, optionlist *oltop, int last,
1698   void *data_block, uschar *unknown_txt)
1699 {
1700 int ptr = 0;
1701 int offset = 0;
1702 int n, count, type, value;
1703 int issecure = 0;
1704 uid_t uid;
1705 gid_t gid;
1706 BOOL boolvalue = TRUE;
1707 BOOL freesptr = TRUE;
1708 optionlist *ol, *ol2;
1709 struct passwd *pw;
1710 void *reset_point;
1711 int intbase = 0;
1712 uschar *inttype = US"";
1713 uschar *sptr;
1714 uschar *s = buffer;
1715 uschar **str_target;
1716 uschar name[64];
1717 uschar name2[64];
1718
1719 /* There may be leading spaces; thereafter, we expect an option name starting
1720 with a letter. */
1721
1722 while (isspace(*s)) s++;
1723 if (!isalpha(*s))
1724   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option setting expected: %s", s);
1725
1726 /* Read the name of the option, and skip any subsequent white space. If
1727 it turns out that what we read was "hide", set the flag indicating that
1728 this is a secure option, and loop to read the next word. */
1729
1730 for (n = 0; n < 2; n++)
1731   {
1732   while (isalnum(*s) || *s == '_')
1733     {
1734     if (ptr < sizeof(name)-1) name[ptr++] = *s;
1735     s++;
1736     }
1737   name[ptr] = 0;
1738   while (isspace(*s)) s++;
1739   if (Ustrcmp(name, "hide") != 0) break;
1740   issecure = opt_secure;
1741   ptr = 0;
1742   }
1743
1744 /* Deal with "no_" or "not_" here for booleans */
1745
1746 if (Ustrncmp(name, "no_", 3) == 0)
1747   {
1748   boolvalue = FALSE;
1749   offset = 3;
1750   }
1751
1752 if (Ustrncmp(name, "not_", 4) == 0)
1753   {
1754   boolvalue = FALSE;
1755   offset = 4;
1756   }
1757
1758 /* Search the list for the given name. A non-existent name, or an option that
1759 is set twice, is a disaster. */
1760
1761 if (!(ol = find_option(name + offset, oltop, last)))
1762   {
1763   if (unknown_txt == NULL) return FALSE;
1764   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, CS unknown_txt, name);
1765   }
1766
1767 if ((ol->type & opt_set)  && !(ol->type & (opt_rep_con | opt_rep_str)))
1768   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1769     "\"%s\" option set for the second time", name);
1770
1771 ol->type |= opt_set | issecure;
1772 type = ol->type & opt_mask;
1773
1774 /* Types with data values must be followed by '='; the "no[t]_" prefix
1775 applies only to boolean values. */
1776
1777 if (type < opt_bool || type > opt_bool_last)
1778   {
1779   if (offset != 0)
1780     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1781       "negation prefix applied to a non-boolean option");
1782   if (*s == 0)
1783     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1784       "unexpected end of line (data missing) after %s", name);
1785   if (*s != '=')
1786     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing \"=\" after %s", name);
1787   }
1788
1789 /* If a boolean wasn't preceded by "no[t]_" it can be followed by = and
1790 true/false/yes/no, or, in the case of opt_expand_bool, a general string that
1791 ultimately expands to one of those values. */
1792
1793 else if (*s != 0 && (offset != 0 || *s != '='))
1794   extra_chars_error(s, US"boolean option ", name, US"");
1795
1796 /* Skip white space after = */
1797
1798 if (*s == '=') while (isspace((*(++s))));
1799
1800 /* If there is a data block and the opt_public flag is not set, change
1801 the data block pointer to the private options block. */
1802
1803 if (data_block != NULL && (ol->type & opt_public) == 0)
1804   data_block = (void *)(((driver_instance *)data_block)->options_block);
1805
1806 /* Now get the data according to the type. */
1807
1808 switch (type)
1809   {
1810   /* If a string value is not enclosed in quotes, it consists of
1811   the rest of the current line, verbatim. Otherwise, string escapes
1812   are processed.
1813
1814   A transport is specified as a string, which is then looked up in the
1815   list of transports. A search type is specified as one of a number of
1816   known strings.
1817
1818   A set or rewrite rules for a driver is specified as a string, which is
1819   then parsed into a suitable chain of control blocks.
1820
1821   Uids and gids are specified as strings which are then looked up in the
1822   passwd file. Lists of uids and gids are similarly specified as colon-
1823   separated strings. */
1824
1825   case opt_stringptr:
1826   case opt_uid:
1827   case opt_gid:
1828   case opt_expand_uid:
1829   case opt_expand_gid:
1830   case opt_uidlist:
1831   case opt_gidlist:
1832   case opt_rewrite:
1833
1834   reset_point = sptr = read_string(s, name);
1835
1836   /* Having read a string, we now have several different ways of using it,
1837   depending on the data type, so do another switch. If keeping the actual
1838   string is not required (because it is interpreted), freesptr is set TRUE,
1839   and at the end we reset the pool. */
1840
1841   switch (type)
1842     {
1843     /* If this was a string, set the variable to point to the new string,
1844     and set the flag so its store isn't reclaimed. If it was a list of rewrite
1845     rules, we still keep the string (for printing), and parse the rules into a
1846     control block and flags word. */
1847
1848     case opt_stringptr:
1849     str_target = data_block ? USS (US data_block + (long int)(ol->value))
1850                             : USS (ol->value);
1851     if (ol->type & opt_rep_con)
1852       {
1853       uschar * saved_condition;
1854       /* We already have a condition, we're conducting a crude hack to let
1855       multiple condition rules be chained together, despite storing them in
1856       text form. */
1857       *str_target = string_copy_malloc( (saved_condition = *str_target)
1858         ? string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
1859             saved_condition, sptr)
1860         : sptr);
1861       /* TODO(pdp): there is a memory leak here and just below
1862       when we set 3 or more conditions; I still don't
1863       understand the store mechanism enough to know
1864       what's the safe way to free content from an earlier store.
1865       AFAICT, stores stack, so freeing an early stored item also stores
1866       all data alloc'd after it.  If we knew conditions were adjacent,
1867       we could survive that, but we don't.  So I *think* we need to take
1868       another bit from opt_type to indicate "malloced"; this seems like
1869       quite a hack, especially for this one case.  It also means that
1870       we can't ever reclaim the store from the *first* condition.
1871
1872       Because we only do this once, near process start-up, I'm prepared to
1873       let this slide for the time being, even though it rankles.  */
1874       }
1875     else if (ol->type & opt_rep_str)
1876       {
1877       uschar sep_o = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
1878       int    sep_i = -(int)sep_o;
1879       const uschar * list = sptr;
1880       uschar * s;
1881       uschar * list_o = *str_target;
1882
1883       while ((s = string_nextinlist(&list, &sep_i, NULL, 0)))
1884         list_o = string_append_listele(list_o, sep_o, s);
1885       if (list_o)
1886         *str_target = string_copy_malloc(list_o);
1887       }
1888     else
1889       {
1890       *str_target = sptr;
1891       freesptr = FALSE;
1892       }
1893     break;
1894
1895     case opt_rewrite:
1896     if (data_block)
1897       *USS (US data_block + (long int)(ol->value)) = sptr;
1898     else
1899       *USS (ol->value) = sptr;
1900     freesptr = FALSE;
1901     if (type == opt_rewrite)
1902       {
1903       int sep = 0;
1904       int *flagptr;
1905       uschar *p = sptr;
1906       rewrite_rule **chain;
1907       optionlist *ol3;
1908
1909       sprintf(CS name2, "*%.50s_rules", name);
1910       ol2 = find_option(name2, oltop, last);
1911       sprintf(CS name2, "*%.50s_flags", name);
1912       ol3 = find_option(name2, oltop, last);
1913
1914       if (ol2 == NULL || ol3 == NULL)
1915         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1916           "rewrite rules not available for driver");
1917
1918       if (data_block == NULL)
1919         {
1920         chain = (rewrite_rule **)(ol2->value);
1921         flagptr = (int *)(ol3->value);
1922         }
1923       else
1924         {
1925         chain = (rewrite_rule **)((uschar *)data_block + (long int)(ol2->value));
1926         flagptr = (int *)((uschar *)data_block + (long int)(ol3->value));
1927         }
1928
1929       while ((p = string_nextinlist(CUSS &sptr, &sep, big_buffer, BIG_BUFFER_SIZE)))
1930         {
1931         rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
1932         *chain = next;
1933         chain = &(next->next);
1934         }
1935
1936       if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0)
1937         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a "
1938           "non-header rewrite - not allowed at transport time -");
1939       }
1940     break;
1941
1942     /* If it was an expanded uid, see if there is any expansion to be
1943     done by checking for the presence of a $ character. If there is, save it
1944     in the corresponding *expand_user option field. Otherwise, fall through
1945     to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds
1946     of data. */
1947
1948     case opt_expand_uid:
1949     sprintf(CS name2, "*expand_%.50s", name);
1950     ol2 = find_option(name2, oltop, last);
1951     if (ol2 != NULL)
1952       {
1953       uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1954
1955       if (data_block == NULL)
1956         *((uschar **)(ol2->value)) = ss;
1957       else
1958         *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
1959
1960       if (ss != NULL)
1961         {
1962         *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1963         freesptr = FALSE;
1964         break;
1965         }
1966       }
1967
1968     /* Look up a fixed uid, and also make use of the corresponding gid
1969     if a passwd entry is returned and the gid has not been set. */
1970
1971     case opt_uid:
1972     if (!route_finduser(sptr, &pw, &uid))
1973       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr);
1974     if (data_block == NULL)
1975       *((uid_t *)(ol->value)) = uid;
1976     else
1977       *((uid_t *)((uschar *)data_block + (long int)(ol->value))) = uid;
1978
1979     /* Set the flag indicating a fixed value is set */
1980
1981     *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1982
1983     /* Handle matching gid if we have a passwd entry: done by finding the
1984     same name with terminating "user" changed to "group"; if not found,
1985     ignore. Also ignore if the value is already set. */
1986
1987     if (pw == NULL) break;
1988     Ustrcpy(name+Ustrlen(name)-4, "group");
1989     ol2 = find_option(name, oltop, last);
1990     if (ol2 != NULL && ((ol2->type & opt_mask) == opt_gid ||
1991         (ol2->type & opt_mask) == opt_expand_gid))
1992       {
1993       BOOL *set_flag = get_set_flag(name, oltop, last, data_block);
1994       if (! *set_flag)
1995         {
1996         if (data_block == NULL)
1997           *((gid_t *)(ol2->value)) = pw->pw_gid;
1998         else
1999           *((gid_t *)((uschar *)data_block + (long int)(ol2->value))) = pw->pw_gid;
2000         *set_flag = TRUE;
2001         }
2002       }
2003     break;
2004
2005     /* If it was an expanded gid, see if there is any expansion to be
2006     done by checking for the presence of a $ character. If there is, save it
2007     in the corresponding *expand_user option field. Otherwise, fall through
2008     to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds
2009     of data. */
2010
2011     case opt_expand_gid:
2012     sprintf(CS name2, "*expand_%.50s", name);
2013     ol2 = find_option(name2, oltop, last);
2014     if (ol2 != NULL)
2015       {
2016       uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
2017
2018       if (data_block == NULL)
2019         *((uschar **)(ol2->value)) = ss;
2020       else
2021         *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
2022
2023       if (ss != NULL)
2024         {
2025         *(get_set_flag(name, oltop, last, data_block)) = FALSE;
2026         freesptr = FALSE;
2027         break;
2028         }
2029       }
2030
2031     /* Handle freestanding gid */
2032
2033     case opt_gid:
2034     if (!route_findgroup(sptr, &gid))
2035       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr);
2036     if (data_block == NULL)
2037       *((gid_t *)(ol->value)) = gid;
2038     else
2039       *((gid_t *)((uschar *)data_block + (long int)(ol->value))) = gid;
2040     *(get_set_flag(name, oltop, last, data_block)) = TRUE;
2041     break;
2042
2043     /* If it was a uid list, look up each individual entry, and build
2044     a vector of uids, with a count in the first element. Put the vector
2045     in malloc store so we can free the string. (We are reading into
2046     permanent store already.) */
2047
2048     case opt_uidlist:
2049       {
2050       int count = 1;
2051       uid_t *list;
2052       int ptr = 0;
2053       const uschar *p;
2054       const uschar *op = expand_string (sptr);
2055
2056       if (op == NULL)
2057         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
2058           name, expand_string_message);
2059
2060       p = op;
2061       if (*p != 0) count++;
2062       while (*p != 0) if (*p++ == ':' && *p != 0) count++;
2063       list = store_malloc(count*sizeof(uid_t));
2064       list[ptr++] = (uid_t)(count - 1);
2065
2066       if (data_block == NULL)
2067         *((uid_t **)(ol->value)) = list;
2068       else
2069         *((uid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
2070
2071       p = op;
2072       while (count-- > 1)
2073         {
2074         int sep = 0;
2075         (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
2076         if (!route_finduser(big_buffer, NULL, &uid))
2077           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found",
2078             big_buffer);
2079         list[ptr++] = uid;
2080         }
2081       }
2082     break;
2083
2084     /* If it was a gid list, look up each individual entry, and build
2085     a vector of gids, with a count in the first element. Put the vector
2086     in malloc store so we can free the string. (We are reading into permanent
2087     store already.) */
2088
2089     case opt_gidlist:
2090       {
2091       int count = 1;
2092       gid_t *list;
2093       int ptr = 0;
2094       const uschar *p;
2095       const uschar *op = expand_string (sptr);
2096
2097       if (op == NULL)
2098         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
2099           name, expand_string_message);
2100
2101       p = op;
2102       if (*p != 0) count++;
2103       while (*p != 0) if (*p++ == ':' && *p != 0) count++;
2104       list = store_malloc(count*sizeof(gid_t));
2105       list[ptr++] = (gid_t)(count - 1);
2106
2107       if (data_block == NULL)
2108         *((gid_t **)(ol->value)) = list;
2109       else
2110         *((gid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
2111
2112       p = op;
2113       while (count-- > 1)
2114         {
2115         int sep = 0;
2116         (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
2117         if (!route_findgroup(big_buffer, &gid))
2118           log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found",
2119             big_buffer);
2120         list[ptr++] = gid;
2121         }
2122       }
2123     break;
2124     }
2125
2126   /* Release store if the value of the string doesn't need to be kept. */
2127
2128   if (freesptr) store_reset(reset_point);
2129   break;
2130
2131   /* Expanded boolean: if no characters follow, or if there are no dollar
2132   characters, this is a fixed-valued boolean, and we fall through. Otherwise,
2133   save the string for later expansion in the alternate place. */
2134
2135   case opt_expand_bool:
2136   if (*s != 0 && Ustrchr(s, '$') != 0)
2137     {
2138     sprintf(CS name2, "*expand_%.50s", name);
2139     ol2 = find_option(name2, oltop, last);
2140     if (ol2 != NULL)
2141       {
2142       reset_point = sptr = read_string(s, name);
2143       if (data_block == NULL)
2144         *((uschar **)(ol2->value)) = sptr;
2145       else
2146         *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = sptr;
2147       freesptr = FALSE;
2148       break;
2149       }
2150     }
2151   /* Fall through */
2152
2153   /* Boolean: if no characters follow, the value is boolvalue. Otherwise
2154   look for yes/not/true/false. Some booleans are stored in a single bit in
2155   a single int. There's a special fudge for verify settings; without a suffix
2156   they set both xx_sender and xx_recipient. The table points to the sender
2157   value; search subsequently for the recipient. There's another special case:
2158   opt_bool_set also notes when a boolean has been set. */
2159
2160   case opt_bool:
2161   case opt_bit:
2162   case opt_bool_verify:
2163   case opt_bool_set:
2164   if (*s != 0)
2165     {
2166     s = readconf_readname(name2, 64, s);
2167     if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0)
2168       boolvalue = TRUE;
2169     else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0)
2170       boolvalue = FALSE;
2171     else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2172       "\"%s\" is not a valid value for the \"%s\" option", name2, name);
2173     if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2),
2174       US"for boolean option ", name);
2175     }
2176
2177   /* Handle single-bit type. */
2178
2179   if (type == opt_bit)
2180     {
2181     int bit = 1 << ((ol->type >> 16) & 31);
2182     int *ptr = (data_block == NULL)?
2183       (int *)(ol->value) :
2184       (int *)((uschar *)data_block + (long int)ol->value);
2185     if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
2186     break;
2187     }
2188
2189   /* Handle full BOOL types */
2190
2191   if (data_block == NULL)
2192     *((BOOL *)(ol->value)) = boolvalue;
2193   else
2194     *((BOOL *)((uschar *)data_block + (long int)(ol->value))) = boolvalue;
2195
2196   /* Verify fudge */
2197
2198   if (type == opt_bool_verify)
2199     {
2200     sprintf(CS name2, "%.50s_recipient", name + offset);
2201     ol2 = find_option(name2, oltop, last);
2202     if (ol2 != NULL)
2203       {
2204       if (data_block == NULL)
2205         *((BOOL *)(ol2->value)) = boolvalue;
2206       else
2207         *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = boolvalue;
2208       }
2209     }
2210
2211   /* Note that opt_bool_set type is set, if there is somewhere to do so */
2212
2213   else if (type == opt_bool_set)
2214     {
2215     sprintf(CS name2, "*set_%.50s", name + offset);
2216     ol2 = find_option(name2, oltop, last);
2217     if (ol2 != NULL)
2218       {
2219       if (data_block == NULL)
2220         *((BOOL *)(ol2->value)) = TRUE;
2221       else
2222         *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = TRUE;
2223       }
2224     }
2225   break;
2226
2227   /* Octal integer */
2228
2229   case opt_octint:
2230   intbase = 8;
2231   inttype = US"octal ";
2232
2233   /*  Integer: a simple(ish) case; allow octal and hex formats, and
2234   suffixes K, M and G. The different types affect output, not input. */
2235
2236   case opt_mkint:
2237   case opt_int:
2238     {
2239     uschar *endptr;
2240     long int lvalue;
2241
2242     errno = 0;
2243     lvalue = strtol(CS s, CSS &endptr, intbase);
2244
2245     if (endptr == s)
2246       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2247         inttype, name);
2248
2249     if (errno != ERANGE)
2250       if (tolower(*endptr) == 'k')
2251         {
2252         if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
2253           else lvalue *= 1024;
2254         endptr++;
2255         }
2256       else if (tolower(*endptr) == 'm')
2257         {
2258         if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
2259           errno = ERANGE;
2260         else lvalue *= 1024*1024;
2261         endptr++;
2262         }
2263       else if (tolower(*endptr) == 'g')
2264         {
2265         if (lvalue > INT_MAX/(1024*1024*1024) || lvalue < INT_MIN/(1024*1024*1024))
2266           errno = ERANGE;
2267         else lvalue *= 1024*1024*1024;
2268         endptr++;
2269         }
2270
2271     if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN)
2272       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2273         "absolute value of integer \"%s\" is too large (overflow)", s);
2274
2275     while (isspace(*endptr)) endptr++;
2276     if (*endptr != 0)
2277       extra_chars_error(endptr, inttype, US"integer value for ", name);
2278
2279     value = (int)lvalue;
2280     }
2281
2282   if (data_block == NULL)
2283     *((int *)(ol->value)) = value;
2284   else
2285     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2286   break;
2287
2288   /*  Integer held in K: again, allow octal and hex formats, and suffixes K, M
2289   and G. */
2290   /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */
2291
2292   case opt_Kint:
2293     {
2294     uschar *endptr;
2295     errno = 0;
2296     value = strtol(CS s, CSS &endptr, intbase);
2297
2298     if (endptr == s)
2299       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
2300         inttype, name);
2301
2302     if (errno != ERANGE)
2303       if (tolower(*endptr) == 'g')
2304         {
2305         if (value > INT_MAX/(1024*1024) || value < INT_MIN/(1024*1024))
2306           errno = ERANGE;
2307         else
2308           value *= 1024*1024;
2309         endptr++;
2310         }
2311       else if (tolower(*endptr) == 'm')
2312         {
2313         if (value > INT_MAX/1024 || value < INT_MIN/1024)
2314           errno = ERANGE;
2315         else
2316           value *= 1024;
2317         endptr++;
2318         }
2319       else if (tolower(*endptr) == 'k')
2320         endptr++;
2321       else
2322         value = (value + 512)/1024;
2323
2324     if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2325       "absolute value of integer \"%s\" is too large (overflow)", s);
2326
2327     while (isspace(*endptr)) endptr++;
2328     if (*endptr != 0)
2329       extra_chars_error(endptr, inttype, US"integer value for ", name);
2330     }
2331
2332   if (data_block == NULL)
2333     *((int *)(ol->value)) = value;
2334   else
2335     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2336   break;
2337
2338   /*  Fixed-point number: held to 3 decimal places. */
2339
2340   case opt_fixed:
2341   if (sscanf(CS s, "%d%n", &value, &count) != 1)
2342     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2343       "fixed-point number expected for %s", name);
2344
2345   if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2346     "integer \"%s\" is too large (overflow)", s);
2347
2348   value *= 1000;
2349
2350   if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2351     "integer \"%s\" is too large (overflow)", s);
2352
2353   /* We get a coverity error here for using count, as it derived
2354   from the tainted buffer pointed to by s, as parsed by sscanf().
2355   By the definition of sscanf we must be aceessing between start
2356   and end of s (assuming it is nul-terminated...) so ignore the error.  */
2357   /* coverity[tainted_data] */
2358   if (s[count] == '.')
2359     {
2360     int d = 100;
2361     while (isdigit(s[++count]))
2362       {
2363       value += (s[count] - '0') * d;
2364       d /= 10;
2365       }
2366     }
2367
2368   while (isspace(s[count])) count++;
2369
2370   if (s[count] != 0)
2371     extra_chars_error(s+count, US"fixed-point value for ", name, US"");
2372
2373   if (data_block == NULL)
2374     *((int *)(ol->value)) = value;
2375   else
2376     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2377   break;
2378
2379   /* There's a special routine to read time values. */
2380
2381   case opt_time:
2382   value = readconf_readtime(s, 0, FALSE);
2383   if (value < 0)
2384     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2385       name);
2386   if (data_block == NULL)
2387     *((int *)(ol->value)) = value;
2388   else
2389     *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2390   break;
2391
2392   /* A time list is a list of colon-separated times, with the first
2393   element holding the size of the list and the second the number of
2394   entries used. */
2395
2396   case opt_timelist:
2397     {
2398     int count = 0;
2399     int *list = (data_block == NULL)?
2400       (int *)(ol->value) :
2401       (int *)((uschar *)data_block + (long int)(ol->value));
2402
2403     if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
2404       {
2405       int terminator = 0;
2406       uschar *snext = Ustrchr(s, ':');
2407       if (snext != NULL)
2408         {
2409         uschar *ss = snext;
2410         while (ss > s && isspace(ss[-1])) ss--;
2411         terminator = *ss;
2412         }
2413       value = readconf_readtime(s, terminator, FALSE);
2414       if (value < 0)
2415         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2416           name);
2417       if (count > 1 && value <= list[count])
2418         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2419           "time value out of order for %s", name);
2420       list[count+1] = value;
2421       if (snext == NULL) break;
2422       s = snext + 1;
2423       while (isspace(*s)) s++;
2424       }
2425
2426     if (count > list[0] - 2)
2427       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many time values for %s",
2428         name);
2429     if (count > 0 && list[2] == 0) count = 0;
2430     list[1] = count;
2431     break;
2432     }
2433
2434   case opt_func:
2435     {
2436     void (*fn)() = ol->value;
2437     fn(name, s);
2438     break;
2439     }
2440   }
2441
2442 return TRUE;
2443 }
2444
2445
2446
2447 /*************************************************
2448 *               Print a time value               *
2449 *************************************************/
2450
2451 /*
2452 Argument:  a time value in seconds
2453 Returns:   pointer to a fixed buffer containing the time as a string,
2454            in readconf_readtime() format
2455 */
2456
2457 uschar *
2458 readconf_printtime(int t)
2459 {
2460 int s, m, h, d, w;
2461 uschar *p = time_buffer;
2462
2463 if (t < 0)
2464   {
2465   *p++ = '-';
2466   t = -t;
2467   }
2468
2469 s = t % 60;
2470 t /= 60;
2471 m = t % 60;
2472 t /= 60;
2473 h = t % 24;
2474 t /= 24;
2475 d = t % 7;
2476 w = t/7;
2477
2478 if (w > 0) { sprintf(CS p, "%dw", w); while (*p) p++; }
2479 if (d > 0) { sprintf(CS p, "%dd", d); while (*p) p++; }
2480 if (h > 0) { sprintf(CS p, "%dh", h); while (*p) p++; }
2481 if (m > 0) { sprintf(CS p, "%dm", m); while (*p) p++; }
2482 if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
2483
2484 return time_buffer;
2485 }
2486
2487
2488
2489 /*************************************************
2490 *      Print an individual option value          *
2491 *************************************************/
2492
2493 /* This is used by the -bP option, so prints to the standard output.
2494 The entire options list is passed in as an argument, because some options come
2495 in pairs - typically uid/gid settings, which can either be explicit numerical
2496 values, or strings to be expanded later. If the numerical value is unset,
2497 search for "*expand_<name>" to see if there is a string equivalent.
2498
2499 Arguments:
2500   ol             option entry, or NULL for an unknown option
2501   name           option name
2502   options_block  NULL for main configuration options; otherwise points to
2503                    a driver block; if the option doesn't have opt_public
2504                    set, then options_block->options_block is where the item
2505                    resides.
2506   oltop          points to the option list in which ol exists
2507   last           one more than the offset of the last entry in optop
2508   no_labels      do not show "foo = " at the start.
2509
2510 Returns:         nothing
2511 */
2512
2513 static void
2514 print_ol(optionlist *ol, uschar *name, void *options_block,
2515   optionlist *oltop, int last, BOOL no_labels)
2516 {
2517 struct passwd *pw;
2518 struct group *gr;
2519 optionlist *ol2;
2520 void *value;
2521 uid_t *uidlist;
2522 gid_t *gidlist;
2523 uschar *s;
2524 uschar name2[64];
2525
2526 if (ol == NULL)
2527   {
2528   printf("%s is not a known option\n", name);
2529   return;
2530   }
2531
2532 /* Non-admin callers cannot see options that have been flagged secure by the
2533 "hide" prefix. */
2534
2535 if (!admin_user && (ol->type & opt_secure) != 0)
2536   {
2537   if (no_labels)
2538     printf("%s\n", hidden);
2539   else
2540     printf("%s = %s\n", name, hidden);
2541   return;
2542   }
2543
2544 /* Else show the value of the option */
2545
2546 value = ol->value;
2547 if (options_block != NULL)
2548   {
2549   if ((ol->type & opt_public) == 0)
2550     options_block = (void *)(((driver_instance *)options_block)->options_block);
2551   value = (void *)((uschar *)options_block + (long int)value);
2552   }
2553
2554 switch(ol->type & opt_mask)
2555   {
2556   case opt_stringptr:
2557   case opt_rewrite:        /* Show the text value */
2558   s = *((uschar **)value);
2559   if (!no_labels) printf("%s = ", name);
2560   printf("%s\n", (s == NULL)? US"" : string_printing2(s, FALSE));
2561   break;
2562
2563   case opt_int:
2564   if (!no_labels) printf("%s = ", name);
2565   printf("%d\n", *((int *)value));
2566   break;
2567
2568   case opt_mkint:
2569     {
2570     int x = *((int *)value);
2571     if (x != 0 && (x & 1023) == 0)
2572       {
2573       int c = 'K';
2574       x >>= 10;
2575       if ((x & 1023) == 0)
2576         {
2577         c = 'M';
2578         x >>= 10;
2579         }
2580       if (!no_labels) printf("%s = ", name);
2581       printf("%d%c\n", x, c);
2582       }
2583     else
2584       {
2585       if (!no_labels) printf("%s = ", name);
2586       printf("%d\n", x);
2587       }
2588     }
2589   break;
2590
2591   case opt_Kint:
2592     {
2593     int x = *((int *)value);
2594     if (!no_labels) printf("%s = ", name);
2595     if (x == 0) printf("0\n");
2596       else if ((x & 1023) == 0) printf("%dM\n", x >> 10);
2597         else printf("%dK\n", x);
2598     }
2599   break;
2600
2601   case opt_octint:
2602   if (!no_labels) printf("%s = ", name);
2603   printf("%#o\n", *((int *)value));
2604   break;
2605
2606   /* Can be negative only when "unset", in which case integer */
2607
2608   case opt_fixed:
2609     {
2610     int x = *((int *)value);
2611     int f = x % 1000;
2612     int d = 100;
2613     if (x < 0) printf("%s =\n", name); else
2614       {
2615       if (!no_labels) printf("%s = ", name);
2616       printf("%d.", x/1000);
2617       do
2618         {
2619         printf("%d", f/d);
2620         f %= d;
2621         d /= 10;
2622         }
2623       while (f != 0);
2624       printf("\n");
2625       }
2626     }
2627   break;
2628
2629   /* If the numerical value is unset, try for the string value */
2630
2631   case opt_expand_uid:
2632   if (! *get_set_flag(name, oltop, last, options_block))
2633     {
2634     sprintf(CS name2, "*expand_%.50s", name);
2635     ol2 = find_option(name2, oltop, last);
2636     if (ol2 != NULL)
2637       {
2638       void *value2 = ol2->value;
2639       if (options_block != NULL)
2640         value2 = (void *)((uschar *)options_block + (long int)value2);
2641       s = *((uschar **)value2);
2642       if (!no_labels) printf("%s = ", name);
2643       printf("%s\n", (s == NULL)? US"" : string_printing(s));
2644       break;
2645       }
2646     }
2647
2648   /* Else fall through */
2649
2650   case opt_uid:
2651   if (!no_labels) printf("%s = ", name);
2652   if (! *get_set_flag(name, oltop, last, options_block))
2653     printf("\n");
2654   else
2655     {
2656     pw = getpwuid(*((uid_t *)value));
2657     if (pw == NULL)
2658       printf("%ld\n", (long int)(*((uid_t *)value)));
2659     else printf("%s\n", pw->pw_name);
2660     }
2661   break;
2662
2663   /* If the numerical value is unset, try for the string value */
2664
2665   case opt_expand_gid:
2666   if (! *get_set_flag(name, oltop, last, options_block))
2667     {
2668     sprintf(CS name2, "*expand_%.50s", name);
2669     ol2 = find_option(name2, oltop, last);
2670     if (ol2 != NULL && (ol2->type & opt_mask) == opt_stringptr)
2671       {
2672       void *value2 = ol2->value;
2673       if (options_block != NULL)
2674         value2 = (void *)((uschar *)options_block + (long int)value2);
2675       s = *((uschar **)value2);
2676       if (!no_labels) printf("%s = ", name);
2677       printf("%s\n", (s == NULL)? US"" : string_printing(s));
2678       break;
2679       }
2680     }
2681
2682   /* Else fall through */
2683
2684   case opt_gid:
2685   if (!no_labels) printf("%s = ", name);
2686   if (! *get_set_flag(name, oltop, last, options_block))
2687     printf("\n");
2688   else
2689     {
2690     gr = getgrgid(*((int *)value));
2691     if (gr == NULL)
2692        printf("%ld\n", (long int)(*((int *)value)));
2693     else printf("%s\n", gr->gr_name);
2694     }
2695   break;
2696
2697   case opt_uidlist:
2698   uidlist = *((uid_t **)value);
2699   if (!no_labels) printf("%s =", name);
2700   if (uidlist != NULL)
2701     {
2702     int i;
2703     uschar sep = ' ';
2704     if (no_labels) sep = '\0';
2705     for (i = 1; i <= (int)(uidlist[0]); i++)
2706       {
2707       uschar *name = NULL;
2708       pw = getpwuid(uidlist[i]);
2709       if (pw != NULL) name = US pw->pw_name;
2710       if (sep != '\0') printf("%c", sep);
2711       if (name != NULL) printf("%s", name);
2712         else printf("%ld", (long int)(uidlist[i]));
2713       sep = ':';
2714       }
2715     }
2716   printf("\n");
2717   break;
2718
2719   case opt_gidlist:
2720   gidlist = *((gid_t **)value);
2721   if (!no_labels) printf("%s =", name);
2722   if (gidlist != NULL)
2723     {
2724     int i;
2725     uschar sep = ' ';
2726     if (no_labels) sep = '\0';
2727     for (i = 1; i <= (int)(gidlist[0]); i++)
2728       {
2729       uschar *name = NULL;
2730       gr = getgrgid(gidlist[i]);
2731       if (gr != NULL) name = US gr->gr_name;
2732       if (sep != '\0') printf("%c", sep);
2733       if (name != NULL) printf("%s", name);
2734         else printf("%ld", (long int)(gidlist[i]));
2735       sep = ':';
2736       }
2737     }
2738   printf("\n");
2739   break;
2740
2741   case opt_time:
2742   if (!no_labels) printf("%s = ", name);
2743   printf("%s\n", readconf_printtime(*((int *)value)));
2744   break;
2745
2746   case opt_timelist:
2747     {
2748     int i;
2749     int *list = (int *)value;
2750     if (!no_labels) printf("%s = ", name);
2751     for (i = 0; i < list[1]; i++)
2752       printf("%s%s", (i == 0)? "" : ":", readconf_printtime(list[i+2]));
2753     printf("\n");
2754     }
2755   break;
2756
2757   case opt_bit:
2758   printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))?
2759     "" : "no_", name);
2760   break;
2761
2762   case opt_expand_bool:
2763   sprintf(CS name2, "*expand_%.50s", name);
2764   ol2 = find_option(name2, oltop, last);
2765   if (ol2 != NULL && ol2->value != NULL)
2766     {
2767     void *value2 = ol2->value;
2768     if (options_block != NULL)
2769       value2 = (void *)((uschar *)options_block + (long int)value2);
2770     s = *((uschar **)value2);
2771     if (s != NULL)
2772       {
2773       if (!no_labels) printf("%s = ", name);
2774       printf("%s\n", string_printing(s));
2775       break;
2776       }
2777     /* s == NULL => string not set; fall through */
2778     }
2779
2780   /* Fall through */
2781
2782   case opt_bool:
2783   case opt_bool_verify:
2784   case opt_bool_set:
2785   printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name);
2786   break;
2787   }
2788 }
2789
2790
2791
2792 /*************************************************
2793 *        Print value from main configuration     *
2794 *************************************************/
2795
2796 /* This function, called as a result of encountering the -bP option,
2797 causes the value of any main configuration variable to be output if the
2798 second argument is NULL. There are some special values:
2799
2800   all                print all main configuration options
2801   config_file        print the name of the configuration file
2802                      (configure_file will still work, for backward
2803                      compatibility)
2804   routers            print the routers' configurations
2805   transports         print the transports' configuration
2806   authenticators     print the authenticators' configuration
2807   macros             print the macros' configuration
2808   router_list        print a list of router names
2809   transport_list     print a list of transport names
2810   authenticator_list print a list of authentication mechanism names
2811   macro_list         print a list of macro names
2812   +name              print a named list item
2813   local_scan         print the local_scan options
2814   config             print the configuration as it is parsed
2815   environment        print the used execution environment
2816
2817 If the second argument is not NULL, it must be one of "router", "transport",
2818 "authenticator" or "macro" in which case the first argument identifies the
2819 driver whose options are to be printed.
2820
2821 Arguments:
2822   name        option name if type == NULL; else driver name
2823   type        NULL or driver type name, as described above
2824   no_labels   avoid the "foo = " at the start of an item
2825
2826 Returns:      nothing
2827 */
2828
2829 void
2830 readconf_print(uschar *name, uschar *type, BOOL no_labels)
2831 {
2832 BOOL names_only = FALSE;
2833 optionlist *ol;
2834 optionlist *ol2 = NULL;
2835 driver_instance *d = NULL;
2836 macro_item *m;
2837 int size = 0;
2838
2839 if (type == NULL)
2840   {
2841   if (*name == '+')
2842     {
2843     int i;
2844     tree_node *t;
2845     BOOL found = FALSE;
2846     static uschar *types[] = { US"address", US"domain", US"host",
2847       US"localpart" };
2848     static tree_node **anchors[] = { &addresslist_anchor, &domainlist_anchor,
2849       &hostlist_anchor, &localpartlist_anchor };
2850
2851     for (i = 0; i < 4; i++)
2852       {
2853       t = tree_search(*(anchors[i]), name+1);
2854       if (t != NULL)
2855         {
2856         found = TRUE;
2857         if (no_labels)
2858           printf("%s\n", ((namedlist_block *)(t->data.ptr))->string);
2859         else
2860           printf("%slist %s = %s\n", types[i], name+1,
2861             ((namedlist_block *)(t->data.ptr))->string);
2862         }
2863       }
2864
2865     if (!found)
2866       printf("no address, domain, host, or local part list called \"%s\" "
2867         "exists\n", name+1);
2868
2869     return;
2870     }
2871
2872   if (  Ustrcmp(name, "configure_file") == 0
2873      || Ustrcmp(name, "config_file") == 0)
2874     {
2875     printf("%s\n", CS config_main_filename);
2876     return;
2877     }
2878
2879   if (Ustrcmp(name, "all") == 0)
2880     {
2881     for (ol = optionlist_config;
2882          ol < optionlist_config + nelem(optionlist_config); ol++)
2883       {
2884       if ((ol->type & opt_hidden) == 0)
2885         print_ol(ol, US ol->name, NULL,
2886             optionlist_config, nelem(optionlist_config),
2887             no_labels);
2888       }
2889     return;
2890     }
2891
2892   if (Ustrcmp(name, "local_scan") == 0)
2893     {
2894     #ifndef LOCAL_SCAN_HAS_OPTIONS
2895     printf("local_scan() options are not supported\n");
2896     #else
2897     for (ol = local_scan_options;
2898          ol < local_scan_options + local_scan_options_count; ol++)
2899       {
2900       print_ol(ol, US ol->name, NULL, local_scan_options,
2901         local_scan_options_count, no_labels);
2902       }
2903     #endif
2904     return;
2905     }
2906
2907   if (Ustrcmp(name, "config") == 0)
2908     {
2909     print_config(admin_user, no_labels);
2910     return;
2911     }
2912
2913   if (Ustrcmp(name, "routers") == 0)
2914     {
2915     type = US"router";
2916     name = NULL;
2917     }
2918   else if (Ustrcmp(name, "transports") == 0)
2919     {
2920     type = US"transport";
2921     name = NULL;
2922     }
2923
2924   else if (Ustrcmp(name, "authenticators") == 0)
2925     {
2926     type = US"authenticator";
2927     name = NULL;
2928     }
2929
2930   else if (Ustrcmp(name, "macros") == 0)
2931     {
2932     type = US"macro";
2933     name = NULL;
2934     }
2935
2936   else if (Ustrcmp(name, "router_list") == 0)
2937     {
2938     type = US"router";
2939     name = NULL;
2940     names_only = TRUE;
2941     }
2942
2943   else if (Ustrcmp(name, "transport_list") == 0)
2944     {
2945     type = US"transport";
2946     name = NULL;
2947     names_only = TRUE;
2948     }
2949
2950   else if (Ustrcmp(name, "authenticator_list") == 0)
2951     {
2952     type = US"authenticator";
2953     name = NULL;
2954     names_only = TRUE;
2955     }
2956
2957   else if (Ustrcmp(name, "macro_list") == 0)
2958     {
2959     type = US"macro";
2960     name = NULL;
2961     names_only = TRUE;
2962     }
2963
2964   else if (Ustrcmp(name, "environment") == 0)
2965     {
2966     if (environ)
2967       {
2968       uschar ** p;
2969       for (p = USS environ; *p; p++) ;
2970       qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer);
2971
2972       for (p = USS environ; *p; p++)
2973         {
2974         uschar * q;
2975         if (no_labels && (q = Ustrchr(*p, '='))) *q  = '\0';
2976         puts(CS *p);
2977         }
2978       }
2979     return;
2980     }
2981
2982   else
2983     {
2984     print_ol(find_option(name, optionlist_config, nelem(optionlist_config)),
2985       name, NULL, optionlist_config, nelem(optionlist_config), no_labels);
2986     return;
2987     }
2988   }
2989
2990 /* Handle the options for a router or transport. Skip options that are flagged
2991 as hidden. Some of these are options with names starting with '*', used for
2992 internal alternative representations of other options (which the printing
2993 function will sort out). Others are synonyms kept for backward compatibility.
2994 */
2995
2996 if (Ustrcmp(type, "router") == 0)
2997   {
2998   d = (driver_instance *)routers;
2999   ol2 = optionlist_routers;
3000   size = optionlist_routers_size;
3001   }
3002 else if (Ustrcmp(type, "transport") == 0)
3003   {
3004   d = (driver_instance *)transports;
3005   ol2 = optionlist_transports;
3006   size = optionlist_transports_size;
3007   }
3008 else if (Ustrcmp(type, "authenticator") == 0)
3009   {
3010   d = (driver_instance *)auths;
3011   ol2 = optionlist_auths;
3012   size = optionlist_auths_size;
3013   }
3014
3015 else if (Ustrcmp(type, "macro") == 0)
3016   {
3017   /* People store passwords in macros and they were previously not available
3018   for printing.  So we have an admin_users restriction. */
3019   if (!admin_user)
3020     {
3021     fprintf(stderr, "exim: permission denied\n");
3022     exit(EXIT_FAILURE);
3023     }
3024   if (!macros_builtin_created) macros_create_builtin();
3025   for (m = macros; m; m = m->next)
3026     if (!name || Ustrcmp(name, m->name) == 0)
3027       {
3028       if (names_only)
3029         printf("%s\n", CS m->name);
3030       else
3031         printf("%s=%s\n", CS m->name, CS m->replacement);
3032       if (name)
3033         return;
3034       }
3035   if (name)
3036     printf("%s %s not found\n", type, name);
3037   return;
3038   }
3039
3040 if (names_only)
3041   {
3042   for (; d != NULL; d = d->next) printf("%s\n", CS d->name);
3043   return;
3044   }
3045
3046 /* Either search for a given driver, or print all of them */
3047
3048 for (; d != NULL; d = d->next)
3049   {
3050   if (name == NULL)
3051     printf("\n%s %s:\n", d->name, type);
3052   else if (Ustrcmp(d->name, name) != 0) continue;
3053
3054   for (ol = ol2; ol < ol2 + size; ol++)
3055     {
3056     if ((ol->type & opt_hidden) == 0)
3057       print_ol(ol, US ol->name, d, ol2, size, no_labels);
3058     }
3059
3060   for (ol = d->info->options;
3061        ol < d->info->options + *(d->info->options_count); ol++)
3062     {
3063     if ((ol->type & opt_hidden) == 0)
3064       print_ol(ol, US ol->name, d, d->info->options, *(d->info->options_count), no_labels);
3065     }
3066   if (name != NULL) return;
3067   }
3068 if (name != NULL) printf("%s %s not found\n", type, name);
3069 }
3070
3071
3072
3073 /*************************************************
3074 *          Read a named list item                *
3075 *************************************************/
3076
3077 /* This function reads a name and a list (i.e. string). The name is used to
3078 save the list in a tree, sorted by its name. Each entry also has a number,
3079 which can be used for caching tests, but if the string contains any expansion
3080 items other than $key, the number is set negative to inhibit caching. This
3081 mechanism is used for domain, host, and address lists that are referenced by
3082 the "+name" syntax.
3083
3084 Arguments:
3085   anchorp     points to the tree anchor
3086   numberp     points to the current number for this tree
3087   max         the maximum number permitted
3088   s           the text of the option line, starting immediately after the name
3089                 of the list type
3090   tname       the name of the list type, for messages
3091
3092 Returns:      nothing
3093 */
3094
3095 static void
3096 read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s,
3097   uschar *tname)
3098 {
3099 BOOL forcecache = FALSE;
3100 uschar *ss;
3101 tree_node *t;
3102 namedlist_block *nb = store_get(sizeof(namedlist_block));
3103
3104 if (Ustrncmp(s, "_cache", 6) == 0)
3105   {
3106   forcecache = TRUE;
3107   s += 6;
3108   }
3109
3110 if (!isspace(*s))
3111   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unrecognized configuration line");
3112
3113 if (*numberp >= max)
3114  log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many named %ss (max is %d)\n",
3115    tname, max);
3116
3117 while (isspace(*s)) s++;
3118 ss = s;
3119 while (isalnum(*s) || *s == '_') s++;
3120 t = store_get(sizeof(tree_node) + s-ss);
3121 Ustrncpy(t->name, ss, s-ss);
3122 t->name[s-ss] = 0;
3123 while (isspace(*s)) s++;
3124
3125 if (!tree_insertnode(anchorp, t))
3126   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3127     "duplicate name \"%s\" for a named %s", t->name, tname);
3128
3129 t->data.ptr = nb;
3130 nb->number = *numberp;
3131 *numberp += 1;
3132
3133 if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3134   "missing '=' after \"%s\"", t->name);
3135 while (isspace(*s)) s++;
3136 nb->string = read_string(s, t->name);
3137 nb->cache_data = NULL;
3138
3139 /* Check the string for any expansions; if any are found, mark this list
3140 uncacheable unless the user has explicited forced caching. */
3141
3142 if (!forcecache && Ustrchr(nb->string, '$') != NULL) nb->number = -1;
3143 }
3144
3145
3146
3147
3148 /*************************************************
3149 *        Unpick data for a rate limit            *
3150 *************************************************/
3151
3152 /* This function is called to unpick smtp_ratelimit_{mail,rcpt} into four
3153 separate values.
3154
3155 Arguments:
3156   s            string, in the form t,b,f,l
3157                where t is the threshold (integer)
3158                b is the initial delay (time)
3159                f is the multiplicative factor (fixed point)
3160                k is the maximum time (time)
3161   threshold    where to store threshold
3162   base         where to store base in milliseconds
3163   factor       where to store factor in milliseconds
3164   limit        where to store limit
3165
3166 Returns:       nothing (panics on error)
3167 */
3168
3169 static void
3170 unpick_ratelimit(uschar *s, int *threshold, int *base, double *factor,
3171   int *limit)
3172 {
3173 uschar bstring[16], lstring[16];
3174
3175 if (sscanf(CS s, "%d, %15[0123456789smhdw.], %lf, %15s", threshold, bstring,
3176     factor, lstring) == 4)
3177   {
3178   *base = readconf_readtime(bstring, 0, TRUE);
3179   *limit = readconf_readtime(lstring, 0, TRUE);
3180   if (*base >= 0 && *limit >= 0) return;
3181   }
3182 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malformed ratelimit data: %s", s);
3183 }
3184
3185
3186
3187
3188 /*************************************************
3189 *       Drop privs for checking TLS config      *
3190 *************************************************/
3191
3192 /* We want to validate TLS options during readconf, but do not want to be
3193 root when we call into the TLS library, in case of library linkage errors
3194 which cause segfaults; before this check, those were always done as the Exim
3195 runtime user and it makes sense to continue with that.
3196
3197 Assumes:  tls_require_ciphers has been set, if it will be
3198           exim_user has been set, if it will be
3199           exim_group has been set, if it will be
3200
3201 Returns:  bool for "okay"; false will cause caller to immediately exit.
3202 */
3203
3204 #ifdef SUPPORT_TLS
3205 static BOOL
3206 tls_dropprivs_validate_require_cipher(BOOL nowarn)
3207 {
3208 const uschar *errmsg;
3209 pid_t pid;
3210 int rc, status;
3211 void (*oldsignal)(int);
3212
3213 /* If TLS will never be used, no point checking ciphers */
3214
3215 if (  !tls_advertise_hosts
3216    || !*tls_advertise_hosts
3217    || Ustrcmp(tls_advertise_hosts, ":") == 0
3218    )
3219   return TRUE;
3220 else if (!nowarn && !tls_certificate)
3221   log_write(0, LOG_MAIN,
3222     "Warning: No server certificate defined; will use a selfsigned one.\n"
3223     " Suggested action: either install a certificate or change tls_advertise_hosts option");
3224
3225 oldsignal = signal(SIGCHLD, SIG_DFL);
3226
3227 fflush(NULL);
3228 if ((pid = fork()) < 0)
3229   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check");
3230
3231 if (pid == 0)
3232   {
3233   /* in some modes, will have dropped privilege already */
3234   if (!geteuid())
3235     exim_setugid(exim_uid, exim_gid, FALSE,
3236         US"calling tls_validate_require_cipher");
3237
3238   errmsg = tls_validate_require_cipher();
3239   if (errmsg)
3240     {
3241     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3242         "tls_require_ciphers invalid: %s", errmsg);
3243     }
3244   fflush(NULL);
3245   _exit(0);
3246   }
3247
3248 do {
3249   rc = waitpid(pid, &status, 0);
3250 } while (rc < 0 && errno == EINTR);
3251
3252 DEBUG(D_tls)
3253   debug_printf("tls_validate_require_cipher child %d ended: status=0x%x\n",
3254       (int)pid, status);
3255
3256 signal(SIGCHLD, oldsignal);
3257
3258 return status == 0;
3259 }
3260 #endif /* SUPPORT_TLS */
3261
3262
3263
3264
3265 /*************************************************
3266 *         Read main configuration options        *
3267 *************************************************/
3268
3269 /* This function is the first to be called for configuration reading. It
3270 opens the configuration file and reads general configuration settings until
3271 it reaches the end of the configuration section. The file is then left open so
3272 that the remaining configuration data can subsequently be read if needed for
3273 this run of Exim.
3274
3275 The configuration file must be owned either by root or exim, and be writeable
3276 only by root or uid/gid exim. The values for Exim's uid and gid can be changed
3277 in the config file, so the test is done on the compiled in values. A slight
3278 anomaly, to be carefully documented.
3279
3280 The name of the configuration file is taken from a list that is included in the
3281 binary of Exim. It can be altered from the command line, but if that is done,
3282 root privilege is immediately withdrawn unless the caller is root or exim.
3283 The first file on the list that exists is used.
3284
3285 For use on multiple systems that share file systems, first look for a
3286 configuration file whose name has the current node name on the end. If that is
3287 not found, try the generic name. For really contorted configurations, that run
3288 multiple Exims with different uid settings, first try adding the effective uid
3289 before the node name. These complications are going to waste resources on most
3290 systems. Therefore they are available only when requested by compile-time
3291 options. */
3292
3293 void
3294 readconf_main(BOOL nowarn)
3295 {
3296 int sep = 0;
3297 struct stat statbuf;
3298 uschar *s, *filename;
3299 const uschar *list = config_main_filelist;
3300
3301 /* Loop through the possible file names */
3302
3303 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
3304   {
3305
3306   /* Cut out all the fancy processing unless specifically wanted */
3307
3308   #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
3309   uschar *suffix = filename + Ustrlen(filename);
3310
3311   /* Try for the node-specific file if a node name exists */
3312
3313   #ifdef CONFIGURE_FILE_USE_NODE
3314   struct utsname uts;
3315   if (uname(&uts) >= 0)
3316     {
3317     #ifdef CONFIGURE_FILE_USE_EUID
3318     sprintf(CS suffix, ".%ld.%.256s", (long int)original_euid, uts.nodename);
3319     config_file = Ufopen(filename, "rb");
3320     if (config_file == NULL)
3321     #endif  /* CONFIGURE_FILE_USE_EUID */
3322       {
3323       sprintf(CS suffix, ".%.256s", uts.nodename);
3324       config_file = Ufopen(filename, "rb");
3325       }
3326     }
3327   #endif  /* CONFIGURE_FILE_USE_NODE */
3328
3329   /* Otherwise, try the generic name, possibly with the euid added */
3330
3331   #ifdef CONFIGURE_FILE_USE_EUID
3332   if (config_file == NULL)
3333     {
3334     sprintf(CS suffix, ".%ld", (long int)original_euid);
3335     config_file = Ufopen(filename, "rb");
3336     }
3337   #endif  /* CONFIGURE_FILE_USE_EUID */
3338
3339   /* Finally, try the unadorned name */
3340
3341   if (config_file == NULL)
3342     {
3343     *suffix = 0;
3344     config_file = Ufopen(filename, "rb");
3345     }
3346   #else  /* if neither defined */
3347
3348   /* This is the common case when the fancy processing is not included. */
3349
3350   config_file = Ufopen(filename, "rb");
3351   #endif
3352
3353   /* If the file does not exist, continue to try any others. For any other
3354   error, break out (and die). */
3355
3356   if (config_file != NULL || errno != ENOENT) break;
3357   }
3358
3359 /* Now, once we found and opened our configuration file, we change the directory
3360 to a safe place. Later we change to $spool_directory. */
3361
3362 if (Uchdir("/") < 0)
3363   {
3364   perror("exim: chdir `/': ");
3365   exit(EXIT_FAILURE);
3366   }
3367
3368 /* On success, save the name for verification; config_filename is used when
3369 logging configuration errors (it changes for .included files) whereas
3370 config_main_filename is the name shown by -bP. Failure to open a configuration
3371 file is a serious disaster. */
3372
3373 if (config_file != NULL)
3374   {
3375   uschar *p;
3376   config_filename = config_main_filename = string_copy(filename);
3377
3378   p = Ustrrchr(filename, '/');
3379   config_main_directory = p ? string_copyn(filename, p - filename)
3380                             : string_copy(US".");
3381   }
3382 else
3383   {
3384   if (filename == NULL)
3385     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "non-existent configuration file(s): "
3386       "%s", config_main_filelist);
3387   else
3388     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", string_open_failed(errno,
3389       "configuration file %s", filename));
3390   }
3391
3392 /* Check the status of the file we have opened, if we have retained root
3393 privileges and the file isn't /dev/null (which *should* be 0666). */
3394
3395 if (trusted_config && Ustrcmp(filename, US"/dev/null"))
3396   {
3397   if (fstat(fileno(config_file), &statbuf) != 0)
3398     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
3399       big_buffer);
3400
3401   if ((statbuf.st_uid != root_uid                /* owner not root */
3402        #ifdef CONFIGURE_OWNER
3403        && statbuf.st_uid != config_uid           /* owner not the special one */
3404        #endif
3405          ) ||                                    /* or */
3406       (statbuf.st_gid != root_gid                /* group not root & */
3407        #ifdef CONFIGURE_GROUP
3408        && statbuf.st_gid != config_gid           /* group not the special one */
3409        #endif
3410        && (statbuf.st_mode & 020) != 0) ||       /* group writeable  */
3411                                                  /* or */
3412       ((statbuf.st_mode & 2) != 0))              /* world writeable  */
3413
3414     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Exim configuration file %s has the "
3415       "wrong owner, group, or mode", big_buffer);
3416   }
3417
3418 /* Process the main configuration settings. They all begin with a lower case
3419 letter. If we see something starting with an upper case letter, it is taken as
3420 a macro definition. */
3421
3422 while ((s = get_config_line()) != NULL)
3423   {
3424   if (isupper(s[0])) read_macro_assignment(s);
3425
3426   else if (Ustrncmp(s, "domainlist", 10) == 0)
3427     read_named_list(&domainlist_anchor, &domainlist_count,
3428       MAX_NAMED_LIST, s+10, US"domain list");
3429
3430   else if (Ustrncmp(s, "hostlist", 8) == 0)
3431     read_named_list(&hostlist_anchor, &hostlist_count,
3432       MAX_NAMED_LIST, s+8, US"host list");
3433
3434   else if (Ustrncmp(s, US"addresslist", 11) == 0)
3435     read_named_list(&addresslist_anchor, &addresslist_count,
3436       MAX_NAMED_LIST, s+11, US"address list");
3437
3438   else if (Ustrncmp(s, US"localpartlist", 13) == 0)
3439     read_named_list(&localpartlist_anchor, &localpartlist_count,
3440       MAX_NAMED_LIST, s+13, US"local part list");
3441
3442   else
3443     (void) readconf_handle_option(s, optionlist_config, optionlist_config_size,
3444       NULL, US"main option \"%s\" unknown");
3445   }
3446
3447
3448 /* If local_sender_retain is set, local_from_check must be unset. */
3449
3450 if (local_sender_retain && local_from_check)
3451   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "both local_from_check and "
3452     "local_sender_retain are set; this combination is not allowed");
3453
3454 /* If the timezone string is empty, set it to NULL, implying no TZ variable
3455 wanted. */
3456
3457 if (timezone_string != NULL && *timezone_string == 0) timezone_string = NULL;
3458
3459 /* The max retry interval must not be greater than 24 hours. */
3460
3461 if (retry_interval_max > 24*60*60) retry_interval_max = 24*60*60;
3462
3463 /* remote_max_parallel must be > 0 */
3464
3465 if (remote_max_parallel <= 0) remote_max_parallel = 1;
3466
3467 /* Save the configured setting of freeze_tell, so we can re-instate it at the
3468 start of a new SMTP message. */
3469
3470 freeze_tell_config = freeze_tell;
3471
3472 /* The primary host name may be required for expansion of spool_directory
3473 and log_file_path, so make sure it is set asap. It is obtained from uname(),
3474 but if that yields an unqualified value, make a FQDN by using gethostbyname to
3475 canonize it. Some people like upper case letters in their host names, so we
3476 don't force the case. */
3477
3478 if (primary_hostname == NULL)
3479   {
3480   const uschar *hostname;
3481   struct utsname uts;
3482   if (uname(&uts) < 0)
3483     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "uname() failed to yield host name");
3484   hostname = US uts.nodename;
3485
3486   if (Ustrchr(hostname, '.') == NULL)
3487     {
3488     int af = AF_INET;
3489     struct hostent *hostdata;
3490
3491     #if HAVE_IPV6
3492     if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
3493          match_isinlist(hostname, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
3494             MCL_DOMAIN, TRUE, NULL) != OK))
3495       af = AF_INET6;
3496     #else
3497     af = AF_INET;
3498     #endif
3499
3500     for (;;)
3501       {
3502       #if HAVE_IPV6
3503         #if HAVE_GETIPNODEBYNAME
3504         int error_num;
3505         hostdata = getipnodebyname(CS hostname, af, 0, &error_num);
3506         #else
3507         hostdata = gethostbyname2(CS hostname, af);
3508         #endif
3509       #else
3510       hostdata = gethostbyname(CS hostname);
3511       #endif
3512
3513       if (hostdata != NULL)
3514         {
3515         hostname = US hostdata->h_name;
3516         break;
3517         }
3518
3519       if (af == AF_INET) break;
3520       af = AF_INET;
3521       }
3522     }
3523
3524   primary_hostname = string_copy(hostname);
3525   }
3526
3527 /* Set up default value for smtp_active_hostname */
3528
3529 smtp_active_hostname = primary_hostname;
3530
3531 /* If spool_directory wasn't set in the build-time configuration, it must have
3532 got set above. Of course, writing to the log may not work if log_file_path is
3533 not set, but it will at least get to syslog or somewhere, with any luck. */
3534
3535 if (*spool_directory == 0)
3536   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "spool_directory undefined: cannot "
3537     "proceed");
3538
3539 /* Expand the spool directory name; it may, for example, contain the primary
3540 host name. Same comment about failure. */
3541
3542 s = expand_string(spool_directory);
3543 if (s == NULL)
3544   log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand spool_directory "
3545     "\"%s\": %s", spool_directory, expand_string_message);
3546 spool_directory = s;
3547
3548 /* Expand log_file_path, which must contain "%s" in any component that isn't
3549 the null string or "syslog". It is also allowed to contain one instance of %D
3550 or %M. However, it must NOT contain % followed by anything else. */
3551
3552 if (*log_file_path != 0)
3553   {
3554   const uschar *ss, *sss;
3555   int sep = ':';                       /* Fixed for log file path */
3556   s = expand_string(log_file_path);
3557   if (s == NULL)
3558     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand log_file_path "
3559       "\"%s\": %s", log_file_path, expand_string_message);
3560
3561   ss = s;
3562   while ((sss = string_nextinlist(&ss,&sep,big_buffer,big_buffer_size)) != NULL)
3563     {
3564     uschar *t;
3565     if (sss[0] == 0 || Ustrcmp(sss, "syslog") == 0) continue;
3566     t = Ustrstr(sss, "%s");
3567     if (t == NULL)
3568       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" does not "
3569         "contain \"%%s\"", sss);
3570     *t = 'X';
3571     t = Ustrchr(sss, '%');
3572     if (t != NULL)
3573       {
3574       if ((t[1] != 'D' && t[1] != 'M') || Ustrchr(t+2, '%') != NULL)
3575         log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" contains "
3576           "unexpected \"%%\" character", s);
3577       }
3578     }
3579
3580   log_file_path = s;
3581   }
3582
3583 /* Interpret syslog_facility into an integer argument for 'ident' param to
3584 openlog(). Default is LOG_MAIL set in globals.c. Allow the user to omit the
3585 leading "log_". */
3586
3587 if (syslog_facility_str != NULL)
3588   {
3589   int i;
3590   uschar *s = syslog_facility_str;
3591
3592   if ((Ustrlen(syslog_facility_str) >= 4) &&
3593         (strncmpic(syslog_facility_str, US"log_", 4) == 0))
3594     s += 4;
3595
3596   for (i = 0; i < syslog_list_size; i++)
3597     {
3598     if (strcmpic(s, syslog_list[i].name) == 0)
3599       {
3600       syslog_facility = syslog_list[i].value;
3601       break;
3602       }
3603     }
3604
3605   if (i >= syslog_list_size)
3606     {
3607     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3608       "failed to interpret syslog_facility \"%s\"", syslog_facility_str);
3609     }
3610   }
3611
3612 /* Expand pid_file_path */
3613
3614 if (*pid_file_path != 0)
3615   {
3616   s = expand_string(pid_file_path);
3617   if (s == NULL)
3618     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand pid_file_path "
3619       "\"%s\": %s", pid_file_path, expand_string_message);
3620   pid_file_path = s;
3621   }
3622
3623 /* Set default value of process_log_path */
3624
3625 if (process_log_path == NULL || *process_log_path =='\0')
3626   process_log_path = string_sprintf("%s/exim-process.info", spool_directory);
3627
3628 /* Compile the regex for matching a UUCP-style "From_" line in an incoming
3629 message. */
3630
3631 regex_From = regex_must_compile(uucp_from_pattern, FALSE, TRUE);
3632
3633 /* Unpick the SMTP rate limiting options, if set */
3634
3635 if (smtp_ratelimit_mail != NULL)
3636   {
3637   unpick_ratelimit(smtp_ratelimit_mail, &smtp_rlm_threshold,
3638     &smtp_rlm_base, &smtp_rlm_factor, &smtp_rlm_limit);
3639   }
3640
3641 if (smtp_ratelimit_rcpt != NULL)
3642   {
3643   unpick_ratelimit(smtp_ratelimit_rcpt, &smtp_rlr_threshold,
3644     &smtp_rlr_base, &smtp_rlr_factor, &smtp_rlr_limit);
3645   }
3646
3647 /* The qualify domains default to the primary host name */
3648
3649 if (qualify_domain_sender == NULL)
3650   qualify_domain_sender = primary_hostname;
3651 if (qualify_domain_recipient == NULL)
3652   qualify_domain_recipient = qualify_domain_sender;
3653
3654 /* Setting system_filter_user in the configuration sets the gid as well if a
3655 name is given, but a numerical value does not. */
3656
3657 if (system_filter_uid_set && !system_filter_gid_set)
3658   {
3659   struct passwd *pw = getpwuid(system_filter_uid);
3660   if (pw == NULL)
3661     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to look up uid %ld",
3662       (long int)system_filter_uid);
3663   system_filter_gid = pw->pw_gid;
3664   system_filter_gid_set = TRUE;
3665   }
3666
3667 /* If the errors_reply_to field is set, check that it is syntactically valid
3668 and ensure it contains a domain. */
3669
3670 if (errors_reply_to != NULL)
3671   {
3672   uschar *errmess;
3673   int start, end, domain;
3674   uschar *recipient = parse_extract_address(errors_reply_to, &errmess,
3675     &start, &end, &domain, FALSE);
3676
3677   if (recipient == NULL)
3678     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3679       "error in errors_reply_to (%s): %s", errors_reply_to, errmess);
3680
3681   if (domain == 0)
3682     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3683       "errors_reply_to (%s) does not contain a domain", errors_reply_to);
3684   }
3685
3686 /* If smtp_accept_queue or smtp_accept_max_per_host is set, then
3687 smtp_accept_max must also be set. */
3688
3689 if (smtp_accept_max == 0 &&
3690     (smtp_accept_queue > 0 || smtp_accept_max_per_host != NULL))
3691   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3692     "smtp_accept_max must be set if smtp_accept_queue or "
3693     "smtp_accept_max_per_host is set");
3694
3695 /* Set up the host number if anything is specified. It is an expanded string
3696 so that it can be computed from the host name, for example. We do this last
3697 so as to ensure that everything else is set up before the expansion. */
3698
3699 if (host_number_string != NULL)
3700   {
3701   long int n;
3702   uschar *end;
3703   uschar *s = expand_string(host_number_string);
3704   if (s == NULL)
3705     log_write(0, LOG_MAIN|LOG_PANIC_DIE,
3706         "failed to expand localhost_number \"%s\": %s",
3707         host_number_string, expand_string_message);
3708   n = Ustrtol(s, &end, 0);
3709   while (isspace(*end)) end++;
3710   if (*end != 0)
3711     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3712       "localhost_number value is not a number: %s", s);
3713   if (n > LOCALHOST_MAX)
3714     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3715       "localhost_number is greater than the maximum allowed value (%d)",
3716         LOCALHOST_MAX);
3717   host_number = n;
3718   }
3719
3720 #ifdef SUPPORT_TLS
3721 /* If tls_verify_hosts is set, tls_verify_certificates must also be set */
3722
3723 if ((tls_verify_hosts != NULL || tls_try_verify_hosts != NULL) &&
3724      tls_verify_certificates == NULL)
3725   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3726     "tls_%sverify_hosts is set, but tls_verify_certificates is not set",
3727     (tls_verify_hosts != NULL)? "" : "try_");
3728
3729 /* This also checks that the library linkage is working and we can call
3730 routines in it, so call even if tls_require_ciphers is unset */
3731 if (!tls_dropprivs_validate_require_cipher(nowarn))
3732   exit(1);
3733
3734 /* Magic number: at time of writing, 1024 has been the long-standing value
3735 used by so many clients, and what Exim used to use always, that it makes
3736 sense to just min-clamp this max-clamp at that. */
3737 if (tls_dh_max_bits < 1024)
3738   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3739       "tls_dh_max_bits is too small, must be at least 1024 for interop");
3740
3741 /* If openssl_options is set, validate it */
3742 if (openssl_options != NULL)
3743   {
3744 # ifdef USE_GNUTLS
3745   log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3746     "openssl_options is set but we're using GnuTLS");
3747 # else
3748   long dummy;
3749   if (!(tls_openssl_options_parse(openssl_options, &dummy)))
3750     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3751       "openssl_options parse error: %s", openssl_options);
3752 # endif
3753   }
3754 #endif  /*SUPPORT_TLS*/
3755
3756 if (!nowarn && !keep_environment && environ && *environ)
3757   log_write(0, LOG_MAIN,
3758       "Warning: purging the environment.\n"
3759       " Suggested action: use keep_environment.");
3760 }
3761
3762
3763
3764 /*************************************************
3765 *          Initialize one driver                 *
3766 *************************************************/
3767
3768 /* This is called once the driver's generic options, if any, have been read.
3769 We can now find the driver, set up defaults for the private options, and
3770 unset any "set" bits in the private options table (which might have been
3771 set by another incarnation of the same driver).
3772
3773 Arguments:
3774   d                   pointer to driver instance block, with generic
3775                         options filled in
3776   drivers_available   vector of available drivers
3777   size_of_info        size of each block in drivers_available
3778   class               class of driver, for error message
3779
3780 Returns:              pointer to the driver info block
3781 */
3782
3783 static driver_info *
3784 init_driver(driver_instance *d, driver_info *drivers_available,
3785   int size_of_info, uschar *class)
3786 {
3787 driver_info *dd;
3788
3789 for (dd = drivers_available; dd->driver_name[0] != 0;
3790      dd = (driver_info *)(((uschar *)dd) + size_of_info))
3791   {
3792   if (Ustrcmp(d->driver_name, dd->driver_name) == 0)
3793     {
3794     int i;
3795     int len = dd->options_len;
3796     d->info = dd;
3797     d->options_block = store_get(len);
3798     memcpy(d->options_block, dd->options_block, len);
3799     for (i = 0; i < *(dd->options_count); i++)
3800       dd->options[i].type &= ~opt_set;
3801     return dd;
3802     }
3803   }
3804
3805 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3806   "%s %s: cannot find %s driver \"%s\"", class, d->name, class, d->driver_name);
3807
3808 return NULL;   /* never obeyed */
3809 }
3810
3811
3812
3813
3814 /*************************************************
3815 *             Initialize driver list             *
3816 *************************************************/
3817
3818 /* This function is called for routers, transports, and authentication
3819 mechanisms. It reads the data from the current point in the configuration file
3820 up to the end of the section, and sets up a chain of instance blocks according
3821 to the file's contents. The file will already have been opened by a call to
3822 readconf_main, and must be left open for subsequent reading of further data.
3823
3824 Any errors cause a panic crash. Note that the blocks with names driver_info and
3825 driver_instance must map the first portions of all the _info and _instance
3826 blocks for this shared code to work.
3827
3828 Arguments:
3829   class                      "router", "transport", or "authenticator"
3830   anchor                     &routers, &transports, &auths
3831   drivers_available          available drivers
3832   size_of_info               size of each info block
3833   instance_default           points to default data for an instance
3834   instance_size              size of instance block
3835   driver_optionlist          generic option list
3836   driver_optionlist_count    count of generic option list
3837
3838 Returns:                     nothing
3839 */
3840
3841 void
3842 readconf_driver_init(
3843   uschar *class,
3844   driver_instance **anchor,
3845   driver_info *drivers_available,
3846   int size_of_info,
3847   void *instance_default,
3848   int  instance_size,
3849   optionlist *driver_optionlist,
3850   int  driver_optionlist_count)
3851 {
3852 driver_instance **p = anchor;
3853 driver_instance *d = NULL;
3854 uschar *buffer;
3855
3856 while ((buffer = get_config_line()) != NULL)
3857   {
3858   uschar name[64];
3859   uschar *s;
3860
3861   /* Read the first name on the line and test for the start of a new driver. A
3862   macro definition indicates the end of the previous driver. If this isn't the
3863   start of a new driver, the line will be re-read. */
3864
3865   s = readconf_readname(name, sizeof(name), buffer);
3866
3867   /* Handle macro definition, first finishing off the initialization of the
3868   previous driver, if any. */
3869
3870   if (isupper(*name) && *s == '=')
3871     {
3872     if (d)
3873       {
3874       if (!d->driver_name)
3875         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3876           "no driver defined for %s \"%s\"", class, d->name);
3877       (d->info->init)(d);
3878       d = NULL;
3879       }
3880     read_macro_assignment(buffer);
3881     continue;
3882     }
3883
3884   /* If the line starts with a name terminated by a colon, we are at the
3885   start of the definition of a new driver. The rest of the line must be
3886   blank. */
3887
3888   if (*s++ == ':')
3889     {
3890     int i;
3891
3892     /* Finish off initializing the previous driver. */
3893
3894     if (d)
3895       {
3896       if (!d->driver_name)
3897         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3898           "no driver defined for %s \"%s\"", class, d->name);
3899       (d->info->init)(d);
3900       }
3901
3902     /* Check that we haven't already got a driver of this name */
3903
3904     for (d = *anchor; d; d = d->next)
3905       if (Ustrcmp(name, d->name) == 0)
3906         log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3907           "there are two %ss called \"%s\"", class, name);
3908
3909     /* Set up a new driver instance data block on the chain, with
3910     its default values installed. */
3911
3912     d = store_get(instance_size);
3913     memcpy(d, instance_default, instance_size);
3914     *p = d;
3915     p = &d->next;
3916     d->name = string_copy(name);
3917
3918     /* Clear out the "set" bits in the generic options */
3919
3920     for (i = 0; i < driver_optionlist_count; i++)
3921       driver_optionlist[i].type &= ~opt_set;
3922
3923     /* Check nothing more on this line, then do the next loop iteration. */
3924
3925     while (isspace(*s)) s++;
3926     if (*s != 0) extra_chars_error(s, US"driver name ", name, US"");
3927     continue;
3928     }
3929
3930   /* Not the start of a new driver. Give an error if we have not set up a
3931   current driver yet. */
3932
3933   if (!d)
3934     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s name missing", class);
3935
3936   /* First look to see if this is a generic option; if it is "driver",
3937   initialize the driver. If is it not a generic option, we can look for a
3938   private option provided that the driver has been previously set up. */
3939
3940   if (readconf_handle_option(buffer, driver_optionlist,
3941         driver_optionlist_count, d, NULL))
3942     {
3943     if (!d->info && d->driver_name)
3944       init_driver(d, drivers_available, size_of_info, class);
3945     }
3946
3947   /* Handle private options - pass the generic block because some may
3948   live therein. A flag with each option indicates if it is in the public
3949   block. */
3950
3951   else if (d->info)
3952     readconf_handle_option(buffer, d->info->options,
3953       *(d->info->options_count), d, US"option \"%s\" unknown");
3954
3955   /* The option is not generic and the driver name has not yet been given. */
3956
3957   else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option \"%s\" unknown "
3958     "(\"driver\" must be specified before any private options)", name);
3959   }
3960
3961 /* Run the initialization function for the final driver. */
3962
3963 if (d)
3964   {
3965   if (!d->driver_name)
3966     log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3967       "no driver defined for %s \"%s\"", class, d->name);
3968   (d->info->init)(d);
3969   }
3970 }
3971
3972
3973
3974 /*************************************************
3975 *            Check driver dependency             *
3976 *************************************************/
3977
3978 /* This function is passed a driver instance and a string. It checks whether
3979 any of the string options for the driver contains the given string as an
3980 expansion variable.
3981
3982 Arguments:
3983   d        points to a driver instance block
3984   s        the string to search for
3985
3986 Returns:   TRUE if a dependency is found
3987 */
3988
3989 BOOL
3990 readconf_depends(driver_instance *d, uschar *s)
3991 {
3992 int count = *(d->info->options_count);
3993 optionlist *ol;
3994 uschar *ss;
3995
3996 for (ol = d->info->options; ol < d->info->options + count; ol++)
3997   {
3998   void *options_block;
3999   uschar *value;
4000   int type = ol->type & opt_mask;
4001   if (type != opt_stringptr) continue;
4002   options_block = ((ol->type & opt_public) == 0)? d->options_block : (void *)d;
4003   value = *(uschar **)((uschar *)options_block + (long int)(ol->value));
4004   if (value != NULL && (ss = Ustrstr(value, s)) != NULL)
4005     {
4006     if (ss <= value || (ss[-1] != '$' && ss[-1] != '{') ||
4007       isalnum(ss[Ustrlen(s)])) continue;
4008     DEBUG(D_transport) debug_printf("driver %s: \"%s\" option depends on %s\n",
4009       d->name, ol->name, s);
4010     return TRUE;
4011     }
4012   }
4013
4014 DEBUG(D_transport) debug_printf("driver %s does not depend on %s\n", d->name, s);
4015 return FALSE;
4016 }
4017
4018
4019
4020
4021 /*************************************************
4022 *      Decode an error type for retries          *
4023 *************************************************/
4024
4025 /* This function is global because it is also called from the main
4026 program when testing retry information. It decodes strings such as "quota_7d"
4027 into numerical error codes.
4028
4029 Arguments:
4030   pp           points to start of text
4031   p            points past end of text
4032   basic_errno  points to an int to receive the main error number
4033   more_errno   points to an int to receive the secondary error data
4034
4035 Returns:       NULL if decoded correctly; else points to error text
4036 */
4037
4038 uschar *
4039 readconf_retry_error(const uschar *pp, const uschar *p,
4040   int *basic_errno, int *more_errno)
4041 {
4042 int len;
4043 const uschar *q = pp;
4044 while (q < p && *q != '_') q++;
4045 len = q - pp;
4046
4047 if (len == 5 && strncmpic(pp, US"quota", len) == 0)
4048   {
4049   *basic_errno = ERRNO_EXIMQUOTA;
4050   if (q != p && (*more_errno = readconf_readtime(q+1, *p, FALSE)) < 0)
4051       return US"bad time value";
4052   }
4053
4054 else if (len == 7 && strncmpic(pp, US"refused", len) == 0)
4055   {
4056   *basic_errno = ECONNREFUSED;
4057   if (q != p)
4058     {
4059     if (strncmpic(q+1, US"MX", p-q-1) == 0) *more_errno = 'M';
4060     else if (strncmpic(q+1, US"A", p-q-1) == 0) *more_errno = 'A';
4061     else return US"A or MX expected after \"refused\"";
4062     }
4063   }
4064
4065 else if (len == 7 && strncmpic(pp, US"timeout", len) == 0)
4066   {
4067   *basic_errno = ETIMEDOUT;
4068   if (q != p)
4069     {
4070     int i;
4071     int xlen = p - q - 1;
4072     const uschar *x = q + 1;
4073
4074     static uschar *extras[] =
4075       { US"A", US"MX", US"connect", US"connect_A",  US"connect_MX" };
4076     static int values[] =
4077       { 'A',   'M',    RTEF_CTOUT,  RTEF_CTOUT|'A', RTEF_CTOUT|'M' };
4078
4079     for (i = 0; i < sizeof(extras)/sizeof(uschar *); i++)
4080       if (strncmpic(x, extras[i], xlen) == 0)
4081         {
4082         *more_errno = values[i];
4083         break;
4084         }
4085
4086     if (i >= sizeof(extras)/sizeof(uschar *))
4087       if (strncmpic(x, US"DNS", xlen) == 0)
4088         log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer "
4089           "available in retry rules (it has never worked) - treated as "
4090           "\"timeout\"");
4091       else
4092         return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
4093     }
4094   }
4095
4096 else if (strncmpic(pp, US"mail_4", 6) == 0 ||
4097          strncmpic(pp, US"rcpt_4", 6) == 0 ||
4098          strncmpic(pp, US"data_4", 6) == 0)
4099   {
4100   BOOL bad = FALSE;
4101   int x = 255;                           /* means "any 4xx code" */
4102   if (p != pp + 8) bad = TRUE; else
4103     {
4104     int a = pp[6], b = pp[7];
4105     if (isdigit(a))
4106       {
4107       x = (a - '0') * 10;
4108       if (isdigit(b)) x += b - '0';
4109       else if (b == 'x') x += 100;
4110       else bad = TRUE;
4111       }
4112     else if (a != 'x' || b != 'x') bad = TRUE;
4113     }
4114
4115   if (bad)
4116     return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where "
4117       "x is literal and d is any digit", pp);
4118
4119   *basic_errno = *pp == 'm' ? ERRNO_MAIL4XX :
4120                  *pp == 'r' ? ERRNO_RCPT4XX : ERRNO_DATA4XX;
4121   *more_errno = x << 8;
4122   }
4123
4124 else if (len == 4 && strncmpic(pp, US"auth", len) == 0 &&
4125          strncmpic(q+1, US"failed", p-q-1) == 0)
4126   *basic_errno = ERRNO_AUTHFAIL;
4127
4128 else if (strncmpic(pp, US"lost_connection", p - pp) == 0)
4129   *basic_errno = ERRNO_SMTPCLOSED;
4130
4131 else if (strncmpic(pp, US"tls_required", p - pp) == 0)
4132   *basic_errno = ERRNO_TLSREQUIRED;
4133
4134 else if (strncmpic(pp, US"lookup", p - pp) == 0)
4135   *basic_errno = ERRNO_UNKNOWNHOST;
4136
4137 else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
4138   return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp);
4139
4140 return NULL;
4141 }
4142
4143
4144
4145
4146 /*************************************************
4147 *                Read retry information          *
4148 *************************************************/
4149
4150 /* Each line of retry information contains:
4151
4152 .  A domain name pattern or an address pattern;
4153
4154 .  An error name, possibly with additional data, or *;
4155
4156 .  An optional sequence of retry items, each consisting of an identifying
4157    letter, a cutoff time, and optional parameters.
4158
4159 All this is decoded and placed into a control block. */
4160
4161
4162 /* Subroutine to read an argument, preceded by a comma and terminated
4163 by comma, semicolon, whitespace, or newline. The types are: 0 = time value,
4164 1 = fixed point number (returned *1000).
4165
4166 Arguments:
4167   paddr     pointer to pointer to current character; updated
4168   type      0 => read a time; 1 => read a fixed point number
4169
4170 Returns:    time in seconds or fixed point number * 1000
4171 */
4172
4173 static int
4174 retry_arg(const uschar **paddr, int type)
4175 {
4176 const uschar *p = *paddr;
4177 const uschar *pp;
4178
4179 if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");
4180
4181 while (isspace(*p)) p++;
4182 pp = p;
4183 while (isalnum(*p) || (type == 1 && *p == '.')) p++;
4184
4185 if (*p != 0 && !isspace(*p) && *p != ',' && *p != ';')
4186   log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma or semicolon expected");
4187
4188 *paddr = p;
4189 switch (type)
4190   {
4191   case 0: return readconf_readtime(pp, *p, FALSE);
4192   case 1: return readconf_readfixed(pp, *p);
4193   }
4194 return 0;    /* Keep picky compilers happy */
4195 }
4196
4197 /* The function proper */
4198
4199 void
4200 readconf_retries(void)
4201 {
4202 retry_config **chain = &retries;
4203 retry_config *next;
4204 const uschar *p;
4205
4206 while ((p = get_config_line()))
4207   {
4208   retry_rule **rchain;
4209   const uschar *pp;
4210   uschar *error;
4211
4212   next = store_get(sizeof(retry_config));
4213   next->next = NULL;
4214   *chain = next;
4215   chain = &(next->next);
4216   next->basic_errno = next->more_errno = 0;
4217   next->senders = NULL;
4218   next->rules = NULL;
4219   rchain = &(next->rules);
4220
4221   next->pattern = string_dequote(&p);
4222   while (isspace(*p)) p++;
4223   pp = p;
4224   while (mac_isgraph(*p)) p++;
4225   if (p - pp <= 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4226     "missing error type in retry rule");
4227
4228   /* Test error names for things we understand. */
4229
4230   if ((error = readconf_retry_error(pp, p, &next->basic_errno,
4231        &next->more_errno)))
4232     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s", error);
4233
4234   /* There may be an optional address list of senders to be used as another
4235   constraint on the rule. This was added later, so the syntax is a bit of a
4236   fudge. Anything that is not a retry rule starting "F," or "G," is treated as
4237   an address list. */
4238
4239   while (isspace(*p)) p++;
4240   if (Ustrncmp(p, "senders", 7) == 0)
4241     {
4242     p += 7;
4243     while (isspace(*p)) p++;
4244     if (*p++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4245       "\"=\" expected after \"senders\" in retry rule");
4246     while (isspace(*p)) p++;
4247     next->senders = string_dequote(&p);
4248     }
4249
4250   /* Now the retry rules. Keep the maximum timeout encountered. */
4251
4252   while (isspace(*p)) p++;
4253
4254   while (*p != 0)
4255     {
4256     retry_rule *rule = store_get(sizeof(retry_rule));
4257     *rchain = rule;
4258     rchain = &(rule->next);
4259     rule->next = NULL;
4260     rule->rule = toupper(*p++);
4261     rule->timeout = retry_arg(&p, 0);
4262     if (rule->timeout > retry_maximum_timeout)
4263       retry_maximum_timeout = rule->timeout;
4264
4265     switch (rule->rule)
4266       {
4267       case 'F':   /* Fixed interval */
4268         rule->p1 = retry_arg(&p, 0);
4269         break;
4270
4271       case 'G':   /* Geometrically increasing intervals */
4272       case 'H':   /* Ditto, but with randomness */
4273         rule->p1 = retry_arg(&p, 0);
4274         rule->p2 = retry_arg(&p, 1);
4275         break;
4276
4277       default:
4278         log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
4279         break;
4280       }
4281
4282     if (rule->timeout <= 0 || rule->p1 <= 0 ||
4283           (rule->rule != 'F' && rule->p2 < 1000))
4284       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4285         "bad parameters for retry rule");
4286
4287     while (isspace(*p)) p++;
4288     if (*p == ';')
4289       {
4290       p++;
4291       while (isspace(*p)) p++;
4292       }
4293     else if (*p != 0)
4294       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "semicolon expected");
4295     }
4296   }
4297 }
4298
4299
4300
4301 /*************************************************
4302 *         Initialize authenticators              *
4303 *************************************************/
4304
4305 static void
4306 readconf_options_auths(void)
4307 {
4308 struct auth_info * ai;
4309
4310 readconf_options_from_list(optionlist_auths, optionlist_auths_size, US"AUTHENTICATORS", NULL);
4311
4312 for (ai = auths_available; ai->driver_name[0]; ai++)
4313   {
4314   macro_create(string_sprintf("_DRIVER_AUTHENTICATOR_%T", ai->driver_name), US"y", FALSE, TRUE);
4315   readconf_options_from_list(ai->options, (unsigned)*ai->options_count, US"AUTHENTICATOR", ai->driver_name);
4316   }
4317 }
4318
4319
4320 /* Read the authenticators section of the configuration file.
4321
4322 Arguments:   none
4323 Returns:     nothing
4324 */
4325
4326 static void
4327 auths_init(void)
4328 {
4329 auth_instance *au, *bu;
4330
4331 readconf_driver_init(US"authenticator",
4332   (driver_instance **)(&auths),      /* chain anchor */
4333   (driver_info *)auths_available,    /* available drivers */
4334   sizeof(auth_info),                 /* size of info block */
4335   &auth_defaults,                    /* default values for generic options */
4336   sizeof(auth_instance),             /* size of instance block */
4337   optionlist_auths,                  /* generic options */
4338   optionlist_auths_size);
4339
4340 for (au = auths; au; au = au->next)
4341   {
4342   if (!au->public_name)
4343     log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no public name specified for "
4344       "the %s authenticator", au->name);
4345
4346   for (bu = au->next; bu; bu = bu->next)
4347     if (strcmpic(au->public_name, bu->public_name) == 0)
4348       if ((au->client && bu->client) || (au->server && bu->server))
4349         log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "two %s authenticators "
4350           "(%s and %s) have the same public name (%s)",
4351           au->client ? US"client" : US"server", au->name, bu->name,
4352           au->public_name);
4353   }
4354 }
4355
4356
4357
4358
4359 /*************************************************
4360 *             Read ACL information               *
4361 *************************************************/
4362
4363 /* If this run of Exim is not doing something that involves receiving a
4364 message, we can just skip over the ACL information. No need to parse it.
4365
4366 First, we have a function for acl_read() to call back to get the next line. We
4367 need to remember the line we passed, because at the end it will contain the
4368 name of the next ACL. */
4369
4370 static uschar *acl_line;
4371
4372 static uschar *
4373 acl_callback(void)
4374 {
4375 acl_line = get_config_line();
4376 return acl_line;
4377 }
4378
4379
4380 /* Now the main function:
4381
4382 Arguments:    none
4383 Returns:      nothing
4384 */
4385
4386 static void
4387 readconf_acl(void)
4388 {
4389 uschar *p;
4390
4391 /* Read each ACL and add it into the tree. Macro (re)definitions are allowed
4392 between ACLs. */
4393
4394 acl_line = get_config_line();
4395
4396 while(acl_line != NULL)
4397   {
4398   uschar name[64];
4399   tree_node *node;
4400   uschar *error;
4401
4402   p = readconf_readname(name, sizeof(name), acl_line);
4403   if (isupper(*name) && *p == '=')
4404     {
4405     read_macro_assignment(acl_line);
4406     acl_line = get_config_line();
4407     continue;
4408     }
4409
4410   if (*p != ':' || name[0] == 0)
4411     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing or malformed ACL name");
4412
4413   node = store_get(sizeof(tree_node) + Ustrlen(name));
4414   Ustrcpy(node->name, name);
4415   if (!tree_insertnode(&acl_anchor, node))
4416     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4417       "there are two ACLs called \"%s\"", name);
4418
4419   node->data.ptr = acl_read(acl_callback, &error);
4420
4421   if (node->data.ptr == NULL && error != NULL)
4422     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "error in ACL: %s", error);
4423   }
4424 }
4425
4426
4427
4428 /*************************************************
4429 *     Read configuration for local_scan()        *
4430 *************************************************/
4431
4432 /* This function is called after "begin local_scan" is encountered in the
4433 configuration file. If the local_scan() function allows for configuration
4434 options, we can process them. Otherwise, we expire in a panic.
4435
4436 Arguments:  none
4437 Returns:    nothing
4438 */
4439
4440 static void
4441 local_scan_init(void)
4442 {
4443 #ifndef LOCAL_SCAN_HAS_OPTIONS
4444 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "local_scan() options not supported: "
4445   "(LOCAL_SCAN_HAS_OPTIONS not defined in Local/Makefile)");
4446 #else
4447
4448 uschar *p;
4449 while ((p = get_config_line()) != NULL)
4450   {
4451   (void) readconf_handle_option(p, local_scan_options, local_scan_options_count,
4452     NULL, US"local_scan option \"%s\" unknown");
4453   }
4454 #endif
4455 }
4456
4457
4458
4459 /*************************************************
4460 *     Read rest of configuration (after main)    *
4461 *************************************************/
4462
4463 /* This function reads the rest of the runtime configuration, after the main
4464 configuration. It is called only when actually needed. Each subsequent section
4465 of the configuration starts with a line of the form
4466
4467   begin name
4468
4469 where the name is "routers", "transports", etc. A section is terminated by
4470 hitting the next "begin" line, and the next name is left in next_section.
4471 Because it may confuse people as to whether the names are singular or plural,
4472 we add "s" if it's missing. There is always enough room in next_section for
4473 this. This function is basically just a switch.
4474
4475 Arguments:   none
4476 Returns:     nothing
4477 */
4478
4479 static uschar *section_list[] = {
4480   US"acls",
4481   US"authenticators",
4482   US"local_scans",
4483   US"retrys",
4484   US"rewrites",
4485   US"routers",
4486   US"transports"};
4487
4488 void
4489 readconf_rest(void)
4490 {
4491 int had = 0;
4492
4493 while(next_section[0] != 0)
4494   {
4495   int bit;
4496   int first = 0;
4497   int last = sizeof(section_list) / sizeof(uschar *);
4498   int mid = last/2;
4499   int n = Ustrlen(next_section);
4500
4501   if (tolower(next_section[n-1]) != 's') Ustrcpy(next_section+n, "s");
4502
4503   for (;;)
4504     {
4505     int c = strcmpic(next_section, section_list[mid]);
4506     if (c == 0) break;
4507     if (c > 0) first = mid + 1; else last = mid;
4508     if (first >= last)
4509       log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4510         "\"%.*s\" is not a known configuration section name", n, next_section);
4511     mid = (last + first)/2;
4512     }
4513
4514   bit = 1 << mid;
4515   if (((had ^= bit) & bit) == 0)
4516     log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4517       "\"%.*s\" section is repeated in the configuration file", n,
4518         next_section);
4519
4520   switch(mid)
4521     {
4522     case 0: readconf_acl(); break;
4523     case 1: auths_init(); break;
4524     case 2: local_scan_init(); break;
4525     case 3: readconf_retries(); break;
4526     case 4: readconf_rewrites(); break;
4527     case 5: route_init(); break;
4528     case 6: transport_init(); break;
4529     }
4530   }
4531
4532 (void)fclose(config_file);
4533 }
4534
4535 /* Init the storage for the pre-parsed config lines */
4536 void
4537 readconf_save_config(const uschar *s)
4538 {
4539   save_config_line(string_sprintf("# Exim Configuration (%s)",
4540     running_in_test_harness ? US"X" : s));
4541 }
4542
4543 static void
4544 save_config_position(const uschar *file, int line)
4545 {
4546   save_config_line(string_sprintf("# %d \"%s\"", line, file));
4547 }
4548
4549 /* Append a pre-parsed logical line to the config lines store,
4550 this operates on a global (static) list that holds all the pre-parsed
4551 config lines, we do no further processing here, output formatting and
4552 honouring of <hide> or macros will be done during output */
4553 static void
4554 save_config_line(const uschar* line)
4555 {
4556 static config_line_item *current;
4557 config_line_item *next;
4558
4559 next = (config_line_item*) store_get(sizeof(config_line_item));
4560 next->line = string_copy(line);
4561 next->next = NULL;
4562
4563 if (!config_lines) config_lines = next;
4564 else current->next = next;
4565
4566 current = next;
4567 }
4568
4569 /* List the parsed config lines, care about nice formatting and
4570 hide the <hide> values unless we're the admin user */
4571 void
4572 print_config(BOOL admin, BOOL terse)
4573 {
4574 config_line_item *i;
4575 const int TS = terse ? 0 : 2;
4576 int indent = 0;
4577
4578 for (i = config_lines; i; i = i->next)
4579   {
4580   uschar *current;
4581   uschar *p;
4582
4583   /* skip over to the first non-space */
4584   for (current = i->line; *current && isspace(*current); ++current)
4585     ;
4586
4587   if (*current == '\0')
4588     continue;
4589
4590   /* Collapse runs of spaces. We stop this if we encounter one of the
4591    * following characters: "'$, as this may indicate careful formatting */
4592   for (p = current; *p; ++p)
4593     {
4594     uschar *next;
4595     if (!isspace(*p)) continue;
4596     if (*p != ' ') *p = ' ';
4597
4598     for (next = p; isspace(*next); ++next)
4599       ;
4600
4601     if (next - p > 1)
4602       memmove(p+1, next, Ustrlen(next)+1);
4603
4604     if (*next == '"' || *next == '\'' || *next == '$')
4605       break;
4606     }
4607
4608   /* # lines */
4609   if (current[0] == '#')
4610     puts(CCS current);
4611
4612   /* begin lines are left aligned */
4613   else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5]))
4614     {
4615     if (!terse) puts("");
4616     puts(CCS current);
4617     indent = TS;
4618     }
4619
4620   /* router/acl/transport block names */
4621   else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '='))
4622     {
4623     if (!terse) puts("");
4624     printf("%*s%s\n", TS, "", current);
4625     indent = 2 * TS;
4626     }
4627
4628   /* hidden lines (all MACROS or lines prefixed with "hide") */
4629   else if (  !admin
4630           && (  isupper(*current)
4631              || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
4632              )
4633           )
4634     {
4635     if ((p = Ustrchr(current, '=')))
4636       {
4637       *p = '\0';
4638       printf("%*s%s= %s\n", indent, "", current, hidden);
4639       }
4640     /* e.g.: hide split_spool_directory */
4641     else
4642       printf("%*s\n", indent, hidden);
4643     }
4644
4645   else
4646     /* rest is public */
4647     printf("%*s%s\n", indent, "", current);
4648   }
4649 }
4650
4651 /* vi: aw ai sw=2
4652 */
4653 /* End of readconf.c */