Redis: move from Experimental to mainline
[exim.git] / src / src / expand.c
index 89e0ac7794f54526f74e3fe87534a6757a91dafa..a51dac5700b6db164dc51c6314060edc0a1ce2df 100644 (file)
@@ -111,7 +111,7 @@ static uschar *item_table[] = {
   US"hash",
   US"hmac",
   US"if",
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
   US"imapfolder",
 #endif
   US"length",
@@ -141,7 +141,7 @@ enum {
   EITEM_HASH,
   EITEM_HMAC,
   EITEM_IF,
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
   EITEM_IMAPFOLDER,
 #endif
   EITEM_LENGTH,
@@ -173,7 +173,7 @@ static uschar *op_table_underscore[] = {
   US"reverse_ip",
   US"time_eval",
   US"time_interval"
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
  ,US"utf8_domain_from_alabel",
   US"utf8_domain_to_alabel",
   US"utf8_localpart_from_alabel",
@@ -188,7 +188,7 @@ enum {
   EOP_REVERSE_IP,
   EOP_TIME_EVAL,
   EOP_TIME_INTERVAL
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
  ,EOP_UTF8_DOMAIN_FROM_ALABEL,
   EOP_UTF8_DOMAIN_TO_ALABEL,
   EOP_UTF8_LOCALPART_FROM_ALABEL,
@@ -210,6 +210,8 @@ static uschar *op_table_main[] = {
   US"hash",
   US"hex2b64",
   US"hexquote",
+  US"ipv6denorm",
+  US"ipv6norm",
   US"l",
   US"lc",
   US"length",
@@ -248,6 +250,8 @@ enum {
   EOP_HASH,
   EOP_HEX2B64,
   EOP_HEXQUOTE,
+  EOP_IPV6DENORM,
+  EOP_IPV6NORM,
   EOP_L,
   EOP_LC,
   EOP_LENGTH,
@@ -462,6 +466,7 @@ static var_entry var_table[] = {
   { "bounce_return_size_limit", vtype_int,    &bounce_return_size_limit },
   { "caller_gid",          vtype_gid,         &real_gid },
   { "caller_uid",          vtype_uid,         &real_uid },
+  { "callout_address",     vtype_stringptr,   &callout_address },
   { "compile_date",        vtype_stringptr,   &version_date },
   { "compile_number",      vtype_stringptr,   &version_cnumber },
   { "config_dir",          vtype_stringptr,   &config_main_directory },
@@ -488,6 +493,7 @@ static var_entry var_table[] = {
   { "dkim_headernames",    vtype_dkim,        (void *)DKIM_HEADERNAMES },
   { "dkim_identity",       vtype_dkim,        (void *)DKIM_IDENTITY },
   { "dkim_key_granularity",vtype_dkim,        (void *)DKIM_KEY_GRANULARITY },
+  { "dkim_key_length",     vtype_int,         &dkim_key_length },
   { "dkim_key_nosubdomains",vtype_dkim,       (void *)DKIM_NOSUBDOMAINS },
   { "dkim_key_notes",      vtype_dkim,        (void *)DKIM_KEY_NOTES },
   { "dkim_key_srvtype",    vtype_dkim,        (void *)DKIM_KEY_SRVTYPE },
@@ -510,7 +516,7 @@ static var_entry var_table[] = {
   { "dnslist_value",       vtype_stringptr,   &dnslist_value },
   { "domain",              vtype_stringptr,   &deliver_domain },
   { "domain_data",         vtype_stringptr,   &deliver_domain_data },
-#ifdef EXPERIMENTAL_EVENT
+#ifndef DISABLE_EVENT
   { "event_data",          vtype_stringptr,   &event_data },
 
   /*XXX want to use generic vars for as many of these as possible*/
@@ -567,7 +573,7 @@ static var_entry var_table[] = {
   { "message_id",          vtype_stringptr,   &message_id },
   { "message_linecount",   vtype_int,         &message_linecount },
   { "message_size",        vtype_int,         &message_size },
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
   { "message_smtputf8",    vtype_bool,        &message_smtputf8 },
 #endif
 #ifdef WITH_CONTENT_SCAN
@@ -605,13 +611,16 @@ static var_entry var_table[] = {
   { "parent_domain",       vtype_stringptr,   &deliver_domain_parent },
   { "parent_local_part",   vtype_stringptr,   &deliver_localpart_parent },
   { "pid",                 vtype_pid,         NULL },
+#ifndef DISABLE_PRDR
+  { "prdr_requested",      vtype_bool,        &prdr_requested },
+#endif
   { "primary_hostname",    vtype_stringptr,   &primary_hostname },
-#ifdef EXPERIMENTAL_PROXY
-  { "proxy_host_address",  vtype_stringptr,   &proxy_host_address },
-  { "proxy_host_port",     vtype_int,         &proxy_host_port },
+#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
+  { "proxy_external_address",vtype_stringptr, &proxy_external_address },
+  { "proxy_external_port", vtype_int,         &proxy_external_port },
+  { "proxy_local_address", vtype_stringptr,   &proxy_local_address },
+  { "proxy_local_port",    vtype_int,         &proxy_local_port },
   { "proxy_session",       vtype_bool,        &proxy_session },
-  { "proxy_target_address",vtype_stringptr,   &proxy_target_address },
-  { "proxy_target_port",   vtype_int,         &proxy_target_port },
 #endif
   { "prvscheck_address",   vtype_stringptr,   &prvscheck_address },
   { "prvscheck_keynum",    vtype_stringptr,   &prvscheck_keynum },
@@ -1266,7 +1275,7 @@ certfield * cp;
 
 if (!(vp = find_var_ent(certvar)))
   {
-  expand_string_message = 
+  expand_string_message =
     string_sprintf("no variable named \"%s\"", certvar);
   return NULL;          /* Unknown variable name */
   }
@@ -1274,7 +1283,7 @@ if (!(vp = find_var_ent(certvar)))
 want to do that in future */
 if (vp->type != vtype_cert)
   {
-  expand_string_message = 
+  expand_string_message =
     string_sprintf("\"%s\" is not a certificate", certvar);
   return NULL;          /* Unknown variable name */
   }
@@ -1294,7 +1303,7 @@ for(cp = certfields;
     return (*cp->getfn)( *(void **)vp->value, modifier );
     }
 
-expand_string_message = 
+expand_string_message =
   string_sprintf("bad field selector \"%s\" for certextract", field);
 return NULL;
 }
@@ -1726,7 +1735,14 @@ if (Ustrncmp(name, "auth", 4) == 0)
   uschar *endptr;
   int n = Ustrtoul(name + 4, &endptr, 10);
   if (*endptr == 0 && n != 0 && n <= AUTH_VARS)
-    return (auth_vars[n-1] == NULL)? US"" : auth_vars[n-1];
+    return !auth_vars[n-1] ? US"" : auth_vars[n-1];
+  }
+else if (Ustrncmp(name, "regex", 5) == 0)
+  {
+  uschar *endptr;
+  int n = Ustrtoul(name + 5, &endptr, 10);
+  if (*endptr == 0 && n != 0 && n <= REGEX_VARS)
+    return !regex_vars[n-1] ? US"" : regex_vars[n-1];
   }
 
 /* For all other variables, search the table */
@@ -4079,7 +4095,7 @@ while (*s != 0)
       continue;
       }
 
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
     case EITEM_IMAPFOLDER:
       {                                /* ${imapfolder {name}{sep]{specials}} */
       uschar *sub_arg[3];
@@ -4100,9 +4116,9 @@ while (*s != 0)
        }
       else if (Ustrlen(sub_arg[1]) != 1)
        {
-       expand_string_message = 
+       expand_string_message =
          string_sprintf(
-               "IMAP folder separator must be one character, found \"%s\"", 
+               "IMAP folder separator must be one character, found \"%s\"",
                sub_arg[1]);
        goto EXPAND_FAILED;
        }
@@ -6395,6 +6411,39 @@ while (*s != 0)
         continue;
         }
 
+      case EOP_IPV6NORM:
+      case EOP_IPV6DENORM:
+       {
+        int type = string_is_ip_address(sub, NULL);
+       int binary[4];
+       uschar buffer[44];
+
+       switch (type)
+         {
+         case 6:
+           (void) host_aton(sub, binary);
+           break;
+
+         case 4:       /* convert to IPv4-mapped IPv6 */
+           binary[0] = binary[1] = 0;
+           binary[2] = 0x0000ffff;
+           (void) host_aton(sub, binary+3);
+           break;
+
+         case 0:
+           expand_string_message =
+             string_sprintf("\"%s\" is not an IP address", sub);
+           goto EXPAND_FAILED;
+         }
+
+       yield = string_cat(yield, &size, &ptr, buffer,
+                 c == EOP_IPV6NORM
+                   ? ipv6_nmtoa(binary, buffer)
+                   : host_nmtoa(4, binary, -1, buffer, ':')
+                 );
+       continue;
+       }
+
       case EOP_ADDRESS:
       case EOP_LOCAL_PART:
       case EOP_DOMAIN:
@@ -6628,7 +6677,7 @@ while (*s != 0)
         }
 
          /* replace illegal UTF-8 sequences by replacement character  */
-         
+
       #define UTF8_REPLACEMENT_CHAR US"?"
 
       case EOP_UTF8CLEAN:
@@ -6637,7 +6686,7 @@ while (*s != 0)
         int bytes_left = 0;
        long codepoint = -1;
         uschar seq_buff[4];                    /* accumulate utf-8 here */
-        
+
         while (*sub != 0)
          {
          int complete = 0;
@@ -6708,7 +6757,7 @@ while (*s != 0)
         continue;
         }
 
-#ifdef EXPERIMENTAL_INTERNATIONAL
+#ifdef SUPPORT_I18N
       case EOP_UTF8_DOMAIN_TO_ALABEL:
        {
         uschar * error = NULL;
@@ -7433,22 +7482,22 @@ for (i = 1; i < argc; i++)
     if (Ustrspn(argv[i], "abcdefghijklmnopqrtsuvwxyz0123456789-.:/") ==
         Ustrlen(argv[i]))
       {
-      #ifdef LOOKUP_LDAP
+#ifdef LOOKUP_LDAP
       eldap_default_servers = argv[i];
-      #endif
-      #ifdef LOOKUP_MYSQL
+#endif
+#ifdef LOOKUP_MYSQL
       mysql_servers = argv[i];
-      #endif
-      #ifdef LOOKUP_PGSQL
+#endif
+#ifdef LOOKUP_PGSQL
       pgsql_servers = argv[i];
-      #endif
-      #ifdef EXPERIMENTAL_REDIS
+#endif
+#ifdef LOOKUP_REDIS
       redis_servers = argv[i];
-      #endif
+#endif
       }
-  #ifdef EXIM_PERL
+#ifdef EXIM_PERL
   else opt_perl_startup = argv[i];
-  #endif
+#endif
   }
 
 printf("Testing string expansion: debug_level = %d\n\n", debug_level);