1 /* $NetBSD: reject_deliver_request.c,v 1.3 2026/05/09 18:49: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 /* Wietse Venema 45 /* porcupine.org 46 /*--*/ 47 48 /* 49 * System library. 50 */ 51 #include <sys_defs.h> 52 #include <string.h> 53 54 /* 55 * Utility library. 56 */ 57 #include <msg.h> 58 59 /* 60 * Global library. 61 */ 62 #include <bounce.h> 63 #include <defer.h> 64 #include <deliver_completed.h> 65 #include <deliver_request.h> 66 #include <recipient_list.h> 67 68 /* reject_deliver_request - reject an entire delivery request */ 69 70 int reject_deliver_request(const char *service, DELIVER_REQUEST *request, 71 const char *code, 72 const char *format,...) 73 { 74 const char myname[] = "reject_deliver_request"; 75 va_list ap; 76 RECIPIENT *rcpt; 77 DSN_BUF *why; 78 int status; 79 int result = 0; 80 int n; 81 82 /* 83 * Format something that we can pass to bounce_append() or 84 * defer_append(). 85 */ 86 va_start(ap, format); 87 why = vdsb_simple(dsb_create(), code, format, ap); 88 va_end(ap); 89 (void) DSN_FROM_DSN_BUF(why); 90 if (strchr("45", vstring_str(why->status)[0]) == 0) 91 msg_panic("%s: bad enhanced status code %s", myname, code); 92 93 /* 94 * Blindly bounce or defer all recipients. 95 */ 96 for (n = 0; n < request->rcpt_list.len; n++) { 97 rcpt = request->rcpt_list.info + n; 98 status = (vstring_str(why->status)[0] != '4' ? 99 bounce_append : defer_append) 100 (DEL_REQ_TRACE_FLAGS(request->flags), 101 request->queue_id, 102 &request->msg_stats, rcpt, 103 service, NO_TLS_STATS, &why->dsn); 104 if (status == 0) 105 deliver_completed(request->fp, rcpt->offset); 106 result |= status; 107 } 108 dsb_free(why); 109 return (result); 110 } 111