Add "continue" modifier.
[exim.git] / src / src / acl.c
index 0f484f21dfc33c83049f5c3217ab674bb304e7cd..afbb93e5c8ad6750a1fd8bd4f315ab68386fe3f0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.71 2007/02/06 11:16:21 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.74 2007/02/14 15:33:40 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -53,6 +53,7 @@ enum { ACLC_ACL,
        ACLC_BMI_OPTIN,
 #endif
        ACLC_CONDITION,
+       ACLC_CONTINUE,
        ACLC_CONTROL,
 #ifdef WITH_CONTENT_SCAN
        ACLC_DECODE,
@@ -101,10 +102,10 @@ enum { ACLC_ACL,
 #endif
        ACLC_VERIFY };
 
-/* ACL conditions/modifiers: "delay", "control", "endpass", "message",
-"log_message", "log_reject_target", "logwrite", and "set" are modifiers that
-look like conditions but always return TRUE. They are used for their side
-effects. */
+/* ACL conditions/modifiers: "delay", "control", "continue", "endpass",
+"message", "log_message", "log_reject_target", "logwrite", and "set" are
+modifiers that look like conditions but always return TRUE. They are used for
+their side effects. */
 
 static uschar *conditions[] = {
   US"acl",
@@ -114,6 +115,7 @@ static uschar *conditions[] = {
   US"bmi_optin",
 #endif
   US"condition",
+  US"continue",
   US"control",
 #ifdef WITH_CONTENT_SCAN
   US"decode",
@@ -188,7 +190,8 @@ enum {
   CONTROL_FAKEREJECT,
   CONTROL_NO_MULTILINE,
   CONTROL_NO_PIPELINING,
-  CONTROL_NO_DELAY_FLUSH
+  CONTROL_NO_DELAY_FLUSH,
+  CONTROL_NO_CALLOUT_FLUSH
 };
 
 /* ACL control names; keep in step with the table above! This list is used for
@@ -220,7 +223,8 @@ static uschar *controls[] = {
   US"fakereject",
   US"no_multiline",
   US"no_pipelining",
-  US"no_delay_flush"
+  US"no_delay_flush",
+  US"no_callout_flush"
 };
 
 /* Flags to indicate for which conditions/modifiers a string expansion is done
@@ -235,6 +239,7 @@ static uschar cond_expand_at_top[] = {
   TRUE,    /* bmi_optin */
 #endif
   TRUE,    /* condition */
+  TRUE,    /* continue */
   TRUE,    /* control */
 #ifdef WITH_CONTENT_SCAN
   TRUE,    /* decode */
@@ -294,6 +299,7 @@ static uschar cond_modifiers[] = {
   TRUE,    /* bmi_optin */
 #endif
   FALSE,   /* condition */
+  TRUE,    /* continue */
   TRUE,    /* control */
 #ifdef WITH_CONTENT_SCAN
   FALSE,   /* decode */
@@ -343,9 +349,9 @@ static uschar cond_modifiers[] = {
   FALSE    /* verify */
 };
 
-/* Bit map vector of which conditions are not allowed at certain times. For
-each condition, there's a bitmap of dis-allowed times. For some, it is easier
-to specify the negation of a small number of allowed times. */
+/* Bit map vector of which conditions and modifiers are not allowed at certain
+times. For each condition, there's a bitmap of dis-allowed times. For some, it
+is easier to specify the negation of a small number of allowed times. */
 
 static unsigned int cond_forbids[] = {
   0,                                               /* acl */
@@ -373,6 +379,8 @@ static unsigned int cond_forbids[] = {
 
   0,                                               /* condition */
 
+  0,                                               /* continue */
+
   /* Certain types of control are always allowed, so we let it through
   always and check in the control processing itself. */
 
@@ -598,6 +606,9 @@ static unsigned int control_forbids[] = {
     (1<<ACL_WHERE_NOTSMTP_START),
 
   (1<<ACL_WHERE_NOTSMTP)|                          /* no_delay_flush */
+    (1<<ACL_WHERE_NOTSMTP_START),
+
+  (1<<ACL_WHERE_NOTSMTP)|                          /* no_callout_flush */
     (1<<ACL_WHERE_NOTSMTP_START)
 };
 
@@ -621,6 +632,7 @@ static control_def controls_list[] = {
   { US"caselower_local_part",    CONTROL_CASELOWER_LOCAL_PART, FALSE },
   { US"enforce_sync",            CONTROL_ENFORCE_SYNC, FALSE },
   { US"freeze",                  CONTROL_FREEZE, TRUE },
+  { US"no_callout_flush",        CONTROL_NO_CALLOUT_FLUSH, FALSE },
   { US"no_delay_flush",          CONTROL_NO_DELAY_FLUSH, FALSE },
   { US"no_enforce_sync",         CONTROL_NO_ENFORCE_SYNC, FALSE },
   { US"no_multiline_responses",  CONTROL_NO_MULTILINE, FALSE },
@@ -2548,6 +2560,9 @@ for (; cb != NULL; cb = cb->next)
       *log_msgptr = string_sprintf("invalid \"condition\" value \"%s\"", arg);
     break;
 
+    case ACLC_CONTINUE:    /* Always succeeds */
+    break;
+
     case ACLC_CONTROL:
     control_type = decode_control(arg, &p, where, log_msgptr);
 
@@ -2615,6 +2630,10 @@ for (; cb != NULL; cb = cb->next)
       disable_delay_flush = TRUE;
       break;
 
+      case CONTROL_NO_CALLOUT_FLUSH:
+      disable_callout_flush = TRUE;
+      break;
+
       case CONTROL_FAKEDEFER:
       case CONTROL_FAKEREJECT:
       fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
@@ -3637,48 +3656,9 @@ if (rc == FAIL_DROP && where == ACL_WHERE_MAILAUTH)
 /* Before giving a response, take a look at the length of any user message, and
 split it up into multiple lines if possible. */
 
-if (*user_msgptr != NULL && Ustrlen(*user_msgptr) > 75)
-  {
-  uschar *s = *user_msgptr = string_copy(*user_msgptr);
-  uschar *ss = s;
-
-  for (;;)
-    {
-    int i = 0;
-    while (i < 75 && *ss != 0 && *ss != '\n') ss++, i++;
-    if (*ss == 0) break;
-    if (*ss == '\n')
-      s = ++ss;
-    else
-      {
-      uschar *t = ss + 1;
-      uschar *tt = NULL;
-      while (--t > s + 35)
-        {
-        if (*t == ' ')
-          {
-          if (t[-1] == ':') { tt = t; break; }
-          if (tt == NULL) tt = t;
-          }
-        }
-
-      if (tt == NULL)          /* Can't split behind - try ahead */
-        {
-        t = ss + 1;
-        while (*t != 0)
-          {
-          if (*t == ' ' || *t == '\n')
-            { tt = t; break; }
-          t++;
-          }
-        }
-
-      if (tt == NULL) break;   /* Can't find anywhere to split */
-      *tt = '\n';
-      s = ss = tt+1;
-      }
-    }
-  }
+*user_msgptr = string_split_message(*user_msgptr);
+if (fake_response != OK)
+  fake_response_text = string_split_message(fake_response_text);
 
 return rc;
 }