Flush SMTP output buffer before "delay" in an ACL; add control =
[exim.git] / src / src / acl.c
index 3e06cdf303a15474dcd3ccf597659e25cd7fb9c2..517063635fc77e224615e880e0bcce50d89c7108 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.69 2007/01/30 11:45:20 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.70 2007/02/05 12:35:46 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -187,7 +187,8 @@ enum {
   CONTROL_FAKEDEFER,
   CONTROL_FAKEREJECT,
   CONTROL_NO_MULTILINE,
-  CONTROL_NO_PIPELINING
+  CONTROL_NO_PIPELINING,
+  CONTROL_NO_DELAY_FLUSH
 };
 
 /* ACL control names; keep in step with the table above! This list is used for
@@ -219,9 +220,10 @@ static uschar *controls[] = {
   US"fakereject",
   US"no_multiline",
   US"no_pipelining",
+  US"no_delay_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. */
 
@@ -593,6 +595,9 @@ static unsigned int control_forbids[] = {
     (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)
 };
 
@@ -616,6 +621,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_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 },
@@ -2605,6 +2611,10 @@ for (; cb != NULL; cb = cb->next)
       pipelining_enable = FALSE;
       break;
 
+      case CONTROL_NO_DELAY_FLUSH:
+      disable_delay_flush = TRUE;
+      break;
+
       case CONTROL_FAKEDEFER:
       case CONTROL_FAKEREJECT:
       fake_response = (control_type == CONTROL_FAKEDEFER) ? DEFER : FAIL;
@@ -2720,13 +2730,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) fflush(smtp_out);
           while (delay > 0) delay = sleep(delay);
           }
         }