{ "acl_smtp_auth", opt_stringptr, &acl_smtp_auth },
{ "acl_smtp_connect", opt_stringptr, &acl_smtp_connect },
{ "acl_smtp_data", opt_stringptr, &acl_smtp_data },
+#ifdef EXPERIMENTAL_PRDR
+ { "acl_smtp_data_prdr", opt_stringptr, &acl_smtp_data_prdr },
+#endif
#ifndef DISABLE_DKIM
{ "acl_smtp_dkim", opt_stringptr, &acl_smtp_dkim },
#endif
{ "acl_smtp_starttls", opt_stringptr, &acl_smtp_starttls },
#endif
{ "acl_smtp_vrfy", opt_stringptr, &acl_smtp_vrfy },
+ { "add_environment", opt_stringptr, &add_environment },
{ "admin_groups", opt_gidlist, &admin_groups },
{ "allow_domain_literals", opt_bool, &allow_domain_literals },
{ "allow_mx_to_ip", opt_bool, &allow_mx_to_ip },
{ "disable_ipv6", opt_bool, &disable_ipv6 },
#ifndef DISABLE_DKIM
{ "dkim_verify_signers", opt_stringptr, &dkim_verify_signers },
+#endif
+#ifdef EXPERIMENTAL_DMARC
+ { "dmarc_forensic_sender", opt_stringptr, &dmarc_forensic_sender },
+ { "dmarc_history_file", opt_stringptr, &dmarc_history_file },
+ { "dmarc_tld_file", opt_stringptr, &dmarc_tld_file },
#endif
{ "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist },
{ "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern },
{ "dns_csa_search_limit", opt_int, &dns_csa_search_limit },
{ "dns_csa_use_reverse", opt_bool, &dns_csa_use_reverse },
+ { "dns_dnssec_ok", opt_int, &dns_dnssec_ok },
{ "dns_ipv4_lookup", opt_stringptr, &dns_ipv4_lookup },
{ "dns_retrans", opt_time, &dns_retrans },
{ "dns_retry", opt_int, &dns_retry },
{ "gecos_name", opt_stringptr, &gecos_name },
{ "gecos_pattern", opt_stringptr, &gecos_pattern },
#ifdef SUPPORT_TLS
+ { "gnutls_allow_auto_pkcs11", opt_bool, &gnutls_allow_auto_pkcs11 },
{ "gnutls_compat_mode", opt_bool, &gnutls_compat_mode },
/* These three gnutls_require_* options stopped working in Exim 4.80 */
{ "gnutls_require_kx", opt_stringptr, &gnutls_require_kx },
{ "ignore_bounce_errors_after", opt_time, &ignore_bounce_errors_after },
{ "ignore_fromline_hosts", opt_stringptr, &ignore_fromline_hosts },
{ "ignore_fromline_local", opt_bool, &ignore_fromline_local },
+ { "keep_environment", opt_stringptr, &keep_environment },
{ "keep_malformed", opt_time, &keep_malformed },
#ifdef LOOKUP_LDAP
{ "ldap_ca_cert_dir", opt_stringptr, &eldap_ca_cert_dir },
#endif
{ "pid_file_path", opt_stringptr, &pid_file_path },
{ "pipelining_advertise_hosts", opt_stringptr, &pipelining_advertise_hosts },
+#ifdef EXPERIMENTAL_PRDR
+ { "prdr_enable", opt_bool, &prdr_enable },
+#endif
{ "preserve_message_logs", opt_bool, &preserve_message_logs },
{ "primary_hostname", opt_stringptr, &primary_hostname },
{ "print_topbitchars", opt_bool, &print_topbitchars },
{ "recipient_unqualified_hosts", opt_stringptr, &recipient_unqualified_hosts },
{ "recipients_max", opt_int, &recipients_max },
{ "recipients_max_reject", opt_bool, &recipients_max_reject },
+#ifdef EXPERIMENTAL_REDIS
+ { "redis_servers", opt_stringptr, &redis_servers },
+#endif
{ "remote_max_parallel", opt_int, &remote_max_parallel },
{ "remote_sort_domains", opt_stringptr, &remote_sort_domains },
{ "retry_data_expire", opt_time, &retry_data_expire },
{ "tls_crl", opt_stringptr, &tls_crl },
{ "tls_dh_max_bits", opt_int, &tls_dh_max_bits },
{ "tls_dhparam", opt_stringptr, &tls_dhparam },
-#if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS)
+# if defined(EXPERIMENTAL_OCSP) && !defined(USE_GNUTLS)
{ "tls_ocsp_file", opt_stringptr, &tls_ocsp_file },
-#endif
- { "tls_on_connect_ports", opt_stringptr, &tls_on_connect_ports },
+# endif
+ { "tls_on_connect_ports", opt_stringptr, &tls_in.on_connect_ports },
{ "tls_privatekey", opt_stringptr, &tls_privatekey },
{ "tls_remember_esmtp", opt_bool, &tls_remember_esmtp },
{ "tls_require_ciphers", opt_stringptr, &tls_require_ciphers },
gid_t gid;
BOOL boolvalue = TRUE;
BOOL freesptr = TRUE;
-BOOL extra_condition = FALSE;
optionlist *ol, *ol2;
struct passwd *pw;
void *reset_point;
log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, CS unknown_txt, name);
}
-if ((ol->type & opt_set) != 0)
- {
- uschar *mname = name;
- if (Ustrncmp(mname, "no_", 3) == 0) mname += 3;
- if (Ustrcmp(mname, "condition") == 0)
- extra_condition = TRUE;
- else
- log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
- "\"%s\" option set for the second time", mname);
- }
+if ((ol->type & opt_set) && !(ol->type & (opt_rep_con | opt_rep_str)))
+ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
+ "\"%s\" option set for the second time", name);
ol->type |= opt_set | issecure;
type = ol->type & opt_mask;
str_target = (uschar **)(ol->value);
else
str_target = (uschar **)((uschar *)data_block + (long int)(ol->value));
- if (extra_condition)
+ if (ol->type & opt_rep_con)
{
/* We already have a condition, we're conducting a crude hack to let
multiple condition rules be chained together, despite storing them in
strtemp = string_sprintf("${if and{{bool_lax{%s}}{bool_lax{%s}}}}",
saved_condition, sptr);
*str_target = string_copy_malloc(strtemp);
- /* TODO(pdp): there is a memory leak here when we set 3 or more
- conditions; I still don't understand the store mechanism enough
- to know what's the safe way to free content from an earlier store.
+ /* TODO(pdp): there is a memory leak here and just below
+ when we set 3 or more conditions; I still don't
+ understand the store mechanism enough to know
+ what's the safe way to free content from an earlier store.
AFAICT, stores stack, so freeing an early stored item also stores
all data alloc'd after it. If we knew conditions were adjacent,
we could survive that, but we don't. So I *think* we need to take
Because we only do this once, near process start-up, I'm prepared to
let this slide for the time being, even though it rankles. */
}
+ else if (*str_target && (ol->type & opt_rep_str))
+ {
+ uschar sep = Ustrncmp(name, "headers_add", 11)==0 ? '\n' : ':';
+ saved_condition = *str_target;
+ strtemp = saved_condition + Ustrlen(saved_condition)-1;
+ if (*strtemp == sep) *strtemp = 0; /* eliminate trailing list-sep */
+ strtemp = string_sprintf("%s%c%s", saved_condition, sep, sptr);
+ *str_target = string_copy_malloc(strtemp);
+ }
else
{
*str_target = sptr;
macro_list print a list of macro names
+name print a named list item
local_scan print the local_scan options
+ environment print the used execution environment
If the second argument is not NULL, it must be one of "router", "transport",
"authenticator" or "macro" in which case the first argument identifies the
names_only = TRUE;
}
+ else if (Ustrcmp(name, "environment") == 0)
+ {
+ if (environ)
+ {
+ uschar **p;
+ size_t n;
+ for (p = USS environ; *p; p++) ;
+ n = p - USS environ;
+ qsort(environ, p - USS environ, sizeof(*p), (__compar_fn_t) string_compare_by_pointer);
+
+ for (p = USS environ; *p; p++)
+ {
+ if (no_labels) *(Ustrchr(*p, '=')) = '\0';
+ puts(*p);
+ }
+ }
+ return;
+ }
+
else
{
print_ol(find_option(name, optionlist_config, optionlist_config_size),
while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
!= NULL)
{
+
+ /* To avoid confusion: Exim changes to / at the very beginning and
+ * and to $spool_directory later. */
+ if (filename[0] != '/')
+ {
+ fprintf(stderr, "-C %s: only absolute names are allowed\n", filename);
+ exit(EXIT_FAILURE);
+ }
+
/* Cut out all the fancy processing unless specifically wanted */
#if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
# endif
}
#endif
+
+if ((!add_environment || *add_environment == '\0') && !keep_environment)
+ log_write(0, LOG_MAIN,
+ "WARNING: purging the environment.\n"
+ " Suggested action: use keep_environment and add_environment.\n");
}
pp = p;
while (mac_isgraph(*p)) p++;
if (p - pp <= 0) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN,
- "missing error type");
+ "missing error type in retry rule");
/* Test error names for things we understand. */
/* Now the main function:
-Arguments:
- skip TRUE when this Exim process is doing something that will
- not need the ACL data
-
+Arguments: none
Returns: nothing
*/
static void
-readconf_acl(BOOL skip)
+readconf_acl(void)
{
uschar *p;
-/* Not receiving messages, don't need to parse the ACL data */
-
-if (skip)
- {
- DEBUG(D_acl) debug_printf("skipping ACL configuration - not needed\n");
- while ((p = get_config_line()) != NULL);
- return;
- }
-
/* Read each ACL and add it into the tree. Macro (re)definitions are allowed
between ACLs. */
we add "s" if it's missing. There is always enough room in next_section for
this. This function is basically just a switch.
-Arguments:
- skip_acl TRUE if ACL information is not needed
-
+Arguments: none
Returns: nothing
*/
US"transports"};
void
-readconf_rest(BOOL skip_acl)
+readconf_rest(void)
{
int had = 0;
switch(mid)
{
- case 0: readconf_acl(skip_acl); break;
+ case 0: readconf_acl(); break;
case 1: auths_init(); break;
case 2: local_scan_init(); break;
case 3: readconf_retries(); break;