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 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 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