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
reject_deliver_request(const char * service,DELIVER_REQUEST * request,const char * code,const char * format,...)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