1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2014 */
6 /* See the file NOTICE for conditions of use and distribution. */
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. */
14 #define CSTATE_STACK_SIZE 10
17 /* Structure for chain (stack) of .included files */
19 typedef struct config_file_item {
20 struct config_file_item *next;
26 /* Structure of table of conditional words and their state transitions */
28 typedef struct cond_item {
36 /* Structure of table of syslog facility names and values */
38 typedef struct syslog_fac_item {
44 /* Static variables */
46 static config_file_item *config_file_stack = NULL; /* For includes */
48 static uschar *syslog_facility_str = NULL;
49 static uschar next_section[24];
50 static uschar time_buffer[24];
52 /* State variables for conditional loading (.ifdef / .else / .endif) */
54 static int cstate = 0;
55 static int cstate_stack_ptr = -1;
56 static int cstate_stack[CSTATE_STACK_SIZE];
58 /* Table of state transitions for handling conditional inclusions. There are
59 four possible state transitions:
63 .elifdef true (or .else)
66 .endif just causes the previous cstate to be popped off the stack */
68 static int next_cstate[3][4] =
70 /* State 0: reading from file, or reading until next .else or .endif */
72 /* State 1: condition failed, skipping until next .else or .endif */
74 /* State 2: skipping until .endif */
78 /* Table of conditionals and the states to set. For each name, there are four
79 values: the length of the name (to save computing it each time), the state to
80 set if a macro was found in the line, the state to set if a macro was not found
81 in the line, and a stack manipulation setting which is:
83 -1 pull state value off the stack
84 0 don't alter the stack
85 +1 push value onto stack, before setting new state
88 static cond_item cond_list[] = {
89 { US"ifdef", 5, 0, 1, 1 },
90 { US"ifndef", 6, 1, 0, 1 },
91 { US"elifdef", 7, 2, 3, 0 },
92 { US"elifndef", 8, 3, 2, 0 },
93 { US"else", 4, 2, 2, 0 },
94 { US"endif", 5, 0, 0, -1 }
97 static int cond_list_size = sizeof(cond_list)/sizeof(cond_item);
99 /* Table of syslog facility names and their values */
101 static syslog_fac_item syslog_list[] = {
102 { US"mail", LOG_MAIL },
103 { US"user", LOG_USER },
104 { US"news", LOG_NEWS },
105 { US"uucp", LOG_UUCP },
106 { US"local0", LOG_LOCAL0 },
107 { US"local1", LOG_LOCAL1 },
108 { US"local2", LOG_LOCAL2 },
109 { US"local3", LOG_LOCAL3 },
110 { US"local4", LOG_LOCAL4 },
111 { US"local5", LOG_LOCAL5 },
112 { US"local6", LOG_LOCAL6 },
113 { US"local7", LOG_LOCAL7 },
114 { US"daemon", LOG_DAEMON }
117 static int syslog_list_size = sizeof(syslog_list)/sizeof(syslog_fac_item);
122 /*************************************************
123 * Main configuration options *
124 *************************************************/
126 /* The list of options that can be set in the main configuration file. This
127 must be in alphabetic order because it is searched by binary chop. */
129 static optionlist optionlist_config[] = {
130 { "*set_exim_group", opt_bool|opt_hidden, &exim_gid_set },
131 { "*set_exim_user", opt_bool|opt_hidden, &exim_uid_set },
132 { "*set_system_filter_group", opt_bool|opt_hidden, &system_filter_gid_set },
133 { "*set_system_filter_user", opt_bool|opt_hidden, &system_filter_uid_set },
134 { "accept_8bitmime", opt_bool, &accept_8bitmime },
135 { "acl_not_smtp", opt_stringptr, &acl_not_smtp },
136 #ifdef WITH_CONTENT_SCAN
137 { "acl_not_smtp_mime", opt_stringptr, &acl_not_smtp_mime },
139 { "acl_not_smtp_start", opt_stringptr, &acl_not_smtp_start },
140 { "acl_smtp_auth", opt_stringptr, &acl_smtp_auth },
141 { "acl_smtp_connect", opt_stringptr, &acl_smtp_connect },
142 { "acl_smtp_data", opt_stringptr, &acl_smtp_data },
144 { "acl_smtp_data_prdr", opt_stringptr, &acl_smtp_data_prdr },
147 { "acl_smtp_dkim", opt_stringptr, &acl_smtp_dkim },
149 { "acl_smtp_etrn", opt_stringptr, &acl_smtp_etrn },
150 { "acl_smtp_expn", opt_stringptr, &acl_smtp_expn },
151 { "acl_smtp_helo", opt_stringptr, &acl_smtp_helo },
152 { "acl_smtp_mail", opt_stringptr, &acl_smtp_mail },
153 { "acl_smtp_mailauth", opt_stringptr, &acl_smtp_mailauth },
154 #ifdef WITH_CONTENT_SCAN
155 { "acl_smtp_mime", opt_stringptr, &acl_smtp_mime },
157 { "acl_smtp_notquit", opt_stringptr, &acl_smtp_notquit },
158 { "acl_smtp_predata", opt_stringptr, &acl_smtp_predata },
159 { "acl_smtp_quit", opt_stringptr, &acl_smtp_quit },
160 { "acl_smtp_rcpt", opt_stringptr, &acl_smtp_rcpt },
162 { "acl_smtp_starttls", opt_stringptr, &acl_smtp_starttls },
164 { "acl_smtp_vrfy", opt_stringptr, &acl_smtp_vrfy },
165 { "admin_groups", opt_gidlist, &admin_groups },
166 { "allow_domain_literals", opt_bool, &allow_domain_literals },
167 { "allow_mx_to_ip", opt_bool, &allow_mx_to_ip },
168 { "allow_utf8_domains", opt_bool, &allow_utf8_domains },
169 { "auth_advertise_hosts", opt_stringptr, &auth_advertise_hosts },
170 { "auto_thaw", opt_time, &auto_thaw },
171 #ifdef WITH_CONTENT_SCAN
172 { "av_scanner", opt_stringptr, &av_scanner },
174 { "bi_command", opt_stringptr, &bi_command },
175 #ifdef EXPERIMENTAL_BRIGHTMAIL
176 { "bmi_config_file", opt_stringptr, &bmi_config_file },
178 { "bounce_message_file", opt_stringptr, &bounce_message_file },
179 { "bounce_message_text", opt_stringptr, &bounce_message_text },
180 { "bounce_return_body", opt_bool, &bounce_return_body },
181 { "bounce_return_message", opt_bool, &bounce_return_message },
182 { "bounce_return_size_limit", opt_mkint, &bounce_return_size_limit },
183 { "bounce_sender_authentication",opt_stringptr,&bounce_sender_authentication },
184 { "callout_domain_negative_expire", opt_time, &callout_cache_domain_negative_expire },
185 { "callout_domain_positive_expire", opt_time, &callout_cache_domain_positive_expire },
186 { "callout_negative_expire", opt_time, &callout_cache_negative_expire },
187 { "callout_positive_expire", opt_time, &callout_cache_positive_expire },
188 { "callout_random_local_part",opt_stringptr, &callout_random_local_part },
189 { "check_log_inodes", opt_int, &check_log_inodes },
190 { "check_log_space", opt_Kint, &check_log_space },
191 { "check_rfc2047_length", opt_bool, &check_rfc2047_length },
192 { "check_spool_inodes", opt_int, &check_spool_inodes },
193 { "check_spool_space", opt_Kint, &check_spool_space },
194 { "daemon_smtp_port", opt_stringptr|opt_hidden, &daemon_smtp_port },
195 { "daemon_smtp_ports", opt_stringptr, &daemon_smtp_port },
196 { "daemon_startup_retries", opt_int, &daemon_startup_retries },
197 { "daemon_startup_sleep", opt_time, &daemon_startup_sleep },
198 #ifdef EXPERIMENTAL_DCC
199 { "dcc_direct_add_header", opt_bool, &dcc_direct_add_header },
200 { "dccifd_address", opt_stringptr, &dccifd_address },
201 { "dccifd_options", opt_stringptr, &dccifd_options },
203 { "delay_warning", opt_timelist, &delay_warning },
204 { "delay_warning_condition", opt_stringptr, &delay_warning_condition },
205 { "deliver_drop_privilege", opt_bool, &deliver_drop_privilege },
206 { "deliver_queue_load_max", opt_fixed, &deliver_queue_load_max },
207 { "delivery_date_remove", opt_bool, &delivery_date_remove },
208 #ifdef ENABLE_DISABLE_FSYNC
209 { "disable_fsync", opt_bool, &disable_fsync },
211 { "disable_ipv6", opt_bool, &disable_ipv6 },
213 { "dkim_verify_signers", opt_stringptr, &dkim_verify_signers },
215 #ifdef EXPERIMENTAL_DMARC
216 { "dmarc_forensic_sender", opt_stringptr, &dmarc_forensic_sender },
217 { "dmarc_history_file", opt_stringptr, &dmarc_history_file },
218 { "dmarc_tld_file", opt_stringptr, &dmarc_tld_file },
220 { "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist },
221 { "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern },
222 { "dns_csa_search_limit", opt_int, &dns_csa_search_limit },
223 { "dns_csa_use_reverse", opt_bool, &dns_csa_use_reverse },
224 { "dns_dnssec_ok", opt_int, &dns_dnssec_ok },
225 { "dns_ipv4_lookup", opt_stringptr, &dns_ipv4_lookup },
226 { "dns_retrans", opt_time, &dns_retrans },
227 { "dns_retry", opt_int, &dns_retry },
228 { "dns_use_edns0", opt_int, &dns_use_edns0 },
229 /* This option is now a no-op, retained for compability */
230 { "drop_cr", opt_bool, &drop_cr },
231 /*********************************************************/
232 { "dsn_advertise_hosts", opt_stringptr, &dsn_advertise_hosts },
233 { "dsn_from", opt_stringptr, &dsn_from },
234 { "envelope_to_remove", opt_bool, &envelope_to_remove },
235 { "errors_copy", opt_stringptr, &errors_copy },
236 { "errors_reply_to", opt_stringptr, &errors_reply_to },
237 #ifdef EXPERIMENTAL_EVENT
238 { "event_action", opt_stringptr, &event_action },
240 { "exim_group", opt_gid, &exim_gid },
241 { "exim_path", opt_stringptr, &exim_path },
242 { "exim_user", opt_uid, &exim_uid },
243 { "extra_local_interfaces", opt_stringptr, &extra_local_interfaces },
244 { "extract_addresses_remove_arguments", opt_bool, &extract_addresses_remove_arguments },
245 { "finduser_retries", opt_int, &finduser_retries },
246 { "freeze_tell", opt_stringptr, &freeze_tell },
247 { "gecos_name", opt_stringptr, &gecos_name },
248 { "gecos_pattern", opt_stringptr, &gecos_pattern },
250 { "gnutls_allow_auto_pkcs11", opt_bool, &gnutls_allow_auto_pkcs11 },
251 { "gnutls_compat_mode", opt_bool, &gnutls_compat_mode },
252 /* These three gnutls_require_* options stopped working in Exim 4.80 */
253 /* From 4.83 we log a warning; a future relase will remove them */
254 { "gnutls_require_kx", opt_stringptr, &gnutls_require_kx },
255 { "gnutls_require_mac", opt_stringptr, &gnutls_require_mac },
256 { "gnutls_require_protocols", opt_stringptr, &gnutls_require_proto },
258 { "header_line_maxsize", opt_int, &header_line_maxsize },
259 { "header_maxsize", opt_int, &header_maxsize },
260 { "headers_charset", opt_stringptr, &headers_charset },
261 { "helo_accept_junk_hosts", opt_stringptr, &helo_accept_junk_hosts },
262 { "helo_allow_chars", opt_stringptr, &helo_allow_chars },
263 { "helo_lookup_domains", opt_stringptr, &helo_lookup_domains },
264 { "helo_try_verify_hosts", opt_stringptr, &helo_try_verify_hosts },
265 { "helo_verify_hosts", opt_stringptr, &helo_verify_hosts },
266 { "hold_domains", opt_stringptr, &hold_domains },
267 { "host_lookup", opt_stringptr, &host_lookup },
268 { "host_lookup_order", opt_stringptr, &host_lookup_order },
269 { "host_reject_connection", opt_stringptr, &host_reject_connection },
270 { "hosts_connection_nolog", opt_stringptr, &hosts_connection_nolog },
271 { "hosts_treat_as_local", opt_stringptr, &hosts_treat_as_local },
273 { "ibase_servers", opt_stringptr, &ibase_servers },
275 { "ignore_bounce_errors_after", opt_time, &ignore_bounce_errors_after },
276 { "ignore_fromline_hosts", opt_stringptr, &ignore_fromline_hosts },
277 { "ignore_fromline_local", opt_bool, &ignore_fromline_local },
278 { "keep_malformed", opt_time, &keep_malformed },
280 { "ldap_ca_cert_dir", opt_stringptr, &eldap_ca_cert_dir },
281 { "ldap_ca_cert_file", opt_stringptr, &eldap_ca_cert_file },
282 { "ldap_cert_file", opt_stringptr, &eldap_cert_file },
283 { "ldap_cert_key", opt_stringptr, &eldap_cert_key },
284 { "ldap_cipher_suite", opt_stringptr, &eldap_cipher_suite },
285 { "ldap_default_servers", opt_stringptr, &eldap_default_servers },
286 { "ldap_require_cert", opt_stringptr, &eldap_require_cert },
287 { "ldap_start_tls", opt_bool, &eldap_start_tls },
288 { "ldap_version", opt_int, &eldap_version },
290 { "local_from_check", opt_bool, &local_from_check },
291 { "local_from_prefix", opt_stringptr, &local_from_prefix },
292 { "local_from_suffix", opt_stringptr, &local_from_suffix },
293 { "local_interfaces", opt_stringptr, &local_interfaces },
294 { "local_scan_timeout", opt_time, &local_scan_timeout },
295 { "local_sender_retain", opt_bool, &local_sender_retain },
296 { "localhost_number", opt_stringptr, &host_number_string },
297 { "log_file_path", opt_stringptr, &log_file_path },
298 { "log_selector", opt_stringptr, &log_selector_string },
299 { "log_timezone", opt_bool, &log_timezone },
300 { "lookup_open_max", opt_int, &lookup_open_max },
301 { "max_username_length", opt_int, &max_username_length },
302 { "message_body_newlines", opt_bool, &message_body_newlines },
303 { "message_body_visible", opt_mkint, &message_body_visible },
304 { "message_id_header_domain", opt_stringptr, &message_id_domain },
305 { "message_id_header_text", opt_stringptr, &message_id_text },
306 { "message_logs", opt_bool, &message_logs },
307 { "message_size_limit", opt_stringptr, &message_size_limit },
308 #ifdef SUPPORT_MOVE_FROZEN_MESSAGES
309 { "move_frozen_messages", opt_bool, &move_frozen_messages },
311 { "mua_wrapper", opt_bool, &mua_wrapper },
313 { "mysql_servers", opt_stringptr, &mysql_servers },
315 { "never_users", opt_uidlist, &never_users },
317 { "openssl_options", opt_stringptr, &openssl_options },
320 { "oracle_servers", opt_stringptr, &oracle_servers },
322 { "percent_hack_domains", opt_stringptr, &percent_hack_domains },
324 { "perl_at_start", opt_bool, &opt_perl_at_start },
325 { "perl_startup", opt_stringptr, &opt_perl_startup },
328 { "pgsql_servers", opt_stringptr, &pgsql_servers },
330 { "pid_file_path", opt_stringptr, &pid_file_path },
331 { "pipelining_advertise_hosts", opt_stringptr, &pipelining_advertise_hosts },
333 { "prdr_enable", opt_bool, &prdr_enable },
335 { "preserve_message_logs", opt_bool, &preserve_message_logs },
336 { "primary_hostname", opt_stringptr, &primary_hostname },
337 { "print_topbitchars", opt_bool, &print_topbitchars },
338 { "process_log_path", opt_stringptr, &process_log_path },
339 { "prod_requires_admin", opt_bool, &prod_requires_admin },
340 #ifdef EXPERIMENTAL_PROXY
341 { "proxy_required_hosts", opt_stringptr, &proxy_required_hosts },
343 { "qualify_domain", opt_stringptr, &qualify_domain_sender },
344 { "qualify_recipient", opt_stringptr, &qualify_domain_recipient },
345 { "queue_domains", opt_stringptr, &queue_domains },
346 { "queue_list_requires_admin",opt_bool, &queue_list_requires_admin },
347 { "queue_only", opt_bool, &queue_only },
348 { "queue_only_file", opt_stringptr, &queue_only_file },
349 { "queue_only_load", opt_fixed, &queue_only_load },
350 { "queue_only_load_latch", opt_bool, &queue_only_load_latch },
351 { "queue_only_override", opt_bool, &queue_only_override },
352 { "queue_run_in_order", opt_bool, &queue_run_in_order },
353 { "queue_run_max", opt_int, &queue_run_max },
354 { "queue_smtp_domains", opt_stringptr, &queue_smtp_domains },
355 { "receive_timeout", opt_time, &receive_timeout },
356 { "received_header_text", opt_stringptr, &received_header_text },
357 { "received_headers_max", opt_int, &received_headers_max },
358 { "recipient_unqualified_hosts", opt_stringptr, &recipient_unqualified_hosts },
359 { "recipients_max", opt_int, &recipients_max },
360 { "recipients_max_reject", opt_bool, &recipients_max_reject },
361 #ifdef EXPERIMENTAL_REDIS
362 { "redis_servers", opt_stringptr, &redis_servers },
364 { "remote_max_parallel", opt_int, &remote_max_parallel },
365 { "remote_sort_domains", opt_stringptr, &remote_sort_domains },
366 { "retry_data_expire", opt_time, &retry_data_expire },
367 { "retry_interval_max", opt_time, &retry_interval_max },
368 { "return_path_remove", opt_bool, &return_path_remove },
369 { "return_size_limit", opt_mkint|opt_hidden, &bounce_return_size_limit },
370 { "rfc1413_hosts", opt_stringptr, &rfc1413_hosts },
371 { "rfc1413_query_timeout", opt_time, &rfc1413_query_timeout },
372 { "sender_unqualified_hosts", opt_stringptr, &sender_unqualified_hosts },
373 { "smtp_accept_keepalive", opt_bool, &smtp_accept_keepalive },
374 { "smtp_accept_max", opt_int, &smtp_accept_max },
375 { "smtp_accept_max_nonmail", opt_int, &smtp_accept_max_nonmail },
376 { "smtp_accept_max_nonmail_hosts", opt_stringptr, &smtp_accept_max_nonmail_hosts },
377 { "smtp_accept_max_per_connection", opt_int, &smtp_accept_max_per_connection },
378 { "smtp_accept_max_per_host", opt_stringptr, &smtp_accept_max_per_host },
379 { "smtp_accept_queue", opt_int, &smtp_accept_queue },
380 { "smtp_accept_queue_per_connection", opt_int, &smtp_accept_queue_per_connection },
381 { "smtp_accept_reserve", opt_int, &smtp_accept_reserve },
382 { "smtp_active_hostname", opt_stringptr, &raw_active_hostname },
383 { "smtp_banner", opt_stringptr, &smtp_banner },
384 { "smtp_check_spool_space", opt_bool, &smtp_check_spool_space },
385 { "smtp_connect_backlog", opt_int, &smtp_connect_backlog },
386 { "smtp_enforce_sync", opt_bool, &smtp_enforce_sync },
387 { "smtp_etrn_command", opt_stringptr, &smtp_etrn_command },
388 { "smtp_etrn_serialize", opt_bool, &smtp_etrn_serialize },
389 { "smtp_load_reserve", opt_fixed, &smtp_load_reserve },
390 { "smtp_max_synprot_errors", opt_int, &smtp_max_synprot_errors },
391 { "smtp_max_unknown_commands",opt_int, &smtp_max_unknown_commands },
392 { "smtp_ratelimit_hosts", opt_stringptr, &smtp_ratelimit_hosts },
393 { "smtp_ratelimit_mail", opt_stringptr, &smtp_ratelimit_mail },
394 { "smtp_ratelimit_rcpt", opt_stringptr, &smtp_ratelimit_rcpt },
395 { "smtp_receive_timeout", opt_time, &smtp_receive_timeout },
396 { "smtp_reserve_hosts", opt_stringptr, &smtp_reserve_hosts },
397 { "smtp_return_error_details",opt_bool, &smtp_return_error_details },
398 #ifdef WITH_CONTENT_SCAN
399 { "spamd_address", opt_stringptr, &spamd_address },
401 #ifdef EXPERIMENTAL_SPF
402 { "spf_guess", opt_stringptr, &spf_guess },
404 { "split_spool_directory", opt_bool, &split_spool_directory },
405 { "spool_directory", opt_stringptr, &spool_directory },
407 { "sqlite_lock_timeout", opt_int, &sqlite_lock_timeout },
409 #ifdef EXPERIMENTAL_SRS
410 { "srs_config", opt_stringptr, &srs_config },
411 { "srs_hashlength", opt_int, &srs_hashlength },
412 { "srs_hashmin", opt_int, &srs_hashmin },
413 { "srs_maxage", opt_int, &srs_maxage },
414 { "srs_secrets", opt_stringptr, &srs_secrets },
415 { "srs_usehash", opt_bool, &srs_usehash },
416 { "srs_usetimestamp", opt_bool, &srs_usetimestamp },
418 { "strict_acl_vars", opt_bool, &strict_acl_vars },
419 { "strip_excess_angle_brackets", opt_bool, &strip_excess_angle_brackets },
420 { "strip_trailing_dot", opt_bool, &strip_trailing_dot },
421 { "syslog_duplication", opt_bool, &syslog_duplication },
422 { "syslog_facility", opt_stringptr, &syslog_facility_str },
423 { "syslog_processname", opt_stringptr, &syslog_processname },
424 { "syslog_timestamp", opt_bool, &syslog_timestamp },
425 { "system_filter", opt_stringptr, &system_filter },
426 { "system_filter_directory_transport", opt_stringptr,&system_filter_directory_transport },
427 { "system_filter_file_transport",opt_stringptr,&system_filter_file_transport },
428 { "system_filter_group", opt_gid, &system_filter_gid },
429 { "system_filter_pipe_transport",opt_stringptr,&system_filter_pipe_transport },
430 { "system_filter_reply_transport",opt_stringptr,&system_filter_reply_transport },
431 { "system_filter_user", opt_uid, &system_filter_uid },
432 { "tcp_nodelay", opt_bool, &tcp_nodelay },
433 #ifdef USE_TCP_WRAPPERS
434 { "tcp_wrappers_daemon_name", opt_stringptr, &tcp_wrappers_daemon_name },
436 { "timeout_frozen_after", opt_time, &timeout_frozen_after },
437 { "timezone", opt_stringptr, &timezone_string },
439 { "tls_advertise_hosts", opt_stringptr, &tls_advertise_hosts },
440 { "tls_certificate", opt_stringptr, &tls_certificate },
441 { "tls_crl", opt_stringptr, &tls_crl },
442 { "tls_dh_max_bits", opt_int, &tls_dh_max_bits },
443 { "tls_dhparam", opt_stringptr, &tls_dhparam },
444 # ifndef DISABLE_OCSP
445 { "tls_ocsp_file", opt_stringptr, &tls_ocsp_file },
447 { "tls_on_connect_ports", opt_stringptr, &tls_in.on_connect_ports },
448 { "tls_privatekey", opt_stringptr, &tls_privatekey },
449 { "tls_remember_esmtp", opt_bool, &tls_remember_esmtp },
450 { "tls_require_ciphers", opt_stringptr, &tls_require_ciphers },
451 { "tls_try_verify_hosts", opt_stringptr, &tls_try_verify_hosts },
452 { "tls_verify_certificates", opt_stringptr, &tls_verify_certificates },
453 { "tls_verify_hosts", opt_stringptr, &tls_verify_hosts },
455 { "trusted_groups", opt_gidlist, &trusted_groups },
456 { "trusted_users", opt_uidlist, &trusted_users },
457 { "unknown_login", opt_stringptr, &unknown_login },
458 { "unknown_username", opt_stringptr, &unknown_username },
459 { "untrusted_set_sender", opt_stringptr, &untrusted_set_sender },
460 { "uucp_from_pattern", opt_stringptr, &uucp_from_pattern },
461 { "uucp_from_sender", opt_stringptr, &uucp_from_sender },
462 { "warn_message_file", opt_stringptr, &warn_message_file },
463 { "write_rejectlog", opt_bool, &write_rejectlog }
466 static int optionlist_config_size =
467 sizeof(optionlist_config)/sizeof(optionlist);
471 /*************************************************
472 * Find the name of an option *
473 *************************************************/
475 /* This function is to aid debugging. Various functions take arguments that are
476 pointer variables in the options table or in option tables for various drivers.
477 For debugging output, it is useful to be able to find the name of the option
478 which is currently being processed. This function finds it, if it exists, by
479 searching the table(s).
481 Arguments: a value that is presumed to be in the table above
482 Returns: the option name, or an empty string
486 readconf_find_option(void *p)
490 transport_instance *t;
492 for (i = 0; i < optionlist_config_size; i++)
493 if (p == optionlist_config[i].value) return US optionlist_config[i].name;
495 for (r = routers; r != NULL; r = r->next)
497 router_info *ri = r->info;
498 for (i = 0; i < *ri->options_count; i++)
500 if ((ri->options[i].type & opt_mask) != opt_stringptr) continue;
501 if (p == (char *)(r->options_block) + (long int)(ri->options[i].value))
502 return US ri->options[i].name;
506 for (t = transports; t != NULL; t = t->next)
508 transport_info *ti = t->info;
509 for (i = 0; i < *ti->options_count; i++)
511 optionlist * op = &ti->options[i];
512 if ((op->type & opt_mask) != opt_stringptr) continue;
513 if (p == ( op->type & opt_public
515 : (char *)t->options_block
517 + (long int)op->value)
528 /*************************************************
529 * Deal with an assignment to a macro *
530 *************************************************/
532 /* This function is called when a line that starts with an upper case letter is
533 encountered. The argument "line" should contain a complete logical line, and
534 start with the first letter of the macro name. The macro name and the
535 replacement text are extracted and stored. Redefinition of existing,
536 non-command line, macros is permitted using '==' instead of '='.
539 s points to the start of the logical line
545 read_macro_assignment(uschar *s)
551 macro_item *mlast = NULL;
553 while (isalnum(*s) || *s == '_')
555 if (namelen >= sizeof(name) - 1)
556 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
557 "macro name too long (maximum is " SIZE_T_FMT " characters)", sizeof(name) - 1);
558 name[namelen++] = *s++;
562 while (isspace(*s)) s++;
564 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "malformed macro definition");
571 while (isspace(*s)) s++;
573 /* If an existing macro of the same name was defined on the command line, we
574 just skip this definition. It's an error to attempt to redefine a macro without
575 redef set to TRUE, or to redefine a macro when it hasn't been defined earlier.
576 It is also an error to define a macro whose name begins with the name of a
577 previously defined macro. Note: it is documented that the other way round
580 for (m = macros; m != NULL; m = m->next)
582 int len = Ustrlen(m->name);
584 if (Ustrcmp(m->name, name) == 0)
586 if (!m->command_line && !redef)
587 log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "macro \"%s\" is already "
588 "defined (use \"==\" if you want to redefine it", name);
592 if (len < namelen && Ustrstr(name, m->name) != NULL)
593 log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
594 "a macro because previously defined macro \"%s\" is a substring",
597 /* We cannot have this test, because it is documented that a substring
598 macro is permitted (there is even an example).
600 * if (len > namelen && Ustrstr(m->name, name) != NULL)
601 * log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "\"%s\" cannot be defined as "
602 * "a macro because it is a substring of previously defined macro \"%s\"",
609 /* Check for an overriding command-line definition. */
611 if (m != NULL && m->command_line) return;
613 /* Redefinition must refer to an existing macro. */
618 log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "can't redefine an undefined macro "
622 /* We have a new definition. The macro_item structure includes a final vector
623 called "name" which is one byte long. Thus, adding "namelen" gives us enough
624 room to store the "name" string. */
628 m = store_get(sizeof(macro_item) + namelen);
629 if (macros == NULL) macros = m; else mlast->next = m;
630 Ustrncpy(m->name, name, namelen);
631 m->name[namelen] = 0;
633 m->command_line = FALSE;
636 /* Set the value of the new or redefined macro */
638 m->replacement = string_copy(s);
645 /*************************************************
646 * Read configuration line *
647 *************************************************/
649 /* A logical line of text is read from the configuration file into the big
650 buffer, taking account of macros, .includes, and continuations. The size of
651 big_buffer is increased if necessary. The count of configuration lines is
652 maintained. Physical input lines starting with # (ignoring leading white space,
653 and after macro replacement) and empty logical lines are always ignored.
654 Leading and trailing spaces are removed.
656 If we hit a line of the form "begin xxxx", the xxxx is placed in the
657 next_section vector, and the function returns NULL, indicating the end of a
658 configuration section. On end-of-file, NULL is returned with next_section
663 Returns: a pointer to the first non-blank in the line,
664 or NULL if eof or end of section is reached
668 get_config_line(void)
670 int startoffset = 0; /* To first non-blank char in logical line */
671 int len = 0; /* Of logical line so far */
677 /* Loop for handling continuation lines, skipping comments, and dealing with
682 if (Ufgets(big_buffer+len, big_buffer_size-len, config_file) == NULL)
684 if (config_file_stack != NULL) /* EOF inside .include */
686 (void)fclose(config_file);
687 config_file = config_file_stack->file;
688 config_filename = config_file_stack->filename;
689 config_lineno = config_file_stack->lineno;
690 config_file_stack = config_file_stack->next;
694 /* EOF at top level */
696 if (cstate_stack_ptr >= 0)
697 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
698 "Unexpected end of configuration file: .endif missing");
700 if (len != 0) break; /* EOF after continuation */
701 next_section[0] = 0; /* EOF at start of logical line */
706 newlen = len + Ustrlen(big_buffer + len);
708 /* Handle pathologically long physical lines - yes, it did happen - by
709 extending big_buffer at this point. The code also copes with very long
712 while (newlen == big_buffer_size - 1 && big_buffer[newlen - 1] != '\n')
715 big_buffer_size += BIG_BUFFER_SIZE;
716 newbuffer = store_malloc(big_buffer_size);
718 /* This use of strcpy is OK because we know that the string in the old
719 buffer is shorter than the new buffer. */
721 Ustrcpy(newbuffer, big_buffer);
722 store_free(big_buffer);
723 big_buffer = newbuffer;
724 if (Ufgets(big_buffer+newlen, big_buffer_size-newlen, config_file) == NULL)
726 newlen += Ustrlen(big_buffer + newlen);
729 /* Find the true start of the physical line - leading spaces are always
732 ss = big_buffer + len;
733 while (isspace(*ss)) ss++;
735 /* Process the physical line for macros. If this is the start of the logical
736 line, skip over initial text at the start of the line if it starts with an
737 upper case character followed by a sequence of name characters and an equals
738 sign, because that is the definition of a new macro, and we don't do
739 replacement therein. */
742 if (len == 0 && isupper(*s))
744 while (isalnum(*s) || *s == '_') s++;
745 while (isspace(*s)) s++;
746 if (*s != '=') s = ss; /* Not a macro definition */
749 /* For each defined macro, scan the line (from after XXX= if present),
750 replacing all occurrences of the macro. */
753 for (m = macros; m != NULL; m = m->next)
758 while ((p = Ustrstr(t, m->name)) != NULL)
761 int namelen = Ustrlen(m->name);
762 int replen = Ustrlen(m->replacement);
764 /* Expand the buffer if necessary */
766 while (newlen - namelen + replen + 1 > big_buffer_size)
768 int newsize = big_buffer_size + BIG_BUFFER_SIZE;
769 uschar *newbuffer = store_malloc(newsize);
770 memcpy(newbuffer, big_buffer, newlen + 1);
771 p = newbuffer + (p - big_buffer);
772 s = newbuffer + (s - big_buffer);
773 ss = newbuffer + (ss - big_buffer);
774 t = newbuffer + (t - big_buffer);
775 big_buffer_size = newsize;
776 store_free(big_buffer);
777 big_buffer = newbuffer;
780 /* Shuffle the remaining characters up or down in the buffer before
781 copying in the replacement text. Don't rescan the replacement for this
785 moveby = replen - namelen;
788 memmove(p + replen, pp, (big_buffer + newlen) - pp + 1);
791 Ustrncpy(p, m->replacement, replen);
797 /* An empty macro replacement at the start of a line could mean that ss no
798 longer points to the first non-blank character. */
800 while (isspace(*ss)) ss++;
802 /* Check for comment lines - these are physical lines. */
804 if (*ss == '#') continue;
806 /* Handle conditionals, which are also applied to physical lines. Conditions
807 are of the form ".ifdef ANYTEXT" and are treated as true if any macro
808 expansion occured on the rest of the line. A preliminary test for the leading
809 '.' saves effort on most lines. */
815 /* Search the list of conditional directives */
817 for (i = 0; i < cond_list_size; i++)
820 cond_item *c = cond_list+i;
821 if (Ustrncmp(ss+1, c->name, c->namelen) != 0) continue;
823 /* The following character must be white space or end of string */
825 n = ss[1 + c->namelen];
826 if (n != ' ' && n != 't' && n != '\n' && n != 0) break;
828 /* .ifdef and .ifndef push the current state onto the stack, then set
829 a new one from the table. Stack overflow is an error */
833 if (cstate_stack_ptr >= CSTATE_STACK_SIZE - 1)
834 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
835 ".%s nested too deeply", c->name);
836 cstate_stack[++cstate_stack_ptr] = cstate;
837 cstate = next_cstate[cstate][macro_found? c->action1 : c->action2];
840 /* For any of the others, stack underflow is an error. The next state
841 comes either from the stack (.endif) or from the table. */
845 if (cstate_stack_ptr < 0)
846 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
847 ".%s without matching .ifdef", c->name);
848 cstate = (c->pushpop < 0)? cstate_stack[cstate_stack_ptr--] :
849 next_cstate[cstate][macro_found? c->action1 : c->action2];
852 /* Having dealt with a directive, break the loop */
857 /* If we have handled a conditional directive, continue with the next
858 physical line. Otherwise, fall through. */
860 if (i < cond_list_size) continue;
863 /* If the conditional state is not 0 (actively using these lines), ignore
866 if (cstate != 0) continue; /* Conditional skip */
868 /* Handle .include lines - these are also physical lines. */
870 if (Ustrncmp(ss, ".include", 8) == 0 &&
872 (Ustrncmp(ss+8, "_if_exists", 10) == 0 && isspace(ss[18]))))
875 int include_if_exists = isspace(ss[8])? 0 : 10;
876 config_file_item *save;
879 ss += 9 + include_if_exists;
880 while (isspace(*ss)) ss++;
881 t = ss + Ustrlen(ss);
882 while (t > ss && isspace(t[-1])) t--;
883 if (*ss == '\"' && t[-1] == '\"')
891 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, ".include specifies a non-"
892 "absolute path \"%s\"", ss);
894 if (include_if_exists != 0 && (Ustat(ss, &statbuf) != 0)) continue;
896 save = store_get(sizeof(config_file_item));
897 save->next = config_file_stack;
898 config_file_stack = save;
899 save->file = config_file;
900 save->filename = config_filename;
901 save->lineno = config_lineno;
903 config_file = Ufopen(ss, "rb");
904 if (config_file == NULL)
905 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to open included "
906 "configuration file %s", ss);
907 config_filename = string_copy(ss);
912 /* If this is the start of the logical line, remember where the non-blank
913 data starts. Otherwise shuffle down continuation lines to remove leading
917 startoffset = ss - big_buffer;
920 s = big_buffer + len;
923 memmove(s, ss, (newlen - len) - (ss - s) + 1);
928 /* Accept the new addition to the line. Remove trailing white space. */
931 while (len > 0 && isspace(big_buffer[len-1])) len--;
934 /* We are done if the line does not end in backslash and contains some data.
935 Empty logical lines are ignored. For continuations, remove the backslash and
936 go round the loop to read the continuation line. */
940 if (big_buffer[len-1] != '\\') break; /* End of logical line */
941 big_buffer[--len] = 0; /* Remove backslash */
943 } /* Loop for reading multiple physical lines */
945 /* We now have a logical line. Test for the end of a configuration section (or,
946 more accurately, for the start of the next section). Place the name of the next
947 section in next_section, and return NULL. If the name given is longer than
948 next_section, truncate it. It will be unrecognized later, because all the known
949 section names do fit. Leave space for pluralizing. */
951 s = big_buffer + startoffset; /* First non-space character */
952 if (strncmpic(s, US"begin ", 6) == 0)
955 while (isspace(*s)) s++;
956 if (big_buffer + len - s > sizeof(next_section) - 2)
957 s[sizeof(next_section) - 2] = 0;
958 Ustrcpy(next_section, s);
962 /* Return the first non-blank character. */
969 /*************************************************
971 *************************************************/
973 /* The yield is the pointer to the next uschar. Names longer than the
974 output space are silently truncated. This function is also used from acl.c when
978 name where to put the name
982 Returns: new input pointer
986 readconf_readname(uschar *name, int len, uschar *s)
989 while (isspace(*s)) s++;
992 while (isalnum(*s) || *s == '_')
994 if (p < len-1) name[p++] = *s;
999 while (isspace(*s)) s++;
1006 /*************************************************
1007 * Read a time value *
1008 *************************************************/
1010 /* This function is also called from outside, to read argument
1011 time values. The format of a time value is:
1013 [<n>w][<n>d][<n>h][<n>m][<n>s]
1015 as long as at least one is present. If a format error is encountered,
1016 return a negative value. The value must be terminated by the given
1021 terminator required terminating character
1022 return_msec if TRUE, allow fractional seconds and return milliseconds
1024 Returns: the time value, or -1 on syntax error
1025 value is seconds if return_msec is FALSE
1026 value is milliseconds if return_msec is TRUE
1030 readconf_readtime(uschar *s, int terminator, BOOL return_msec)
1038 if (!isdigit(*s)) return -1;
1039 (void)sscanf(CS s, "%d%n", &value, &count);
1044 case 'w': value *= 7;
1045 case 'd': value *= 24;
1046 case 'h': value *= 60;
1047 case 'm': value *= 60;
1052 if (!return_msec) return -1;
1053 (void)sscanf(CS s, "%lf%n", &fraction, &count);
1055 if (*s++ != 's') return -1;
1056 yield += (int)(fraction * 1000.0);
1062 if (return_msec) value *= 1000;
1064 if (*s == terminator) return yield;
1066 /* Control never reaches here. */
1071 /*************************************************
1072 * Read a fixed point value *
1073 *************************************************/
1075 /* The value is returned *1000
1079 terminator required terminator
1081 Returns: the value, or -1 on error
1085 readconf_readfixed(uschar *s, int terminator)
1089 if (!isdigit(*s)) return -1;
1090 (void)sscanf(CS s, "%d%n", &value, &count);
1092 yield = value * 1000;
1096 while (isdigit((*(++s))))
1098 yield += (*s - '0') * m;
1103 return (*s == terminator)? yield : (-1);
1108 /*************************************************
1109 * Find option in list *
1110 *************************************************/
1112 /* The lists are always in order, so binary chop can be used.
1115 name the option name to search for
1116 ol the first entry in the option list
1117 last one more than the offset of the last entry in the option list
1119 Returns: pointer to an option entry, or NULL if not found
1123 find_option(uschar *name, optionlist *ol, int last)
1126 while (last > first)
1128 int middle = (first + last)/2;
1129 int c = Ustrcmp(name, ol[middle].name);
1130 if (c == 0) return ol + middle;
1131 else if (c > 0) first = middle + 1;
1139 /*************************************************
1140 * Find a set flag in option list *
1141 *************************************************/
1143 /* Because some versions of Unix make no restrictions on the values of uids and
1144 gids (even negative ones), we cannot represent "unset" by a special value.
1145 There is therefore a separate boolean variable for each one indicating whether
1146 a value is set or not. This function returns a pointer to the boolean, given
1147 the original option name. It is a major disaster if the flag cannot be found.
1150 name the name of the uid or gid option
1151 oltop points to the start of the relevant option list
1152 last one more than the offset of the last item in the option list
1153 data_block NULL when reading main options => data values in the option
1154 list are absolute addresses; otherwise they are byte offsets
1155 in data_block (used for driver options)
1157 Returns: a pointer to the boolean flag.
1161 get_set_flag(uschar *name, optionlist *oltop, int last, void *data_block)
1165 sprintf(CS name2, "*set_%.50s", name);
1166 ol = find_option(name2, oltop, last);
1167 if (ol == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1168 "Exim internal error: missing set flag for %s", name);
1169 return (data_block == NULL)? (BOOL *)(ol->value) :
1170 (BOOL *)((uschar *)data_block + (long int)(ol->value));
1176 /*************************************************
1177 * Output extra characters message and die *
1178 *************************************************/
1180 /* Called when an option line has junk on the end. Sometimes this is because
1181 the sysadmin thinks comments are permitted.
1184 s points to the extra characters
1185 t1..t3 strings to insert in the log message
1187 Returns: doesn't return; dies
1191 extra_chars_error(uschar *s, uschar *t1, uschar *t2, uschar *t3)
1193 uschar *comment = US"";
1194 if (*s == '#') comment = US" (# is comment only at line start)";
1195 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1196 "extra characters follow %s%s%s%s", t1, t2, t3, comment);
1201 /*************************************************
1202 * Read rewrite information *
1203 *************************************************/
1205 /* Each line of rewrite information contains:
1207 . A complete address in the form user@domain, possibly with
1208 leading * for each part; or alternatively, a regex.
1210 . A replacement string (which will be expanded).
1212 . An optional sequence of one-letter flags, indicating which
1213 headers etc. to apply this rule to.
1215 All this is decoded and placed into a control block. The OR of the flags is
1216 maintained in a common word.
1219 p points to the string that makes up the rule
1220 existflags points to the overall flag word
1221 isglobal TRUE if reading global rewrite rules
1223 Returns: the control block for the parsed rule.
1226 static rewrite_rule *
1227 readconf_one_rewrite(uschar *p, int *existflags, BOOL isglobal)
1229 rewrite_rule *next = store_get(sizeof(rewrite_rule));
1232 next->key = string_dequote(&p);
1234 while (isspace(*p)) p++;
1236 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1237 "missing rewrite replacement string");
1240 next->replacement = string_dequote(&p);
1242 while (*p != 0) switch (*p++)
1244 case ' ': case '\t': break;
1246 case 'q': next->flags |= rewrite_quit; break;
1247 case 'w': next->flags |= rewrite_whole; break;
1249 case 'h': next->flags |= rewrite_all_headers; break;
1250 case 's': next->flags |= rewrite_sender; break;
1251 case 'f': next->flags |= rewrite_from; break;
1252 case 't': next->flags |= rewrite_to; break;
1253 case 'c': next->flags |= rewrite_cc; break;
1254 case 'b': next->flags |= rewrite_bcc; break;
1255 case 'r': next->flags |= rewrite_replyto; break;
1257 case 'E': next->flags |= rewrite_all_envelope; break;
1258 case 'F': next->flags |= rewrite_envfrom; break;
1259 case 'T': next->flags |= rewrite_envto; break;
1261 case 'Q': next->flags |= rewrite_qualify; break;
1262 case 'R': next->flags |= rewrite_repeat; break;
1265 next->flags |= rewrite_smtp;
1266 if (next->key[0] != '^' && Ustrncmp(next->key, "\\N^", 3) != 0)
1267 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1268 "rewrite rule has the S flag but is not a regular expression");
1272 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1273 "unknown rewrite flag character '%c' "
1274 "(could be missing quotes round replacement item)", p[-1]);
1278 /* If no action flags are set, set all the "normal" rewrites. */
1280 if ((next->flags & (rewrite_all | rewrite_smtp)) == 0)
1281 next->flags |= isglobal? rewrite_all : rewrite_all_headers;
1283 /* Remember which exist, for optimization, and return the rule */
1285 *existflags |= next->flags;
1292 /*************************************************
1293 * Read global rewrite information *
1294 *************************************************/
1296 /* Each line is a single rewrite rule; it is parsed into a control block
1297 by readconf_one_rewrite(), and its flags are ORed into the global flag
1298 word rewrite_existflags. */
1301 readconf_rewrites(void)
1303 rewrite_rule **chain = &global_rewrite_rules;
1306 while ((p = get_config_line()) != NULL)
1308 rewrite_rule *next = readconf_one_rewrite(p, &rewrite_existflags, TRUE);
1310 chain = &(next->next);
1316 /*************************************************
1318 *************************************************/
1320 /* Strings are read into the normal store pool. As long we aren't too
1321 near the end of the current block, the string will just use what is necessary
1322 on the top of the stacking pool, because string_cat() uses the extension
1326 s the rest of the input line
1327 name the option name (for errors)
1329 Returns: pointer to the string
1333 read_string(uschar *s, uschar *name)
1338 if (*s != '\"') return string_copy(s);
1341 yield = string_dequote(&s);
1343 if (s == ss+1 || s[-1] != '\"')
1344 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1345 "missing quote at end of string value for %s", name);
1347 if (*s != 0) extra_chars_error(s, US"string value for ", name, US"");
1353 /*************************************************
1354 * Handle option line *
1355 *************************************************/
1357 /* This function is called from several places to process a line containing the
1358 setting of an option. The first argument is the line to be decoded; it has been
1359 checked not to be empty and not to start with '#'. Trailing newlines and white
1360 space have been removed. The second argument is a pointer to the list of
1361 variable names that are to be recognized, together with their types and
1362 locations, and the third argument gives the number of entries in the list.
1364 The fourth argument is a pointer to a data block. If it is NULL, then the data
1365 values in the options list are absolute addresses. Otherwise, they are byte
1366 offsets in the data block.
1368 String option data may continue onto several lines; this function reads further
1369 data from config_file if necessary.
1371 The yield of this function is normally zero. If a string continues onto
1372 multiple lines, then the data value is permitted to be followed by a comma
1373 or a semicolon (for use in drivers) and the yield is that character.
1376 buffer contains the configuration line to be handled
1377 oltop points to the start of the relevant option list
1378 last one more than the offset of the last item in the option list
1379 data_block NULL when reading main options => data values in the option
1380 list are absolute addresses; otherwise they are byte offsets
1381 in data_block when they have opt_public set; otherwise
1382 they are byte offsets in data_block->options_block.
1383 unknown_txt format string to use in panic message for unknown option;
1384 must contain %s for option name
1385 if given as NULL, don't panic on unknown option
1387 Returns: TRUE if an option was read successfully,
1388 FALSE false for an unknown option if unknown_txt == NULL,
1389 otherwise panic and die on an unknown option
1393 readconf_handle_option(uschar *buffer, optionlist *oltop, int last,
1394 void *data_block, uschar *unknown_txt)
1398 int n, count, type, value;
1402 BOOL boolvalue = TRUE;
1403 BOOL freesptr = TRUE;
1404 optionlist *ol, *ol2;
1408 uschar *inttype = US"";
1411 uschar *saved_condition, *strtemp;
1412 uschar **str_target;
1416 /* There may be leading spaces; thereafter, we expect an option name starting
1419 while (isspace(*s)) s++;
1421 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option setting expected: %s", s);
1423 /* Read the name of the option, and skip any subsequent white space. If
1424 it turns out that what we read was "hide", set the flag indicating that
1425 this is a secure option, and loop to read the next word. */
1427 for (n = 0; n < 2; n++)
1429 while (isalnum(*s) || *s == '_')
1431 if (ptr < sizeof(name)-1) name[ptr++] = *s;
1435 while (isspace(*s)) s++;
1436 if (Ustrcmp(name, "hide") != 0) break;
1437 issecure = opt_secure;
1441 /* Deal with "no_" or "not_" here for booleans */
1443 if (Ustrncmp(name, "no_", 3) == 0)
1449 if (Ustrncmp(name, "not_", 4) == 0)
1455 /* Search the list for the given name. A non-existent name, or an option that
1456 is set twice, is a disaster. */
1458 ol = find_option(name + offset, oltop, last);
1462 if (unknown_txt == NULL) return FALSE;
1463 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, CS unknown_txt, name);
1466 if ((ol->type & opt_set) && !(ol->type & (opt_rep_con | opt_rep_str)))
1467 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1468 "\"%s\" option set for the second time", name);
1470 ol->type |= opt_set | issecure;
1471 type = ol->type & opt_mask;
1473 /* Types with data values must be followed by '='; the "no[t]_" prefix
1474 applies only to boolean values. */
1476 if (type < opt_bool || type > opt_bool_last)
1479 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1480 "negation prefix applied to a non-boolean option");
1482 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1483 "unexpected end of line (data missing) after %s", name);
1485 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing \"=\" after %s", name);
1488 /* If a boolean wasn't preceded by "no[t]_" it can be followed by = and
1489 true/false/yes/no, or, in the case of opt_expand_bool, a general string that
1490 ultimately expands to one of those values. */
1492 else if (*s != 0 && (offset != 0 || *s != '='))
1493 extra_chars_error(s, US"boolean option ", name, US"");
1495 /* Skip white space after = */
1497 if (*s == '=') while (isspace((*(++s))));
1499 /* If there is a data block and the opt_public flag is not set, change
1500 the data block pointer to the private options block. */
1502 if (data_block != NULL && (ol->type & opt_public) == 0)
1503 data_block = (void *)(((driver_instance *)data_block)->options_block);
1505 /* Now get the data according to the type. */
1509 /* If a string value is not enclosed in quotes, it consists of
1510 the rest of the current line, verbatim. Otherwise, string escapes
1513 A transport is specified as a string, which is then looked up in the
1514 list of transports. A search type is specified as one of a number of
1517 A set or rewrite rules for a driver is specified as a string, which is
1518 then parsed into a suitable chain of control blocks.
1520 Uids and gids are specified as strings which are then looked up in the
1521 passwd file. Lists of uids and gids are similarly specified as colon-
1522 separated strings. */
1527 case opt_expand_uid:
1528 case opt_expand_gid:
1533 reset_point = sptr = read_string(s, name);
1535 /* Having read a string, we now have several different ways of using it,
1536 depending on the data type, so do another switch. If keeping the actual
1537 string is not required (because it is interpreted), freesptr is set TRUE,
1538 and at the end we reset the pool. */
1542 /* If this was a string, set the variable to point to the new string,
1543 and set the flag so its store isn't reclaimed. If it was a list of rewrite
1544 rules, we still keep the string (for printing), and parse the rules into a
1545 control block and flags word. */
1548 if (data_block == NULL)
1549 str_target = (uschar **)(ol->value);
1551 str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
1552 if (ol->type & opt_rep_con)
1554 /* We already have a condition, we're conducting a crude hack to let
1555 multiple condition rules be chained together, despite storing them in
1557 saved_condition = *str_target;
1558 strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
1559 saved_condition, sptr);
1560 *str_target = string_copy_malloc(strtemp);
1561 /* TODO(pdp): there is a memory leak here and just below
1562 when we set 3 or more conditions; I still don't
1563 understand the store mechanism enough to know
1564 what's the safe way to free content from an earlier store.
1565 AFAICT, stores stack, so freeing an early stored item also stores
1566 all data alloc'd after it. If we knew conditions were adjacent,
1567 we could survive that, but we don't. So I *think* we need to take
1568 another bit from opt_type to indicate "malloced"; this seems like
1569 quite a hack, especially for this one case. It also means that
1570 we can't ever reclaim the store from the *first* condition.
1572 Because we only do this once, near process start-up, I'm prepared to
1573 let this slide for the time being, even though it rankles. */
1575 else if (ol->type & opt_rep_str)
1577 uschar sep = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
1580 /* Strip trailing whitespace and seperators */
1581 for (cp = sptr + Ustrlen(sptr) - 1;
1582 cp >= sptr && (*cp == '\n' || *cp == '\t' || *cp == ' ' || *cp == sep);
1586 *str_target = string_copy_malloc(
1587 *str_target ? string_sprintf("%s%c%s", *str_target, sep, sptr)
1598 if (data_block == NULL)
1599 *((uschar **)(ol->value)) = sptr;
1601 *((uschar **)((uschar *)data_block + (long int)(ol->value))) = sptr;
1603 if (type == opt_rewrite)
1608 rewrite_rule **chain;
1611 sprintf(CS name2, "*%.50s_rules", name);
1612 ol2 = find_option(name2, oltop, last);
1613 sprintf(CS name2, "*%.50s_flags", name);
1614 ol3 = find_option(name2, oltop, last);
1616 if (ol2 == NULL || ol3 == NULL)
1617 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1618 "rewrite rules not available for driver");
1620 if (data_block == NULL)
1622 chain = (rewrite_rule **)(ol2->value);
1623 flagptr = (int *)(ol3->value);
1627 chain = (rewrite_rule **)((uschar *)data_block + (long int)(ol2->value));
1628 flagptr = (int *)((uschar *)data_block + (long int)(ol3->value));
1631 while ((p = string_nextinlist(&sptr, &sep, big_buffer, BIG_BUFFER_SIZE))
1634 rewrite_rule *next = readconf_one_rewrite(p, flagptr, FALSE);
1636 chain = &(next->next);
1639 if ((*flagptr & (rewrite_all_envelope | rewrite_smtp)) != 0)
1640 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "rewrite rule specifies a "
1641 "non-header rewrite - not allowed at transport time -");
1645 /* If it was an expanded uid, see if there is any expansion to be
1646 done by checking for the presence of a $ character. If there is, save it
1647 in the corresponding *expand_user option field. Otherwise, fall through
1648 to treat it as a fixed uid. Ensure mutual exclusivity of the two kinds
1651 case opt_expand_uid:
1652 sprintf(CS name2, "*expand_%.50s", name);
1653 ol2 = find_option(name2, oltop, last);
1656 uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1658 if (data_block == NULL)
1659 *((uschar **)(ol2->value)) = ss;
1661 *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
1665 *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1671 /* Look up a fixed uid, and also make use of the corresponding gid
1672 if a passwd entry is returned and the gid has not been set. */
1675 if (!route_finduser(sptr, &pw, &uid))
1676 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found", sptr);
1677 if (data_block == NULL)
1678 *((uid_t *)(ol->value)) = uid;
1680 *((uid_t *)((uschar *)data_block + (long int)(ol->value))) = uid;
1682 /* Set the flag indicating a fixed value is set */
1684 *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1686 /* Handle matching gid if we have a passwd entry: done by finding the
1687 same name with terminating "user" changed to "group"; if not found,
1688 ignore. Also ignore if the value is already set. */
1690 if (pw == NULL) break;
1691 Ustrcpy(name+Ustrlen(name)-4, "group");
1692 ol2 = find_option(name, oltop, last);
1693 if (ol2 != NULL && ((ol2->type & opt_mask) == opt_gid ||
1694 (ol2->type & opt_mask) == opt_expand_gid))
1696 BOOL *set_flag = get_set_flag(name, oltop, last, data_block);
1699 if (data_block == NULL)
1700 *((gid_t *)(ol2->value)) = pw->pw_gid;
1702 *((gid_t *)((uschar *)data_block + (long int)(ol2->value))) = pw->pw_gid;
1708 /* If it was an expanded gid, see if there is any expansion to be
1709 done by checking for the presence of a $ character. If there is, save it
1710 in the corresponding *expand_user option field. Otherwise, fall through
1711 to treat it as a fixed gid. Ensure mutual exclusivity of the two kinds
1714 case opt_expand_gid:
1715 sprintf(CS name2, "*expand_%.50s", name);
1716 ol2 = find_option(name2, oltop, last);
1719 uschar *ss = (Ustrchr(sptr, '$') != NULL)? sptr : NULL;
1721 if (data_block == NULL)
1722 *((uschar **)(ol2->value)) = ss;
1724 *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = ss;
1728 *(get_set_flag(name, oltop, last, data_block)) = FALSE;
1734 /* Handle freestanding gid */
1737 if (!route_findgroup(sptr, &gid))
1738 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found", sptr);
1739 if (data_block == NULL)
1740 *((gid_t *)(ol->value)) = gid;
1742 *((gid_t *)((uschar *)data_block + (long int)(ol->value))) = gid;
1743 *(get_set_flag(name, oltop, last, data_block)) = TRUE;
1746 /* If it was a uid list, look up each individual entry, and build
1747 a vector of uids, with a count in the first element. Put the vector
1748 in malloc store so we can free the string. (We are reading into
1749 permanent store already.) */
1757 uschar *op = expand_string (sptr);
1760 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
1761 name, expand_string_message);
1764 if (*p != 0) count++;
1765 while (*p != 0) if (*p++ == ':' && *p != 0) count++;
1766 list = store_malloc(count*sizeof(uid_t));
1767 list[ptr++] = (uid_t)(count - 1);
1769 if (data_block == NULL)
1770 *((uid_t **)(ol->value)) = list;
1772 *((uid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
1778 (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
1779 if (!route_finduser(big_buffer, NULL, &uid))
1780 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "user %s was not found",
1787 /* If it was a gid list, look up each individual entry, and build
1788 a vector of gids, with a count in the first element. Put the vector
1789 in malloc store so we can free the string. (We are reading into permanent
1798 uschar *op = expand_string (sptr);
1801 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "failed to expand %s: %s",
1802 name, expand_string_message);
1805 if (*p != 0) count++;
1806 while (*p != 0) if (*p++ == ':' && *p != 0) count++;
1807 list = store_malloc(count*sizeof(gid_t));
1808 list[ptr++] = (gid_t)(count - 1);
1810 if (data_block == NULL)
1811 *((gid_t **)(ol->value)) = list;
1813 *((gid_t **)((uschar *)data_block + (long int)(ol->value))) = list;
1819 (void)string_nextinlist(&p, &sep, big_buffer, BIG_BUFFER_SIZE);
1820 if (!route_findgroup(big_buffer, &gid))
1821 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "group %s was not found",
1829 /* Release store if the value of the string doesn't need to be kept. */
1831 if (freesptr) store_reset(reset_point);
1834 /* Expanded boolean: if no characters follow, or if there are no dollar
1835 characters, this is a fixed-valued boolean, and we fall through. Otherwise,
1836 save the string for later expansion in the alternate place. */
1838 case opt_expand_bool:
1839 if (*s != 0 && Ustrchr(s, '$') != 0)
1841 sprintf(CS name2, "*expand_%.50s", name);
1842 ol2 = find_option(name2, oltop, last);
1845 reset_point = sptr = read_string(s, name);
1846 if (data_block == NULL)
1847 *((uschar **)(ol2->value)) = sptr;
1849 *((uschar **)((uschar *)data_block + (long int)(ol2->value))) = sptr;
1856 /* Boolean: if no characters follow, the value is boolvalue. Otherwise
1857 look for yes/not/true/false. Some booleans are stored in a single bit in
1858 a single int. There's a special fudge for verify settings; without a suffix
1859 they set both xx_sender and xx_recipient. The table points to the sender
1860 value; search subsequently for the recipient. There's another special case:
1861 opt_bool_set also notes when a boolean has been set. */
1865 case opt_bool_verify:
1869 s = readconf_readname(name2, 64, s);
1870 if (strcmpic(name2, US"true") == 0 || strcmpic(name2, US"yes") == 0)
1872 else if (strcmpic(name2, US"false") == 0 || strcmpic(name2, US"no") == 0)
1874 else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1875 "\"%s\" is not a valid value for the \"%s\" option", name2, name);
1876 if (*s != 0) extra_chars_error(s, string_sprintf("\"%s\" ", name2),
1877 US"for boolean option ", name);
1880 /* Handle single-bit type. */
1882 if (type == opt_bit)
1884 int bit = 1 << ((ol->type >> 16) & 31);
1885 int *ptr = (data_block == NULL)?
1886 (int *)(ol->value) :
1887 (int *)((uschar *)data_block + (long int)ol->value);
1888 if (boolvalue) *ptr |= bit; else *ptr &= ~bit;
1892 /* Handle full BOOL types */
1894 if (data_block == NULL)
1895 *((BOOL *)(ol->value)) = boolvalue;
1897 *((BOOL *)((uschar *)data_block + (long int)(ol->value))) = boolvalue;
1901 if (type == opt_bool_verify)
1903 sprintf(CS name2, "%.50s_recipient", name + offset);
1904 ol2 = find_option(name2, oltop, last);
1907 if (data_block == NULL)
1908 *((BOOL *)(ol2->value)) = boolvalue;
1910 *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = boolvalue;
1914 /* Note that opt_bool_set type is set, if there is somewhere to do so */
1916 else if (type == opt_bool_set)
1918 sprintf(CS name2, "*set_%.50s", name + offset);
1919 ol2 = find_option(name2, oltop, last);
1922 if (data_block == NULL)
1923 *((BOOL *)(ol2->value)) = TRUE;
1925 *((BOOL *)((uschar *)data_block + (long int)(ol2->value))) = TRUE;
1934 inttype = US"octal ";
1936 /* Integer: a simple(ish) case; allow octal and hex formats, and
1937 suffixes K and M. The different types affect output, not input. */
1946 lvalue = strtol(CS s, CSS &endptr, intbase);
1949 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
1952 if (errno != ERANGE)
1954 if (tolower(*endptr) == 'k')
1956 if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE;
1957 else lvalue *= 1024;
1960 else if (tolower(*endptr) == 'm')
1962 if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024))
1964 else lvalue *= 1024*1024;
1969 if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN)
1970 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
1971 "absolute value of integer \"%s\" is too large (overflow)", s);
1973 while (isspace(*endptr)) endptr++;
1975 extra_chars_error(endptr, inttype, US"integer value for ", name);
1977 value = (int)lvalue;
1980 if (data_block == NULL)
1981 *((int *)(ol->value)) = value;
1983 *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
1986 /* Integer held in K: again, allow octal and hex formats, and suffixes K and
1993 value = strtol(CS s, CSS &endptr, intbase);
1996 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s",
1999 if (errno != ERANGE)
2001 if (tolower(*endptr) == 'm')
2003 if (value > INT_MAX/1024 || value < INT_MIN/1024) errno = ERANGE;
2007 else if (tolower(*endptr) == 'k')
2013 value = (value + 512)/1024;
2017 if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2018 "absolute value of integer \"%s\" is too large (overflow)", s);
2020 while (isspace(*endptr)) endptr++;
2022 extra_chars_error(endptr, inttype, US"integer value for ", name);
2025 if (data_block == NULL)
2026 *((int *)(ol->value)) = value;
2028 *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2031 /* Fixed-point number: held to 3 decimal places. */
2034 if (sscanf(CS s, "%d%n", &value, &count) != 1)
2035 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2036 "fixed-point number expected for %s", name);
2038 if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2039 "integer \"%s\" is too large (overflow)", s);
2043 if (value < 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2044 "integer \"%s\" is too large (overflow)", s);
2046 if (s[count] == '.')
2049 while (isdigit(s[++count]))
2051 value += (s[count] - '0') * d;
2056 while (isspace(s[count])) count++;
2059 extra_chars_error(s+count, US"fixed-point value for ", name, US"");
2061 if (data_block == NULL)
2062 *((int *)(ol->value)) = value;
2064 *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2067 /* There's a special routine to read time values. */
2070 value = readconf_readtime(s, 0, FALSE);
2072 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2074 if (data_block == NULL)
2075 *((int *)(ol->value)) = value;
2077 *((int *)((uschar *)data_block + (long int)(ol->value))) = value;
2080 /* A time list is a list of colon-separated times, with the first
2081 element holding the size of the list and the second the number of
2087 int *list = (data_block == NULL)?
2088 (int *)(ol->value) :
2089 (int *)((uschar *)data_block + (long int)(ol->value));
2091 if (*s != 0) for (count = 1; count <= list[0] - 2; count++)
2094 uschar *snext = Ustrchr(s, ':');
2098 while (ss > s && isspace(ss[-1])) ss--;
2101 value = readconf_readtime(s, terminator, FALSE);
2103 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "invalid time value for %s",
2105 if (count > 1 && value <= list[count])
2106 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2107 "time value out of order for %s", name);
2108 list[count+1] = value;
2109 if (snext == NULL) break;
2111 while (isspace(*s)) s++;
2114 if (count > list[0] - 2)
2115 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many time values for %s",
2117 if (count > 0 && list[2] == 0) count = 0;
2129 /*************************************************
2130 * Print a time value *
2131 *************************************************/
2134 Argument: a time value in seconds
2135 Returns: pointer to a fixed buffer containing the time as a string,
2136 in readconf_readtime() format
2140 readconf_printtime(int t)
2143 uschar *p = time_buffer;
2160 if (w > 0) { sprintf(CS p, "%dw", w); while (*p) p++; }
2161 if (d > 0) { sprintf(CS p, "%dd", d); while (*p) p++; }
2162 if (h > 0) { sprintf(CS p, "%dh", h); while (*p) p++; }
2163 if (m > 0) { sprintf(CS p, "%dm", m); while (*p) p++; }
2164 if (s > 0 || p == time_buffer) sprintf(CS p, "%ds", s);
2171 /*************************************************
2172 * Print an individual option value *
2173 *************************************************/
2175 /* This is used by the -bP option, so prints to the standard output.
2176 The entire options list is passed in as an argument, because some options come
2177 in pairs - typically uid/gid settings, which can either be explicit numerical
2178 values, or strings to be expanded later. If the numerical value is unset,
2179 search for "*expand_<name>" to see if there is a string equivalent.
2182 ol option entry, or NULL for an unknown option
2184 options_block NULL for main configuration options; otherwise points to
2185 a driver block; if the option doesn't have opt_public
2186 set, then options_block->options_block is where the item
2188 oltop points to the option list in which ol exists
2189 last one more than the offset of the last entry in optop
2190 no_labels do not show "foo = " at the start.
2196 print_ol(optionlist *ol, uschar *name, void *options_block,
2197 optionlist *oltop, int last, BOOL no_labels)
2210 printf("%s is not a known option\n", name);
2214 /* Non-admin callers cannot see options that have been flagged secure by the
2217 if (!admin_user && (ol->type & opt_secure) != 0)
2219 const char * const hidden = "<value not displayable>";
2221 printf("%s\n", hidden);
2223 printf("%s = %s\n", name, hidden);
2227 /* Else show the value of the option */
2230 if (options_block != NULL)
2232 if ((ol->type & opt_public) == 0)
2233 options_block = (void *)(((driver_instance *)options_block)->options_block);
2234 value = (void *)((uschar *)options_block + (long int)value);
2237 switch(ol->type & opt_mask)
2240 case opt_rewrite: /* Show the text value */
2241 s = *((uschar **)value);
2242 if (!no_labels) printf("%s = ", name);
2243 printf("%s\n", (s == NULL)? US"" : string_printing2(s, FALSE));
2247 if (!no_labels) printf("%s = ", name);
2248 printf("%d\n", *((int *)value));
2253 int x = *((int *)value);
2254 if (x != 0 && (x & 1023) == 0)
2258 if ((x & 1023) == 0)
2263 if (!no_labels) printf("%s = ", name);
2264 printf("%d%c\n", x, c);
2268 if (!no_labels) printf("%s = ", name);
2276 int x = *((int *)value);
2277 if (!no_labels) printf("%s = ", name);
2278 if (x == 0) printf("0\n");
2279 else if ((x & 1023) == 0) printf("%dM\n", x >> 10);
2280 else printf("%dK\n", x);
2285 if (!no_labels) printf("%s = ", name);
2286 printf("%#o\n", *((int *)value));
2289 /* Can be negative only when "unset", in which case integer */
2293 int x = *((int *)value);
2296 if (x < 0) printf("%s =\n", name); else
2298 if (!no_labels) printf("%s = ", name);
2299 printf("%d.", x/1000);
2312 /* If the numerical value is unset, try for the string value */
2314 case opt_expand_uid:
2315 if (! *get_set_flag(name, oltop, last, options_block))
2317 sprintf(CS name2, "*expand_%.50s", name);
2318 ol2 = find_option(name2, oltop, last);
2321 void *value2 = ol2->value;
2322 if (options_block != NULL)
2323 value2 = (void *)((uschar *)options_block + (long int)value2);
2324 s = *((uschar **)value2);
2325 if (!no_labels) printf("%s = ", name);
2326 printf("%s\n", (s == NULL)? US"" : string_printing(s));
2331 /* Else fall through */
2334 if (!no_labels) printf("%s = ", name);
2335 if (! *get_set_flag(name, oltop, last, options_block))
2339 pw = getpwuid(*((uid_t *)value));
2341 printf("%ld\n", (long int)(*((uid_t *)value)));
2342 else printf("%s\n", pw->pw_name);
2346 /* If the numerical value is unset, try for the string value */
2348 case opt_expand_gid:
2349 if (! *get_set_flag(name, oltop, last, options_block))
2351 sprintf(CS name2, "*expand_%.50s", name);
2352 ol2 = find_option(name2, oltop, last);
2353 if (ol2 != NULL && (ol2->type & opt_mask) == opt_stringptr)
2355 void *value2 = ol2->value;
2356 if (options_block != NULL)
2357 value2 = (void *)((uschar *)options_block + (long int)value2);
2358 s = *((uschar **)value2);
2359 if (!no_labels) printf("%s = ", name);
2360 printf("%s\n", (s == NULL)? US"" : string_printing(s));
2365 /* Else fall through */
2368 if (!no_labels) printf("%s = ", name);
2369 if (! *get_set_flag(name, oltop, last, options_block))
2373 gr = getgrgid(*((int *)value));
2375 printf("%ld\n", (long int)(*((int *)value)));
2376 else printf("%s\n", gr->gr_name);
2381 uidlist = *((uid_t **)value);
2382 if (!no_labels) printf("%s =", name);
2383 if (uidlist != NULL)
2387 if (no_labels) sep = '\0';
2388 for (i = 1; i <= (int)(uidlist[0]); i++)
2390 uschar *name = NULL;
2391 pw = getpwuid(uidlist[i]);
2392 if (pw != NULL) name = US pw->pw_name;
2393 if (sep != '\0') printf("%c", sep);
2394 if (name != NULL) printf("%s", name);
2395 else printf("%ld", (long int)(uidlist[i]));
2403 gidlist = *((gid_t **)value);
2404 if (!no_labels) printf("%s =", name);
2405 if (gidlist != NULL)
2409 if (no_labels) sep = '\0';
2410 for (i = 1; i <= (int)(gidlist[0]); i++)
2412 uschar *name = NULL;
2413 gr = getgrgid(gidlist[i]);
2414 if (gr != NULL) name = US gr->gr_name;
2415 if (sep != '\0') printf("%c", sep);
2416 if (name != NULL) printf("%s", name);
2417 else printf("%ld", (long int)(gidlist[i]));
2425 if (!no_labels) printf("%s = ", name);
2426 printf("%s\n", readconf_printtime(*((int *)value)));
2432 int *list = (int *)value;
2433 if (!no_labels) printf("%s = ", name);
2434 for (i = 0; i < list[1]; i++)
2435 printf("%s%s", (i == 0)? "" : ":", readconf_printtime(list[i+2]));
2441 printf("%s%s\n", ((*((int *)value)) & (1 << ((ol->type >> 16) & 31)))?
2445 case opt_expand_bool:
2446 sprintf(CS name2, "*expand_%.50s", name);
2447 ol2 = find_option(name2, oltop, last);
2448 if (ol2 != NULL && ol2->value != NULL)
2450 void *value2 = ol2->value;
2451 if (options_block != NULL)
2452 value2 = (void *)((uschar *)options_block + (long int)value2);
2453 s = *((uschar **)value2);
2456 if (!no_labels) printf("%s = ", name);
2457 printf("%s\n", string_printing(s));
2460 /* s == NULL => string not set; fall through */
2466 case opt_bool_verify:
2468 printf("%s%s\n", (*((BOOL *)value))? "" : "no_", name);
2475 /*************************************************
2476 * Print value from main configuration *
2477 *************************************************/
2479 /* This function, called as a result of encountering the -bP option,
2480 causes the value of any main configuration variable to be output if the
2481 second argument is NULL. There are some special values:
2483 all print all main configuration options
2484 configure_file print the name of the configuration file
2485 routers print the routers' configurations
2486 transports print the transports' configuration
2487 authenticators print the authenticators' configuration
2488 macros print the macros' configuration
2489 router_list print a list of router names
2490 transport_list print a list of transport names
2491 authenticator_list print a list of authentication mechanism names
2492 macro_list print a list of macro names
2493 +name print a named list item
2494 local_scan print the local_scan options
2496 If the second argument is not NULL, it must be one of "router", "transport",
2497 "authenticator" or "macro" in which case the first argument identifies the
2498 driver whose options are to be printed.
2501 name option name if type == NULL; else driver name
2502 type NULL or driver type name, as described above
2503 no_labels avoid the "foo = " at the start of an item
2509 readconf_print(uschar *name, uschar *type, BOOL no_labels)
2511 BOOL names_only = FALSE;
2513 optionlist *ol2 = NULL;
2514 driver_instance *d = NULL;
2525 static uschar *types[] = { US"address", US"domain", US"host",
2527 static tree_node **anchors[] = { &addresslist_anchor, &domainlist_anchor,
2528 &hostlist_anchor, &localpartlist_anchor };
2530 for (i = 0; i < 4; i++)
2532 t = tree_search(*(anchors[i]), name+1);
2537 printf("%s\n", ((namedlist_block *)(t->data.ptr))->string);
2539 printf("%slist %s = %s\n", types[i], name+1,
2540 ((namedlist_block *)(t->data.ptr))->string);
2545 printf("no address, domain, host, or local part list called \"%s\" "
2546 "exists\n", name+1);
2551 if (Ustrcmp(name, "configure_file") == 0)
2553 printf("%s\n", CS config_main_filename);
2557 if (Ustrcmp(name, "all") == 0)
2559 for (ol = optionlist_config;
2560 ol < optionlist_config + optionlist_config_size; ol++)
2562 if ((ol->type & opt_hidden) == 0)
2563 print_ol(ol, US ol->name, NULL,
2564 optionlist_config, optionlist_config_size,
2570 if (Ustrcmp(name, "local_scan") == 0)
2572 #ifndef LOCAL_SCAN_HAS_OPTIONS
2573 printf("local_scan() options are not supported\n");
2575 for (ol = local_scan_options;
2576 ol < local_scan_options + local_scan_options_count; ol++)
2578 print_ol(ol, US ol->name, NULL, local_scan_options,
2579 local_scan_options_count, no_labels);
2585 if (Ustrcmp(name, "routers") == 0)
2590 else if (Ustrcmp(name, "transports") == 0)
2592 type = US"transport";
2596 else if (Ustrcmp(name, "authenticators") == 0)
2598 type = US"authenticator";
2602 else if (Ustrcmp(name, "macros") == 0)
2608 else if (Ustrcmp(name, "router_list") == 0)
2615 else if (Ustrcmp(name, "transport_list") == 0)
2617 type = US"transport";
2622 else if (Ustrcmp(name, "authenticator_list") == 0)
2624 type = US"authenticator";
2629 else if (Ustrcmp(name, "macro_list") == 0)
2638 print_ol(find_option(name, optionlist_config, optionlist_config_size),
2639 name, NULL, optionlist_config, optionlist_config_size, no_labels);
2644 /* Handle the options for a router or transport. Skip options that are flagged
2645 as hidden. Some of these are options with names starting with '*', used for
2646 internal alternative representations of other options (which the printing
2647 function will sort out). Others are synonyms kept for backward compatibility.
2650 if (Ustrcmp(type, "router") == 0)
2652 d = (driver_instance *)routers;
2653 ol2 = optionlist_routers;
2654 size = optionlist_routers_size;
2656 else if (Ustrcmp(type, "transport") == 0)
2658 d = (driver_instance *)transports;
2659 ol2 = optionlist_transports;
2660 size = optionlist_transports_size;
2662 else if (Ustrcmp(type, "authenticator") == 0)
2664 d = (driver_instance *)auths;
2665 ol2 = optionlist_auths;
2666 size = optionlist_auths_size;
2669 else if (Ustrcmp(type, "macro") == 0)
2671 /* People store passwords in macros and they were previously not available
2672 for printing. So we have an admin_users restriction. */
2675 fprintf(stderr, "exim: permission denied\n");
2678 for (m = macros; m != NULL; m = m->next)
2680 if (name == NULL || Ustrcmp(name, m->name) == 0)
2683 printf("%s\n", CS m->name);
2685 printf("%s=%s\n", CS m->name, CS m->replacement);
2691 printf("%s %s not found\n", type, name);
2697 for (; d != NULL; d = d->next) printf("%s\n", CS d->name);
2701 /* Either search for a given driver, or print all of them */
2703 for (; d != NULL; d = d->next)
2706 printf("\n%s %s:\n", d->name, type);
2707 else if (Ustrcmp(d->name, name) != 0) continue;
2709 for (ol = ol2; ol < ol2 + size; ol++)
2711 if ((ol->type & opt_hidden) == 0)
2712 print_ol(ol, US ol->name, d, ol2, size, no_labels);
2715 for (ol = d->info->options;
2716 ol < d->info->options + *(d->info->options_count); ol++)
2718 if ((ol->type & opt_hidden) == 0)
2719 print_ol(ol, US ol->name, d, d->info->options, *(d->info->options_count), no_labels);
2721 if (name != NULL) return;
2723 if (name != NULL) printf("%s %s not found\n", type, name);
2728 /*************************************************
2729 * Read a named list item *
2730 *************************************************/
2732 /* This function reads a name and a list (i.e. string). The name is used to
2733 save the list in a tree, sorted by its name. Each entry also has a number,
2734 which can be used for caching tests, but if the string contains any expansion
2735 items other than $key, the number is set negative to inhibit caching. This
2736 mechanism is used for domain, host, and address lists that are referenced by
2740 anchorp points to the tree anchor
2741 numberp points to the current number for this tree
2742 max the maximum number permitted
2743 s the text of the option line, starting immediately after the name
2745 tname the name of the list type, for messages
2751 read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s,
2754 BOOL forcecache = FALSE;
2757 namedlist_block *nb = store_get(sizeof(namedlist_block));
2759 if (Ustrncmp(s, "_cache", 6) == 0)
2766 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unrecognized configuration line");
2768 if (*numberp >= max)
2769 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "too many named %ss (max is %d)\n",
2772 while (isspace(*s)) s++;
2774 while (isalnum(*s) || *s == '_') s++;
2775 t = store_get(sizeof(tree_node) + s-ss);
2776 Ustrncpy(t->name, ss, s-ss);
2778 while (isspace(*s)) s++;
2780 if (!tree_insertnode(anchorp, t))
2781 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2782 "duplicate name \"%s\" for a named %s", t->name, tname);
2785 nb->number = *numberp;
2788 if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
2789 "missing '=' after \"%s\"", t->name);
2790 while (isspace(*s)) s++;
2791 nb->string = read_string(s, t->name);
2792 nb->cache_data = NULL;
2794 /* Check the string for any expansions; if any are found, mark this list
2795 uncacheable unless the user has explicited forced caching. */
2797 if (!forcecache && Ustrchr(nb->string, '$') != NULL) nb->number = -1;
2803 /*************************************************
2804 * Unpick data for a rate limit *
2805 *************************************************/
2807 /* This function is called to unpick smtp_ratelimit_{mail,rcpt} into four
2811 s string, in the form t,b,f,l
2812 where t is the threshold (integer)
2813 b is the initial delay (time)
2814 f is the multiplicative factor (fixed point)
2815 k is the maximum time (time)
2816 threshold where to store threshold
2817 base where to store base in milliseconds
2818 factor where to store factor in milliseconds
2819 limit where to store limit
2821 Returns: nothing (panics on error)
2825 unpick_ratelimit(uschar *s, int *threshold, int *base, double *factor,
2828 uschar bstring[16], lstring[16];
2830 if (sscanf(CS s, "%d, %15[0123456789smhdw.], %lf, %15s", threshold, bstring,
2831 factor, lstring) == 4)
2833 *base = readconf_readtime(bstring, 0, TRUE);
2834 *limit = readconf_readtime(lstring, 0, TRUE);
2835 if (*base >= 0 && *limit >= 0) return;
2837 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "malformed ratelimit data: %s", s);
2843 /*************************************************
2844 * Drop privs for checking TLS config *
2845 *************************************************/
2847 /* We want to validate TLS options during readconf, but do not want to be
2848 root when we call into the TLS library, in case of library linkage errors
2849 which cause segfaults; before this check, those were always done as the Exim
2850 runtime user and it makes sense to continue with that.
2852 Assumes: tls_require_ciphers has been set, if it will be
2853 exim_user has been set, if it will be
2854 exim_group has been set, if it will be
2856 Returns: bool for "okay"; false will cause caller to immediately exit.
2861 tls_dropprivs_validate_require_cipher(void)
2863 const uschar *errmsg;
2866 void (*oldsignal)(int);
2868 oldsignal = signal(SIGCHLD, SIG_DFL);
2871 if ((pid = fork()) < 0)
2872 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "fork failed for TLS check");
2876 /* in some modes, will have dropped privilege already */
2878 exim_setugid(exim_uid, exim_gid, FALSE,
2879 US"calling tls_validate_require_cipher");
2881 errmsg = tls_validate_require_cipher();
2884 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
2885 "tls_require_ciphers invalid: %s", errmsg);
2892 rc = waitpid(pid, &status, 0);
2893 } while (rc < 0 && errno == EINTR);
2896 debug_printf("tls_validate_require_cipher child %d ended: status=0x%x\n",
2899 signal(SIGCHLD, oldsignal);
2903 #endif /* SUPPORT_TLS */
2908 /*************************************************
2909 * Read main configuration options *
2910 *************************************************/
2912 /* This function is the first to be called for configuration reading. It
2913 opens the configuration file and reads general configuration settings until
2914 it reaches the end of the configuration section. The file is then left open so
2915 that the remaining configuration data can subsequently be read if needed for
2918 The configuration file must be owned either by root or exim, and be writeable
2919 only by root or uid/gid exim. The values for Exim's uid and gid can be changed
2920 in the config file, so the test is done on the compiled in values. A slight
2921 anomaly, to be carefully documented.
2923 The name of the configuration file is taken from a list that is included in the
2924 binary of Exim. It can be altered from the command line, but if that is done,
2925 root privilege is immediately withdrawn unless the caller is root or exim.
2926 The first file on the list that exists is used.
2928 For use on multiple systems that share file systems, first look for a
2929 configuration file whose name has the current node name on the end. If that is
2930 not found, try the generic name. For really contorted configurations, that run
2931 multiple Exims with different uid settings, first try adding the effective uid
2932 before the node name. These complications are going to waste resources on most
2933 systems. Therefore they are available only when requested by compile-time
2940 struct stat statbuf;
2941 uschar *s, *filename;
2942 uschar *list = config_main_filelist;
2944 /* Loop through the possible file names */
2946 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
2949 /* Cut out all the fancy processing unless specifically wanted */
2951 #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
2952 uschar *suffix = filename + Ustrlen(filename);
2954 /* Try for the node-specific file if a node name exists */
2956 #ifdef CONFIGURE_FILE_USE_NODE
2958 if (uname(&uts) >= 0)
2960 #ifdef CONFIGURE_FILE_USE_EUID
2961 sprintf(CS suffix, ".%ld.%.256s", (long int)original_euid, uts.nodename);
2962 config_file = Ufopen(filename, "rb");
2963 if (config_file == NULL)
2964 #endif /* CONFIGURE_FILE_USE_EUID */
2966 sprintf(CS suffix, ".%.256s", uts.nodename);
2967 config_file = Ufopen(filename, "rb");
2970 #endif /* CONFIGURE_FILE_USE_NODE */
2972 /* Otherwise, try the generic name, possibly with the euid added */
2974 #ifdef CONFIGURE_FILE_USE_EUID
2975 if (config_file == NULL)
2977 sprintf(CS suffix, ".%ld", (long int)original_euid);
2978 config_file = Ufopen(filename, "rb");
2980 #endif /* CONFIGURE_FILE_USE_EUID */
2982 /* Finally, try the unadorned name */
2984 if (config_file == NULL)
2987 config_file = Ufopen(filename, "rb");
2989 #else /* if neither defined */
2991 /* This is the common case when the fancy processing is not included. */
2993 config_file = Ufopen(filename, "rb");
2996 /* If the file does not exist, continue to try any others. For any other
2997 error, break out (and die). */
2999 if (config_file != NULL || errno != ENOENT) break;
3002 /* On success, save the name for verification; config_filename is used when
3003 logging configuration errors (it changes for .included files) whereas
3004 config_main_filename is the name shown by -bP. Failure to open a configuration
3005 file is a serious disaster. */
3007 if (config_file != NULL)
3010 config_filename = config_main_filename = string_copy(filename);
3012 p = Ustrrchr(filename, '/');
3013 config_main_directory = p ? string_copyn(filename, p - filename)
3014 : string_copy(US".");
3018 if (filename == NULL)
3019 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "non-existent configuration file(s): "
3020 "%s", config_main_filelist);
3022 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", string_open_failed(errno,
3023 "configuration file %s", filename));
3026 /* Check the status of the file we have opened, if we have retained root
3027 privileges and the file isn't /dev/null (which *should* be 0666). */
3029 if (trusted_config && Ustrcmp(filename, US"/dev/null"))
3031 if (fstat(fileno(config_file), &statbuf) != 0)
3032 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
3035 if ((statbuf.st_uid != root_uid /* owner not root */
3036 #ifdef CONFIGURE_OWNER
3037 && statbuf.st_uid != config_uid /* owner not the special one */
3040 (statbuf.st_gid != root_gid /* group not root & */
3041 #ifdef CONFIGURE_GROUP
3042 && statbuf.st_gid != config_gid /* group not the special one */
3044 && (statbuf.st_mode & 020) != 0) || /* group writeable */
3046 ((statbuf.st_mode & 2) != 0)) /* world writeable */
3048 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Exim configuration file %s has the "
3049 "wrong owner, group, or mode", big_buffer);
3052 /* Process the main configuration settings. They all begin with a lower case
3053 letter. If we see something starting with an upper case letter, it is taken as
3054 a macro definition. */
3056 while ((s = get_config_line()) != NULL)
3058 if (isupper(s[0])) read_macro_assignment(s);
3060 else if (Ustrncmp(s, "domainlist", 10) == 0)
3061 read_named_list(&domainlist_anchor, &domainlist_count,
3062 MAX_NAMED_LIST, s+10, US"domain list");
3064 else if (Ustrncmp(s, "hostlist", 8) == 0)
3065 read_named_list(&hostlist_anchor, &hostlist_count,
3066 MAX_NAMED_LIST, s+8, US"host list");
3068 else if (Ustrncmp(s, US"addresslist", 11) == 0)
3069 read_named_list(&addresslist_anchor, &addresslist_count,
3070 MAX_NAMED_LIST, s+11, US"address list");
3072 else if (Ustrncmp(s, US"localpartlist", 13) == 0)
3073 read_named_list(&localpartlist_anchor, &localpartlist_count,
3074 MAX_NAMED_LIST, s+13, US"local part list");
3077 (void) readconf_handle_option(s, optionlist_config, optionlist_config_size,
3078 NULL, US"main option \"%s\" unknown");
3082 /* If local_sender_retain is set, local_from_check must be unset. */
3084 if (local_sender_retain && local_from_check)
3085 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "both local_from_check and "
3086 "local_sender_retain are set; this combination is not allowed");
3088 /* If the timezone string is empty, set it to NULL, implying no TZ variable
3091 if (timezone_string != NULL && *timezone_string == 0) timezone_string = NULL;
3093 /* The max retry interval must not be greater than 24 hours. */
3095 if (retry_interval_max > 24*60*60) retry_interval_max = 24*60*60;
3097 /* remote_max_parallel must be > 0 */
3099 if (remote_max_parallel <= 0) remote_max_parallel = 1;
3101 /* Save the configured setting of freeze_tell, so we can re-instate it at the
3102 start of a new SMTP message. */
3104 freeze_tell_config = freeze_tell;
3106 /* The primary host name may be required for expansion of spool_directory
3107 and log_file_path, so make sure it is set asap. It is obtained from uname(),
3108 but if that yields an unqualified value, make a FQDN by using gethostbyname to
3109 canonize it. Some people like upper case letters in their host names, so we
3110 don't force the case. */
3112 if (primary_hostname == NULL)
3116 if (uname(&uts) < 0)
3117 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "uname() failed to yield host name");
3118 hostname = US uts.nodename;
3120 if (Ustrchr(hostname, '.') == NULL)
3123 struct hostent *hostdata;
3126 if (!disable_ipv6 && (dns_ipv4_lookup == NULL ||
3127 match_isinlist(hostname, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,
3137 #if HAVE_GETIPNODEBYNAME
3139 hostdata = getipnodebyname(CS hostname, af, 0, &error_num);
3141 hostdata = gethostbyname2(CS hostname, af);
3144 hostdata = gethostbyname(CS hostname);
3147 if (hostdata != NULL)
3149 hostname = US hostdata->h_name;
3153 if (af == AF_INET) break;
3158 primary_hostname = string_copy(hostname);
3161 /* Set up default value for smtp_active_hostname */
3163 smtp_active_hostname = primary_hostname;
3165 /* If spool_directory wasn't set in the build-time configuration, it must have
3166 got set above. Of course, writing to the log may not work if log_file_path is
3167 not set, but it will at least get to syslog or somewhere, with any luck. */
3169 if (*spool_directory == 0)
3170 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "spool_directory undefined: cannot "
3173 /* Expand the spool directory name; it may, for example, contain the primary
3174 host name. Same comment about failure. */
3176 s = expand_string(spool_directory);
3178 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand spool_directory "
3179 "\"%s\": %s", spool_directory, expand_string_message);
3180 spool_directory = s;
3182 /* Expand log_file_path, which must contain "%s" in any component that isn't
3183 the null string or "syslog". It is also allowed to contain one instance of %D
3184 or %M. However, it must NOT contain % followed by anything else. */
3186 if (*log_file_path != 0)
3189 int sep = ':'; /* Fixed for log file path */
3190 s = expand_string(log_file_path);
3192 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand log_file_path "
3193 "\"%s\": %s", log_file_path, expand_string_message);
3196 while ((sss = string_nextinlist(&ss,&sep,big_buffer,big_buffer_size)) != NULL)
3199 if (sss[0] == 0 || Ustrcmp(sss, "syslog") == 0) continue;
3200 t = Ustrstr(sss, "%s");
3202 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" does not "
3203 "contain \"%%s\"", sss);
3205 t = Ustrchr(sss, '%');
3208 if ((t[1] != 'D' && t[1] != 'M') || Ustrchr(t+2, '%') != NULL)
3209 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "log_file_path \"%s\" contains "
3210 "unexpected \"%%\" character", s);
3217 /* Interpret syslog_facility into an integer argument for 'ident' param to
3218 openlog(). Default is LOG_MAIL set in globals.c. Allow the user to omit the
3221 if (syslog_facility_str != NULL)
3224 uschar *s = syslog_facility_str;
3226 if ((Ustrlen(syslog_facility_str) >= 4) &&
3227 (strncmpic(syslog_facility_str, US"log_", 4) == 0))
3230 for (i = 0; i < syslog_list_size; i++)
3232 if (strcmpic(s, syslog_list[i].name) == 0)
3234 syslog_facility = syslog_list[i].value;
3239 if (i >= syslog_list_size)
3241 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3242 "failed to interpret syslog_facility \"%s\"", syslog_facility_str);
3246 /* Expand pid_file_path */
3248 if (*pid_file_path != 0)
3250 s = expand_string(pid_file_path);
3252 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to expand pid_file_path "
3253 "\"%s\": %s", pid_file_path, expand_string_message);
3257 /* Set default value of process_log_path */
3259 if (process_log_path == NULL || *process_log_path =='\0')
3260 process_log_path = string_sprintf("%s/exim-process.info", spool_directory);
3262 /* Compile the regex for matching a UUCP-style "From_" line in an incoming
3265 regex_From = regex_must_compile(uucp_from_pattern, FALSE, TRUE);
3267 /* Unpick the SMTP rate limiting options, if set */
3269 if (smtp_ratelimit_mail != NULL)
3271 unpick_ratelimit(smtp_ratelimit_mail, &smtp_rlm_threshold,
3272 &smtp_rlm_base, &smtp_rlm_factor, &smtp_rlm_limit);
3275 if (smtp_ratelimit_rcpt != NULL)
3277 unpick_ratelimit(smtp_ratelimit_rcpt, &smtp_rlr_threshold,
3278 &smtp_rlr_base, &smtp_rlr_factor, &smtp_rlr_limit);
3281 /* The qualify domains default to the primary host name */
3283 if (qualify_domain_sender == NULL)
3284 qualify_domain_sender = primary_hostname;
3285 if (qualify_domain_recipient == NULL)
3286 qualify_domain_recipient = qualify_domain_sender;
3288 /* Setting system_filter_user in the configuration sets the gid as well if a
3289 name is given, but a numerical value does not. */
3291 if (system_filter_uid_set && !system_filter_gid_set)
3293 struct passwd *pw = getpwuid(system_filter_uid);
3295 log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Failed to look up uid %ld",
3296 (long int)system_filter_uid);
3297 system_filter_gid = pw->pw_gid;
3298 system_filter_gid_set = TRUE;
3301 /* If the errors_reply_to field is set, check that it is syntactically valid
3302 and ensure it contains a domain. */
3304 if (errors_reply_to != NULL)
3307 int start, end, domain;
3308 uschar *recipient = parse_extract_address(errors_reply_to, &errmess,
3309 &start, &end, &domain, FALSE);
3311 if (recipient == NULL)
3312 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3313 "error in errors_reply_to (%s): %s", errors_reply_to, errmess);
3316 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3317 "errors_reply_to (%s) does not contain a domain", errors_reply_to);
3320 /* If smtp_accept_queue or smtp_accept_max_per_host is set, then
3321 smtp_accept_max must also be set. */
3323 if (smtp_accept_max == 0 &&
3324 (smtp_accept_queue > 0 || smtp_accept_max_per_host != NULL))
3325 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3326 "smtp_accept_max must be set if smtp_accept_queue or "
3327 "smtp_accept_max_per_host is set");
3329 /* Set up the host number if anything is specified. It is an expanded string
3330 so that it can be computed from the host name, for example. We do this last
3331 so as to ensure that everything else is set up before the expansion. */
3333 if (host_number_string != NULL)
3337 uschar *s = expand_string(host_number_string);
3339 log_write(0, LOG_MAIN|LOG_PANIC_DIE,
3340 "failed to expand localhost_number \"%s\": %s",
3341 host_number_string, expand_string_message);
3342 n = Ustrtol(s, &end, 0);
3343 while (isspace(*end)) end++;
3345 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3346 "localhost_number value is not a number: %s", s);
3347 if (n > LOCALHOST_MAX)
3348 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3349 "localhost_number is greater than the maximum allowed value (%d)",
3355 /* If tls_verify_hosts is set, tls_verify_certificates must also be set */
3357 if ((tls_verify_hosts != NULL || tls_try_verify_hosts != NULL) &&
3358 tls_verify_certificates == NULL)
3359 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3360 "tls_%sverify_hosts is set, but tls_verify_certificates is not set",
3361 (tls_verify_hosts != NULL)? "" : "try_");
3363 /* This also checks that the library linkage is working and we can call
3364 routines in it, so call even if tls_require_ciphers is unset */
3365 if (!tls_dropprivs_validate_require_cipher())
3368 /* Magic number: at time of writing, 1024 has been the long-standing value
3369 used by so many clients, and what Exim used to use always, that it makes
3370 sense to just min-clamp this max-clamp at that. */
3371 if (tls_dh_max_bits < 1024)
3372 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3373 "tls_dh_max_bits is too small, must be at least 1024 for interop");
3375 /* If openssl_options is set, validate it */
3376 if (openssl_options != NULL)
3379 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3380 "openssl_options is set but we're using GnuTLS");
3383 if (!(tls_openssl_options_parse(openssl_options, &dummy)))
3384 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3385 "openssl_options parse error: %s", openssl_options);
3389 if (gnutls_require_kx || gnutls_require_mac || gnutls_require_proto)
3390 log_write(0, LOG_MAIN, "WARNING: main options"
3391 " gnutls_require_kx, gnutls_require_mac and gnutls_require_protocols"
3393 #endif /*SUPPORT_TLS*/
3398 /*************************************************
3399 * Initialize one driver *
3400 *************************************************/
3402 /* This is called once the driver's generic options, if any, have been read.
3403 We can now find the driver, set up defaults for the private options, and
3404 unset any "set" bits in the private options table (which might have been
3405 set by another incarnation of the same driver).
3408 d pointer to driver instance block, with generic
3410 drivers_available vector of available drivers
3411 size_of_info size of each block in drivers_available
3412 class class of driver, for error message
3414 Returns: pointer to the driver info block
3417 static driver_info *
3418 init_driver(driver_instance *d, driver_info *drivers_available,
3419 int size_of_info, uschar *class)
3423 for (dd = drivers_available; dd->driver_name[0] != 0;
3424 dd = (driver_info *)(((uschar *)dd) + size_of_info))
3426 if (Ustrcmp(d->driver_name, dd->driver_name) == 0)
3429 int len = dd->options_len;
3431 d->options_block = store_get(len);
3432 memcpy(d->options_block, dd->options_block, len);
3433 for (i = 0; i < *(dd->options_count); i++)
3434 dd->options[i].type &= ~opt_set;
3439 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3440 "%s %s: cannot find %s driver \"%s\"", class, d->name, class, d->driver_name);
3442 return NULL; /* never obeyed */
3448 /*************************************************
3449 * Initialize driver list *
3450 *************************************************/
3452 /* This function is called for routers, transports, and authentication
3453 mechanisms. It reads the data from the current point in the configuration file
3454 up to the end of the section, and sets up a chain of instance blocks according
3455 to the file's contents. The file will already have been opened by a call to
3456 readconf_main, and must be left open for subsequent reading of further data.
3458 Any errors cause a panic crash. Note that the blocks with names driver_info and
3459 driver_instance must map the first portions of all the _info and _instance
3460 blocks for this shared code to work.
3463 class "router", "transport", or "authenticator"
3464 anchor &routers, &transports, &auths
3465 drivers_available available drivers
3466 size_of_info size of each info block
3467 instance_default points to default data for an instance
3468 instance_size size of instance block
3469 driver_optionlist generic option list
3470 driver_optionlist_count count of generic option list
3476 readconf_driver_init(
3478 driver_instance **anchor,
3479 driver_info *drivers_available,
3481 void *instance_default,
3483 optionlist *driver_optionlist,
3484 int driver_optionlist_count)
3486 driver_instance **p = anchor;
3487 driver_instance *d = NULL;
3490 while ((buffer = get_config_line()) != NULL)
3495 /* Read the first name on the line and test for the start of a new driver. A
3496 macro definition indicates the end of the previous driver. If this isn't the
3497 start of a new driver, the line will be re-read. */
3499 s = readconf_readname(name, sizeof(name), buffer);
3501 /* Handle macro definition, first finishing off the initialization of the
3502 previous driver, if any. */
3504 if (isupper(*name) && *s == '=')
3508 if (d->driver_name == NULL)
3509 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3510 "no driver defined for %s \"%s\"", class, d->name);
3514 read_macro_assignment(buffer);
3518 /* If the line starts with a name terminated by a colon, we are at the
3519 start of the definition of a new driver. The rest of the line must be
3526 /* Finish off initializing the previous driver. */
3530 if (d->driver_name == NULL)
3531 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3532 "no driver defined for %s \"%s\"", class, d->name);
3536 /* Check that we haven't already got a driver of this name */
3538 for (d = *anchor; d != NULL; d = d->next)
3539 if (Ustrcmp(name, d->name) == 0)
3540 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3541 "there are two %ss called \"%s\"", class, name);
3543 /* Set up a new driver instance data block on the chain, with
3544 its default values installed. */
3546 d = store_get(instance_size);
3547 memcpy(d, instance_default, instance_size);
3550 d->name = string_copy(name);
3552 /* Clear out the "set" bits in the generic options */
3554 for (i = 0; i < driver_optionlist_count; i++)
3555 driver_optionlist[i].type &= ~opt_set;
3557 /* Check nothing more on this line, then do the next loop iteration. */
3559 while (isspace(*s)) s++;
3560 if (*s != 0) extra_chars_error(s, US"driver name ", name, US"");
3564 /* Not the start of a new driver. Give an error if we have not set up a
3565 current driver yet. */
3567 if (d == NULL) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3568 "%s name missing", class);
3570 /* First look to see if this is a generic option; if it is "driver",
3571 initialize the driver. If is it not a generic option, we can look for a
3572 private option provided that the driver has been previously set up. */
3574 if (readconf_handle_option(buffer, driver_optionlist,
3575 driver_optionlist_count, d, NULL))
3577 if (d->info == NULL && d->driver_name != NULL)
3578 init_driver(d, drivers_available, size_of_info, class);
3581 /* Handle private options - pass the generic block because some may
3582 live therein. A flag with each option indicates if it is in the public
3585 else if (d->info != NULL)
3587 readconf_handle_option(buffer, d->info->options,
3588 *(d->info->options_count), d, US"option \"%s\" unknown");
3591 /* The option is not generic and the driver name has not yet been given. */
3593 else log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "option \"%s\" unknown "
3594 "(\"driver\" must be specified before any private options)", name);
3597 /* Run the initialization function for the final driver. */
3601 if (d->driver_name == NULL)
3602 log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
3603 "no driver defined for %s \"%s\"", class, d->name);
3610 /*************************************************
3611 * Check driver dependency *
3612 *************************************************/
3614 /* This function is passed a driver instance and a string. It checks whether
3615 any of the string options for the driver contains the given string as an
3619 d points to a driver instance block
3620 s the string to search for
3622 Returns: TRUE if a dependency is found
3626 readconf_depends(driver_instance *d, uschar *s)
3628 int count = *(d->info->options_count);
3632 for (ol = d->info->options; ol < d->info->options + count; ol++)
3634 void *options_block;
3636 int type = ol->type & opt_mask;
3637 if (type != opt_stringptr) continue;
3638 options_block = ((ol->type & opt_public) == 0)? d->options_block : (void *)d;
3639 value = *(uschar **)((uschar *)options_block + (long int)(ol->value));
3640 if (value != NULL && (ss = Ustrstr(value, s)) != NULL)
3642 if (ss <= value || (ss[-1] != '$' && ss[-1] != '{') ||
3643 isalnum(ss[Ustrlen(s)])) continue;
3644 DEBUG(D_transport) debug_printf("driver %s: \"%s\" option depends on %s\n",
3645 d->name, ol->name, s);
3650 DEBUG(D_transport) debug_printf("driver %s does not depend on %s\n", d->name, s);
3657 /*************************************************
3658 * Decode an error type for retries *
3659 *************************************************/
3661 /* This function is global because it is also called from the main
3662 program when testing retry information. It decodes strings such as "quota_7d"
3663 into numerical error codes.
3666 pp points to start of text
3667 p points past end of text
3668 basic_errno points to an int to receive the main error number
3669 more_errno points to an int to receive the secondary error data
3671 Returns: NULL if decoded correctly; else points to error text
3675 readconf_retry_error(uschar *pp, uschar *p, int *basic_errno, int *more_errno)
3679 while (q < p && *q != '_') q++;
3682 if (len == 5 && strncmpic(pp, US"quota", len) == 0)
3684 *basic_errno = ERRNO_EXIMQUOTA;
3685 if (q != p && (*more_errno = readconf_readtime(q+1, *p, FALSE)) < 0)
3686 return US"bad time value";
3689 else if (len == 7 && strncmpic(pp, US"refused", len) == 0)
3691 *basic_errno = ECONNREFUSED;
3694 if (strncmpic(q+1, US"MX", p-q-1) == 0) *more_errno = 'M';
3695 else if (strncmpic(q+1, US"A", p-q-1) == 0) *more_errno = 'A';
3696 else return US"A or MX expected after \"refused\"";
3700 else if (len == 7 && strncmpic(pp, US"timeout", len) == 0)
3702 *basic_errno = ETIMEDOUT;
3706 int xlen = p - q - 1;
3709 static uschar *extras[] =
3710 { US"A", US"MX", US"connect", US"connect_A", US"connect_MX" };
3711 static int values[] =
3712 { 'A', 'M', RTEF_CTOUT, RTEF_CTOUT|'A', RTEF_CTOUT|'M' };
3714 for (i = 0; i < sizeof(extras)/sizeof(uschar *); i++)
3716 if (strncmpic(x, extras[i], xlen) == 0)
3718 *more_errno = values[i];
3723 if (i >= sizeof(extras)/sizeof(uschar *))
3725 if (strncmpic(x, US"DNS", xlen) == 0)
3727 log_write(0, LOG_MAIN|LOG_PANIC, "\"timeout_dns\" is no longer "
3728 "available in retry rules (it has never worked) - treated as "
3731 else return US"\"A\", \"MX\", or \"connect\" expected after \"timeout\"";
3736 else if (strncmpic(pp, US"mail_4", 6) == 0 ||
3737 strncmpic(pp, US"rcpt_4", 6) == 0 ||
3738 strncmpic(pp, US"data_4", 6) == 0)
3741 int x = 255; /* means "any 4xx code" */
3742 if (p != pp + 8) bad = TRUE; else
3744 int a = pp[6], b = pp[7];
3748 if (isdigit(b)) x += b - '0';
3749 else if (b == 'x') x += 100;
3752 else if (a != 'x' || b != 'x') bad = TRUE;
3756 return string_sprintf("%.4s_4 must be followed by xx, dx, or dd, where "
3757 "x is literal and d is any digit", pp);
3759 *basic_errno = (*pp == 'm')? ERRNO_MAIL4XX :
3760 (*pp == 'r')? ERRNO_RCPT4XX : ERRNO_DATA4XX;
3761 *more_errno = x << 8;
3764 else if (len == 4 && strncmpic(pp, US"auth", len) == 0 &&
3765 strncmpic(q+1, US"failed", p-q-1) == 0)
3766 *basic_errno = ERRNO_AUTHFAIL;
3768 else if (strncmpic(pp, US"lost_connection", p - pp) == 0)
3769 *basic_errno = ERRNO_SMTPCLOSED;
3771 else if (strncmpic(pp, US"tls_required", p - pp) == 0)
3772 *basic_errno = ERRNO_TLSREQUIRED;
3774 else if (len != 1 || Ustrncmp(pp, "*", 1) != 0)
3775 return string_sprintf("unknown or malformed retry error \"%.*s\"", (int) (p-pp), pp);
3783 /*************************************************
3784 * Read retry information *
3785 *************************************************/
3787 /* Each line of retry information contains:
3789 . A domain name pattern or an address pattern;
3791 . An error name, possibly with additional data, or *;
3793 . An optional sequence of retry items, each consisting of an identifying
3794 letter, a cutoff time, and optional parameters.
3796 All this is decoded and placed into a control block. */
3799 /* Subroutine to read an argument, preceded by a comma and terminated
3800 by comma, semicolon, whitespace, or newline. The types are: 0 = time value,
3801 1 = fixed point number (returned *1000).
3804 paddr pointer to pointer to current character; updated
3805 type 0 => read a time; 1 => read a fixed point number
3807 Returns: time in seconds or fixed point number * 1000
3811 retry_arg(uschar **paddr, int type)
3816 if (*p++ != ',') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma expected");
3818 while (isspace(*p)) p++;
3820 while (isalnum(*p) || (type == 1 && *p == '.')) p++;
3822 if (*p != 0 && !isspace(*p) && *p != ',' && *p != ';')
3823 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "comma or semicolon expected");
3829 return readconf_readtime(pp, *p, FALSE);
3831 return readconf_readfixed(pp, *p);
3833 return 0; /* Keep picky compilers happy */
3836 /* The function proper */
3839 readconf_retries(void)
3841 retry_config **chain = &retries;
3845 while ((p = get_config_line()) != NULL)
3847 retry_rule **rchain;
3850 next = store_get(sizeof(retry_config));
3853 chain = &(next->next);
3854 next->basic_errno = next->more_errno = 0;
3855 next->senders = NULL;
3857 rchain = &(next->rules);
3859 next->pattern = string_dequote(&p);
3860 while (isspace(*p)) p++;
3862 while (mac_isgraph(*p)) p++;
3863 if (p - pp <= 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3864 "missing error type in retry rule");
3866 /* Test error names for things we understand. */
3868 if ((error = readconf_retry_error(pp, p, &(next->basic_errno),
3869 &(next->more_errno))) != NULL)
3870 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%s", error);
3872 /* There may be an optional address list of senders to be used as another
3873 constraint on the rule. This was added later, so the syntax is a bit of a
3874 fudge. Anything that is not a retry rule starting "F," or "G," is treated as
3877 while (isspace(*p)) p++;
3878 if (Ustrncmp(p, "senders", 7) == 0)
3881 while (isspace(*p)) p++;
3882 if (*p++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3883 "\"=\" expected after \"senders\" in retry rule");
3884 while (isspace(*p)) p++;
3885 next->senders = string_dequote(&p);
3888 /* Now the retry rules. Keep the maximum timeout encountered. */
3890 while (isspace(*p)) p++;
3894 retry_rule *rule = store_get(sizeof(retry_rule));
3896 rchain = &(rule->next);
3898 rule->rule = toupper(*p++);
3899 rule->timeout = retry_arg(&p, 0);
3900 if (rule->timeout > retry_maximum_timeout)
3901 retry_maximum_timeout = rule->timeout;
3905 case 'F': /* Fixed interval */
3906 rule->p1 = retry_arg(&p, 0);
3909 case 'G': /* Geometrically increasing intervals */
3910 case 'H': /* Ditto, but with randomness */
3911 rule->p1 = retry_arg(&p, 0);
3912 rule->p2 = retry_arg(&p, 1);
3916 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "unknown retry rule letter");
3920 if (rule->timeout <= 0 || rule->p1 <= 0 ||
3921 (rule->rule != 'F' && rule->p2 < 1000))
3922 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
3923 "bad parameters for retry rule");
3925 while (isspace(*p)) p++;
3929 while (isspace(*p)) p++;
3932 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "semicolon expected");
3939 /*************************************************
3940 * Initialize authenticators *
3941 *************************************************/
3943 /* Read the authenticators section of the configuration file.
3952 auth_instance *au, *bu;
3953 readconf_driver_init(US"authenticator",
3954 (driver_instance **)(&auths), /* chain anchor */
3955 (driver_info *)auths_available, /* available drivers */
3956 sizeof(auth_info), /* size of info block */
3957 &auth_defaults, /* default values for generic options */
3958 sizeof(auth_instance), /* size of instance block */
3959 optionlist_auths, /* generic options */
3960 optionlist_auths_size);
3962 for (au = auths; au != NULL; au = au->next)
3964 if (au->public_name == NULL)
3965 log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "no public name specified for "
3966 "the %s authenticator", au->name);
3967 for (bu = au->next; bu != NULL; bu = bu->next)
3969 if (strcmpic(au->public_name, bu->public_name) == 0)
3971 if ((au->client && bu->client) || (au->server && bu->server))
3972 log_write(0, LOG_PANIC_DIE|LOG_CONFIG, "two %s authenticators "
3973 "(%s and %s) have the same public name (%s)",
3974 (au->client)? US"client" : US"server", au->name, bu->name,
3984 /*************************************************
3985 * Read ACL information *
3986 *************************************************/
3988 /* If this run of Exim is not doing something that involves receiving a
3989 message, we can just skip over the ACL information. No need to parse it.
3991 First, we have a function for acl_read() to call back to get the next line. We
3992 need to remember the line we passed, because at the end it will contain the
3993 name of the next ACL. */
3995 static uschar *acl_line;
4000 acl_line = get_config_line();
4005 /* Now the main function:
4016 /* Read each ACL and add it into the tree. Macro (re)definitions are allowed
4019 acl_line = get_config_line();
4021 while(acl_line != NULL)
4027 p = readconf_readname(name, sizeof(name), acl_line);
4028 if (isupper(*name) && *p == '=')
4030 read_macro_assignment(acl_line);
4031 acl_line = get_config_line();
4035 if (*p != ':' || name[0] == 0)
4036 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing or malformed ACL name");
4038 node = store_get(sizeof(tree_node) + Ustrlen(name));
4039 Ustrcpy(node->name, name);
4040 if (!tree_insertnode(&acl_anchor, node))
4041 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4042 "there are two ACLs called \"%s\"", name);
4044 node->data.ptr = acl_read(acl_callback, &error);
4046 if (node->data.ptr == NULL && error != NULL)
4047 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "error in ACL: %s", error);
4053 /*************************************************
4054 * Read configuration for local_scan() *
4055 *************************************************/
4057 /* This function is called after "begin local_scan" is encountered in the
4058 configuration file. If the local_scan() function allows for configuration
4059 options, we can process them. Otherwise, we expire in a panic.
4066 local_scan_init(void)
4068 #ifndef LOCAL_SCAN_HAS_OPTIONS
4069 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "local_scan() options not supported: "
4070 "(LOCAL_SCAN_HAS_OPTIONS not defined in Local/Makefile)");
4074 while ((p = get_config_line()) != NULL)
4076 (void) readconf_handle_option(p, local_scan_options, local_scan_options_count,
4077 NULL, US"local_scan option \"%s\" unknown");
4084 /*************************************************
4085 * Read rest of configuration (after main) *
4086 *************************************************/
4088 /* This function reads the rest of the runtime configuration, after the main
4089 configuration. It is called only when actually needed. Each subsequent section
4090 of the configuration starts with a line of the form
4094 where the name is "routers", "transports", etc. A section is terminated by
4095 hitting the next "begin" line, and the next name is left in next_section.
4096 Because it may confuse people as to whether the names are singular or plural,
4097 we add "s" if it's missing. There is always enough room in next_section for
4098 this. This function is basically just a switch.
4104 static uschar *section_list[] = {
4118 while(next_section[0] != 0)
4122 int last = sizeof(section_list) / sizeof(uschar *);
4124 int n = Ustrlen(next_section);
4126 if (tolower(next_section[n-1]) != 's') Ustrcpy(next_section+n, "s");
4130 int c = strcmpic(next_section, section_list[mid]);
4132 if (c > 0) first = mid + 1; else last = mid;
4134 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4135 "\"%.*s\" is not a known configuration section name", n, next_section);
4136 mid = (last + first)/2;
4140 if (((had ^= bit) & bit) == 0)
4141 log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
4142 "\"%.*s\" section is repeated in the configuration file", n,
4147 case 0: readconf_acl(); break;
4148 case 1: auths_init(); break;
4149 case 2: local_scan_init(); break;
4150 case 3: readconf_retries(); break;
4151 case 4: readconf_rewrites(); break;
4152 case 5: route_init(); break;
4153 case 6: transport_init(); break;
4157 (void)fclose(config_file);
4162 /* End of readconf.c */