From 328c5688dbe0f4c14418f22350ccd99b3fe8ac71 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Fri, 28 Apr 2017 23:54:35 +0100 Subject: [PATCH] Support wire-format spoolfiles --- doc/doc-docbook/spec.xfpt | 30 ++++++++- doc/doc-txt/NewStuff | 6 ++ doc/doc-txt/OptionLists.txt | 1 + src/src/deliver.c | 2 - src/src/dkim_transport.c | 18 +++-- src/src/globals.c | 2 + src/src/globals.h | 2 + src/src/pdkim/pdkim.c | 6 +- src/src/readconf.c | 1 + src/src/receive.c | 49 +++++++++++++- src/src/spam.c | 4 +- src/src/spool_in.c | 7 ++ src/src/spool_mbox.c | 60 +++++++++-------- src/src/spool_out.c | 5 +- src/src/transport.c | 111 +++++++++++++++++++++++++------ src/src/transports/smtp.c | 3 + src/src/verify.c | 1 + test/confs/0906 | 89 +++++++++++++++++++++++++ test/confs/4530 | 1 + test/log/0906 | 9 +++ test/log/4530 | 17 +++++ test/mail/0906.a | 109 +++++++++++++++++++++++++++++++ test/mail/4530.y | 26 ++++++++ test/mail/4530.z | 26 ++++++++ test/scripts/0000-Basic/0906 | 122 ++++++++++++++++++++++++++++++++++ test/scripts/4500-DKIM/4530 | 66 +++++++++++++++++++ test/stderr/0143 | 1 + test/stderr/0169 | 1 + test/stderr/0275 | 1 - test/stderr/0386 | 2 + test/stderr/0393 | 3 + test/stderr/0402 | 2 + test/stderr/0404 | 1 + test/stderr/0408 | 1 + test/stderr/0476 | 1 + test/stderr/0487 | 1 + test/stderr/0512 | 2 + test/stderr/2600 | 1 + test/stderr/4520 | 6 +- test/stderr/5004 | 1 + test/stderr/5005 | 2 + test/stderr/5006 | 1 + test/stderr/5008 | 2 + test/stdout/0906 | 123 +++++++++++++++++++++++++++++++++++ test/stdout/4530 | 75 +++++++++++++++++++++ 45 files changed, 930 insertions(+), 70 deletions(-) create mode 100644 test/confs/0906 create mode 120000 test/confs/4530 create mode 100644 test/log/0906 create mode 100644 test/log/4530 create mode 100644 test/mail/0906.a create mode 100644 test/mail/4530.y create mode 100644 test/mail/4530.z create mode 100644 test/scripts/0000-Basic/0906 create mode 100644 test/scripts/4500-DKIM/4530 create mode 100644 test/stdout/0906 create mode 100644 test/stdout/4530 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 7a1b491c0..e5c433fbb 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -13566,6 +13566,7 @@ listed in more than one group. .row &%message_body_visible%& "how much to show in &$message_body$&" .row &%mua_wrapper%& "run in &""MUA wrapper""& mode" .row &%print_topbitchars%& "top-bit characters are printing" +.row &%spool_wireformat%& "use wire-format spool data files when possible" .row &%timezone%& "force time zone" .endtable @@ -16821,6 +16822,25 @@ as failures in the configuration file. By using this option to override the compiled-in path, it is possible to run tests of Exim without using the standard spool. +.new +.option spool_wireformat main boolean false +.cindex "spool directory" "file formats" +If this option is set, Exim may for some messages use an alternate format +for data-files in the spool which matches the wire format. +Doing this permits more efficient message reception and transmission. +Currently it is only done for messages received using the EMSTP CHUNKING +option. + +Users of the local_scan() API (see &<>&), +and any external programs which are passed a reference to a message data file +(except via the &"regex"&, &"malware"& or &"spam"&) ACL conditions) +will need to be aware of the potential different format. + +Using any of the ACL conditions noted will negate the reception benefit +(as a Unix-mbox-format file is contructed for them). +The transimssion benefit is maintained. +.wen + .option sqlite_lock_timeout main time 5s .cindex "sqlite lookup type" "lock timeout" This option controls the timeout that the &(sqlite)& lookup uses when trying to @@ -38094,8 +38114,8 @@ The address of an authenticated sender &-- the value of the &$authenticated_sender$& variable. .vitem "&%-body_linecount%&&~<&'number'&>" -This records the number of lines in the body of the message, and is always -present. +This records the number of lines in the body of the message, and is +present unless &%-spool_file_wireformat%& is. .vitem "&%-body_zerocount%&&~<&'number'&>" This records the number of binary zero bytes in the body of the message, and is @@ -38177,6 +38197,12 @@ to ensure that the caller is displayed in queue listings). If a message was scanned by SpamAssassin, this is present. It records the value of &$spam_score_int$&. +.vitem &%-spool_file_wireformat%& +The -D file for this message is in wire-format (for ESMTP CHUNKING) +rather than Unix-format. +The line-ending is CRLF rather than newline. +There is still, however, no leading-dot-stuffing. + .vitem &%-tls_certificate_verified%& A TLS certificate was received from the client that sent this message, and the certificate was verified by the server. diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 5f446f792..cb2346f69 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -29,6 +29,12 @@ Version 4.90 6. The reproducible build $SOURCE_DATE_EPOCH environment variable is now supported. + 7. Optionally, an alternate format for spool data-files which matches the + wire format - meaning more efficient reception and transmission (at the + cost of difficulty with standard Unix tools). Only used for messages + received using the ESMTP CHUNKING option, and when a new main-section + option "spool_wireformat" (false by default) is set. + Version 4.89 ------------ diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt index b6439e6ed..95d321e5c 100644 --- a/doc/doc-txt/OptionLists.txt +++ b/doc/doc-txt/OptionLists.txt @@ -529,6 +529,7 @@ socket string* unset lmtp spamd_address string* + main 4.50 with content scan split_spool_directory boolean false main 1.70 spool_directory string ++ main +spool_wireformat boolean false main 4.90 sqlite_lock_timeout time 5s main 4.53 strict_acl_vars boolean false main 4.64 srv_fail_domains domain list unset dnslookup 4.43 diff --git a/src/src/deliver.c b/src/src/deliver.c index 2787d0040..262ae454f 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -3890,14 +3890,12 @@ for (;;) /* Normally we do not repeat this loop */ maxpipe = 0; FD_ZERO(&select_pipes); for (poffset = 0; poffset < remote_max_parallel; poffset++) - { if (parlist[poffset].pid != 0) { int fd = parlist[poffset].fd; FD_SET(fd, &select_pipes); if (fd > maxpipe) maxpipe = fd; } - } /* Stick in a 60-second timeout, just in case. */ diff --git a/src/src/dkim_transport.c b/src/src/dkim_transport.c index 2aba56054..4538b36e3 100644 --- a/src/src/dkim_transport.c +++ b/src/src/dkim_transport.c @@ -45,9 +45,6 @@ DEBUG(D_transport) debug_printf("send file fd=%d size=%d\n", out_fd, size - off) /*XXX should implement timeout, like transport_write_block_fd() ? */ -/* Rewind file */ -lseek(in_fd, off, SEEK_SET); - #ifdef HAVE_LINUX_SENDFILE /* We can use sendfile() to shove the file contents to the socket. However only if we don't use TLS, @@ -69,6 +66,9 @@ else { int sread, wwritten; + /* Rewind file */ + lseek(in_fd, off, SEEK_SET); + /* Send file down the original fd */ while((sread = read(in_fd, deliver_out_buffer, DELIVER_OUT_BUFFER_SIZE)) >0) { @@ -118,6 +118,7 @@ dkt_direct(transport_ctx * tctx, struct ob_dkim * dkim, { int save_fd = tctx->u.fd; int save_options = tctx->options; +BOOL save_wireformat = spool_file_wireformat; uschar * hdrs, * dkim_signature; int siglen, hsize; const uschar * errstr; @@ -125,7 +126,8 @@ BOOL rc; DEBUG(D_transport) debug_printf("dkim signing direct-mode\n"); -/* Get headers in string for signing and transmission */ +/* Get headers in string for signing and transmission. Do CRLF +and dotstuffing (but no body nor dot-termination) */ tctx->u.msg = NULL; tctx->options = tctx->options & ~(topt_end_dot | topt_use_bdat) @@ -155,14 +157,18 @@ else if (!(rc = dkt_sign_fail(dkim, &errno))) /* Write the signature and headers into the deliver-out-buffer. This should mean they go out in the same packet as the MAIL, RCPT and (first) BDAT commands (transport_write_message() sizes the BDAT for the buffered amount) - for short -messages, the BDAT LAST command. We want no CRLF or dotstuffing expansion */ +messages, the BDAT LAST command. We want no dotstuffing expansion here, it +having already been done - but we have to say we want CRLF output format, and +temporarily set the marker for possible already-CRLF input. */ -tctx->options &= ~(topt_use_crlf | topt_escape_headers); +tctx->options &= ~topt_escape_headers; +spool_file_wireformat = TRUE; transport_write_reset(0); if ( !write_chunk(tctx, dkim_signature, siglen) || !write_chunk(tctx, hdrs, hsize)) return FALSE; +spool_file_wireformat = save_wireformat; tctx->options = save_options | topt_no_headers | topt_continuation; if (!(transport_write_message(tctx, 0))) diff --git a/src/src/globals.c b/src/src/globals.c index d61e894f3..f722fab12 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1363,6 +1363,8 @@ uschar *spf_smtp_comment = NULL; BOOL split_spool_directory = FALSE; uschar *spool_directory = US SPOOL_DIRECTORY "\0<--------------Space to patch spool_directory->"; +BOOL spool_file_wireformat = FALSE; +BOOL spool_wireformat = FALSE; #ifdef EXPERIMENTAL_SRS uschar *srs_config = NULL; uschar *srs_db_address = NULL; diff --git a/src/src/globals.h b/src/src/globals.h index 1c58a936b..e31517bf4 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -872,6 +872,8 @@ extern uschar *spf_smtp_comment; /* spf comment to include in SMTP reply * #endif extern BOOL split_spool_directory; /* TRUE to use multiple subdirs */ extern uschar *spool_directory; /* Name of spool directory */ +extern BOOL spool_file_wireformat; /* current -D file has CRLF rather than NL */ +extern BOOL spool_wireformat; /* can write wireformat -D files */ #ifdef EXPERIMENTAL_SRS extern uschar *srs_config; /* SRS config secret:max age:hash length:use timestamp:use hash */ extern uschar *srs_db_address; /* SRS db address */ diff --git a/src/src/pdkim/pdkim.c b/src/src/pdkim/pdkim.c index e4384d7f7..61e3161d4 100644 --- a/src/src/pdkim/pdkim.c +++ b/src/src/pdkim/pdkim.c @@ -1419,7 +1419,7 @@ while (sig) } DEBUG(D_acl) debug_printf( - "PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>>>>\n"); + "PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>>\n"); /* SIGNING ---------------------------------------------------------------- */ /* When signing, walk through our header list and add them to the hash. As we @@ -1732,10 +1732,10 @@ DEBUG(D_acl) pdkim_signature s = *sig; ev_ctx vctx; - debug_printf("PDKIM (checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + debug_printf("PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); if (!pdkim_key_from_dns(ctx, &s, &vctx, errstr)) debug_printf("WARNING: bad dkim key in dns\n"); - debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); + debug_printf("PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"); } return ctx; } diff --git a/src/src/readconf.c b/src/src/readconf.c index 340a0c0eb..f43a3d163 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -432,6 +432,7 @@ static optionlist optionlist_config[] = { #endif { "split_spool_directory", opt_bool, &split_spool_directory }, { "spool_directory", opt_stringptr, &spool_directory }, + { "spool_wireformat", opt_bool, &spool_wireformat }, #ifdef LOOKUP_SQLITE { "sqlite_lock_timeout", opt_int, &sqlite_lock_timeout }, #endif diff --git a/src/src/receive.c b/src/src/receive.c index 731c76d77..3d92a8479 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -1016,6 +1016,46 @@ for(;;) /*NOTREACHED*/ } +static int +read_message_bdat_smtp_wire(FILE *fout) +{ +int ch; + +/* Remember that this message uses wireformat. */ + +DEBUG(D_receive) debug_printf("CHUNKING: writing spoolfile in wire format\n"); +spool_file_wireformat = TRUE; + +/* Unfortunately cannot use sendfile() even if not TLS +as that requires (on linux) mmap-like operations on the input fd. + +XXX but worthwhile doing a block interface to the bdat_getc buffer +in the future */ + +for (;;) switch (ch = bdat_getc(GETC_BUFFER_UNLIMITED)) + { + case EOF: return END_EOF; + case EOD: return END_DOT; + case ERR: return END_PROTOCOL; + + default: + message_size++; +/*XXX not done: +linelength +max_received_linelength +body_linecount +body_zerocount +*/ + if (fout) + { + if (fputc(ch, fout) == EOF) return END_WERROR; + if (message_size > thismessage_size_limit) return END_SIZE; + } + break; + } +/*NOTREACHED*/ +} + @@ -3078,9 +3118,11 @@ if (!ferror(data_file) && !(receive_feof)() && message_ended != END_DOT) { if (smtp_input) { - message_ended = chunking_state > CHUNKING_OFFERED - ? read_message_bdat_smtp(data_file) - : read_message_data_smtp(data_file); + message_ended = chunking_state <= CHUNKING_OFFERED + ? read_message_data_smtp(data_file) + : spool_wireformat + ? read_message_bdat_smtp_wire(data_file) + : read_message_bdat_smtp(data_file); receive_linecount++; /* The terminating "." line */ } else message_ended = read_message_data(data_file); @@ -4258,6 +4300,7 @@ if (smtp_input) else if (chunking_state > CHUNKING_OFFERED) { +/*XXX rethink for spool_wireformat */ smtp_printf("250- %u byte chunk, total %d\r\n250 OK id=%s\r\n", chunking_datasize, message_size+message_linecount, message_id); chunking_state = CHUNKING_OFFERED; diff --git a/src/src/spam.c b/src/src/spam.c index 477ab62b4..49776a30d 100644 --- a/src/src/spam.c +++ b/src/src/spam.c @@ -265,9 +265,9 @@ if (spam_ok && Ustrcmp(prev_user_name, user_name) == 0) return override ? OK : spam_rc; /* make sure the eml mbox file is spooled up */ + if (!(mbox_file = spool_mbox(&mbox_size, NULL, NULL))) - { - /* error while spooling */ + { /* error while spooling */ log_write(0, LOG_MAIN|LOG_PANIC, "%s error while creating mbox spool file", loglabel); return DEFER; diff --git a/src/src/spool_in.c b/src/src/spool_in.c index 6ed566411..0bdf92e3b 100644 --- a/src/src/spool_in.c +++ b/src/src/spool_in.c @@ -284,6 +284,9 @@ sender_ident = NULL; sender_local = FALSE; sender_set_untrusted = FALSE; smtp_active_hostname = primary_hostname; +#ifndef COMPILE_UTILITY +spool_file_wireformat = FALSE; +#endif tree_nonrecipients = NULL; #ifdef EXPERIMENTAL_BRIGHTMAIL @@ -603,6 +606,10 @@ for (;;) else if (Ustrncmp(p, "pam_score_int ", 14) == 0) spam_score_int = string_copy(big_buffer + 16); #endif +#ifndef COMPILE_UTILITY + else if (Ustrncmp(p, "pool_file_wireformat", 20) == 0) + spool_file_wireformat = TRUE; +#endif #if defined(SUPPORT_I18N) && !defined(COMPILE_UTILITY) else if (Ustrncmp(p, "mtputf8", 7) == 0) message_smtputf8 = TRUE; diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index 89bdb7ddc..8ca468a85 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -62,8 +62,8 @@ if (!spool_mbox_ok) } /* open [message_id].eml file for writing */ - mbox_file = modefopen(mbox_path, "wb", SPOOL_MODE); - if (mbox_file == NULL) + + if (!(mbox_file = modefopen(mbox_path, "wb", SPOOL_MODE))) { log_write(0, LOG_MAIN|LOG_PANIC, "%s", string_open_failed(errno, "scan file %s", mbox_path)); @@ -80,33 +80,25 @@ if (!spool_mbox_ok) "${if def:sender_address{X-Envelope-From: <${sender_address}>\n}}" "${if def:recipients{X-Envelope-To: ${recipients}\n}}"); - if (temp_string != NULL) - { - i = fwrite(temp_string, Ustrlen(temp_string), 1, mbox_file); - if (i != 1) + if (temp_string) + if (fwrite(temp_string, Ustrlen(temp_string), 1, mbox_file) != 1) { log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ mailbox headers to %s", mbox_path); goto OUT; } - } - /* write all header lines to mbox file */ - my_headerlist = header_list; - for (my_headerlist = header_list; my_headerlist != NULL; - my_headerlist = my_headerlist->next) - { - /* skip deleted headers */ - if (my_headerlist->type == '*') continue; + /* write all non-deleted header lines to mbox file */ - i = fwrite(my_headerlist->text, my_headerlist->slen, 1, mbox_file); - if (i != 1) - { - log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ - message headers to %s", mbox_path); - goto OUT; - } - } + for (my_headerlist = header_list; my_headerlist; + my_headerlist = my_headerlist->next) + if (my_headerlist->type != '*') + if (fwrite(my_headerlist->text, my_headerlist->slen, 1, mbox_file) != 1) + { + log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ + message headers to %s", mbox_path); + goto OUT; + } /* End headers */ if (fwrite("\n", 1, 1, mbox_file) != 1) @@ -151,18 +143,32 @@ if (!spool_mbox_ok) do { - j = fread(buffer, 1, sizeof(buffer), data_file); + uschar * s; + + if (!spool_file_wireformat || source_file_override) + j = fread(buffer, 1, sizeof(buffer), data_file); + else /* needs CRLF -> NL */ + if ((s = fgets(buffer, sizeof(buffer), data_file))) + { + uschar * p = s + Ustrlen(s) - 1; + + if (*p == '\n' && p[-1] == '\r') + *--p = '\n'; + else if (*p == '\r') + ungetc(*p--, data_file); + + j = p - buffer; + } + else + j = 0; if (j > 0) - { - i = fwrite(buffer, j, 1, mbox_file); - if (i != 1) + if (fwrite(buffer, j, 1, mbox_file) != 1) { log_write(0, LOG_MAIN|LOG_PANIC, "Error/short write while writing \ message body to %s", mbox_path); goto OUT; } - } } while (j > 0); (void)fclose(mbox_file); diff --git a/src/src/spool_out.c b/src/src/spool_out.c index 652506fb3..ebe089d4f 100644 --- a/src/src/spool_out.c +++ b/src/src/spool_out.c @@ -197,7 +197,10 @@ tree_walk(acl_var_m, &acl_var_write, f); /* Now any other data that needs to be remembered. */ -fprintf(f, "-body_linecount %d\n", body_linecount); +if (spool_file_wireformat) + fprintf(f, "-spool_file_wireformat\n"); +else + fprintf(f, "-body_linecount %d\n", body_linecount); fprintf(f, "-max_received_linelength %d\n", max_received_linelength); if (body_zerocount > 0) fprintf(f, "-body_zerocount %d\n", body_zerocount); diff --git a/src/src/transport.c b/src/src/transport.c index 0f20efe1b..7806e3957 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -11,6 +11,10 @@ transports. */ #include "exim.h" +#ifdef HAVE_LINUX_SENDFILE +# include +#endif + /* Structure for keeping list of addresses that have been added to Envelope-To:, in order to avoid duplication. */ @@ -483,13 +487,22 @@ for (ptr = start; ptr < end; ptr++) chunk_ptr = deliver_out_buffer; } + /* Remove CR before NL if required */ + + if ( *ptr == '\r' && ptr[1] == '\n' + && (!tctx || !(tctx->options & topt_use_crlf)) + && spool_file_wireformat + ) + ptr++; + if ((ch = *ptr) == '\n') { int left = end - ptr - 1; /* count of chars left after NL */ /* Insert CR before NL if required */ - if (tctx && tctx->options & topt_use_crlf) *chunk_ptr++ = '\r'; + if (tctx && tctx->options & topt_use_crlf && !spool_file_wireformat) + *chunk_ptr++ = '\r'; *chunk_ptr++ = '\n'; transport_newlines++; @@ -749,9 +762,7 @@ for (h = header_list; h; h = h->next) if (h->type != htype_old) /* Header removed */ else - { DEBUG(D_transport) debug_printf("removed header line:\n%s---\n", h->text); - } } /* Add on any address-specific headers. If there are multiple addresses, @@ -890,7 +901,7 @@ Returns: TRUE on success; FALSE (with errno) on failure. BOOL internal_transport_write_message(transport_ctx * tctx, int size_limit) { -int len; +int len, size = 0; /* Initialize pointer in output buffer. */ @@ -906,17 +917,21 @@ if (tctx->check_string && tctx->escape_string) nl_escape_length = Ustrlen(nl_escape); } +/* Whether the escaping mechanism is applied to headers or not is controlled by +an option (set for SMTP, not otherwise). Negate the length if not wanted till +after the headers. */ + +if (!(tctx->options & topt_escape_headers)) + nl_check_length = -nl_check_length; + /* Write the headers if required, including any that have to be added. If there -are header rewriting rules, apply them. */ +are header rewriting rules, apply them. The datasource is not the -D spoolfile +so temporarily hide the global that adjusts for its format. */ if (!(tctx->options & topt_no_headers)) { - /* Whether the escaping mechanism is applied to headers or not is controlled by - an option (set for SMTP, not otherwise). Negate the length if not wanted till - after the headers. */ - - if (!(tctx->options & topt_escape_headers)) - nl_check_length = -nl_check_length; + BOOL save_wireformat = spool_file_wireformat; + spool_file_wireformat = FALSE; /* Add return-path: if requested. */ @@ -925,7 +940,7 @@ if (!(tctx->options & topt_no_headers)) uschar buffer[ADDRESS_MAXLENGTH + 20]; int n = sprintf(CS buffer, "Return-path: <%.*s>\n", ADDRESS_MAXLENGTH, return_path); - if (!write_chunk(tctx, buffer, n)) return FALSE; + if (!write_chunk(tctx, buffer, n)) goto bad; } /* Add envelope-to: if requested */ @@ -938,19 +953,18 @@ if (!(tctx->options & topt_no_headers)) struct aci *dlist = NULL; void *reset_point = store_get(0); - if (!write_chunk(tctx, US"Envelope-to: ", 13)) return FALSE; + if (!write_chunk(tctx, US"Envelope-to: ", 13)) goto bad; /* Pick up from all the addresses. The plist and dlist variables are anchors for lists of addresses already handled; they have to be defined at this level because write_env_to() calls itself recursively. */ for (p = tctx->addr; p; p = p->next) - if (!write_env_to(p, &plist, &dlist, &first, tctx)) - return FALSE; + if (!write_env_to(p, &plist, &dlist, &first, tctx)) goto bad; /* Add a final newline and reset the store used for tracking duplicates */ - if (!write_chunk(tctx, US"\n", 1)) return FALSE; + if (!write_chunk(tctx, US"\n", 1)) goto bad; store_reset(reset_point); } @@ -960,7 +974,7 @@ if (!(tctx->options & topt_no_headers)) { uschar buffer[100]; int n = sprintf(CS buffer, "Delivery-date: %s\n", tod_stamp(tod_full)); - if (!write_chunk(tctx, buffer, n)) return FALSE; + if (!write_chunk(tctx, buffer, n)) goto bad; } /* Then the message's headers. Don't write any that are flagged as "old"; @@ -970,7 +984,13 @@ if (!(tctx->options & topt_no_headers)) addr is not NULL. */ if (!transport_headers_send(tctx, &write_chunk)) + { +bad: + spool_file_wireformat = save_wireformat; return FALSE; + } + + spool_file_wireformat = save_wireformat; } /* When doing RFC3030 CHUNKING output, work out how much data would be in a @@ -988,7 +1008,7 @@ suboptimal. */ if (tctx->options & topt_use_bdat) { off_t fsize; - int hsize, size = 0; + int hsize; if ((hsize = chunk_ptr - deliver_out_buffer) < 0) hsize = 0; @@ -999,7 +1019,7 @@ if (tctx->options & topt_use_bdat) if (size_limit > 0 && fsize > size_limit) fsize = size_limit; size = hsize + fsize; - if (tctx->options & topt_use_crlf) + if (tctx->options & topt_use_crlf && !spool_file_wireformat) size += body_linecount; /* account for CRLF-expansion */ /* With topt_use_bdat we never do dot-stuffing; no need to @@ -1039,6 +1059,52 @@ negative in cases where it isn't to apply to the headers). Then ensure the body is positioned at the start of its file (following the message id), then write it, applying the size limit if required. */ +/* If we have a wireformat -D file (CRNL lines, non-dotstuffed, no ending dot) +and we want to send a body without dotstuffing or ending-dot, in-clear, +then we can just dump it using sendfile. +This should get used for CHUNKING output and also for writing the -K file for +dkim signing, when we had CHUNKING input. */ + +#ifdef HAVE_LINUX_SENDFILE +if ( spool_file_wireformat + && !(tctx->options & (topt_no_body | topt_end_dot)) + && !nl_check_length + && tls_out.active != tctx->u.fd + ) + { + ssize_t copied = 0; + off_t offset = SPOOL_DATA_START_OFFSET; + + /* Write out any header data in the buffer */ + + if ((len = chunk_ptr - deliver_out_buffer) > 0) + { + if (!transport_write_block(tctx, deliver_out_buffer, len, TRUE)) + return FALSE; + size -= len; + } + + DEBUG(D_transport) debug_printf("using sendfile for body\n"); + + while(size > 0) + { + if ((copied = sendfile(tctx->u.fd, deliver_datafile, &offset, size)) <= 0) break; + size -= copied; + } + return copied >= 0; + } +#else +DEBUG(D_transport) debug_printf("cannot use sendfile for body: no support\n"); +#endif + +DEBUG(D_transport) + if (!(tctx->options & topt_no_body)) + debug_printf("cannot use sendfile for body: %s\n", + !spool_file_wireformat ? "spoolfile not wireformat" + : tctx->options & topt_end_dot ? "terminating dot wanted" + : nl_check_length ? "dot- or From-stuffing wanted" + : "TLS output wanted"); + if (!(tctx->options & topt_no_body)) { int size = size_limit; @@ -1077,6 +1143,7 @@ return (len = chunk_ptr - deliver_out_buffer) <= 0 || + /************************************************* * External interface to write the message * *************************************************/ @@ -1098,6 +1165,7 @@ BOOL transport_write_message(transport_ctx * tctx, int size_limit) { BOOL last_filter_was_NL = TRUE; +BOOL save_spool_file_wireformat = spool_file_wireformat; int rc, len, yield, fd_read, fd_write, save_errno; int pfd[2] = {-1, -1}; pid_t filter_pid, write_pid; @@ -1215,8 +1283,10 @@ DEBUG(D_transport) debug_printf("copying from the filter\n"); /* Copy the output of the filter, remembering if the last character was NL. If no data is returned, that counts as "ended with NL" (default setting of the -variable is TRUE). */ +variable is TRUE). The output should always be unix-format as we converted +any wireformat source on writing input to the filter. */ +spool_file_wireformat = FALSE; chunk_ptr = deliver_out_buffer; for (;;) @@ -1256,6 +1326,7 @@ there has been an error, kill the processes before waiting for them, just to be sure. Also apply a paranoia timeout. */ TIDY_UP: +spool_file_wireformat = save_spool_file_wireformat; save_errno = errno; (void)close(fd_read); diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index e28a5bfe6..ecba054a2 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -2254,6 +2254,9 @@ included in the count.) */ if (sx->peer_offered & PEER_OFFERED_SIZE) { +/*XXX problem here under spool_files_wireformat? +Or just forget about lines? Or inflate by a fixed proportion? */ + sprintf(CS p, " SIZE=%d", message_size+message_linecount+sx->ob->size_addition); while (*p) p++; } diff --git a/src/src/verify.c b/src/src/verify.c index 706d42a0f..6a50af506 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -1344,6 +1344,7 @@ tctx.tblock = cutthrough.addr.transport; tctx.addr = &cutthrough.addr; tctx.check_string = US"."; tctx.escape_string = US".."; +/*XXX check under spool_files_wireformat. Might be irrelevant */ tctx.options = topt_use_crlf; if (!transport_headers_send(&tctx, &cutthrough_write_chunk)) diff --git a/test/confs/0906 b/test/confs/0906 new file mode 100644 index 000000000..2e8d35a91 --- /dev/null +++ b/test/confs/0906 @@ -0,0 +1,89 @@ +# Exim test configuration 0906 +SERVER= + +exim_path = EXIM_PATH +keep_environment = +host_lookup_order = bydns +spool_directory = DIR/spool +log_file_path = DIR/spool/log/SERVER%slog +gecos_pattern = "" +gecos_name = CALLER_NAME +chunking_advertise_hosts = * +tls_advertise_hosts = ${if eq {SRV}{tls} {*}} + +# ----- Main settings ----- + +spool_wireformat = true + +primary_hostname = testhost.test.ex +domainlist local_domains = @ : test.ex + +acl_smtp_rcpt = accept +log_selector = +received_recipients + +.ifdef _OPT_MAIN_TLS_CERTIFICATE +tls_certificate = DIR/aux-fixed/cert1 +tls_privatekey = DIR/aux-fixed/cert1 +.endif + +# ----- ACL ----- + +# ----- Routers ----- + +begin routers + +to_server: + driver = accept + condition = ${if = {$received_port}{PORT_S}} + transport = remote_smtp${if eq {OPT}{dkim} {_dkim}} + errors_to = "" + +fail_remote_domains: + driver = redirect + domains = ! +local_domains + data = :fail: unrouteable mail domain "$domain" + +localuser: + driver = accept + transport = local_delivery + + +# ----- Transports ----- + +begin transports + +local_delivery: + driver = appendfile + file = DIR/test-mail/$local_part + headers_add = "X-body-linecount: $body_linecount\n\ + X-message-linecount: $message_linecount\n\ + X-received-count: $received_count" + return_path_add + user = CALLER + +remote_smtp: + driver = smtp + hosts = 127.0.0.1 + port = PORT_D + allow_localhost + +remote_smtp_dkim: + driver = smtp + hosts = 127.0.0.1 + port = PORT_D + allow_localhost + +.ifdef OPT + dkim_domain = test.ex + dkim_selector = sel + dkim_private_key = DIR/aux-fixed/dkim/dkim.private +.ifndef HEADERS_MAXSIZE + dkim_sign_headers = LIST +.endif +.endif + +# ----- Retry ----- + +begin retry +* * F,30m,5m; +# End diff --git a/test/confs/4530 b/test/confs/4530 new file mode 120000 index 000000000..a8ce02c97 --- /dev/null +++ b/test/confs/4530 @@ -0,0 +1 @@ +0906 \ No newline at end of file diff --git a/test/log/0906 b/test/log/0906 new file mode 100644 index 000000000..e6a99e12d --- /dev/null +++ b/test/log/0906 @@ -0,0 +1,9 @@ + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 port 1224 +1999-03-02 09:44:33 10HmaX-0005vi-00 <= sender@dom H=(test.com) [127.0.0.1] P=esmtp K S=sss for a@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtp K S=sss for a@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 => a R=localuser T=local_delivery +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 10HmaX-0005vi-00 => a@test.ex R=to_server T=remote_smtp H=127.0.0.1 [127.0.0.1] K C="250- 8392 byte chunk, total 8599\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed diff --git a/test/log/4530 b/test/log/4530 new file mode 100644 index 000000000..d360cb102 --- /dev/null +++ b/test/log/4530 @@ -0,0 +1,17 @@ + +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1224 port 1225 +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=esmtp S=sss for z@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtp K S=sss for z@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 => z R=localuser T=local_delivery +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 10HmaX-0005vi-00 => z@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] K C="250- 652 byte chunk, total 652\\n250 OK id=10HmaY-0005vi-00" +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@bloggs.com H=(xxx) [127.0.0.1] P=esmtp K S=sss for y@test.ex +1999-03-02 09:44:33 10HmbA-0005vi-00 DKIM: d=test.ex s=sel c=relaxed/relaxed a=rsa-sha256 b=1024 [verification succeeded] +1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> H=localhost (testhost.test.ex) [127.0.0.1] P=esmtp K S=sss for y@test.ex +1999-03-02 09:44:33 10HmbA-0005vi-00 => y R=localuser T=local_delivery +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 10HmaZ-0005vi-00 => y@test.ex R=to_server T=remote_smtp_dkim H=127.0.0.1 [127.0.0.1] K C="250- 652 byte chunk, total 652\\n250 OK id=10HmbA-0005vi-00" +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed diff --git a/test/mail/0906.a b/test/mail/0906.a new file mode 100644 index 000000000..e5a07fc2d --- /dev/null +++ b/test/mail/0906.a @@ -0,0 +1,109 @@ +From MAILER-DAEMON Tue Mar 02 09:44:33 1999 +Return-path: <> +Received: from localhost ([127.0.0.1] helo=testhost.test.ex) + by testhost.test.ex with esmtp (Exim x.yz) + id 10HmaY-0005vi-00 + for a@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Received: from [127.0.0.1] (helo=test.com) + by testhost.test.ex with esmtp (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for a@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Subject: foo +X-body-linecount: 0 +X-message-linecount: 10 +X-received-count: 2 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +.dot +tail + diff --git a/test/mail/4530.y b/test/mail/4530.y new file mode 100644 index 000000000..580e21dc7 --- /dev/null +++ b/test/mail/4530.y @@ -0,0 +1,26 @@ +From MAILER-DAEMON Tue Mar 02 09:44:33 1999 +Return-path: <> +Received: from localhost ([127.0.0.1] helo=testhost.test.ex) + by testhost.test.ex with esmtp (Exim x.yz) + id 10HmbA-0005vi-00 + for y@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex; + s=sel; h=LIST; bh=CVpkzY75tV/NCKk5pPx4GnM3NX83xwCiT0xVwo0G1Rs=; b=TIqPqpKM5qf + ZFlv2H8yio5RybWA3sLCtVmE6HmBhBKqW+uqLKG2grqJhVMJ3qXnvQQ3ixnMjMlJqfCpEBtxfsSR9 + MGLPP9ZMdlrBNEL6XKlgE+X8bAra5zkuLZs8gy8H3/mtEfoKPs4ltB/ZK/j2FHG2+CEx+TDTIkh9E + wkAMrA=; +Received: from [127.0.0.1] (helo=xxx) + by testhost.test.ex with esmtp (Exim x.yz) + (envelope-from ) + id 10HmaZ-0005vi-00 + for y@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Subject: simple test +X-body-linecount: 0 +X-message-linecount: 15 +X-received-count: 2 + +Line 1: This is a simple test. +Line 2: This is a simple test. +.Line 3 has a leading dot +last line: 4 + diff --git a/test/mail/4530.z b/test/mail/4530.z new file mode 100644 index 000000000..2e74291f5 --- /dev/null +++ b/test/mail/4530.z @@ -0,0 +1,26 @@ +From MAILER-DAEMON Tue Mar 02 09:44:33 1999 +Return-path: <> +Received: from localhost ([127.0.0.1] helo=testhost.test.ex) + by testhost.test.ex with esmtp (Exim x.yz) + id 10HmaY-0005vi-00 + for z@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=test.ex; + s=sel; h=LIST; bh=CVpkzY75tV/NCKk5pPx4GnM3NX83xwCiT0xVwo0G1Rs=; b=TIqPqpKM5qf + ZFlv2H8yio5RybWA3sLCtVmE6HmBhBKqW+uqLKG2grqJhVMJ3qXnvQQ3ixnMjMlJqfCpEBtxfsSR9 + MGLPP9ZMdlrBNEL6XKlgE+X8bAra5zkuLZs8gy8H3/mtEfoKPs4ltB/ZK/j2FHG2+CEx+TDTIkh9E + wkAMrA=; +Received: from [127.0.0.1] (helo=xxx) + by testhost.test.ex with esmtp (Exim x.yz) + (envelope-from ) + id 10HmaX-0005vi-00 + for z@test.ex; Tue, 2 Mar 1999 09:44:33 +0000 +Subject: simple test +X-body-linecount: 0 +X-message-linecount: 15 +X-received-count: 2 + +Line 1: This is a simple test. +Line 2: This is a simple test. +.Line 3 has a leading dot +last line: 4 + diff --git a/test/scripts/0000-Basic/0906 b/test/scripts/0000-Basic/0906 new file mode 100644 index 000000000..f80899fee --- /dev/null +++ b/test/scripts/0000-Basic/0906 @@ -0,0 +1,122 @@ +# CHUNKING, spool_wireformat +# +exim -bd -DSERVER=server -oX PORT_D:PORT_S +**** +# +# Basic long message +client 127.0.0.1 PORT_S +??? 220 +EHLO test.com +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +BDAT 8408 LAST +Subject: foo + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 + +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +.dot +tail +??? 250- +??? 250 +QUIT +**** +# +sleep 1 +killdaemon +no_msglog_check diff --git a/test/scripts/4500-DKIM/4530 b/test/scripts/4500-DKIM/4530 new file mode 100644 index 000000000..822f2fe02 --- /dev/null +++ b/test/scripts/4500-DKIM/4530 @@ -0,0 +1,66 @@ +# DKIM, CHUNKING, wireformat-spoolfile +# +exim -bd -DSERVER=server -DOPT=dkim -oX PORT_S:PORT_D +**** +# +# 1: non-CHUNKING injection; will not be stored as wireformat therefore +# onward-send will not use sendfile. Should still be signed, and verify correctly. +client 127.0.0.1 PORT_S +??? 220 +EHLO xxx +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +DATA +??? 354 +Subject: simple test + +Line 1: This is a simple test. +Line 2: This is a simple test. +..Line 3 has a leading dot +last line: 4 +. +??? 250 +QUIT +??? 221 +**** +sleep 1 +# +# 2: CHUNKING injection; should be stored as wireformat therefore +# onward-send should not use sendfile. Should still be signed, and verify correctly. +client 127.0.0.1 PORT_S +??? 220 +EHLO xxx +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +MAIL FROM: +??? 250 +RCPT TO: +??? 250 +BDAT 129 LAST +Subject: simple test + +Line 1: This is a simple test. +Line 2: This is a simple test. +.Line 3 has a leading dot +last line: 4 +??? 250- +??? 250 +QUIT +??? 221 +**** +sleep 1 +# +killdaemon +no_msglog_check diff --git a/test/stderr/0143 b/test/stderr/0143 index 3de426629..b1d0ff9b6 100644 --- a/test/stderr/0143 +++ b/test/stderr/0143 @@ -38,6 +38,7 @@ cmd buf flush ddd bytes cmd buf flush ddd bytes SMTP<< 354 Send data SMTP>> writing message and terminating "." +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=300 SMTP<< 250 OK ok=1 send_quit=1 send_rset=0 continue_more=0 yield=0 first_address is NULL diff --git a/test/stderr/0169 b/test/stderr/0169 index 70f11bf4f..30ed85f8d 100644 --- a/test/stderr/0169 +++ b/test/stderr/0169 @@ -24,6 +24,7 @@ writing to file TESTSUITE/test-mail/userx Exim quota = 52428800 old size = sssss this message = sss (included) file count quota = 0 count = 0 writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 quota = 52428800 threshold = 21495808 old size = sssss message size = sss diff --git a/test/stderr/0275 b/test/stderr/0275 index 3ec0da1d4..5f76af09a 100644 --- a/test/stderr/0275 +++ b/test/stderr/0275 @@ -163,7 +163,6 @@ LOG: MAIN <= CALLER@test.ex U=CALLER P=local S=sss created log directory TESTSUITE/spool/log search_tidyup called -release cutthrough conn: msg passed for delivery exec TESTSUITE/eximdir/exim -DEXIM_PATH=TESTSUITE/eximdir/exim -C TESTSUITE/test-config -d=0xfbb95cfd -odi -Mc 10HmaX-0005vi-00 Exim version x.yz .... changed uid/gid: forcing real = effective diff --git a/test/stderr/0386 b/test/stderr/0386 index 44e856da2..6fb8a5536 100644 --- a/test/stderr/0386 +++ b/test/stderr/0386 @@ -310,6 +310,7 @@ lock file created mailbox TESTSUITE/test-mail/2 is locked writing to file TESTSUITE/test-mail/2 writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd @@ -490,6 +491,7 @@ lock file created mailbox TESTSUITE/test-mail/2 is locked writing to file TESTSUITE/test-mail/2 writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/0393 b/test/stderr/0393 index dd0887f09..7fb82e35c 100644 --- a/test/stderr/0393 +++ b/test/stderr/0393 @@ -28,6 +28,7 @@ mailbox TESTSUITE/test-mail/userx is locked writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 process pppp running as transport filter: fd_write=dddd fd_read=dddd +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 process pppp writing to transport filter copying from the filter @@ -70,6 +71,7 @@ lock file created mailbox TESTSUITE/test-mail/userx is locked writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd @@ -108,6 +110,7 @@ lock file created mailbox TESTSUITE/test-mail/userx is locked writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/0402 b/test/stderr/0402 index a007de31c..7f301651b 100644 --- a/test/stderr/0402 +++ b/test/stderr/0402 @@ -487,6 +487,7 @@ writing to file TESTSUITE/test-mail/junk └─────result: From CALLER@test.ex Tue Mar 02 09:44:33 1999 writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd @@ -542,6 +543,7 @@ writing to file TESTSUITE/test-mail/junk └─────result: From CALLER@test.ex Tue Mar 02 09:44:33 1999 writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/0404 b/test/stderr/0404 index d3d8f4c64..3b7605ba7 100644 --- a/test/stderr/0404 +++ b/test/stderr/0404 @@ -18004,6 +18004,7 @@ writing to file TESTSUITE/test-mail/sender writing data block fd=dddd size=sss timeout=0 flushing headers buffer writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/0408 b/test/stderr/0408 index f3d6d6b1a..9cdb41d96 100644 --- a/test/stderr/0408 +++ b/test/stderr/0408 @@ -159,6 +159,7 @@ lock file created mailbox TESTSUITE/test-mail/userx is locked writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/0476 b/test/stderr/0476 index 59ea69f58..675c6239c 100644 --- a/test/stderr/0476 +++ b/test/stderr/0476 @@ -52,6 +52,7 @@ set_process_info: pppp delivering 10HmaX-0005vi-00 LOG: MAIN ** userx@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]: SMTP error from remote mail server after RCPT TO:: 550 NO set_process_info: pppp tidying up after delivering 10HmaX-0005vi-00 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 Exim version x.yz .... configuration file is TESTSUITE/test-config diff --git a/test/stderr/0487 b/test/stderr/0487 index 7319b67dd..70da61fff 100644 --- a/test/stderr/0487 +++ b/test/stderr/0487 @@ -163,6 +163,7 @@ writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 rewrite_one_header: type=F: From: unqualified +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/0512 b/test/stderr/0512 index 1cdf5f013..07025d5d7 100644 --- a/test/stderr/0512 +++ b/test/stderr/0512 @@ -59,6 +59,7 @@ LOG: MAIN == userx@myhost.test.ex R=r1 T=t1 defer (dd): Connection refused LOG: MAIN ** userx@myhost.test.ex: retry timeout exceeded +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 Exim version x.yz .... configuration file is TESTSUITE/test-config @@ -122,6 +123,7 @@ LOG: MAIN == userx@myhost.test.ex R=r1 T=t1 defer (dd): Connection refused LOG: MAIN ** userx@myhost.test.ex: retry timeout exceeded +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 Exim version x.yz .... configuration file is TESTSUITE/test-config diff --git a/test/stderr/2600 b/test/stderr/2600 index 4e9974733..599be797a 100644 --- a/test/stderr/2600 +++ b/test/stderr/2600 @@ -439,6 +439,7 @@ lock file created mailbox TESTSUITE/test-mail/userx is locked writing to file TESTSUITE/test-mail/userx writing data block fd=dddd size=sss timeout=0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 writing data block fd=dddd size=sss timeout=0 appendfile yields 0 with errno=dd more_errno=dd diff --git a/test/stderr/4520 b/test/stderr/4520 index c2a856bb1..c1bafcdcc 100644 --- a/test/stderr/4520 +++ b/test/stderr/4520 @@ -23,18 +23,18 @@ cmd buf flush ddd bytes SMTP<< 250 OK SMTP<< 250 Accepted SMTP<< 354 Enter message, ending with "." on a line by itself -PDKIM (checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +PDKIM (checking verify key)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> PDKIM >> Parsing public key record >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Raw record: v=DKIM1\;{SP}p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd+cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+YdhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB v=DKIM1\ p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXRFf+VhT+lCgFhhSkinZKcFNeRzjYdW8vT29Rbb3NadvTFwAd+cVLPFwZL8H5tUD/7JbUPqNTCPxmpgIL+V5T4tEZMorHatvvUM2qfcpQ45IfsZ+YdhbIiAslHCpy4xNxIR3zylgqRUF4+Dtsaqy3a5LhwMiKCLrnzhXk1F1hxwIDAQAB Error while parsing public key record WARNING: bad dkim key in dns -PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< +PDKIM (finished checking verify key)<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< content{CR}{LF} PDKIM [test.ex] Body bytes hashed: 9 PDKIM [test.ex] Body hash computed: fc06f48221d98ad6106c3845b33a2a41152482ab9e697f736ad26db4853fa657 -PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>>>> +PDKIM >> Header data for hash, canonicalized, in sequence >>>>>>>>>>>> sender:CALLER_NAME{SP}{CR}{LF} message-id:{CR}{LF} from:nobody@example.com{CR}{LF} diff --git a/test/stderr/5004 b/test/stderr/5004 index ad5c9b331..bedf5be2e 100644 --- a/test/stderr/5004 +++ b/test/stderr/5004 @@ -155,6 +155,7 @@ created directory TESTSUITE/test-mail/new created directory TESTSUITE/test-mail/cur delivering in maildir format in TESTSUITE/test-mail writing to tmp/MAILDIR.mail.test.ex +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 renaming temporary file renamed tmp/MAILDIR.mail.test.ex as new/MAILDIR.mail.test.ex diff --git a/test/stderr/5005 b/test/stderr/5005 index 8b28b7055..a68bc11c9 100644 --- a/test/stderr/5005 +++ b/test/stderr/5005 @@ -149,6 +149,7 @@ delivering in maildir format in TESTSUITE/test-mail/nofile writing to tmp/MAILDIR.myhost.test.ex Exim quota = 500 old size = sssss this message = sss (included) file count quota = 0 count = 0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 added 'ddd 1' to maildirsize file renaming temporary file @@ -338,6 +339,7 @@ delivering in maildir format in TESTSUITE/test-mail/userx writing to tmp/MAILDIR.myhost.test.ex Exim quota = 500 old size = sssss this message = sss (included) file count quota = 0 count = 0 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 added 'ddd 1' to maildirsize file renaming temporary file diff --git a/test/stderr/5006 b/test/stderr/5006 index dce0d0050..771f5fd56 100644 --- a/test/stderr/5006 +++ b/test/stderr/5006 @@ -147,6 +147,7 @@ maildir_compute_size (timestamp_only): ddddddd returning maildir size=sss filecount=0 delivering in maildir format in TESTSUITE/test-mail/userx writing to tmp/MAILDIR.myhost.test.ex +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 added 'ddd 1' to maildirsize file renaming temporary file diff --git a/test/stderr/5008 b/test/stderr/5008 index fd4ae87ec..b3bf8f785 100644 --- a/test/stderr/5008 +++ b/test/stderr/5008 @@ -25,6 +25,7 @@ delivering in maildir format in TESTSUITE/test-mail/userx writing to tmp/MAILDIR.myhost.test.ex Exim quota = 1048576 old size = sssss this message = sss (included) file count quota = 0 count = -1 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 renaming temporary file renamed tmp/MAILDIR.myhost.test.ex as new/MAILDIR.myhost.test.ex @@ -64,6 +65,7 @@ delivering in maildir format in TESTSUITE/test-mail/userx writing to tmp/MAILDIR.myhost.test.ex Exim quota = 1048576 old size = sssss this message = sss (included) file count quota = 20 count = 4 +cannot use sendfile for body: spoolfile not wireformat writing data block fd=dddd size=sss timeout=0 renaming temporary file renamed tmp/MAILDIR.myhost.test.ex as new/MAILDIR.myhost.test.ex diff --git a/test/stdout/0906 b/test/stdout/0906 new file mode 100644 index 000000000..57be5fe3d --- /dev/null +++ b/test/stdout/0906 @@ -0,0 +1,123 @@ +Connecting to 127.0.0.1 port 1224 ... connected +??? 220 +<<< 220 testhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO test.com +??? 250- +<<< 250-testhost.test.ex Hello test.com [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> BDAT 8408 LAST +>>> Subject: foo +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 +>>> .dot +>>> tail +??? 250- +<<< 250- 8408 byte chunk, total 8408 +??? 250 +<<< 250 OK id=10HmaX-0005vi-00 +>>> QUIT +End of script diff --git a/test/stdout/4530 b/test/stdout/4530 new file mode 100644 index 000000000..a1f5cb471 --- /dev/null +++ b/test/stdout/4530 @@ -0,0 +1,75 @@ +Connecting to 127.0.0.1 port 1224 ... connected +??? 220 +<<< 220 testhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xxx +??? 250- +<<< 250-testhost.test.ex Hello xxx [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> DATA +??? 354 +<<< 354 Enter message, ending with "." on a line by itself +>>> Subject: simple test +>>> +>>> Line 1: This is a simple test. +>>> Line 2: This is a simple test. +>>> ..Line 3 has a leading dot +>>> last line: 4 +>>> . +??? 250 +<<< 250 OK id=10HmaX-0005vi-00 +>>> QUIT +??? 221 +<<< 221 testhost.test.ex closing connection +End of script +Connecting to 127.0.0.1 port 1224 ... connected +??? 220 +<<< 220 testhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xxx +??? 250- +<<< 250-testhost.test.ex Hello xxx [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-8BITMIME +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-CHUNKING +??? 250 +<<< 250 HELP +>>> MAIL FROM: +??? 250 +<<< 250 OK +>>> RCPT TO: +??? 250 +<<< 250 Accepted +>>> BDAT 129 LAST +>>> Subject: simple test +>>> +>>> Line 1: This is a simple test. +>>> Line 2: This is a simple test. +>>> .Line 3 has a leading dot +>>> last line: 4 +??? 250- +<<< 250- 129 byte chunk, total 129 +??? 250 +<<< 250 OK id=10HmaZ-0005vi-00 +>>> QUIT +??? 221 +<<< 221 testhost.test.ex closing connection +End of script -- 2.25.1