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
trace_append(int flags,const char * id,MSG_STATS * stats,RECIPIENT * rcpt,const char * relay,DSN * dsn)113 int 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
trace_flush(int flags,const char * queue,const char * id,const char * encoding,const char * sender,const char * dsn_envid,int dsn_ret)151 int 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