1 /* $NetBSD: sent.c,v 1.3 2020/03/18 19:05:16 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* sent 3 6 /* SUMMARY 7 /* log that a message was or could be sent 8 /* SYNOPSIS 9 /* #include <sent.h> 10 /* 11 /* int sent(flags, queue_id, stats, recipient, relay, dsn) 12 /* int flags; 13 /* const char *queue_id; 14 /* MSG_STATS *stats; 15 /* RECIPIENT *recipient; 16 /* const char *relay; 17 /* DSN *dsn; 18 /* DESCRIPTION 19 /* sent() logs that a message was successfully delivered, 20 /* updates the address verification service, or updates a 21 /* sender-requested message delivery record. The 22 /* flags argument determines the action. 23 /* 24 /* Arguments: 25 /* .IP flags 26 /* Zero or more of the following: 27 /* .RS 28 /* .IP SENT_FLAG_NONE 29 /* The message is a normal delivery request. 30 /* .IP DEL_REQ_FLAG_MTA_VRFY 31 /* The message is an MTA-requested address verification probe. 32 /* Update the address verification database. 33 /* .IP DEL_REQ_FLAG_USR_VRFY 34 /* The message is a user-requested address expansion probe. 35 /* Update the message delivery record. 36 /* .IP DEL_REQ_FLAG_RECORD 37 /* This is a normal message with logged delivery. Update the 38 /* the message delivery record. 39 /* .RE 40 /* .IP queue_id 41 /* The message queue id. 42 /* .IP stats 43 /* Time stamps from different message delivery stages 44 /* and session reuse count. 45 /* .IP recipient 46 /* Recipient information. See recipient_list(3). 47 /* .IP relay 48 /* Name of the host we're talking to. 49 /* .IP dsn 50 /* Delivery status. See dsn(3). The action is ignored in case 51 /* of a probe message. Otherwise, "delivered" is assumed when 52 /* no action is specified. 53 /* DIAGNOSTICS 54 /* A non-zero result means the operation failed. 55 /* 56 /* Fatal: out of memory. 57 /* BUGS 58 /* Should be replaced by routines with an attribute-value based 59 /* interface instead of an interface that uses a rigid argument list. 60 /* LICENSE 61 /* .ad 62 /* .fi 63 /* The Secure Mailer license must be distributed with this software. 64 /* AUTHOR(S) 65 /* Wietse Venema 66 /* IBM T.J. Watson Research 67 /* P.O. Box 704 68 /* Yorktown Heights, NY 10598, USA 69 /* 70 /* Wietse Venema 71 /* Google, Inc. 72 /* 111 8th Avenue 73 /* New York, NY 10011, USA 74 /*--*/ 75 76 /* System library. */ 77 78 #include <sys_defs.h> 79 #include <string.h> 80 81 /* Utility library. */ 82 83 #include <msg.h> 84 #include <vstring.h> 85 86 /* Global library. */ 87 88 #define DSN_INTERN 89 #include <mail_params.h> 90 #include <verify.h> 91 #include <log_adhoc.h> 92 #include <trace.h> 93 #include <defer.h> 94 #include <sent.h> 95 #include <dsn_util.h> 96 #include <dsn_mask.h> 97 98 /* Application-specific. */ 99 100 /* sent - log that a message was or could be sent */ 101 102 int sent(int flags, const char *id, MSG_STATS *stats, 103 RECIPIENT *recipient, const char *relay, 104 DSN *dsn) 105 { 106 DSN my_dsn = *dsn; 107 DSN *dsn_res; 108 int status; 109 110 /* 111 * Sanity check. 112 */ 113 if (my_dsn.status[0] != '2' || !dsn_valid(my_dsn.status)) { 114 msg_warn("sent: ignoring dsn code \"%s\"", my_dsn.status); 115 my_dsn.status = "2.0.0"; 116 } 117 118 /* 119 * DSN filter (Postfix 3.0). 120 */ 121 if (delivery_status_filter != 0 122 && (dsn_res = dsn_filter_lookup(delivery_status_filter, &my_dsn)) != 0) 123 my_dsn = *dsn_res; 124 125 /* 126 * MTA-requested address verification information is stored in the verify 127 * service database. 128 */ 129 if (flags & DEL_REQ_FLAG_MTA_VRFY) { 130 my_dsn.action = "deliverable"; 131 status = verify_append(id, stats, recipient, relay, &my_dsn, 132 DEL_RCPT_STAT_OK); 133 return (status); 134 } 135 136 /* 137 * User-requested address verification information is logged and mailed 138 * to the requesting user. 139 */ 140 if (flags & DEL_REQ_FLAG_USR_VRFY) { 141 my_dsn.action = "deliverable"; 142 status = trace_append(flags, id, stats, recipient, relay, &my_dsn); 143 return (status); 144 } 145 146 /* 147 * Normal mail delivery. May also send a delivery record to the user. 148 */ 149 else { 150 151 /* Readability macros: record all deliveries, or the delayed ones. */ 152 #define REC_ALL_SENT(flags) (flags & DEL_REQ_FLAG_RECORD) 153 #define REC_DLY_SENT(flags, rcpt) \ 154 ((flags & DEL_REQ_FLAG_REC_DLY_SENT) \ 155 && (rcpt->dsn_notify == 0 || (rcpt->dsn_notify & DSN_NOTIFY_DELAY))) 156 157 if (my_dsn.action == 0 || my_dsn.action[0] == 0) 158 my_dsn.action = "delivered"; 159 160 if (((REC_ALL_SENT(flags) == 0 && REC_DLY_SENT(flags, recipient) == 0) 161 || trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0) 162 && ((recipient->dsn_notify & DSN_NOTIFY_SUCCESS) == 0 163 || trace_append(flags, id, stats, recipient, relay, &my_dsn) == 0)) { 164 log_adhoc(id, stats, recipient, relay, &my_dsn, "sent"); 165 status = 0; 166 } else { 167 VSTRING *junk = vstring_alloc(100); 168 169 vstring_sprintf(junk, "%s: %s service failed", 170 id, var_trace_service); 171 my_dsn.reason = vstring_str(junk); 172 my_dsn.status = "4.3.0"; 173 status = defer_append(flags, id, stats, recipient, relay, &my_dsn); 174 vstring_free(junk); 175 } 176 return (status); 177 } 178 } 179