# include "macro_predef.h"
#endif
+#define READCONF_DEBUG if (FALSE) /* Change to TRUE to enable */
+
+
static uschar * syslog_facility_str;
static void fn_smtp_receive_timeout(const uschar *, const uschar *);
#endif
{ "dns_again_means_nonexist", opt_stringptr, &dns_again_means_nonexist },
{ "dns_check_names_pattern", opt_stringptr, &check_dns_names_pattern },
+ { "dns_cname_loops", opt_int, &dns_cname_loops },
{ "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 },
{ "local_from_prefix", opt_stringptr, &local_from_prefix },
{ "local_from_suffix", opt_stringptr, &local_from_suffix },
{ "local_interfaces", opt_stringptr, &local_interfaces },
+#ifdef HAVE_LOCAL_SCAN
{ "local_scan_timeout", opt_time, &local_scan_timeout },
+#endif
{ "local_sender_retain", opt_bool, &local_sender_retain },
{ "localhost_number", opt_stringptr, &host_number_string },
{ "log_file_path", opt_stringptr, &log_file_path },
{ "timezone", opt_stringptr, &timezone_string },
{ "tls_advertise_hosts", opt_stringptr, &tls_advertise_hosts },
#ifdef SUPPORT_TLS
+# ifdef EXPERIMENTAL_REQUIRETLS
+ { "tls_advertise_requiretls", opt_stringptr, &tls_advertise_requiretls },
+# endif
{ "tls_certificate", opt_stringptr, &tls_certificate },
{ "tls_crl", opt_stringptr, &tls_crl },
{ "tls_dh_max_bits", opt_int, &tls_dh_max_bits },
}
}
+void
+options_logging(void)
+{
+bit_table * bp;
+uschar buf[64];
+
+for (bp = log_options; bp < log_options + log_options_count; bp++)
+ {
+ spf(buf, sizeof(buf), US"_LOG_%T", bp->name);
+ builtin_macro_create(buf);
+ }
+}
+
#else /*!MACRO_PREDEF*/
/* We have a new definition; append to the list.
Args:
- name Name of the macro. Must be in storage persistent past the call
- val Expansion result for the macro. Ditto persistence.
+ name Name of the macro; will be copied
+ val Expansion result for the macro; will be copied
*/
macro_item *
{
macro_item * m = store_get(sizeof(macro_item));
-/* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */
+READCONF_DEBUG fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val);
m->next = NULL;
m->command_line = command_line;
m->namelen = Ustrlen(name);
m->replen = Ustrlen(val);
-m->name = name;
-m->replacement = val;
+m->name = string_copy(name);
+m->replacement = string_copy(val);
if (mlast)
mlast->next = m;
else
macros = m;
mlast = m;
+if (!macros_user)
+ macros_user = m;
return m;
}
if (!m->command_line && !redef)
{
log_write(0, LOG_CONFIG|LOG_PANIC, "macro \"%s\" is already "
- "defined (use \"==\" if you want to redefine it", name);
+ "defined (use \"==\" if you want to redefine it)", name);
return FALSE;
}
break;
/* We have a new definition. */
else
- (void) macro_create(string_copy(name), string_copy(s), FALSE);
+ (void) macro_create(name, s, FALSE);
return TRUE;
}
/* Process line for macros. The line is in big_buffer starting at offset len.
Expand big_buffer if needed. Handle definitions of new macros, and
-imacro expansions, rewriting the line in thw buffer.
+macro expansions, rewriting the line in the buffer.
Arguments:
len Offset in buffer of start of line
/* Skip leading chars which cannot start a macro name, to avoid multiple
pointless rescans in Ustrstr calls. */
-while (*s && !isupper(*s) && *s != '_') s++;
+while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
/* For each defined macro, scan the line (from after XXX= if present),
replacing all occurrences of the macro. */
*macro_found = FALSE;
-for (m = macros; m; m = m->next)
+if (*s) for (m = *s == '_' ? macros : macros_user; m; m = m->next)
{
uschar * p, *pp;
- uschar * t = s;
+ uschar * t;
+
+ while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
+ if (!*s) break;
+ t = s;
while ((p = Ustrstr(t, m->name)) != NULL)
{
int moveby;
-/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */
+ READCONF_DEBUG fprintf(stderr, "%s: matched '%s' in '%.*s'\n", __FUNCTION__,
+ m->name, (int) Ustrlen(ss)-1, ss);
/* Expand the buffer if necessary */
while (*newlen - m->namelen + m->replen + 1 > big_buffer_size)
}
Ustrncpy(p, m->replacement, m->replen);
t = p + m->replen;
- while (*t && !isupper(*t) && *t != '_') t++;
+ while (*t && !isupper(*t) && !(*t == '_' && isupper(t[1]))) t++;
*macro_found = TRUE;
}
}
/* Non-admin callers cannot see options that have been flagged secure by the
"hide" prefix. */
-if (!admin_user && ol->type & opt_secure)
+if (!f.admin_user && ol->type & opt_secure)
{
if (no_labels)
printf("%s\n", hidden);
if (Ustrcmp(name, "config") == 0)
{
- print_config(admin_user, no_labels);
+ print_config(f.admin_user, no_labels);
return TRUE;
}
{
/* People store passwords in macros and they were previously not available
for printing. So we have an admin_users restriction. */
- if (!admin_user)
+ if (!f.admin_user)
{
fprintf(stderr, "exim: permission denied\n");
return FALSE;
{
if (names_only)
printf("%s\n", CS m->name);
+ else if (no_labels)
+ printf("%s\n", CS m->replacement);
else
printf("%s=%s\n", CS m->name, CS m->replacement);
if (name)
/* Check the status of the file we have opened, if we have retained root
privileges and the file isn't /dev/null (which *should* be 0666). */
-if (trusted_config && Ustrcmp(filename, US"/dev/null"))
+if (f.trusted_config && Ustrcmp(filename, US"/dev/null"))
{
if (fstat(fileno(config_file), &statbuf) != 0)
log_write(0, LOG_MAIN|LOG_PANIC_DIE, "failed to stat configuration file %s",
readconf_save_config(const uschar *s)
{
save_config_line(string_sprintf("# Exim Configuration (%s)",
- running_in_test_harness ? US"X" : s));
+ f.running_in_test_harness ? US"X" : s));
}
static void