Builtin macros for OpenSSL options
[exim.git] / src / src / readconf.c
index 5d519e9968df2e8c4cb77b95a800bb2de8e7a69d..b4474757a7d70d7699ed6d028e4363e205e7296b 100644 (file)
@@ -15,6 +15,9 @@ implementation of the conditional .ifdef etc. */
 # 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 *);
 
@@ -123,6 +126,7 @@ static optionlist optionlist_config[] = {
 #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 },
@@ -195,7 +199,9 @@ static optionlist optionlist_config[] = {
   { "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 },
@@ -345,6 +351,9 @@ static optionlist optionlist_config[] = {
   { "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 },
@@ -403,6 +412,19 @@ for (ai = auths_available; ai->driver_name[0]; ai++)
   }
 }
 
+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*/
 
@@ -599,8 +621,8 @@ return US"";
 /* 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 *
@@ -608,18 +630,20 @@ macro_create(const uschar * name, const uschar * val, BOOL command_line)
 {
 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;
 }
 
@@ -686,7 +710,7 @@ for (m = macros; m; m = m->next)
     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;
@@ -731,7 +755,7 @@ if (redef)
 
 /* We have a new definition. */
 else
-  (void) macro_create(string_copy(name), string_copy(s), FALSE);
+  (void) macro_create(name, s, FALSE);
 return TRUE;
 }
 
@@ -741,7 +765,7 @@ 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
@@ -780,22 +804,26 @@ if (len == 0 && isupper(*s))
 /* 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, ss);
     /* Expand the buffer if necessary */
 
     while (*newlen - m->namelen + m->replen + 1 > big_buffer_size)
@@ -824,7 +852,7 @@ for (m = macros; m; m = m->next)
       }
     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;
     }
   }
@@ -2398,7 +2426,7 @@ if (!ol)
 /* 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);
@@ -2757,7 +2785,7 @@ if (!type)
 
   if (Ustrcmp(name, "config") == 0)
     {
-    print_config(admin_user, no_labels);
+    print_config(f.admin_user, no_labels);
     return TRUE;
     }
 
@@ -2858,7 +2886,7 @@ else if (Ustrcmp(type, "macro") == 0)
   {
   /* 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;
@@ -2868,6 +2896,8 @@ else if (Ustrcmp(type, "macro") == 0)
       {
       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)
@@ -3263,7 +3293,7 @@ if (Uchdir("/") < 0)
 /* 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",
@@ -4389,7 +4419,7 @@ void
 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