+else if (!dont_deliver)
+ retry_update(&addr_defer, &addr_failed, &addr_succeed);
+
+/* Send DSN for successful messages if requested */
+addr_senddsn = NULL;
+
+for (addr_dsntmp = addr_succeed; addr_dsntmp; addr_dsntmp = addr_dsntmp->next)
+ {
+ /* af_ignore_error not honored here. it's not an error */
+ DEBUG(D_deliver) debug_printf("DSN: processing router : %s\n"
+ "DSN: processing successful delivery address: %s\n"
+ "DSN: Sender_address: %s\n"
+ "DSN: orcpt: %s flags: %d\n"
+ "DSN: envid: %s ret: %d\n"
+ "DSN: Final recipient: %s\n"
+ "DSN: Remote SMTP server supports DSN: %d\n",
+ addr_dsntmp->router->name,
+ addr_dsntmp->address,
+ sender_address,
+ addr_dsntmp->dsn_orcpt, addr_dsntmp->dsn_flags,
+ dsn_envid, dsn_ret,
+ addr_dsntmp->address,
+ addr_dsntmp->dsn_aware
+ );
+
+ /* send report if next hop not DSN aware or a router flagged "last DSN hop"
+ and a report was requested */
+ if ( ( addr_dsntmp->dsn_aware != dsn_support_yes
+ || addr_dsntmp->dsn_flags & rf_dsnlasthop
+ )
+ && addr_dsntmp->dsn_flags & rf_dsnflags
+ && addr_dsntmp->dsn_flags & rf_notify_success
+ )
+ {
+ /* copy and relink address_item and send report with all of them at once later */
+ address_item * addr_next = addr_senddsn;
+ addr_senddsn = store_get(sizeof(address_item));
+ *addr_senddsn = *addr_dsntmp;
+ addr_senddsn->next = addr_next;
+ }
+ else
+ DEBUG(D_deliver) debug_printf("DSN: not sending DSN success message\n");
+ }
+
+if (addr_senddsn)
+ {
+ pid_t pid;
+ int fd;
+
+ /* create exim process to send message */
+ pid = child_open_exim(&fd);
+
+ DEBUG(D_deliver) debug_printf("DSN: child_open_exim returns: %d\n", pid);
+
+ if (pid < 0) /* Creation of child failed */
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Process %d (parent %d) failed to "
+ "create child process to send failure message: %s", getpid(),
+ getppid(), strerror(errno));
+
+ DEBUG(D_deliver) debug_printf("DSN: child_open_exim failed\n");
+ }
+ else /* Creation of child succeeded */
+ {
+ FILE *f = fdopen(fd, "wb");
+ /* header only as required by RFC. only failure DSN needs to honor RET=FULL */
+ uschar * bound;
+ transport_ctx tctx = {0};
+
+ DEBUG(D_deliver)
+ debug_printf("sending error message to: %s\n", sender_address);
+
+ /* build unique id for MIME boundary */
+ bound = string_sprintf(TIME_T_FMT "-eximdsn-%d", time(NULL), rand());
+ DEBUG(D_deliver) debug_printf("DSN: MIME boundary: %s\n", bound);
+
+ if (errors_reply_to)
+ fprintf(f, "Reply-To: %s\n", errors_reply_to);
+
+ fprintf(f, "Auto-Submitted: auto-generated\n"
+ "From: Mail Delivery System <Mailer-Daemon@%s>\n"
+ "To: %s\n"
+ "Subject: Delivery Status Notification\n"
+ "Content-Type: multipart/report; report-type=delivery-status; boundary=%s\n"
+ "MIME-Version: 1.0\n\n"
+
+ "--%s\n"
+ "Content-type: text/plain; charset=us-ascii\n\n"
+
+ "This message was created automatically by mail delivery software.\n"
+ " ----- The following addresses had successful delivery notifications -----\n",
+ qualify_domain_sender, sender_address, bound, bound);
+
+ for (addr_dsntmp = addr_senddsn; addr_dsntmp;
+ addr_dsntmp = addr_dsntmp->next)
+ fprintf(f, "<%s> (relayed %s)\n\n",
+ addr_dsntmp->address,
+ (addr_dsntmp->dsn_flags & rf_dsnlasthop) == 1
+ ? "via non DSN router"
+ : addr_dsntmp->dsn_aware == dsn_support_no
+ ? "to non-DSN-aware mailer"
+ : "via non \"Remote SMTP\" router"
+ );
+
+ fprintf(f, "--%s\n"
+ "Content-type: message/delivery-status\n\n"
+ "Reporting-MTA: dns; %s\n",
+ bound, smtp_active_hostname);
+
+ if (dsn_envid)
+ { /* must be decoded from xtext: see RFC 3461:6.3a */
+ uschar *xdec_envid;
+ if (auth_xtextdecode(dsn_envid, &xdec_envid) > 0)
+ fprintf(f, "Original-Envelope-ID: %s\n", dsn_envid);
+ else
+ fprintf(f, "X-Original-Envelope-ID: error decoding xtext formatted ENVID\n");
+ }
+ fputc('\n', f);
+
+ for (addr_dsntmp = addr_senddsn;
+ addr_dsntmp;
+ addr_dsntmp = addr_dsntmp->next)
+ {
+ if (addr_dsntmp->dsn_orcpt)
+ fprintf(f,"Original-Recipient: %s\n", addr_dsntmp->dsn_orcpt);
+
+ fprintf(f, "Action: delivered\n"
+ "Final-Recipient: rfc822;%s\n"
+ "Status: 2.0.0\n",
+ addr_dsntmp->address);
+
+ if (addr_dsntmp->host_used && addr_dsntmp->host_used->name)
+ fprintf(f, "Remote-MTA: dns; %s\nDiagnostic-Code: smtp; 250 Ok\n\n",
+ addr_dsntmp->host_used->name);
+ else
+ fprintf(f, "Diagnostic-Code: X-Exim; relayed via non %s router\n\n",
+ (addr_dsntmp->dsn_flags & rf_dsnlasthop) == 1 ? "DSN" : "SMTP");
+ }
+
+ fprintf(f, "--%s\nContent-type: text/rfc822-headers\n\n", bound);
+
+ fflush(f);
+ transport_filter_argv = NULL; /* Just in case */
+ return_path = sender_address; /* In case not previously set */
+
+ /* Write the original email out */
+
+ tctx.options = topt_add_return_path | topt_no_body;
+ transport_write_message(fileno(f), &tctx, 0);
+ fflush(f);
+
+ fprintf(f,"\n--%s--\n", bound);
+
+ fflush(f);
+ fclose(f);
+ rc = child_close(pid, 0); /* Waits for child to close, no timeout */
+ }
+ }