tidying
[exim.git] / src / src / readconf.c
index cba33ac35bcd7ccdcc39097bdb2fc63c41a03005..7396c8bd930f7c83694bdf262b5ac1f2dc9ae3a6 100644 (file)
@@ -11,11 +11,14 @@ implementation of the conditional .ifdef etc. */
 
 #include "exim.h"
 
+extern char **environ;
+
 static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
 static void save_config_line(const uschar* line);
 static void save_config_position(const uschar *file, int line);
 static void print_config(BOOL admin);
 
+
 #define CSTATE_STACK_SIZE 10
 
 
@@ -178,6 +181,7 @@ static optionlist optionlist_config[] = {
   { "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 },
@@ -194,6 +198,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 +256,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 },
@@ -286,7 +291,7 @@ static optionlist optionlist_config[] = {
   { "host_reject_connection",   opt_stringptr,   &host_reject_connection },
   { "hosts_connection_nolog",   opt_stringptr,   &hosts_connection_nolog },
 #ifdef SUPPORT_PROXY
-  { "hosts_proxy",              opt_stringptr,   &proxy_required_hosts },
+  { "hosts_proxy",              opt_stringptr,   &hosts_proxy },
 #endif
   { "hosts_treat_as_local",     opt_stringptr,   &hosts_treat_as_local },
 #ifdef LOOKUP_IBASE
@@ -295,6 +300,7 @@ static optionlist optionlist_config[] = {
   { "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 },
@@ -375,7 +381,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 +419,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
@@ -2033,6 +2039,7 @@ switch (type)
 
   /*  Integer held in K: again, allow octal and hex formats, and suffixes K and
   M. */
+  /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */
 
   case opt_Kint:
     {
@@ -2548,6 +2555,7 @@ second argument is NULL. There are some special values:
   +name              print a named list item
   local_scan         print the local_scan options
   config             print the configuration as it is parsed
+  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
@@ -2696,6 +2704,23 @@ if (type == NULL)
     names_only = TRUE;
     }
 
+  else if (Ustrcmp(name, "environment") == 0)
+    {
+    if (environ)
+      {
+      uschar **p;
+      for (p = USS environ; *p; p++) ;
+      qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer);
+
+      for (p = USS environ; *p; p++)
+        {
+        if (no_labels) *(Ustrchr(*p, '=')) = '\0';
+        puts(CS *p);
+        }
+      }
+    return;
+    }
+
   else
     {
     print_ol(find_option(name, optionlist_config, optionlist_config_size),
@@ -3021,6 +3046,7 @@ const uschar *list = config_main_filelist;
 while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
        != NULL)
   {
+
   /* Cut out all the fancy processing unless specifically wanted */
 
   #if defined(CONFIGURE_FILE_USE_NODE) || defined(CONFIGURE_FILE_USE_EUID)
@@ -3074,6 +3100,15 @@ while((filename = string_nextinlist(&list, &sep, big_buffer, big_buffer_size))
   if (config_file != NULL || errno != ENOENT) break;
   }
 
+/* Now, once we found and opened our configuration file, we change the directory
+to a safe place. Later we change to $spool_directory. */
+
+if (Uchdir("/") < 0)
+  {
+  perror("exim: chdir `/': ");
+  exit(EXIT_FAILURE);
+  }
+
 /* On success, save the name for verification; config_filename is used when
 logging configuration errors (it changes for .included files) whereas
 config_main_filename is the name shown by -bP. Failure to open a configuration
@@ -3466,6 +3501,11 @@ if (gnutls_require_kx || gnutls_require_mac || gnutls_require_proto)
       " gnutls_require_kx, gnutls_require_mac and gnutls_require_protocols"
       " are obsolete\n");
 #endif /*SUPPORT_TLS*/
+
+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");
 }
 
 
@@ -4275,7 +4315,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 */
@@ -4285,48 +4325,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;
     }
 
-  /* hidden lines (MACROS or prefixed with hide) */
-  if (!admin && (isupper(*current)
-    || (strncmp(current, "hide", 4) == 0 && isspace(current[4]))))
+  /* hidden lines (all MACROS or lines prefixed with "hide") */
+  else if (  !admin
+         && (  isupper(*current)
+            || Ustrncmp(current, "hide", 4) == 0 && isspace(current[4])
+            )
+         )
     {
-    if (p = strchr(current, '='))
+    if ((p = Ustrchr(current, '=')))
       {
       *p = '\0';
-      printf("%*s%s = %s\n", indent, "", current, hidden);
+      printf("%*s%s= %s\n", indent, "", current, hidden);
       }
     /* e.g.: hide split_spool_directory */
-    else printf("%*s\n", indent, hidden);
-    continue;
+    else
+      printf("%*s\n", indent, hidden);
     }
 
-  /* rest is public */
-  printf("%*s%s\n", indent, "", current);
-  continue;
+  else
+    /* rest is public */
+    printf("%*s%s\n", indent, "", current);
   }
 }