*/
static int
-read_message_bdat_smtp(FILE *fout)
+read_message_bdat_smtp(FILE * fout)
{
int linelength = 0, ch;
enum CH_STATE ch_state = LF_SEEN;
}
static int
-read_message_bdat_smtp_wire(FILE *fout)
+read_message_bdat_smtp_wire(FILE * fout)
{
int ch;
/* If we hit EOF on a SMTP connection, it's an error, since incoming
SMTP must have a correct "." terminator. */
- if (ch == EOF && smtp_input /* && !smtp_batched_input */)
- {
- smtp_reply = handle_lost_connection(US" (header)");
- smtp_yield = FALSE;
- goto TIDYUP; /* Skip to end of function */
- }
+ if (smtp_input /* && !smtp_batched_input */)
+ if (ch == EOF)
+ {
+ smtp_reply = handle_lost_connection(US" (header)");
+ smtp_yield = FALSE;
+ goto TIDYUP; /* Skip to end of function */
+ }
+ else if (ch == ERR)
+ goto TIDYUP;
/* See if we are at the current header's size limit - there must be at least
four bytes left. This allows for the new character plus a zero, plus two for
those from data files use just LF. Treat LF in local SMTP input as a
terminator too. Treat EOF as a line terminator always. */
- if (ch == EOF) goto EOL;
+ if (ch < 0) goto EOL;
/* FUDGE: There are sites out there that don't send CRs before their LFs, and
other MTAs accept this. We are therefore forced into this "liberalisation"
prevent further reading), and break out of the loop, having freed the
empty header, and set next = NULL to indicate no data line. */
- if (ptr == 0 && ch == '.' && f.dot_ends)
+ if (f.dot_ends && ptr == 0 && ch == '.')
{
ch = (receive_getc)(GETC_BUFFER_UNLIMITED);
if (ch == '\r')
ch = (receive_getc)(GETC_BUFFER_UNLIMITED);
if (ch != '\n')
{
- receive_ungetc(ch);
+ if (ch >= 0) receive_ungetc(ch);
ch = '\r'; /* Revert to CR */
}
}
/* Otherwise, put back the character after CR, and turn the bare CR
into LF SP. */
- ch = (receive_ungetc)(ch);
+ if (ch >= 0) (receive_ungetc)(ch);
next->text[ptr++] = '\n';
message_size++;
ch = ' ';
whitespace character. If it is, we have a continuation of this header line.
There is always space for at least one character at this point. */
- if (ch != EOF)
+ if (ch >= 0)
{
int nextch = (receive_getc)(GETC_BUFFER_UNLIMITED);
if (nextch == ' ' || nextch == '\t')
goto OVERSIZE;
continue; /* Iterate the loop */
}
- else if (nextch != EOF) (receive_ungetc)(nextch); /* For next time */
- else ch = EOF; /* Cause main loop to exit at end */
+ else if (nextch >= 0) /* not EOF, ERR etc */
+ (receive_ungetc)(nextch); /* For next time */
+ else ch = nextch; /* Cause main loop to exit at end */
}
/* We have got to the real line end. Terminate the string and release store
else
{
- uschar *p = next->text;
+ uschar * p = next->text;
/* If not a valid header line, break from the header reading loop, leaving
next != NULL, indicating that it holds the first line of the body. */
}
/* The line has been handled. If we have hit EOF, break out of the loop,
- indicating no pending data line. */
+ indicating no pending data line and no more data for the message */
- if (ch == EOF) { next = NULL; break; }
+ if (ch < 0)
+ {
+ next = NULL;
+ if (ch == EOF) message_ended = END_DOT;
+ else if (ch == ERR) message_ended = END_PROTOCOL;
+ break;
+ }
/* Set up for the next header */
/* End of file on any SMTP connection is an error. If an incoming SMTP call
is dropped immediately after valid headers, the next thing we will see is EOF.
We must test for this specially, as further down the reading of the data is
-skipped if already at EOF. */
+skipped if already at EOF.
+In CHUNKING mode, a protocol error makes us give up on the message. */
-if (smtp_input && (receive_feof)())
- {
- smtp_reply = handle_lost_connection(US" (after header)");
- smtp_yield = FALSE;
- goto TIDYUP; /* Skip to end of function */
- }
+if (smtp_input)
+ if ((receive_feof)())
+ {
+ smtp_reply = handle_lost_connection(US" (after header)");
+ smtp_yield = FALSE;
+ goto TIDYUP; /* Skip to end of function */
+ }
+ else if (message_ended == END_PROTOCOL)
+ {
+ smtp_reply = US""; /* no reply needed */
+ goto TIDYUP;
+ }
/* If this is a filter test run and no headers were read, output a warning
in case there is a mistake in the test message. */
if (poll_one_fd(fileno(smtp_in), POLLIN, 0) != 0)
{
int c = (receive_getc)(GETC_BUFFER_UNLIMITED);
- if (c != EOF) (receive_ungetc)(c); else
+ if (c != EOF) (receive_ungetc)(c);
+ else
{
smtp_notquit_exit(US"connection-lost", NULL, NULL);
smtp_reply = US""; /* No attempt to send a response */
Connecting to 127.0.0.1 port 1225 ... connected
??? 220
<<< 220 testhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO tester
+??? 250-
+<<< 250-testhost.test.ex Hello tester [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-8BITMIME
+<<< 250-8BITMIME
+??? 250-PIPELINING
+<<< 250-PIPELINING
+??? 250-CHUNKING
+<<< 250-CHUNKING
+??? 250 HELP
+<<< 250 HELP
+>>> MAIL FROM:<some5ne@some.domain>\r\nRCPT TO:<CALLER@test.ex>\r\nBDAT 86\r\nTo: Susan@random.com\r\nFrom: Sa5@random.com\r\nSubject: This is a bodyless test message\r\nRSET
+??? 250 OK
+<<< 250 OK
+??? 250 Accepted
+<<< 250 Accepted
+??? 250 86 byte chunk received
+<<< 250 86 byte chunk received
+??? 250 Reset OK
+<<< 250 Reset OK
+>>> MAIL FROM:<some6ne@some.domain>\r\nRCPT TO:<CALLER@test.ex>\r\nBDAT 86\r\nTo: Susan@random.com\r\nFrom: Sa6@random.com\r\nSubject: This is a bodyless test message\r\nBDAT 6 LAST\r\nZZ\r\n
+??? 250 OK
+<<< 250 OK
+??? 250 Accepted
+<<< 250 Accepted
+??? 250 86 byte chunk received
+<<< 250 86 byte chunk received
+??? 250- 6 byte chunk, total 93
+<<< 250- 6 byte chunk, total 93
+??? 250 OK
+<<< 250 OK id=10HmbE-0005vi-00
+>>> QUIT
+??? 221
+<<< 221 testhost.test.ex closing connection
+End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 testhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
>>> ehlo tester
??? 250-
<<< 250-testhost.test.ex Hello tester [127.0.0.1]
??? 250-
<<< 250- 98 byte chunk, total 100
??? 250
-<<< 250 OK id=10HmbE-0005vi-00
+<<< 250 OK id=10HmbF-0005vi-00
>>> quit
??? 221
<<< 221 testhost.test.ex closing connection