Support secondary-separator specifier for MX, SRV and TLSA dnsdb lookups
[exim.git] / src / src / expand.c
index 70d7c7d2ff61ef892d8b244f11c440d40a34f408..a929e937c05c8fe5175406e481998675322cca03 100644 (file)
@@ -501,6 +501,7 @@ static var_entry var_table[] = {
   { "host_data",           vtype_stringptr,   &host_data },
   { "host_lookup_deferred",vtype_int,         &host_lookup_deferred },
   { "host_lookup_failed",  vtype_int,         &host_lookup_failed },
+  { "host_port",           vtype_int,         &deliver_host_port },
   { "inode",               vtype_ino,         &deliver_inode },
   { "interface_address",   vtype_stringptr,   &interface_address },
   { "interface_port",      vtype_int,         &interface_port },
@@ -684,6 +685,9 @@ static var_entry var_table[] = {
   { "tls_out_bits",        vtype_int,         &tls_out.bits },
   { "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified },
   { "tls_out_cipher",      vtype_stringptr,   &tls_out.cipher },
+#ifdef EXPERIMENTAL_DANE
+  { "tls_out_dane",        vtype_bool,        &tls_out.dane_verified },
+#endif
   { "tls_out_ocsp",        vtype_int,         &tls_out.ocsp },
   { "tls_out_ourcert",     vtype_cert,        &tls_out.ourcert },
   { "tls_out_peercert",    vtype_cert,        &tls_out.peercert },
@@ -691,6 +695,9 @@ static var_entry var_table[] = {
 #if defined(SUPPORT_TLS)
   { "tls_out_sni",         vtype_stringptr,   &tls_out.sni },
 #endif
+#ifdef EXPERIMENTAL_DANE
+  { "tls_out_tlsa_usage",  vtype_int,         &tls_out.tlsa_usage },
+#endif
 
   { "tls_peerdn",          vtype_stringptr,   &tls_in.peerdn },        /* mind the alphabetical order! */
 #if defined(SUPPORT_TLS)
@@ -706,14 +713,12 @@ static var_entry var_table[] = {
   { "tod_zone",            vtype_todzone,     NULL },
   { "tod_zulu",            vtype_todzulu,     NULL },
 #ifdef EXPERIMENTAL_TPDA
+  { "tpda_data",           vtype_stringptr,   &tpda_data },
+
+  /*XXX want to use generic vars for as many of these as possible*/
   { "tpda_defer_errno",     vtype_int,         &tpda_defer_errno },
-  { "tpda_defer_errstr",    vtype_stringptr,   &tpda_defer_errstr },
-  { "tpda_delivery_confirmation", vtype_stringptr,   &tpda_delivery_confirmation },
-  { "tpda_delivery_domain", vtype_stringptr,   &tpda_delivery_domain },
-  { "tpda_delivery_fqdn",   vtype_stringptr,   &tpda_delivery_fqdn },
-  { "tpda_delivery_ip",     vtype_stringptr,   &tpda_delivery_ip },
-  { "tpda_delivery_local_part",vtype_stringptr,&tpda_delivery_local_part },
-  { "tpda_delivery_port",   vtype_int,         &tpda_delivery_port },
+
+  { "tpda_event",          vtype_stringptr,   &tpda_event },
 #endif
   { "transport_name",      vtype_stringptr,   &transport_name },
   { "value",               vtype_stringptr,   &lookup_value },
@@ -913,7 +918,9 @@ vaguely_random_number(int max)
 #ifdef HAVE_ARC4RANDOM
       /* cryptographically strong randomness, common on *BSD platforms, not
       so much elsewhere.  Alas. */
+#ifndef NOT_HAVE_ARC4RANDOM_STIR
       arc4random_stir();
+#endif
 #elif defined(HAVE_SRANDOM) || defined(HAVE_SRANDOMDEV)
 #ifdef HAVE_SRANDOMDEV
       /* uses random(4) for seeding */
@@ -2745,6 +2752,8 @@ switch(cond_type)
       uschar *save_iterate_item = iterate_item;
       int (*compare)(const uschar *, const uschar *);
 
+      DEBUG(D_expand) debug_printf("condition: %s\n", name);
+
       tempcond = FALSE;
       if (cond_type == ECOND_INLISTI)
         compare = strcmpic;
@@ -2832,6 +2841,8 @@ switch(cond_type)
     int sep = 0;
     uschar *save_iterate_item = iterate_item;
 
+    DEBUG(D_expand) debug_printf("condition: %s\n", name);
+
     while (isspace(*s)) s++;
     if (*s++ != '{') goto COND_FAILED_CURLY_START;     /* }-for-text-editors */
     sub[0] = expand_string_internal(s, TRUE, &s, (yield == NULL), TRUE, resetok);
@@ -5222,25 +5233,28 @@ while (*s != 0)
             while (len > 0 && isspace(p[len-1])) len--;
             p[len] = 0;
 
-            if (*p == 0 && !skipping)
-              {
-              expand_string_message = US"first argument of \"extract\" must "
-                "not be empty";
-              goto EXPAND_FAILED;
-              }
+            if (!skipping)
+             {
+             if (*p == 0)
+               {
+               expand_string_message = US"first argument of \"extract\" must "
+                 "not be empty";
+               goto EXPAND_FAILED;
+               }
 
-            if (*p == '-')
-              {
-              field_number = -1;
-              p++;
-              }
-            while (*p != 0 && isdigit(*p)) x = x * 10 + *p++ - '0';
-            if (*p == 0)
-              {
-              field_number *= x;
-              j = 3;               /* Need 3 args */
-              field_number_set = TRUE;
-              }
+             if (*p == '-')
+               {
+               field_number = -1;
+               p++;
+               }
+             while (*p != 0 && isdigit(*p)) x = x * 10 + *p++ - '0';
+             if (*p == 0)
+               {
+               field_number *= x;
+               j = 3;               /* Need 3 args */
+               field_number_set = TRUE;
+               }
+             }
             }
           }
         else goto EXPAND_FAILED_CURLY;
@@ -6368,18 +6382,16 @@ while (*s != 0)
 
       case EOP_UTF8CLEAN:
         {
-        int seq_len, index = 0;
+        int seq_len = 0, index = 0;
         int bytes_left = 0;
+       long codepoint = -1;
         uschar seq_buff[4];                    /* accumulate utf-8 here */
         
         while (*sub != 0)
          {
-         int complete;
-         long codepoint;
-         uschar c;
+         int complete = 0;
+         uschar c = *sub++;
 
-         complete = 0;
-         c = *sub++;
          if (bytes_left)
            {
            if ((c & 0xc0) != 0x80)
@@ -6394,7 +6406,7 @@ while (*s != 0)
              if (--bytes_left == 0)            /* codepoint complete */
                {
                if(codepoint > 0x10FFFF)        /* is it too large? */
-                 complete = -1;        /* error */
+                 complete = -1;        /* error (RFC3629 limit) */
                else
                  {             /* finished; output utf-8 sequence */
                  yield = string_cat(yield, &size, &ptr, seq_buff, seq_len);