From 7ea1237c783e380d7bdb86c90b13d8203c7ecf26 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Mon, 17 Sep 2018 00:20:24 +0100 Subject: [PATCH] Events: raise msg:fail:internal & msg:complete for -Mrm. Bug 2310 --- doc/doc-txt/ChangeLog | 4 ++++ src/src/deliver.c | 24 +++++++++++++++--------- src/src/exim.c | 6 ++++++ src/src/queue.c | 35 +++++++++++++++++++++++++++++++++-- test/log/5700 | 17 +++++++++++++++++ test/scripts/5700-events/5700 | 20 ++++++++++++++++++++ test/stdout/5700 | 3 +++ 7 files changed, 98 insertions(+), 11 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 617e407ac..8d5f92b7f 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -112,6 +112,10 @@ JH/23 Bug 2318: Fix the noerror command within filters. It wasn't working. The ignore_error flag wasn't being returned from the filter subprocess so was not set for later routers. Investigation and fix by Matthias Kurz. +JH/24 Bug 2310: Raise a msg:fail:internal event for each undelivered recipient, + and a msg:complete for the whole, when a message is manually reoved using + -Mrm. Developement by Matthias Kurz, hacked on by JH. + Exim version 4.91 ----------------- diff --git a/src/src/deliver.c b/src/src/deliver.c index 1f60042ff..1cf757d69 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -851,7 +851,7 @@ if (action) if (!(s = expand_string(action)) && *expand_string_message) log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand event_action %s in %s: %s\n", - event, transport_name, expand_string_message); + event, transport_name ? transport_name : US"main", expand_string_message); event_name = event_data = NULL; @@ -6240,17 +6240,23 @@ if (process_recipients != RECIP_IGNORE) { uschar * save_local = deliver_localpart; const uschar * save_domain = deliver_domain; + uschar * addr = new->address, * errmsg = NULL; + int start, end, dom; - deliver_localpart = expand_string( - string_sprintf("${local_part:%s}", new->address)); - deliver_domain = expand_string( - string_sprintf("${domain:%s}", new->address)); + if (!parse_extract_address(addr, &errmsg, &start, &end, &dom, TRUE)) + log_write(0, LOG_MAIN|LOG_PANIC, + "failed to parse address '%.100s': %s\n", addr, errmsg); + else + { + deliver_localpart = + string_copyn(addr+start, dom ? (dom-1) - start : end - start); + deliver_domain = dom ? CUS string_copyn(addr+dom, end - dom) : CUS""; - (void) event_raise(event_action, - US"msg:fail:internal", new->message); + event_raise(event_action, US"msg:fail:internal", new->message); - deliver_localpart = save_local; - deliver_domain = save_domain; + deliver_localpart = save_local; + deliver_domain = save_domain; + } } #endif } diff --git a/src/src/exim.c b/src/src/exim.c index 9a1cf8b9f..1c27100c7 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -4449,6 +4449,12 @@ if (msg_action_arg > 0 && msg_action != MSG_DELIVER && msg_action != MSG_LOAD) int yield = EXIT_SUCCESS; set_process_info("acting on specified messages"); + /* ACL definitions may be needed when removing a message (-Mrm) because + event_action gets expanded */ + + if (msg_action == MSG_REMOVE) + readconf_rest(); + if (!one_msg_action) { for (i = msg_action_arg; i < argc; i++) diff --git a/src/src/queue.c b/src/src/queue.c index 9f9e409ed..ac1bb7604 100644 --- a/src/src/queue.c +++ b/src/src/queue.c @@ -1255,6 +1255,38 @@ switch(action) else printf("has been removed or did not exist\n"); if (removed) { +#ifndef DISABLE_EVENT + for (i = 0; i < recipients_count; i++) + { + tree_node *delivered = + tree_search(tree_nonrecipients, recipients_list[i].address); + if (!delivered) + { + uschar * save_local = deliver_localpart; + const uschar * save_domain = deliver_domain; + uschar * addr = recipients_list[i].address, * errmsg = NULL; + int start, end, dom; + + if (!parse_extract_address(addr, &errmsg, &start, &end, &dom, TRUE)) + log_write(0, LOG_MAIN|LOG_PANIC, + "failed to parse address '%.100s'\n: %s", addr, errmsg); + else + { + deliver_localpart = + string_copyn(addr+start, dom ? (dom-1) - start : end - start); + deliver_domain = dom + ? CUS string_copyn(addr+dom, end - dom) : CUS""; + + event_raise(event_action, US"msg:fail:internal", + string_sprintf("message removed by %s", username)); + + deliver_localpart = save_local; + deliver_domain = save_domain; + } + } + } + (void) event_raise(event_action, US"msg:complete", NULL); +#endif log_write(0, LOG_MAIN, "removed by %s", username); log_write(0, LOG_MAIN, "Completed"); } @@ -1264,9 +1296,8 @@ switch(action) case MSG_MARK_ALL_DELIVERED: for (i = 0; i < recipients_count; i++) - { tree_add_nonrecipient(recipients_list[i].address); - } + if (spool_write_header(id, SW_MODIFYING, &errmsg) >= 0) { printf("has been modified\n"); diff --git a/test/log/5700 b/test/log/5700 index 56f997459..eda35bca7 100644 --- a/test/log/5700 +++ b/test/log/5700 @@ -96,3 +96,20 @@ 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed 1999-03-02 09:44:33 10HmbC-0005vi-00 event msg:complete 1999-03-02 09:44:33 10HmbC-0005vi-00 . finished: 10HmbC-0005vi-00 +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbE-0005vi-00 event msg:fail:internal +1999-03-02 09:44:33 10HmbE-0005vi-00 . local_part domain reason +1999-03-02 09:44:33 10HmbE-0005vi-00 event msg:complete +1999-03-02 09:44:33 10HmbE-0005vi-00 . finished: 10HmbE-0005vi-00 +1999-03-02 09:44:33 10HmbE-0005vi-00 removed by CALLER +1999-03-02 09:44:33 10HmbE-0005vi-00 Completed +1999-03-02 09:44:33 10HmbF-0005vi-00 <= CALLER@the.local.host.name U=CALLER P=local S=sss +1999-03-02 09:44:33 10HmbF-0005vi-00 address marked delivered by CALLER +1999-03-02 09:44:33 10HmbF-0005vi-00 event msg:fail:internal +1999-03-02 09:44:33 10HmbF-0005vi-00 . local_part domain reason +1999-03-02 09:44:33 10HmbF-0005vi-00 event msg:fail:internal +1999-03-02 09:44:33 10HmbF-0005vi-00 . local_part domain reason +1999-03-02 09:44:33 10HmbF-0005vi-00 event msg:complete +1999-03-02 09:44:33 10HmbF-0005vi-00 . finished: 10HmbF-0005vi-00 +1999-03-02 09:44:33 10HmbF-0005vi-00 removed by CALLER +1999-03-02 09:44:33 10HmbF-0005vi-00 Completed diff --git a/test/scripts/5700-events/5700 b/test/scripts/5700-events/5700 index 1fe31cbfc..42735dbc7 100644 --- a/test/scripts/5700-events/5700 +++ b/test/scripts/5700-events/5700 @@ -111,3 +111,23 @@ A message we will cancel from the queue **** exim -odi -Mg $msg1 **** +# +# +# +# +exim -odq userx@domain1 +A message we will remove from the queue +**** +exim -Mrm $msg1 +**** +# +# +# +# +exim -odq userx@domain1 usery@domain1 userz@domain1 +A message we will remove from the queue that has delivered recipients already. +**** +exim -Mmd $msg1 usery@domain1 +**** +exim -Mrm $msg1 +**** diff --git a/test/stdout/5700 b/test/stdout/5700 index a8f3b7482..066f6ceec 100644 --- a/test/stdout/5700 +++ b/test/stdout/5700 @@ -1,3 +1,6 @@ +Message 10HmbE-0005vi-00 has been removed +Message 10HmbF-0005vi-00 has been modified +Message 10HmbF-0005vi-00 has been removed ******** SERVER ******** Listening on port 1224 ... -- 2.25.1