1 /*	$NetBSD: sent.c,v 1.1.1.1 2009/06/23 10:08:47 tron 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 /*	message delivery record on request by the sender. The
22 /*	flags argument determines the action.
23 /*
24 /*	vsent() implements an alternative interface.
25 /*
26 /*	Arguments:
27 /* .IP flags
28 /*	Zero or more of the following:
29 /* .RS
30 /* .IP SENT_FLAG_NONE
31 /*	The message is a normal delivery request.
32 /* .IP DEL_REQ_FLAG_MTA_VRFY
33 /*	The message is an MTA-requested address verification probe.
34 /*	Update the address verification database.
35 /* .IP DEL_REQ_FLAG_USR_VRFY
36 /*	The message is a user-requested address expansion probe.
37 /*	Update the message delivery record.
38 /* .IP DEL_REQ_FLAG_RECORD
39 /*	This is a normal message with logged delivery. Update the
40 /*	the message delivery record.
41 /* .RE .IP queue_id
42 /*	The message queue id.
43 /* .IP stats
44 /*	Time stamps from different message delivery stages
45 /*	and session reuse count.
46 /* .IP recipient
47 /*	Recipient information. See recipient_list(3).
48 /* .IP relay
49 /*	Name of the host we're talking to.
50 /* .IP dsn
51 /*	Delivery status. See dsn(3). The action is ignored in case
52 /*	of a probe message. Otherwise, "delivered" is assumed when
53 /*	no action is specified.
54 /* DIAGNOSTICS
55 /*	A non-zero result means the operation failed.
56 /*
57 /*	Fatal: out of memory.
58 /* BUGS
59 /*	Should be replaced by routines with an attribute-value based
60 /*	interface instead of an interface that uses a rigid argument list.
61 /* LICENSE
62 /* .ad
63 /* .fi
64 /*	The Secure Mailer license must be distributed with this software.
65 /* AUTHOR(S)
66 /*	Wietse Venema
67 /*	IBM T.J. Watson Research
68 /*	P.O. Box 704
69 /*	Yorktown Heights, NY 10598, USA
70 /*--*/
71 
72 /* System library. */
73 
74 #include <sys_defs.h>
75 #include <string.h>
76 
77 /* Utility library. */
78 
79 #include <msg.h>
80 #include <vstring.h>
81 
82 /* Global library. */
83 
84 #include <mail_params.h>
85 #include <verify.h>
86 #include <log_adhoc.h>
87 #include <trace.h>
88 #include <defer.h>
89 #include <sent.h>
90 #include <dsn_util.h>
91 #include <dsn_mask.h>
92 
93 /* Application-specific. */
94 
95 /* sent - log that a message was or could be sent */
96 
97 int     sent(int flags, const char *id, MSG_STATS *stats,
98 	             RECIPIENT *recipient, const char *relay,
99 	             DSN *dsn)
100 {
101     DSN     my_dsn = *dsn;
102     int     status;
103 
104     /*
105      * Sanity check.
106      */
107     if (my_dsn.status[0] != '2' || !dsn_valid(my_dsn.status)) {
108 	msg_warn("sent: ignoring dsn code \"%s\"", my_dsn.status);
109 	my_dsn.status = "2.0.0";
110     }
111 
112     /*
113      * MTA-requested address verification information is stored in the verify
114      * service database.
115      */
116     if (flags & DEL_REQ_FLAG_MTA_VRFY) {
117 	my_dsn.action = "deliverable";
118 	status = verify_append(id, stats, recipient, relay, &my_dsn,
119 			       DEL_RCPT_STAT_OK);
120 	return (status);
121     }
122 
123     /*
124      * User-requested address verification information is logged and mailed
125      * to the requesting user.
126      */
127     if (flags & DEL_REQ_FLAG_USR_VRFY) {
128 	my_dsn.action = "deliverable";
129 	status = trace_append(flags, id, stats, recipient, relay, &my_dsn);
130 	return (status);
131     }
132 
133     /*
134      * Normal mail delivery. May also send a delivery record to the user.
135      */
136     else {
137 	if (my_dsn.action == 0 || my_dsn.action[0] == 0)
138 	    my_dsn.action = "delivered";
139 
140 	if (((flags & DEL_REQ_FLAG_RECORD) == 0
141 	  || trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)
142 	    && ((recipient->dsn_notify & DSN_NOTIFY_SUCCESS) == 0
143 	|| trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)) {
144 	    log_adhoc(id, stats, recipient, relay, &my_dsn, "sent");
145 	    status = 0;
146 	} else {
147 	    VSTRING *junk = vstring_alloc(100);
148 
149 	    vstring_sprintf(junk, "%s: %s service failed",
150 			    id, var_trace_service);
151 	    my_dsn.reason = vstring_str(junk);
152 	    my_dsn.status ="4.3.0";
153 	    status = defer_append(flags, id, stats, recipient, relay, &my_dsn);
154 	    vstring_free(junk);
155 	}
156 	return (status);
157     }
158 }
159