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