1/*	$NetBSD: trace.c,v 1.3 2022/10/08 16:12:45 christos Exp $	*/
2
3/*++
4/* NAME
5/*	trace 3
6/* SUMMARY
7/*	user requested delivery tracing
8/* SYNOPSIS
9/*	#include <trace.h>
10/*
11/*	int	trace_append(flags, id, stats, rcpt, relay, dsn)
12/*	int	flags;
13/*	const char *id;
14/*	MSG_STATS *stats;
15/*	RECIPIENT *rcpt;
16/*	const char *relay;
17/*	DSN	*dsn;
18/*
19/*	int     trace_flush(flags, queue, id, encoding, sender,
20/*				dsn_envid, dsn_ret)
21/*	int     flags;
22/*	const char *queue;
23/*	const char *id;
24/*	const char *encoding;
25/*	const char *sender;
26/*	const char *dsn_envid;
27/*	int	dsn_ret;
28/* DESCRIPTION
29/*	trace_append() updates the message delivery record that is
30/*	mailed back to the originator. In case of a trace-only
31/*	message, the recipient status is also written to the
32/*	mailer logfile.
33/*
34/*	trace_flush() returns the specified message to the specified
35/*	sender, including the message delivery record log that was built
36/*	with vtrace_append().
37/*
38/*	Arguments:
39/* .IP flags
40/*	The bitwise OR of zero or more of the following (specify
41/*	BOUNCE_FLAG_NONE to request no special processing):
42/* .RS
43/* .IP BOUNCE_FLAG_CLEAN
44/*	Delete the logfile in case of an error (as in: pretend
45/*	that we never even tried to deliver this message).
46/* .RE
47/* .IP queue
48/*	The message queue name of the original message file.
49/* .IP id
50/*	The message queue id.
51/* .IP encoding
52/*	The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
53/* .IP sender
54/*	The sender envelope address.
55/* .IP dsn_envid
56/*	Optional DSN envelope ID.
57/* .IP dsn_ret
58/*	Optional DSN return full/headers option.
59/* .IP stats
60/*	Time stamps from different message delivery stages
61/*	and session reuse count.
62/* .IP rcpt
63/*	Recipient information. See recipient_list(3).
64/* .IP relay
65/*	The host we sent the mail to.
66/* .IP dsn
67/*	Delivery status information. See dsn(3).
68/* DIAGNOSTICS
69/*	A non-zero result means the operation failed.
70/*
71/*	Fatal: out of memory.
72/* BUGS
73/*	Should be replaced by routines with an attribute-value based
74/*	interface instead of an interface that uses a rigid argument list.
75/* LICENSE
76/* .ad
77/* .fi
78/*	The Secure Mailer license must be distributed with this software.
79/* AUTHOR(S)
80/*	Wietse Venema
81/*	IBM T.J. Watson Research
82/*	P.O. Box 704
83/*	Yorktown Heights, NY 10598, USA
84/*
85/*	Wietse Venema
86/*	Google, Inc.
87/*	111 8th Avenue
88/*	New York, NY 10011, USA
89/*--*/
90
91/* System library. */
92
93#include <sys_defs.h>
94#include <stdio.h>
95#include <string.h>
96
97/* Utility library. */
98
99#include <msg.h>
100#include <vstring.h>
101
102/* Global library. */
103
104#include <mail_params.h>
105#include <mail_proto.h>
106#include <log_adhoc.h>
107#include <rcpt_print.h>
108#include <dsn_print.h>
109#include <trace.h>
110
111/* trace_append - append to message delivery record */
112
113int     trace_append(int flags, const char *id, MSG_STATS *stats,
114		             RECIPIENT *rcpt, const char *relay,
115		             DSN *dsn)
116{
117    VSTRING *why = vstring_alloc(100);
118    DSN     my_dsn = *dsn;
119    int     req_stat;
120
121    /*
122     * User-requested address verification, verbose delivery, or DSN SUCCESS
123     * notification.
124     */
125    if (strcmp(relay, NO_RELAY_AGENT) != 0)
126	vstring_sprintf(why, "delivery via %s: ", relay);
127    vstring_strcat(why, my_dsn.reason);
128    my_dsn.reason = vstring_str(why);
129
130    if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
131			    MAIL_ATTR_PROTO_BOUNCE,
132			    SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND),
133			    SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
134			    SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
135			    SEND_ATTR_FUNC(rcpt_print, (const void *) rcpt),
136			  SEND_ATTR_FUNC(dsn_print, (const void *) &my_dsn),
137			    ATTR_TYPE_END) != 0) {
138	msg_warn("%s: %s service failure", id, var_trace_service);
139	req_stat = -1;
140    } else {
141	if (flags & DEL_REQ_FLAG_USR_VRFY)
142	    log_adhoc(id, stats, rcpt, relay, dsn, my_dsn.action);
143	req_stat = 0;
144    }
145    vstring_free(why);
146    return (req_stat);
147}
148
149/* trace_flush - deliver delivery record to the sender */
150
151int     trace_flush(int flags, const char *queue, const char *id,
152		            const char *encoding, const char *sender,
153		            const char *dsn_envid, int dsn_ret)
154{
155    if (mail_command_client(MAIL_CLASS_PRIVATE, var_trace_service,
156			    MAIL_ATTR_PROTO_BOUNCE,
157			    SEND_ATTR_INT(MAIL_ATTR_NREQ, BOUNCE_CMD_TRACE),
158			    SEND_ATTR_INT(MAIL_ATTR_FLAGS, flags),
159			    SEND_ATTR_STR(MAIL_ATTR_QUEUE, queue),
160			    SEND_ATTR_STR(MAIL_ATTR_QUEUEID, id),
161			    SEND_ATTR_STR(MAIL_ATTR_ENCODING, encoding),
162			    SEND_ATTR_STR(MAIL_ATTR_SENDER, sender),
163			    SEND_ATTR_STR(MAIL_ATTR_DSN_ENVID, dsn_envid),
164			    SEND_ATTR_INT(MAIL_ATTR_DSN_RET, dsn_ret),
165			    ATTR_TYPE_END) == 0) {
166	return (0);
167    } else {
168	return (-1);
169    }
170}
171