Go to 20 ACL variables of each type, and make the numbers changeable at
[exim.git] / src / src / acl.c
index 06fa6e8985add3795d19ddcddf39f9bf2ca94c94..286d61568ab1c4a847848121916ba2ab8aa20444 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.47 2005/09/12 10:08:54 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.53 2005/12/12 15:58:53 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -752,17 +752,33 @@ while ((s = (*func)()) != NULL)
 
   if (c == ACLC_SET)
     {
-    if (Ustrncmp(s, "acl_", 4) != 0 || (s[4] != 'c' && s[4] != 'm') ||
-        !isdigit(s[5]) || (!isspace(s[6]) && s[6] != '='))
+    int offset, max, n;
+    uschar *endptr;
+
+    if (Ustrncmp(s, "acl_", 4) != 0) goto BAD_ACL_VAR;
+    if (s[4] == 'c')
+      {
+      offset = 0;
+      max = ACL_CVARS;
+      }
+    else if (s[4] == 'm')
       {
-      *error = string_sprintf("unrecognized name after \"set\" in ACL "
-        "modifier \"set %s\"", s);
+      offset = ACL_CVARS;
+      max = ACL_MVARS;
+      }
+    else goto BAD_ACL_VAR;
+
+    n = Ustrtoul(s + 5, &endptr, 10);
+    if ((*endptr != 0 && *endptr != '=' && !isspace(*endptr)) || n >= max)
+      {
+      BAD_ACL_VAR:
+      *error = string_sprintf("syntax error or unrecognized name after "
+        "\"set\" in ACL modifier \"set %s\"", s);
       return NULL;
       }
 
-    cond->u.varnumber = s[5] - '0';
-    if (s[4] == 'm') cond->u.varnumber += ACL_C_MAX;
-    s += 6;
+    cond->u.varnumber = n + offset;
+    s = endptr;
     while (isspace(*s)) s++;
     }
 
@@ -1146,7 +1162,7 @@ not quite kosher to treat bare domains such as EHLO 192.0.2.57 the same as
 address literals, but it's probably the most friendly thing to do. This is an
 extension to CSA, so we allow it to be turned off for proper conformance. */
 
-if (string_is_ip_address(domain, NULL))
+if (string_is_ip_address(domain, NULL) != 0)
   {
   if (!dns_csa_use_reverse) return CSA_UNKNOWN;
   dns_build_reverse(domain, target);
@@ -1391,10 +1407,8 @@ occurred earlier. If not, we can attempt the verification now. */
 if (strcmpic(ss, US"helo") == 0)
   {
   if (slash != NULL) goto NO_OPTIONS;
-  if (helo_verified) return OK;
-  if (helo_verify_failed) return FAIL;
-  if (smtp_verify_helo()) return helo_verified? OK : FAIL;
-  return DEFER;
+  if (!helo_verified && !helo_verify_failed) smtp_verify_helo();
+  return helo_verified? OK : FAIL;
   }
 
 /* Do Client SMTP Authorization checks in a separate function, and turn the
@@ -2164,16 +2178,16 @@ else
                    + (double)tv.tv_usec / 1000000.0;
   double prev_time = (double)dbd->time_stamp
                    + (double)dbd->time_usec / 1000000.0;
-  double interval = this_time - prev_time;
-
-  double i_over_p = interval / period;
-  double a = exp(-i_over_p);
 
   /* We must avoid division by zero, and deal gracefully with the clock going
   backwards. If we blunder ahead when time is in reverse then the computed
-  rate will become bogusly huge. Clamp i/p to a very small number instead. */
+  rate will be bogus. To be safe we clamp interval to a very small number. */
 
-  if (i_over_p <= 0.0) i_over_p = 1e-9;
+  double interval = this_time - prev_time <= 0.0 ? 1e-9
+                  : this_time - prev_time;
+
+  double i_over_p = interval / period;
+  double a = exp(-i_over_p);
 
   dbd->time_stamp = tv.tv_sec;
   dbd->time_usec = tv.tv_usec;
@@ -2331,8 +2345,8 @@ for (; cb != NULL; cb = cb->next)
     if (cb->type == ACLC_SET)
       {
       int n = cb->u.varnumber;
-      int t = (n < ACL_C_MAX)? 'c' : 'm';
-      if (n >= ACL_C_MAX) n -= ACL_C_MAX;
+      int t = (n < ACL_CVARS)? 'c' : 'm';
+      if (n >= ACL_CVARS) n -= ACL_CVARS;
       debug_printf("acl_%c%d ", t, n);
       lhswidth += 7;
       }
@@ -2499,10 +2513,12 @@ for (; cb != NULL; cb = cb->next)
           submission_domain = string_copyn(p+8, pp-p-8);
           p = pp;
           }
+        /* The name= option must be last, because it swallows the rest of
+        the string. */
         else if (Ustrncmp(p, "/name=", 6) == 0)
           {
           uschar *pp = p + 6;
-          while (*pp != 0 && *pp != '/') pp++;
+          while (*pp != 0) pp++;
           submission_name = string_copy(parse_fix_phrase(p+6, pp-p-6,
             big_buffer, big_buffer_size));
           p = pp;
@@ -2802,7 +2818,7 @@ for (; cb != NULL; cb = cb->next)
     case ACLC_SET:
       {
       int old_pool = store_pool;
-      if (cb->u.varnumber < ACL_C_MAX) store_pool = POOL_PERM;
+      if (cb->u.varnumber < ACL_CVARS) store_pool = POOL_PERM;
       acl_var[cb->u.varnumber] = string_copy(arg);
       store_pool = old_pool;
       }
@@ -3321,7 +3337,7 @@ while (acl != NULL)
     case ACL_WARN:
     if (cond == OK)
       acl_warn(where, *user_msgptr, *log_msgptr);
-    else if (cond == DEFER)
+    else if (cond == DEFER && (log_extra_selector & LX_acl_warn_skipped) != 0)
       log_write(0, LOG_MAIN, "%s Warning: ACL \"warn\" statement skipped: "
         "condition test deferred%s%s", host_and_ident(TRUE),
         (*log_msgptr == NULL)? US"" : US": ",