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