--- amavisd~	Sat Nov 16 05:33:44 2002
+++ amavisd	Sun Nov 17 22:33:19 2002
@@ -963,35 +963,36 @@
     my($msginfo) = @_;
     my($smtp_resp,$exit_code,$dsn_needed);
 
+    my($sender) = $msginfo->sender;
     my($per_recip_data) = $msginfo->per_recip_data;
     my($any_not_done) = scalar(grep {!$_->recip_done} @$per_recip_data);
     if ($forward_method ne '' && $any_not_done)
 	{ die "Explicit forwarding, but not all recips done" }
     if (!@$per_recip_data) {  # no recipients, nothing to do
 	$smtp_resp = "250 2.5.0 Ok"; $exit_code = EX_OK;
-	do_log(5, "one_response_for_all: no recipients, '$smtp_resp'");
+	do_log(5, "one_response_for_all <$sender>: no recipients, '$smtp_resp'");
     }
     if (!defined $smtp_resp) {
-	for my $r (@$per_recip_data) {  # any 4xx code ?
+	for my $r (@$per_recip_data) {     # any 4xx code ?
 	    if ($r->recip_smtp_response =~ /^4/)   # pick the first 4xx code
 		{ $smtp_resp = $r->recip_smtp_response; last }
 	}
 	if (!defined $smtp_resp) {
-	    for my $r (@$per_recip_data) {  # any invalid code ?
-		if ($r->recip_smtp_response !~ /^[245]/) {  # pick the first
-		    $smtp_resp = "451 4.5.0 Bad SMTP response code??? <" .
-				 $r->recip_smtp_response . ">";
-		    last;
+	    for my $r (@$per_recip_data) { # any invalid code ?
+		if ($r->recip_done && $r->recip_smtp_response !~ /^[245]/) {
+		    $smtp_resp = '451 4.5.0 Bad SMTP response code??? "' .
+				 $r->recip_smtp_response . '"';
+		    last;  # pick the first
 		}
 	    }
 	}
 	if (defined $smtp_resp) {
 	    $exit_code = EX_TEMPFAIL;
-	    do_log(5, "one_response_for_all: 4xx found, '$smtp_resp'");
+	    do_log(5, "one_response_for_all <$sender>: 4xx found, '$smtp_resp'");
 	}
     }
     # NOTE: a 2xx SMTP response code is set both by internal DISCARD,
-    # and a genuine successful delivery. To distinguish between the two
+    # and by a genuine successful delivery. To distinguish between the two
     # we need to check $r->recip_destiny as well.
     #
     if (!defined $smtp_resp) {
@@ -1004,8 +1005,8 @@
 	}
 	if ($notall) { $smtp_resp = undef }
 	if (defined $smtp_resp) {
-	    $exit_code = $forward_method ne '' ? 99 : EX_OK;
-	    do_log(5, "one_response_for_all: all DISCARD, '$smtp_resp'");
+	    $exit_code = $forward_method eq '' ? 99 : EX_OK;
+	    do_log(5, "one_response_for_all <$sender>: all DISCARD, '$smtp_resp'");
 	}
     }
     if (!defined $smtp_resp) {
@@ -1027,7 +1028,7 @@
 	if ($notall) { $smtp_resp = undef }
 	if (defined $smtp_resp) {
 	    $exit_code = EX_UNAVAILABLE;
-	    do_log(5, "one_response_for_all: some REJECTs, '$smtp_resp'");
+	    do_log(5, "one_response_for_all <$sender>: some REJECTs, '$smtp_resp'");
 	}
     }
     if (!defined $smtp_resp) {
@@ -1054,7 +1055,7 @@
 	$smtp_resp .= " $drop_cnt DROP" . ($drop_cnt==1?'':'S')  if $drop_cnt;
 	$exit_code = EX_OK;
 	$dsn_needed = $rej_cnt ? 1 : 0;
-	do_log(5, "one_response_for_all: " .
+	do_log(5, "one_response_for_all <$sender>: " .
 		  ($rej_cnt+$drop_cnt > 0 ? 'mixed' : 'success') .
 		  ", '$smtp_resp'");
     }
@@ -2793,6 +2794,7 @@
 	    last;
 	}
     }
+    $best_try_originator;
 }
 
 # Given a dotted-quad IP address try reverse DNS resolve, and then
@@ -3832,7 +3834,7 @@
 BEGIN {
     import Amavis::Util qw(do_log sanitize_str);
     import Amavis::Timing qw(section_time);
-    import Amavis::Conf qw(:notifyconf $myhostname);
+    import Amavis::Conf qw(:notifyconf $myhostname $forward_method);
     import Amavis::Lookup qw(lookup);
     import Amavis::Expand qw(expand);
     import Amavis::rfc2821_2822_Tools;
@@ -3878,9 +3880,10 @@
        $builtins_ref, $template_ref) = @_;
     my($dsn_time) = time;  # time of dsn creation - now
     my($notification);
