1 /* $NetBSD: reject_deliver_request.c,v 1.2 2020/03/18 19:05:16 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* reject_deliver_request 3 6 /* SUMMARY 7 /* reject an entire delivery request 8 /* SYNOPSIS 9 /* #include <reject_deliver_request.h> 10 /* 11 /* int reject_deliver_request( 12 /* const char *service, 13 /* DELIVER_REQUEST *request, 14 /* const char *code, 15 /* const char *format, ...); 16 /* DESCRIPTION 17 /* reject_deliver_request() rejects an entire delivery request 18 /* and bounces or defers all its recipients. The result value 19 /* is the request's delivery status. 20 /* 21 /* Arguments: 22 /* .IP service 23 /* The service name from master.cf. 24 /* .IP request 25 /* The delivery request that is being rejected. 26 /* .IP code 27 /* Enhanced status code, must be in 4.X.X or 5.X.X. form. 28 /* All recipients in the request are bounced or deferred 29 /* depending on the status code value. 30 /* .IP "format, ..." 31 /* Format string and optional arguments. 32 /* DIAGNOSTICS 33 /* Panic: interface violation. Fatal: out of memory. 34 /* LICENSE 35 /* .ad 36 /* .fi 37 /* The Secure Mailer license must be distributed with this software. 38 /* AUTHOR(S) 39 /* Wietse Venema 40 /* Google, Inc. 41 /* 111 8th Avenue 42 /* New York, NY 10011, USA 43 /*--*/ 44 45 /* 46 * System library. 47 */ 48 #include <sys_defs.h> 49 #include <string.h> 50 51 /* 52 * Utility library. 53 */ 54 #include <msg.h> 55 56 /* 57 * Global library. 58 */ 59 #include <bounce.h> 60 #include <defer.h> 61 #include <deliver_completed.h> 62 #include <deliver_request.h> 63 #include <recipient_list.h> 64 65 /* reject_deliver_request - reject an entire delivery request */ 66 67 int reject_deliver_request(const char *service, DELIVER_REQUEST *request, 68 const char *code, 69 const char *format,...) 70 { 71 const char myname[] = "reject_deliver_request"; 72 va_list ap; 73 RECIPIENT *rcpt; 74 DSN_BUF *why; 75 int status; 76 int result = 0; 77 int n; 78 79 /* 80 * Format something that we can pass to bounce_append() or 81 * defer_append(). 82 */ 83 va_start(ap, format); 84 why = vdsb_simple(dsb_create(), code, format, ap); 85 va_end(ap); 86 (void) DSN_FROM_DSN_BUF(why); 87 if (strchr("45", vstring_str(why->status)[0]) == 0) 88 msg_panic("%s: bad enhanced status code %s", myname, code); 89 90 /* 91 * Blindly bounce or defer all recipients. 92 */ 93 for (n = 0; n < request->rcpt_list.len; n++) { 94 rcpt = request->rcpt_list.info + n; 95 status = (vstring_str(why->status)[0] != '4' ? 96 bounce_append : defer_append) 97 (DEL_REQ_TRACE_FLAGS(request->flags), 98 request->queue_id, 99 &request->msg_stats, rcpt, 100 service, &why->dsn); 101 if (status == 0) 102 deliver_completed(request->fp, rcpt->offset); 103 result |= status; 104 } 105 dsb_free(why); 106 return (result); 107 } 108