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