[exim-cvs] Logging: close logfile when non-smtp input is tak…

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Logging: close logfile when non-smtp input is taking a long time. Bug 1891
Gitweb: https://git.exim.org/exim.git/commitdiff/3c55eef24050cec9e50e98e2f5fc12cd45f1ef8a
Commit:     3c55eef24050cec9e50e98e2f5fc12cd45f1ef8a
Parent:     bda76da8a9357f4fc525b5f8b925fae262c28010
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Fri Apr 5 15:22:20 2019 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Fri Apr 5 15:22:20 2019 +0100


    Logging: close logfile when non-smtp input is taking a long time.  Bug 1891
---
 doc/doc-txt/ChangeLog |  6 ++++++
 src/src/receive.c     | 32 +++++++++++++++++++++++++++++---
 2 files changed, 35 insertions(+), 3 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 5913e7a..bea531d 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -58,6 +58,12 @@ JH/12 Bug 2384: fix "-bP smtp_receive_timeout".  Previously it returned no
 JH/13 Bug 2386: Fix builds with Dane under LibreSSL 2.9.0 onward.  Some old
       API was removed, so update to use the newer ones.


+JH/14 Bug 1891: Close the log file if receiving a non-smtp message, without
+      any timeout set, is taking a long time.  Previous we would hang on to a
+      rotated logfile "forever" if the input was arriving with long gaps
+      (a previous attempt to fix addressed lack, for a long time, of initial
+      input).
+


Exim version 4.92
-----------------
diff --git a/src/src/receive.c b/src/src/receive.c
index 0cb3862..64f6275 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -571,6 +571,30 @@ return FALSE;



+/* Pause for a while waiting for input.  If none received in that time,
+close the logfile, if we had one open; then if we wait for a long-running
+datasource (months, in one use-case) log rotation will not leave us holding
+the file copy. */
+
+static void
+log_close_chk(void)
+{
+if (!receive_timeout)
+  {
+  struct timeval t;
+  timesince(&t, &received_time);
+  if (t.tv_sec > 30*60)
+    mainlog_close();
+  else
+    {
+    fd_set r;
+    FD_ZERO(&r); FD_SET(0, &r);
+    t.tv_sec = 30*60 - t.tv_sec; t.tv_usec = 0;
+    if (select(1, &r, NULL, NULL, &t) == 0) mainlog_close();
+    }
+  }
+}
+
 /*************************************************
 *     Read data portion of a non-SMTP message    *
 *************************************************/
@@ -619,9 +643,11 @@ register int linelength = 0;


if (!f.dot_ends)
{
- register int last_ch = '\n';
+ int last_ch = '\n';

-  for (; (ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF; last_ch = ch)
+  for ( ;
+       log_close_chk(), (ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF;
+       last_ch = ch)
     {
     if (ch == 0) body_zerocount++;
     if (last_ch == '\r' && ch != '\n')
@@ -663,7 +689,7 @@ if (!f.dot_ends)


ch_state = 1;

-while ((ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF)
+while (log_close_chk(), (ch = (receive_getc)(GETC_BUFFER_UNLIMITED)) != EOF)
{
if (ch == 0) body_zerocount++;
switch (ch_state)