From 3c55eef24050cec9e50e98e2f5fc12cd45f1ef8a Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 5 Apr 2019 15:22:20 +0100 Subject: [PATCH] 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 5913e7a5f..bea531d33 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 0cb38626a..64f62757d 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) -- 2.25.1