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