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