5 /* bounce_trace_service 3
7 /* send status report to sender, server side
9 /* #include "bounce_service.h"
11 /* int bounce_trace_service(flags, queue_name, queue_id, encoding,
12 /* sender, char *envid, int ret, templates)
20 /* BOUNCE_TEMPLATES *templates;
22 /* This module implements the server side of the trace_flush()
23 /* (send delivery notice) request. The logfile
24 /* is removed after the notice is posted.
26 /* A status report includes a prelude with human-readable text,
27 /* a DSN-style report, and the email message that was subject of
30 /* When a status report is sent, the sender address is the empty
33 /* Fatal error: error opening existing file.
36 /* bounce(3) basic bounce service client interface
40 /* The Secure Mailer license must be distributed with this software.
43 /* IBM T.J. Watson Research
45 /* Yorktown Heights, NY 10598, USA
56 /* Utility library. */
63 #include <mail_params.h>
64 #include <mail_queue.h>
65 #include <post_mail.h>
66 #include <mail_addr.h>
67 #include <mail_error.h>
69 #include <deliver_request.h> /* USR_VRFY and RECORD flags */
71 /* Application-specific. */
73 #include "bounce_service.h"
75 #define STR vstring_str
77 /* bounce_trace_service - send a delivery status notice */
79 int bounce_trace_service(int flags
, char *service
, char *queue_name
,
80 char *queue_id
, char *encoding
,
81 char *recipient
, char *dsn_envid
,
85 BOUNCE_INFO
*bounce_info
;
86 int bounce_status
= 1;
88 VSTRING
*new_id
= vstring_alloc(10);
92 * Initialize. Open queue file, bounce log, etc.
94 * XXX DSN The trace service produces information from the trace logfile
95 * which is used for three types of reports:
97 * a) "what-if" reports that show what would happen without actually
98 * delivering mail (sendmail -bv).
100 * b) A report of actual deliveries (sendmail -v).
102 * c) DSN NOTIFY=SUCCESS reports of successful delivery ("delivered",
103 * "expanded" or "relayed").
105 #define NON_DSN_FLAGS (DEL_REQ_FLAG_USR_VRFY | DEL_REQ_FLAG_RECORD)
107 bounce_info
= bounce_mail_init(service
, queue_name
, queue_id
,
109 flags
& NON_DSN_FLAGS
?
110 ts
->verify
: ts
->success
);
113 * XXX With multi-recipient mail some queue file recipients may have
114 * NOTIFY=SUCCESS and others not. Depending on what subset of recipients
115 * are delivered, a trace file may or may not be created. Even when the
116 * last partial delivery attempt had no NOTIFY=SUCCESS recipients, a
117 * trace file may still exist from a previous partial delivery attempt.
118 * So as long as any recipient in the original queue file had
119 * NOTIFY=SUCCESS we have to always look for the trace file and be
120 * prepared for the file not to exist.
122 * See also comments in qmgr/qmgr_active.c.
124 if (bounce_info
->log_handle
== 0) {
126 msg_info("%s: no trace file -- not sending a notification",
128 bounce_mail_free(bounce_info
);
131 #define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
132 #define NULL_TRACE_FLAGS 0
135 * Send a single bounce with a template message header, some boilerplate
136 * text that pretends that we are a polite mail system, the text with
137 * per-recipient status, and a copy of the original message.
139 * XXX DSN We use the same trace file for "what-if", "verbose delivery" and
140 * "success" delivery reports. This saves file system overhead because
141 * there are fewer potential left-over files to remove up when we create
144 if ((bounce
= post_mail_fopen_nowait(NULL_SENDER
, recipient
,
145 INT_FILT_MASK_BOUNCE
,
149 if (bounce_header(bounce
, bounce_info
, recipient
,
150 NO_POSTMASTER_COPY
) == 0
151 && bounce_boilerplate(bounce
, bounce_info
) == 0
152 && (count
= bounce_diagnostic_log(bounce
, bounce_info
,
153 DSN_NOTIFY_OVERRIDE
)) > 0
154 && bounce_header_dsn(bounce
, bounce_info
) == 0
155 && bounce_diagnostic_dsn(bounce
, bounce_info
,
156 DSN_NOTIFY_OVERRIDE
) > 0) {
157 bounce_original(bounce
, bounce_info
, DSN_RET_HDRS
);
158 bounce_status
= post_mail_fclose(bounce
);
159 if (bounce_status
== 0)
160 msg_info("%s: sender delivery status notification: %s",
161 queue_id
, STR(new_id
));
163 (void) vstream_fclose(bounce
);
170 * Examine the completion status. Delete the trace log file only when the
171 * status notice was posted successfully.
173 if (bounce_status
== 0 && mail_queue_remove(service
, queue_id
)
175 msg_fatal("remove %s %s: %m", service
, queue_id
);
180 bounce_mail_free(bounce_info
);
181 vstring_free(new_id
);
183 return (bounce_status
);