Events: raise msg:fail:internal & msg:complete for -Mrm. Bug 2310
authorMatthias Kurz <m.kurz@irregular.at>
Sun, 16 Sep 2018 23:20:24 +0000 (00:20 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 16 Sep 2018 23:21:30 +0000 (00:21 +0100)
doc/doc-txt/ChangeLog
src/src/deliver.c
src/src/exim.c
src/src/queue.c
test/log/5700
test/scripts/5700-events/5700
test/stdout/5700

index 617e407acb6f571e93b2975521ded8d10dd902f4..8d5f92b7f400164a41a35786b07a243bc8104591 100644 (file)
@@ -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
 -----------------
index 1f60042ff8ab53c3837333552a18fc0e813fde39..1cf757d69b8578550c2217ea194ed45ac4c99a7c 100644 (file)
@@ -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
       }
index 9a1cf8b9f3a20ac312786a8925ecf91815717912..1c27100c7f96fd7d5f55e1689e1976ebc1502966 100644 (file)
@@ -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++)
index 9f9e409ed964f0ac915181287778e39d423fc324..ac1bb760411eed4b93477223fb41ef99fa5eeaaf 100644 (file)
@@ -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");
index 56f997459ba4d587a046b6c4f2d7cebbb2ca4964..eda35bca74fba537ecdbe5b460f6209d1f1c0471 100644 (file)
 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 <userx> domain <domain1> reason <message removed by CALLER>
+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 <usery@domain1> 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 <userx> domain <domain1> reason <message removed 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 <userz> domain <domain1> reason <message removed by CALLER>
+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
index 1fe31cbfc3a412343a29c4efc380111f238e638d..42735dbc7961f79ef9fcdcf6cd7cf20572c9c15e 100644 (file)
@@ -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
+****
index a8f3b7482c13a9dd894b3a5db1b76fb3ff8bb6aa..066f6ceeca8ce3c56262b30563daef0aa89dfc53 100644 (file)
@@ -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 ...