TLS: Whine to log on client config of SNI under too-old OpenSSL version
[exim.git] / src / src / readconf.c
index 10ebc5e17f89aa40ffb7162788a0b89aab1f4078..9de064d958f877f83b92dd7dd3b0b1e650b3b6f5 100644 (file)
@@ -194,6 +194,7 @@ static optionlist optionlist_config[] = {
   { "bounce_message_file",      opt_stringptr,   &bounce_message_file },
   { "bounce_message_text",      opt_stringptr,   &bounce_message_text },
   { "bounce_return_body",       opt_bool,        &bounce_return_body },
+  { "bounce_return_linesize_limit", opt_mkint,   &bounce_return_linesize_limit },
   { "bounce_return_message",    opt_bool,        &bounce_return_message },
   { "bounce_return_size_limit", opt_mkint,       &bounce_return_size_limit },
   { "bounce_sender_authentication",opt_stringptr,&bounce_sender_authentication },
@@ -251,7 +252,7 @@ static optionlist optionlist_config[] = {
   { "envelope_to_remove",       opt_bool,        &envelope_to_remove },
   { "errors_copy",              opt_stringptr,   &errors_copy },
   { "errors_reply_to",          opt_stringptr,   &errors_reply_to },
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
   { "event_action",             opt_stringptr,   &event_action },
 #endif
   { "exim_group",               opt_gid,         &exim_gid },
@@ -285,6 +286,9 @@ static optionlist optionlist_config[] = {
   { "host_lookup_order",        opt_stringptr,   &host_lookup_order },
   { "host_reject_connection",   opt_stringptr,   &host_reject_connection },
   { "hosts_connection_nolog",   opt_stringptr,   &hosts_connection_nolog },
+#ifdef SUPPORT_PROXY
+  { "hosts_proxy",              opt_stringptr,   &hosts_proxy },
+#endif
   { "hosts_treat_as_local",     opt_stringptr,   &hosts_treat_as_local },
 #ifdef LOOKUP_IBASE
   { "ibase_servers",            opt_stringptr,   &ibase_servers },
@@ -354,9 +358,6 @@ static optionlist optionlist_config[] = {
   { "print_topbitchars",        opt_bool,        &print_topbitchars },
   { "process_log_path",         opt_stringptr,   &process_log_path },
   { "prod_requires_admin",      opt_bool,        &prod_requires_admin },
-#ifdef EXPERIMENTAL_PROXY
-  { "proxy_required_hosts",     opt_stringptr,   &proxy_required_hosts },
-#endif
   { "qualify_domain",           opt_stringptr,   &qualify_domain_sender },
   { "qualify_recipient",        opt_stringptr,   &qualify_domain_recipient },
   { "queue_domains",            opt_stringptr,   &queue_domains },
@@ -375,7 +376,7 @@ static optionlist optionlist_config[] = {
   { "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
+#ifdef LOOKUP_REDIS
   { "redis_servers",            opt_stringptr,   &redis_servers },
 #endif
   { "remote_max_parallel",      opt_int,         &remote_max_parallel },
@@ -413,7 +414,7 @@ static optionlist optionlist_config[] = {
   { "smtp_receive_timeout",     opt_func,        &fn_smtp_receive_timeout },
   { "smtp_reserve_hosts",       opt_stringptr,   &smtp_reserve_hosts },
   { "smtp_return_error_details",opt_bool,        &smtp_return_error_details },
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
   { "smtputf8_advertise_hosts", opt_stringptr,   &smtputf8_advertise_hosts },
 #endif
 #ifdef WITH_CONTENT_SCAN
@@ -2534,7 +2535,9 @@ causes the value of any main configuration variable to be output if the
 second argument is NULL. There are some special values:
 
   all                print all main configuration options
-  configure_file     print the name of the configuration file
+  config_file        print the name of the configuration file
+                     (configure_file will still work, for backward
+                     compatibility)
   routers            print the routers' configurations
   transports         print the transports' configuration
   authenticators     print the authenticators' configuration
@@ -2602,7 +2605,8 @@ if (type == NULL)
     return;
     }
 
-  if (Ustrcmp(name, "configure_file") == 0)
+  if ( Ustrcmp(name, "configure_file") == 0
+     ||Ustrcmp(name, "config_file") == 0)
     {
     printf("%s\n", CS config_main_filename);
     return;
@@ -4243,7 +4247,8 @@ save_config_position(const uschar *file, int line)
 
 /* Append a pre-parsed logical line to the config lines store,
 this operates on a global (static) list that holds all the pre-parsed
-config lines */
+config lines, we do no further processing here, output formatting and
+honouring of <hide> or macros will be done during output */
 static void
 save_config_line(const uschar* line)
 {
@@ -4271,7 +4276,7 @@ int indent = 0;
 
 for (i = config_lines; i; i = i->next)
   {
-  const uschar *current;
+  uschar *current;
   uschar *p;
 
   /* skip over to the first non-space */
@@ -4281,45 +4286,63 @@ for (i = config_lines; i; i = i->next)
   if (*current == '\0')
     continue;
 
-  /* TODO: Collapse or insert spaces around the first '=' */
+  /* Collapse runs of spaces. We stop this if we encounter one of the
+   * following characters: "'$, as this may indicate careful formatting */
+  for (p = current; *p; ++p)
+    {
+    uschar *next;
+    if (!isspace(*p)) continue;
+    if (*p != ' ') *p = ' ';
+
+    for (next = p; isspace(*next); ++next)
+      ;
+
+    if (next - p > 1)
+      memmove(p+1, next, Ustrlen(next)+1);
+
+    if (*next == '"' || *next == '\'' || *next == '$')
+      break;
+    }
 
   /* # lines */
   if (current[0] == '#')
-    {
-    puts(current);
-    continue;
-    }
+    puts(CCS current);
 
   /* begin lines are left aligned */
-  if (strncmp(current, "begin", 5) == 0 && isspace(current[5]))
+  else if (Ustrncmp(current, "begin", 5) == 0 && isspace(current[5]))
     {
-    puts(current);
+    puts("");
+    puts(CCS current);
     indent = TS;
-    continue;
     }
 
   /* router/acl/transport block names */
-  if (current[strlen(current)-1] == ':' && !strchr(current, '='))
+  else if (current[Ustrlen(current)-1] == ':' && !Ustrchr(current, '='))
     {
-    printf("%*s%s\n", TS, "", current);
+    printf("\n%*s%s\n", TS, "", current);
     indent = 2 * TS;
-    continue;
     }
 
-  /* as admin we don't care, as we do for "public" lines */
-  if (admin || (!isupper(*current) && (strcmp(current, "hide") != 0)))
+  /* hidden lines (all MACROS or lines prefixed with "hide") */
+  else if (  !admin
+         && (  isupper(*current)
+            || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
+            )
+         )
     {
-    printf("%*s%s\n", indent, "", current);
-    continue;
+    if ((p = Ustrchr(current, '=')))
+      {
+      *p = '\0';
+      printf("%*s%s= %s\n", indent, "", current, hidden);
+      }
+    /* e.g.: hide split_spool_directory */
+    else
+      printf("%*s\n", indent, hidden);
     }
 
-  /* hidden lines */
-  if (p = strchr(current, '='))
-    {
-    *p = '\0';
-    printf("%*s%s = %s\n", indent, "", current, hidden);
-    continue;
-    }
+  else
+    /* rest is public */
+    printf("%*s%s\n", indent, "", current);
   }
 }