Flush SMTP output buffer before "delay" in an ACL; add control =
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 5 Feb 2007 12:35:46 +0000 (12:35 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 5 Feb 2007 12:35:46 +0000 (12:35 +0000)
no_delay_flush to disable this behaviour.

doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
src/src/globals.c
src/src/globals.h
test/confs/0552 [new file with mode: 0644]
test/log/0552 [new file with mode: 0644]
test/scripts/0000-Basic/0552 [new file with mode: 0644]

index 4cb842c..6179dec 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.467 2007/01/31 16:52:12 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.468 2007/02/05 12:35:46 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -71,6 +71,8 @@ PH/13 Added ${rfc2047d: to decoded RFC 2047 strings.
 
 PH/14 Added log_selector = +pid.
 
+PH/15 Flush SMTP output before delaying, unless control=no_delay_flush is set.
+
 
 Exim version 4.66
 -----------------
index ccd5989..ae6c489 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.134 2007/01/31 16:52:12 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.135 2007/02/05 12:35:46 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -232,6 +232,10 @@ Version 4.67
     id to be added to every log line, in square brackets, immediately after the
     time and date.
 
+11. Exim has been modified so that it flushes SMTP output before implementing
+    a delay in an ACL. This behaviour can be disabled by obeying control =
+    no_delay_flush at some earlier point.
+
 
 Version 4.66
 ------------
index 3e06cdf..5170636 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);
           }
         }
index b030c7f..b3bbd7f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.67 2007/01/31 16:52:12 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.68 2007/02/05 12:35:46 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -499,6 +499,7 @@ int     demime_errorlevel      = 0;
 int     demime_ok              = 0;
 uschar *demime_reason          = NULL;
 #endif
+BOOL    disable_delay_flush    = FALSE;
 #ifdef ENABLE_DISABLE_FSYNC
 BOOL    disable_fsync          = FALSE;
 #endif
index 70227d5..570e4c8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.47 2007/01/30 15:10:59 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.48 2007/02/05 12:35:46 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -278,6 +278,7 @@ extern int     demime_errorlevel;      /* Severity of MIME error */
 extern int     demime_ok;              /* Nonzero if message has been demimed */
 extern uschar *demime_reason;          /* Reason for broken MIME container */
 #endif
+extern BOOL    disable_delay_flush;    /* Don't flush before "delay" in ACL */
 #ifdef ENABLE_DISABLE_FSYNC
 extern BOOL    disable_fsync;          /* Not for normal use */
 #endif
diff --git a/test/confs/0552 b/test/confs/0552
new file mode 100644 (file)
index 0000000..3ce7751
--- /dev/null
@@ -0,0 +1,66 @@
+# Exim test configuration 0552
+
+DDF=
+SERVER=
+
+exim_path = EXIM_PATH
+host_lookup_order = bydns
+primary_hostname = myhost.test.ex
+rfc1413_query_timeout = 0s
+spool_directory = DIR/spool
+log_file_path = DIR/spool/log/SERVER%slog
+gecos_pattern = ""
+gecos_name = CALLER_NAME
+
+# ----- Main settings -----
+
+acl_not_smtp = check_not
+acl_smtp_connect = check_connect
+acl_smtp_rcpt = check_rcpt
+
+queue_only
+
+# ----- ACL -----
+
+begin ACL
+
+check_connect:
+  accept DDF
+
+check_rcpt:
+  accept delay = 1s
+
+check_not:
+  accept delay = 1s
+         logwrite = Accept non-SMTP
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+  driver = accept
+  transport = t1
+
+
+# ----- Transports -----
+
+begin transports
+
+t1:
+  driver = smtp
+  port = PORT_D
+  hosts = 127.0.0.1
+  allow_localhost
+  command_timeout = 2s
+
+
+# ----- Retry -----
+
+begin retry
+
+* * F,1d,1s
+
+
+# End
diff --git a/test/log/0552 b/test/log/0552
new file mode 100644 (file)
index 0000000..e5a1fd8
--- /dev/null
@@ -0,0 +1,19 @@
+1999-03-02 09:44:33 10HmaX-0005vi-00 Accept non-SMTP
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx1@test.ex R=r1 T=t1 defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after MAIL FROM:<CALLER@myhost.test.ex> SIZE=1310
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx2@test.ex R=r1 T=t1 defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after MAIL FROM:<CALLER@myhost.test.ex> SIZE=1310
+1999-03-02 09:44:33 10HmaX-0005vi-00 == userx3@test.ex R=r1 T=t1 defer (dd): Connection timed out: SMTP timeout while connected to 127.0.0.1 [127.0.0.1] after MAIL FROM:<CALLER@myhost.test.ex> SIZE=1310
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
+1999-03-02 09:44:33 Start queue run: pid=pppp -qf
+1999-03-02 09:44:33 10HmaX-0005vi-00 => userx1@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmaX-0005vi-00 -> userx2@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmaX-0005vi-00 -> userx3@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]
+1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
+1999-03-02 09:44:33 End queue run: pid=pppp -qf
+
+******** SERVER ********
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225
+1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] lost while reading message data (header)
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex
diff --git a/test/scripts/0000-Basic/0552 b/test/scripts/0000-Basic/0552
new file mode 100644 (file)
index 0000000..1958dbe
--- /dev/null
@@ -0,0 +1,20 @@
+# autoflush for delay
+need_ipv4
+#
+# Put a message on the queue (queue_only is set); this tests that a
+# non-SMTP delay still works.
+exim userx1@test.ex userx2@test.ex userx3@test.ex
+****
+# This daemon is "old-style", without the flush
+exim -DSERVER=server -DDDF=control=no_delay_flush -bd -oX PORT_D
+****
+exim -qf
+****
+killdaemon
+# This daemon should flush before delaying
+exim -DSERVER=server -bd -oX PORT_D
+****
+exim -qf
+****
+killdaemon
+no_msglog_check