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