Split long fakereject and fakedefer messages.
[exim.git] / src / src / acl.c
index a79c31cb52800722498f9bcd574a9302b5427fd4..78b30addc04c8c060747eec9dbca8bb2daa27163 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.67 2006/11/14 16:40:36 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.73 2007/02/07 11:24:56 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2006 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Code for handling Access Control Lists (ACLs) */
@@ -186,7 +186,10 @@ enum {
   #endif
   CONTROL_FAKEDEFER,
   CONTROL_FAKEREJECT,
-  CONTROL_NO_MULTILINE
+  CONTROL_NO_MULTILINE,
+  CONTROL_NO_PIPELINING,
+  CONTROL_NO_DELAY_FLUSH,
+  CONTROL_NO_CALLOUT_FLUSH
 };
 
 /* ACL control names; keep in step with the table above! This list is used for
@@ -214,10 +217,15 @@ static uschar *controls[] = {
   #ifdef WITH_CONTENT_SCAN
   US"no_mbox_unspool",
   #endif
-  US"no_multiline"
+  US"fakedefer",
+  US"fakereject",
+  US"no_multiline",
+  US"no_pipelining",
+  US"no_delay_flush",
+  US"no_callout_flush"
 };
 
-/* Flags to indicate for which conditions /modifiers a string expansion is done
+/* Flags to indicate for which conditions/modifiers a string expansion is done
 at the outer level. In the other cases, expansion already occurs in the
 checking functions. */
 
@@ -586,6 +594,15 @@ static unsigned int control_forbids[] = {
     (1<<ACL_WHERE_MIME)),
 
   (1<<ACL_WHERE_NOTSMTP)|                          /* no_multiline */
+    (1<<ACL_WHERE_NOTSMTP_START),
+
+  (1<<ACL_WHERE_NOTSMTP)|                          /* no_pipelining */
+    (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)
 };
 
@@ -609,8 +626,11 @@ 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 },
+  { US"no_pipelining",           CONTROL_NO_PIPELINING, FALSE },
   { US"queue_only",              CONTROL_QUEUE_ONLY, FALSE },
 #ifdef WITH_CONTENT_SCAN
   { US"no_mbox_unspool",         CONTROL_NO_MBOX_UNSPOOL, FALSE },
@@ -2593,6 +2613,18 @@ for (; cb != NULL; cb = cb->next)
       no_multiline_responses = TRUE;
       break;
 
+      case CONTROL_NO_PIPELINING:
+      pipelining_enable = FALSE;
+      break;
+
+      case CONTROL_NO_DELAY_FLUSH:
+      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;
@@ -2708,13 +2740,18 @@ for (; cb != NULL; cb = cb->next)
         can't. The poll() function does not do the right thing, and in any case
         it is not always available.
 
-        NOTE: If ever this state of affairs changes, remember that we may be
+        NOTE 1: If ever this state of affairs changes, remember that we may be
         dealing with stdin/stdout here, in addition to TCP/IP connections.
-        Whatever is done must work in both cases. To detected the stdin/stdout
-        case, check for smtp_in or smtp_out being NULL. */
+        Also, delays may be specified for non-SMTP input, where smtp_out and
+        smtp_in will be NULL. Whatever is done must work in all cases.
+
+        NOTE 2: The added feature of flushing the output before a delay must
+        apply only to SMTP input. Hence the test for smtp_out being non-NULL.
+        */
 
         else
           {
+          if (smtp_out != NULL && !disable_delay_flush) mac_smtp_fflush();
           while (delay > 0) delay = sleep(delay);
           }
         }
@@ -3610,48 +3647,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;
 }