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