Ssmtp presumes a temporary lack of data on STDIN means it can send the
message off.
# (seq 1 10; sleep 1; seq 11 20; sleep 1; seq 21 30) | /usr/sbin/sendmail
[EMAIL PROTECTED]
1
2
3
4
5
6
7
8
9
10
# echo no good
no good
A delay in stdin, such as e.g. the popularity-contest script output,
causes ssmtp to send the message incomplete, ignoring the rest of the data.
Either the fcntl is reverted and ssmtp uses blocking pipes like John
Eikenberry proposed above (patch 1) - this is a quick fix;
... or the code is fixed by applying Aidas Kasparas' code which is nicer
to non-blocking pipes (patch 2). I added a timeout and corrected a typo
somewhere else in the code.
Please, someone test these patches, choose the best solution, apply it,
and close this over 3 months old bug... hopefully in time for the next
update.
Thanks,
Wouter Van Hemel
--- ssmtp-2.61/ssmtp.c 2005-09-04 18:05:20.000000000 +0200
+++ ssmtp-2.61-wvh/ssmtp.c 2005-09-04 20:01:14.000000000 +0200
@@ -1530,7 +1530,7 @@
/*prevent blocking on pipes, we really shouldnt be using
stdio functions like fgets in the first place */
- fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
+ /* fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK); */
while(fgets(buf, sizeof(buf), stdin)) {
/* Trim off \n, double leading .'s */
--- ssmtp-2.61/ssmtp.c 2005-09-04 18:05:20.000000000 +0200
+++ ssmtp-2.61-wvh/ssmtp.c 2005-09-05 01:32:55.000000000 +0200
@@ -1319,6 +1319,7 @@
struct passwd *pw;
int i, sock;
uid_t uid;
+ int timeout = 0;
outbytes = 0;
@@ -1532,7 +1533,15 @@
stdio functions like fgets in the first place */
fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
- while(fgets(buf, sizeof(buf), stdin)) {
+ /* don't hang forever when reading from stdin */
+ while(!feof(stdin) && timeout < MEDWAIT) {
+ if (!fgets(buf, sizeof(buf), stdin)) {
+ /* if nothing was received, then no transmission
+ * over smtp should be done */
+ sleep(1);
+ timeout++;
+ continue;
+ }
/* Trim off \n, double leading .'s */
standardise(buf);
@@ -1542,6 +1551,11 @@
}
/* End of body */
+ if (timeout >= MEDWAIT) {
+ log_event(LOG_ERR, "killed: timeout on stdin while reading body
-- message saved to dead.letter.");
+ die("Timeout on stdin while reading body");
+ }
+
outbytes += smtp_write(sock, ".");
(void)alarm((unsigned) MAXWAIT);
@@ -1549,7 +1563,7 @@
die("%s", buf);
}
- /* Close conection */
+ /* Close connection */
(void)signal(SIGALRM, SIG_IGN);
outbytes += smtp_write(sock, "QUIT");