From 8669f003e82e39e578787d9ebc1b40f36c024332 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Wed, 27 Jun 2007 11:01:51 +0000 Subject: [PATCH] Add queue_only_load_latch. --- doc/doc-txt/ChangeLog | 4 ++- doc/doc-txt/NewStuff | 7 +++- doc/doc-txt/OptionLists.txt | 4 ++- src/src/daemon.c | 62 ++++++++++++++++++++++-------------- src/src/exim.c | 58 +++++++++++++++++++-------------- src/src/expand.c | 4 +-- src/src/globals.c | 6 ++-- src/src/globals.h | 4 ++- src/src/macros.h | 8 ++++- src/src/readconf.c | 3 +- test/confs/0160 | 2 +- test/confs/0561 | 42 ++++++++++++++++++++++++ test/log/0561 | 30 +++++++++++++++++ test/scripts/0000-Basic/0561 | 43 +++++++++++++++++++++++++ test/stderr/0561 | 2 ++ test/stdout/0561 | 20 ++++++++++++ 16 files changed, 240 insertions(+), 59 deletions(-) create mode 100644 test/confs/0561 create mode 100644 test/log/0561 create mode 100644 test/scripts/0000-Basic/0561 create mode 100644 test/stderr/0561 create mode 100644 test/stdout/0561 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 31bd94acc..2306cf4df 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.519 2007/06/26 11:16:54 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.520 2007/06/27 11:01:51 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -74,6 +74,8 @@ PH/12 Added +ignore_defer and +include_defer to host lists. PH/13 Installed PCRE version 7.2. This needed some changes because of the new way in which PCRE > 7.0 is built. +PH/14 Implemented queue_only_load_latch. + Exim version 4.67 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index f61b1f7a3..0dc366076 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.153 2007/06/26 09:23:34 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.154 2007/06/27 11:01:51 ph10 Exp $ New Features in Exim -------------------- @@ -82,6 +82,11 @@ Version 4.68 +ignore_unknown and +include_unknown. These options should be used with care, probably only in non-critical host lists such as whitelists. + 8. There's a new option called queue_only_load_latch, which defaults true. + If set false when queue_only_load is greater than zero, Exim re-evaluates + the load for each incoming message in an SMTP session. Otherwise, once one + message is queued, the remainder are also. + Version 4.67 ------------ diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt index 2bd046b9e..6c28ebdba 100644 --- a/doc/doc-txt/OptionLists.txt +++ b/doc/doc-txt/OptionLists.txt @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.32 2007/04/11 15:26:10 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.33 2007/06/27 11:01:51 ph10 Exp $ LISTS OF EXIM OPTIONS --------------------- @@ -126,6 +126,7 @@ check_spool_space integer 0 main check_string string "From " appendfile 3.03 unset pipe 3.03 check_srv string* unset dnslookup 4.31 +client_condition string* unset authenticators 4.68 client_ignore_invalid_base64 boolean false plaintext 4.61 client_name string* + cram_md5 3.10 client_secret string* unset cram_md5 3.10 @@ -398,6 +399,7 @@ queue_list_requires_admin boolean true main queue_only boolean false main queue_only_file string unset main 2.05 queue_only_load fixed-point unset main +queue_only_load_latch boolean true main 4.68 queue_only_override boolean true main 4.21 queue_run_in_order boolean false main 1.70 queue_run_max integer 5 main diff --git a/src/src/daemon.c b/src/src/daemon.c index e844403a4..55701f080 100644 --- a/src/src/daemon.c +++ b/src/src/daemon.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/daemon.c,v 1.23 2007/03/14 12:15:56 ph10 Exp $ */ +/* $Cambridge: exim/src/src/daemon.c,v 1.24 2007/06/27 11:01:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -241,7 +241,7 @@ subprocess because it might take time. */ if (smtp_load_reserve >= 0) { - load_average = os_getloadavg(); + load_average = OS_GETLOADAVG(); if (smtp_reserve_hosts == NULL && load_average > smtp_load_reserve) { DEBUG(D_any) debug_printf("rejecting SMTP connection: load average = %.2f\n", @@ -365,6 +365,7 @@ if (pid == 0) int old_pool = store_pool; int save_debug_selector = debug_selector; BOOL local_queue_only; + BOOL session_local_queue_only; #ifdef SA_NOCLDWAIT struct sigaction act; #endif @@ -413,7 +414,7 @@ if (pid == 0) /* Initialize the queueing flags */ queue_check_only(); - local_queue_only = queue_only; + session_local_queue_only = queue_only; /* Close the listening sockets, and set the SIGCHLD handler to SIG_IGN. We also attempt to set things up so that children are automatically reaped, @@ -457,13 +458,15 @@ if (pid == 0) if (debug_daemon) debug_selector = 0; /* If there are too many child processes for immediate delivery, - set the local_queue_only flag, which is initialized from the + set the session_local_queue_only flag, which is initialized from the configured value and may therefore already be TRUE. Leave logging - till later so it will have a message id attached. */ + till later so it will have a message id attached. Note that there is no + possibility of re-calculating this per-message, because the value of + smtp_accept_count does not change in this subprocess. */ if (smtp_accept_queue > 0 && smtp_accept_count > smtp_accept_queue) { - local_queue_only = TRUE; + session_local_queue_only = TRUE; queue_only_reason = 1; } @@ -550,26 +553,37 @@ if (pid == 0) store_reset(reset_point); /* If queue_only is set or if there are too many incoming connections in - existence, local_queue_only will be TRUE. If it is not, check whether we - have received too many messages in this session for immediate delivery. If - not, and queue_only_load is set, check that the load average is below it. - Note that, once set, local_queue_only remains set for any subsequent - messages on the same SMTP connection. This is a deliberate choice; even - though the load average may fall, it doesn't seem right to deliver later - messages on the same call when not delivering earlier ones. */ - - if (!local_queue_only) + existence, session_local_queue_only will be TRUE. If it is not, check + whether we have received too many messages in this session for immediate + delivery. */ + + if (!session_local_queue_only && + smtp_accept_queue_per_connection > 0 && + receive_messagecount > smtp_accept_queue_per_connection) { - if (smtp_accept_queue_per_connection > 0 && - receive_messagecount > smtp_accept_queue_per_connection) - { - local_queue_only = TRUE; - queue_only_reason = 2; - } - else if (queue_only_load >= 0) + session_local_queue_only = TRUE; + queue_only_reason = 2; + } + + /* Initialize local_queue_only from session_local_queue_only. If it is not + true, and queue_only_load is set, check that the load average is below it. + If local_queue_only is set by this means, we also set if for the session if + queue_only_load_latch is true (the default). This means that, once set, + local_queue_only remains set for any subsequent messages on the same SMTP + connection. This is a deliberate choice; even though the load average may + fall, it doesn't seem right to deliver later messages on the same call when + not delivering earlier ones. However, the are special circumstances such as + very long-lived connections from scanning appliances where this is not the + best strategy. In such cases, queue_only_load_latch should be set false. */ + + local_queue_only = session_local_queue_only; + if (!local_queue_only && queue_only_load >= 0) + { + local_queue_only = (load_average = OS_GETLOADAVG()) > queue_only_load; + if (local_queue_only) { - local_queue_only = (load_average = os_getloadavg()) > queue_only_load; - if (local_queue_only) queue_only_reason = 3; + queue_only_reason = 3; + if (queue_only_load_latch) session_local_queue_only = TRUE; } } diff --git a/src/src/exim.c b/src/src/exim.c index 3a89d8b91..12f61a20d 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/exim.c,v 1.56 2007/06/19 14:41:31 ph10 Exp $ */ +/* $Cambridge: exim/src/src/exim.c,v 1.57 2007/06/27 11:01:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1291,6 +1291,7 @@ BOOL one_msg_action = FALSE; BOOL queue_only_set = FALSE; BOOL receiving_message = TRUE; BOOL sender_ident_set = FALSE; +BOOL session_local_queue_only; BOOL unprivileged; BOOL removed_privilege = FALSE; BOOL verify_address_mode = FALSE; @@ -3643,7 +3644,7 @@ if (receiving_message && (is_inetd && smtp_load_reserve >= 0) )) { - load_average = os_getloadavg(); + load_average = OS_GETLOADAVG(); } #endif @@ -4528,11 +4529,11 @@ else sender_address); } -/* Initialize the local_queue-only flag (this will be ignored if mua_wrapper is -set) */ +/* Initialize the session_local_queue-only flag (this will be ignored if +mua_wrapper is set) */ queue_check_only(); -local_queue_only = queue_only; +session_local_queue_only = queue_only; /* For non-SMTP and for batched SMTP input, check that there is enough space on the spool if so configured. On failure, we must not attempt to send an error @@ -4891,27 +4892,36 @@ while (more) } /* Else act on the result of message reception. We should not get here unless - message_id[0] is non-zero. If queue_only is set, local_queue_only will be - TRUE. If it is not, check on the number of messages received in this - connection. If that's OK and queue_only_load is set, check that the load - average is below it. If it is not, set local_queue_only TRUE. Note that it - then remains this way for any subsequent messages on the same SMTP connection. - This is a deliberate choice; even though the load average may fall, it - doesn't seem right to deliver later messages on the same call when not - delivering earlier ones. */ - - if (!local_queue_only) + message_id[0] is non-zero. If queue_only is set, session_local_queue_only + will be TRUE. If it is not, check on the number of messages received in this + connection. */ + + if (!session_local_queue_only && + smtp_accept_queue_per_connection > 0 && + receive_messagecount > smtp_accept_queue_per_connection) { - if (smtp_accept_queue_per_connection > 0 && - receive_messagecount > smtp_accept_queue_per_connection) - { - local_queue_only = TRUE; - queue_only_reason = 2; - } - else if (queue_only_load >= 0) + session_local_queue_only = TRUE; + queue_only_reason = 2; + } + + /* Initialize local_queue_only from session_local_queue_only. If it is false, + and queue_only_load is set, check that the load average is below it. If it is + not, set local_queue_only TRUE. If queue_only_load_latch is true (the + default), we put the whole session into queue_only mode. It then remains this + way for any subsequent messages on the same SMTP connection. This is a + deliberate choice; even though the load average may fall, it doesn't seem + right to deliver later messages on the same call when not delivering earlier + ones. However, there are odd cases where this is not wanted, so this can be + changed by setting queue_only_load_latch false. */ + + local_queue_only = session_local_queue_only; + if (!local_queue_only && queue_only_load >= 0) + { + local_queue_only = (load_average = OS_GETLOADAVG()) > queue_only_load; + if (local_queue_only) { - local_queue_only = (load_average = os_getloadavg()) > queue_only_load; - if (local_queue_only) queue_only_reason = 3; + queue_only_reason = 3; + if (queue_only_load_latch) session_local_queue_only = TRUE; } } diff --git a/src/src/expand.c b/src/src/expand.c index e56f86678..d86ea4658 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/expand.c,v 1.87 2007/06/22 14:38:58 ph10 Exp $ */ +/* $Cambridge: exim/src/src/expand.c,v 1.88 2007/06/27 11:01:51 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -1446,7 +1446,7 @@ while (last > first) return var_buffer; case vtype_load_avg: - sprintf(CS var_buffer, "%d", os_getloadavg()); /* load_average */ + sprintf(CS var_buffer, "%d", OS_GETLOADAVG()); /* load_average */ return var_buffer; case vtype_host_lookup: /* Lookup if not done so */ diff --git a/src/src/globals.c b/src/src/globals.c index f12e8eb34..4a75aed7c 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.75 2007/06/22 14:38:58 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.76 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -828,6 +828,7 @@ BOOL queue_list_requires_admin = TRUE; BOOL queue_only = FALSE; uschar *queue_only_file = NULL; int queue_only_load = -1; +BOOL queue_only_load_latch = TRUE; BOOL queue_only_override = TRUE; BOOL queue_only_policy = FALSE; BOOL queue_run_first_delivery = FALSE; @@ -1006,7 +1007,7 @@ script that sets up a copy of Exim for running in the test harness. It seems that compilers are now clever, and share constant strings if they can. Elsewhere in Exim the string "<" is used. The compiler optimization seems to make use of the end of this string in order to save space. So the patching then -wrecks this. We default this optimization by adding some additional characters +wrecks this. We defeat this optimization by adding some additional characters onto the end of the string. */ uschar *running_status = US">>>running<<<" "\0EXTRA"; @@ -1163,6 +1164,7 @@ BOOL system_filter_uid_set = FALSE; BOOL system_filtering = FALSE; BOOL tcp_nodelay = TRUE; +int test_harness_load_avg = 0; int thismessage_size_limit = 0; int timeout_frozen_after = 0; BOOL timestamps_utc = FALSE; diff --git a/src/src/globals.h b/src/src/globals.h index f80e88b7b..920267d9d 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.h,v 1.55 2007/06/22 14:38:58 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.h,v 1.56 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -527,6 +527,7 @@ extern int queue_run_pipe; /* Pipe for synchronizing */ extern int queue_interval; /* Queue running interval */ extern BOOL queue_only; /* TRUE to disable immediate delivery */ extern int queue_only_load; /* Max load before auto-queue */ +extern BOOL queue_only_load_latch; /* Latch queue_only_load TRUE */ extern uschar *queue_only_file; /* Queue if file exists/not-exists */ extern BOOL queue_only_override; /* Allow override from command line */ extern BOOL queue_only_policy; /* ACL or local_scan wants queue_only */ @@ -735,6 +736,7 @@ extern BOOL system_filter_uid_set; /* TRUE if uid set */ extern BOOL system_filtering; /* TRUE when running system filter */ extern BOOL tcp_nodelay; /* Controls TCP_NODELAY on daemon */ +extern int test_harness_load_avg; /* For use when testing */ extern int thismessage_size_limit; /* Limit for this message */ extern int timeout_frozen_after; /* Max time to keep frozen messages */ extern BOOL timestamps_utc; /* Use UTC for all times */ diff --git a/src/src/macros.h b/src/src/macros.h index 00f9f8eb2..f33ac7475 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/macros.h,v 1.34 2007/06/19 14:41:31 ph10 Exp $ */ +/* $Cambridge: exim/src/src/macros.h,v 1.35 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -15,6 +15,12 @@ a string as a text string. This is sometimes useful for debugging output. */ #define mac_expanded_string(s) mac_string(s) +/* When running in the test harness, the load average is fudged. */ + +#define OS_GETLOADAVG() \ + (running_in_test_harness? (test_harness_load_avg += 10) : os_getloadavg()) + + /* The address_item structure has a word full of 1-bit flags. These macros manipulate them. */ diff --git a/src/src/readconf.c b/src/src/readconf.c index a599ea81f..660a5bf8a 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/readconf.c,v 1.29 2007/02/06 11:11:40 ph10 Exp $ */ +/* $Cambridge: exim/src/src/readconf.c,v 1.30 2007/06/27 11:01:52 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -302,6 +302,7 @@ static optionlist optionlist_config[] = { { "queue_only", opt_bool, &queue_only }, { "queue_only_file", opt_stringptr, &queue_only_file }, { "queue_only_load", opt_fixed, &queue_only_load }, + { "queue_only_load_latch", opt_bool, &queue_only_load_latch }, { "queue_only_override", opt_bool, &queue_only_override }, { "queue_run_in_order", opt_bool, &queue_run_in_order }, { "queue_run_max", opt_int, &queue_run_max }, diff --git a/test/confs/0160 b/test/confs/0160 index 637e642a9..48d493c76 100644 --- a/test/confs/0160 +++ b/test/confs/0160 @@ -43,7 +43,7 @@ smtp: begin retry -* * F,1s,1s +* * F,2s,1s # End diff --git a/test/confs/0561 b/test/confs/0561 new file mode 100644 index 000000000..ecdbf9504 --- /dev/null +++ b/test/confs/0561 @@ -0,0 +1,42 @@ +# Exim test configuration 0561 + +QOLL=true + +exim_path = EXIM_PATH +host_lookup_order = bydns +primary_hostname = myhost.test.ex +rfc1413_query_timeout = 0s +spool_directory = DIR/spool +log_file_path = DIR/spool/log/%slog +gecos_pattern = "" +gecos_name = CALLER_NAME + +# ----- Main settings ----- + +acl_smtp_rcpt = accept + +queue_only_load = 0.001 +queue_only_load_latch = QOLL +queue_run_in_order + + +# ----- Routers ----- + +begin routers + +r1: + driver = manualroute + route_data = 127.0.0.1 + self = send + transport = t1 + + +# ----- Transports ----- + +begin transports + +t1: + driver = smtp + port = PORT_D + +# End diff --git a/test/log/0561 b/test/log/0561 new file mode 100644 index 000000000..6bb3490e3 --- /dev/null +++ b/test/log/0561 @@ -0,0 +1,30 @@ +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss +1999-03-02 09:44:33 10HmaX-0005vi-00 no immediate delivery: load average 0.01 +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss +1999-03-02 09:44:33 10HmaY-0005vi-00 no immediate delivery: load average 0.01 +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 Start queue run: pid=pppp -qq +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaZ-0005vi-00 no immediate delivery: load average 0.01 +1999-03-02 09:44:33 10HmaX-0005vi-00 => userx@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmbA-0005vi-00 no immediate delivery: load average 0.01 +1999-03-02 09:44:33 10HmaY-0005vi-00 => usery@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]* +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qq +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 Start queue run: pid=pppp -qq +1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaX-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmbB-0005vi-00 no immediate delivery: load average 0.01 +1999-03-02 09:44:33 10HmaZ-0005vi-00 => userx@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp S=sss id=E10HmaY-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmbC-0005vi-00 no immediate delivery: load average 0.02 +1999-03-02 09:44:33 10HmbA-0005vi-00 => usery@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1]* +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qq +1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss +1999-03-02 09:44:33 10HmbD-0005vi-00 no immediate delivery: load average 0.01 +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local-smtp S=sss +1999-03-02 09:44:33 10HmbE-0005vi-00 no immediate delivery: load average 0.02 diff --git a/test/scripts/0000-Basic/0561 b/test/scripts/0000-Basic/0561 new file mode 100644 index 000000000..1f55f8d43 --- /dev/null +++ b/test/scripts/0000-Basic/0561 @@ -0,0 +1,43 @@ +# queue_only_load and queue_only_load_latch +need_ipv4 +# +exim -bs +mail from:<> +rcpt to: +data +Message 1. +. +mail from:<> +rcpt to: +data +Message 2. +. +quit +**** +exim -DSERVER=server -bd -oX PORT_D +**** +exim -qq +**** +sleep 1 +killdaemon +exim -DQOLL=false -DSERVER=server -bd -oX PORT_D +**** +exim -qq +**** +sleep 1 +killdaemon +# +exim -bs -DQOLL=false +mail from:<> +rcpt to: +data +Message 3. +. +mail from:<> +rcpt to: +data +Message 4. +. +quit +**** +no_msglog_check diff --git a/test/stderr/0561 b/test/stderr/0561 new file mode 100644 index 000000000..045fadc9b --- /dev/null +++ b/test/stderr/0561 @@ -0,0 +1,2 @@ + +******** SERVER ******** diff --git a/test/stdout/0561 b/test/stdout/0561 new file mode 100644 index 000000000..d37cc1aa0 --- /dev/null +++ b/test/stdout/0561 @@ -0,0 +1,20 @@ +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaX-0005vi-00 +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmaY-0005vi-00 +221 myhost.test.ex closing connection +220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmbD-0005vi-00 +250 OK +250 Accepted +354 Enter message, ending with "." on a line by itself +250 OK id=10HmbE-0005vi-00 +221 myhost.test.ex closing connection -- 2.30.2