xref: /netbsd-src/external/ibm-public/postfix/dist/src/global/sent.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1 /*	$NetBSD: sent.c,v 1.3 2020/03/18 19:05:16 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	sent 3
6 /* SUMMARY
7 /*	log that a message was or could be sent
8 /* SYNOPSIS
9 /*	#include <sent.h>
10 /*
11 /*	int	sent(flags, queue_id, stats, recipient, relay, dsn)
12 /*	int	flags;
13 /*	const char *queue_id;
14 /*	MSG_STATS *stats;
15 /*	RECIPIENT *recipient;
16 /*	const char *relay;
17 /*	DSN *dsn;
18 /* DESCRIPTION
19 /*	sent() logs that a message was successfully delivered,
20 /*	updates the address verification service, or updates a
21 /*	sender-requested message delivery record. The
22 /*	flags argument determines the action.
23 /*
24 /*	Arguments:
25 /* .IP flags
26 /*	Zero or more of the following:
27 /* .RS
28 /* .IP SENT_FLAG_NONE
29 /*	The message is a normal delivery request.
30 /* .IP DEL_REQ_FLAG_MTA_VRFY
31 /*	The message is an MTA-requested address verification probe.
32 /*	Update the address verification database.
33 /* .IP DEL_REQ_FLAG_USR_VRFY
34 /*	The message is a user-requested address expansion probe.
35 /*	Update the message delivery record.
36 /* .IP DEL_REQ_FLAG_RECORD
37 /*	This is a normal message with logged delivery. Update the
38 /*	the message delivery record.
39 /* .RE
40 /* .IP queue_id
41 /*	The message queue id.
42 /* .IP stats
43 /*	Time stamps from different message delivery stages
44 /*	and session reuse count.
45 /* .IP recipient
46 /*	Recipient information. See recipient_list(3).
47 /* .IP relay
48 /*	Name of the host we're talking to.
49 /* .IP dsn
50 /*	Delivery status. See dsn(3). The action is ignored in case
51 /*	of a probe message. Otherwise, "delivered" is assumed when
52 /*	no action is specified.
53 /* DIAGNOSTICS
54 /*	A non-zero result means the operation failed.
55 /*
56 /*	Fatal: out of memory.
57 /* BUGS
58 /*	Should be replaced by routines with an attribute-value based
59 /*	interface instead of an interface that uses a rigid argument list.
60 /* LICENSE
61 /* .ad
62 /* .fi
63 /*	The Secure Mailer license must be distributed with this software.
64 /* AUTHOR(S)
65 /*	Wietse Venema
66 /*	IBM T.J. Watson Research
67 /*	P.O. Box 704
68 /*	Yorktown Heights, NY 10598, USA
69 /*
70 /*	Wietse Venema
71 /*	Google, Inc.
72 /*	111 8th Avenue
73 /*	New York, NY 10011, USA
74 /*--*/
75 
76 /* System library. */
77 
78 #include <sys_defs.h>
79 #include <string.h>
80 
81 /* Utility library. */
82 
83 #include <msg.h>
84 #include <vstring.h>
85 
86 /* Global library. */
87 
88 #define DSN_INTERN
89 #include <mail_params.h>
90 #include <verify.h>
91 #include <log_adhoc.h>
92 #include <trace.h>
93 #include <defer.h>
94 #include <sent.h>
95 #include <dsn_util.h>
96 #include <dsn_mask.h>
97 
98 /* Application-specific. */
99 
100 /* sent - log that a message was or could be sent */
101 
sent(int flags,const char * id,MSG_STATS * stats,RECIPIENT * recipient,const char * relay,DSN * dsn)102 int     sent(int flags, const char *id, MSG_STATS *stats,
103 	             RECIPIENT *recipient, const char *relay,
104 	             DSN *dsn)
105 {
106     DSN     my_dsn = *dsn;
107     DSN    *dsn_res;
108     int     status;
109 
110     /*
111      * Sanity check.
112      */
113     if (my_dsn.status[0] != '2' || !dsn_valid(my_dsn.status)) {
114 	msg_warn("sent: ignoring dsn code \"%s\"", my_dsn.status);
115 	my_dsn.status = "2.0.0";
116     }
117 
118     /*
119      * DSN filter (Postfix 3.0).
120      */
121     if (delivery_status_filter != 0
122      && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0)
123 	my_dsn = *dsn_res;
124 
125     /*
126      * MTA-requested address verification information is stored in the verify
127      * service database.
128      */
129     if (flags & DEL_REQ_FLAG_MTA_VRFY) {
130 	my_dsn.action = "deliverable";
131 	status = verify_append(id, stats, recipient, relay, &my_dsn,
132 			       DEL_RCPT_STAT_OK);
133 	return (status);
134     }
135 
136     /*
137      * User-requested address verification information is logged and mailed
138      * to the requesting user.
139      */
140     if (flags & DEL_REQ_FLAG_USR_VRFY) {
141 	my_dsn.action = "deliverable";
142 	status = trace_append(flags, id, stats, recipient, relay, &my_dsn);
143 	return (status);
144     }
145 
146     /*
147      * Normal mail delivery. May also send a delivery record to the user.
148      */
149     else {
150 
151 	/* Readability macros: record all deliveries, or the delayed ones. */
152 #define REC_ALL_SENT(flags) (flags & DEL_REQ_FLAG_RECORD)
153 #define REC_DLY_SENT(flags, rcpt) \
154 	((flags & DEL_REQ_FLAG_REC_DLY_SENT) \
155 	&& (rcpt->dsn_notify == 0 || (rcpt->dsn_notify & DSN_NOTIFY_DELAY)))
156 
157 	if (my_dsn.action == 0 || my_dsn.action[0] == 0)
158 	    my_dsn.action = "delivered";
159 
160 	if (((REC_ALL_SENT(flags) == 0 && REC_DLY_SENT(flags, recipient) == 0)
161 	  || trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)
162 	    && ((recipient->dsn_notify & DSN_NOTIFY_SUCCESS) == 0
163 	|| trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)) {
164 	    log_adhoc(id, stats, recipient, relay, &my_dsn, "sent");
165 	    status = 0;
166 	} else {
167 	    VSTRING *junk = vstring_alloc(100);
168 
169 	    vstring_sprintf(junk, "%s: %s service failed",
170 			    id, var_trace_service);
171 	    my_dsn.reason = vstring_str(junk);
172 	    my_dsn.status = "4.3.0";
173 	    status = defer_append(flags, id, stats, recipient, relay, &my_dsn);
174 	    vstring_free(junk);
175 	}
176 	return (status);
177     }
178 }
179