-    if ($msginfo->sender_contact eq '') {
-	# must not respond to null return path
+    if ($msginfo->sender eq '') { # must not respond to null return path
 	do_log(4, "Not sending DSN to empty return path");
+    } elsif ($msginfo->sender_contact eq '') {
+	do_log(4, "Not sending DSN to believed-to-be-faked return path");
     } elsif ($msginfo->mime_entity->head->get("precedence")
 	     =~ /bulk|list|junk/i ) {
 	# don't send notifications in response to mail from mailing lists
@@ -3898,8 +3901,13 @@
 	    my($remote_mta) = $r->recip_remote_mta;
 	    my($smtp_resp)  = $r->recip_smtp_response;
 	    if (! $r->recip_done) {
-		do_log(0, "TROUBLE: recipient not done: <" .
-			  $r->recip_addr . "> " . $smtp_resp);
+		if ($forward_method eq '') {  # e.g. milter
+		    # as far as we are concerned all is ok, delivery by MTA-in
+		    $smtp_resp = "250 2.5.0 Ok, continue delivery";
+		} else {
+		    do_log(0, "TROUBLE: recipient not done: <" .
+			      $r->recip_addr . "> " . $smtp_resp);
+		}
 	    }
 	    my($smtp_resp_code, $smtp_resp_enhcode, $smtp_resp_msg);
 	    if ($smtp_resp =~ /^ (\d{3}) \s+ ([245] \. \d{1,3} \. \d{1,3})?
@@ -4795,6 +4803,7 @@
 	# abort if quarantining not successful
 	die "Can not quarantine: '$n_smtp_resp'";
     }
+    do_log(5, "DO_QUARANTINE done");
 }
 
 # If virus found - quarantine it and send notifications
@@ -4826,6 +4835,7 @@
     }
     do_quarantine($conn, $msginfo, $hdr_edits, \@q_addr)  if @q_addr;
 
+    do_log(5, "DO_VIRUS - NOTIFICATIONS, sender: ".$msginfo->sender);
     $hdr_edits = Amavis::Out::EditHeader->new;
 
     # try to find a per-sender administrator
@@ -4879,6 +4889,7 @@
 	    # $notification->purge;
 	}
     }
+    do_log(5, "DO_VIRUS - DONE");
 }
 
 #
@@ -4924,6 +4935,7 @@
 		      join(',', map{"<$_>"} @{$msginfo->recips}),
 		      $s, $VIRUSFILE, join(',',@q_addr) ));
     }
+
     my($hdr_edits) = Amavis::Out::EditHeader->new;
 
     # try to find a per-sender administrator
@@ -4932,6 +4944,7 @@
 	do_log(4, "Skip spam_admin notification for <".$msginfo->sender.
 		  ">, no admin specified");
     } else {  # Notify admin
+	do_log(5, "DO_SPAM - NOTIFICATIONS, sender: ".$msginfo->sender);
 	my($notification) = Amavis::In::Message->new;
 	$notification->sender($mailfrom_notify_spamadmin);
 	$notification->recips([$admin]);
@@ -4950,6 +4963,7 @@
 	    { do_log(0, "FAILED to notify spam admin: $n_smtp_resp") }
 	# $notification->purge;
     }
+    do_log(5, "DO_SPAM DONE");
 }
 
 # Calculate message digest;
@@ -5430,17 +5444,24 @@
 	    do_log(4, "tempdir being removed: $tempdir");
 	    rmdir_recursively($tempdir);
 	}
-	if ($forward_method eq '' && $exit_code != EX_TEMPFAIL) { # e.g. milter
-# TODO: this must be based on exit_code: all or none must be done
-#	    for my $r (@{$msginfo->per_recip_data}) {
-#		# a limited helper program can not do it, but should have been done
-#		my($addr,$newaddr) = ($r->recip_addr, $r->recip_addr_modified);
-#		if ($r->recip_done) {
-#		    do_log(0, "TODO: recip addr <$addr> should be removed");
-#		} elsif ($newaddr ne $addr) {
-#		    do_log(0, "TODO: recip addr <$addr> should be replaced with <$newaddr>");
-#		}
-#	    }
+	if ($forward_method eq '' && $exit_code == EX_OK) { # e.g. milter
+	    # when forwarding is left for MTA on the input side to do,
+	    # warn if there is anything that should be done, but MTA is not
+	    # capable of doing (or a helper program can not pass the request)
+	    my($any_deletes);
+	    for my $r (@{$msginfo->per_recip_data}) {
+		my($addr,$newaddr) = ($r->recip_addr, $r->recip_final_addr);
+		if ($r->recip_done) {
+		    do_log(0, "WARN: recip addr <$addr> should be removed, but MTA can't do it");
+		    $any_deletes++;
+		} elsif ($newaddr ne $addr) {
+		    do_log(0, "WARN: recip addr <$addr> should be replaced with <$newaddr>, but MTA can't do it");
+		}
+	    }
+	    if ($any_deletes) {
+		do_log(0, "WARN: REJECT THE WHOLE MESSAGE, MTA-in can't do the recips deletion");
+		$exit_code = EX_UNAVAILABLE;
+	    }
 	}
     }
     if ($mta_in_type eq 'qmail' && $exit_code == EX_TEMPFAIL) {
