summaryrefslogtreecommitdiffstats
path: root/src/global/reject_deliver_request.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/global/reject_deliver_request.c')
-rw-r--r--src/global/reject_deliver_request.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/global/reject_deliver_request.c b/src/global/reject_deliver_request.c
new file mode 100644
index 0000000..1b1b2a5
--- /dev/null
+++ b/src/global/reject_deliver_request.c
@@ -0,0 +1,105 @@
+/*++
+/* NAME
+/* reject_deliver_request 3
+/* SUMMARY
+/* reject an entire delivery request
+/* SYNOPSIS
+/* #include <reject_deliver_request.h>
+/*
+/* int reject_deliver_request(
+/* const char *service,
+/* DELIVER_REQUEST *request,
+/* const char *code,
+/* const char *format, ...);
+/* DESCRIPTION
+/* reject_deliver_request() rejects an entire delivery request
+/* and bounces or defers all its recipients. The result value
+/* is the request's delivery status.
+/*
+/* Arguments:
+/* .IP service
+/* The service name from master.cf.
+/* .IP request
+/* The delivery request that is being rejected.
+/* .IP code
+/* Enhanced status code, must be in 4.X.X or 5.X.X. form.
+/* All recipients in the request are bounced or deferred
+/* depending on the status code value.
+/* .IP "format, ..."
+/* Format string and optional arguments.
+/* DIAGNOSTICS
+/* Panic: interface violation. Fatal: out of memory.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+#include <string.h>
+
+ /*
+ * Utility library.
+ */
+#include <msg.h>
+
+ /*
+ * Global library.
+ */
+#include <bounce.h>
+#include <defer.h>
+#include <deliver_completed.h>
+#include <deliver_request.h>
+#include <recipient_list.h>
+
+/* reject_deliver_request - reject an entire delivery request */
+
+int reject_deliver_request(const char *service, DELIVER_REQUEST *request,
+ const char *code,
+ const char *format,...)
+{
+ const char myname[] = "reject_deliver_request";
+ va_list ap;
+ RECIPIENT *rcpt;
+ DSN_BUF *why;
+ int status;
+ int result = 0;
+ int n;
+
+ /*
+ * Format something that we can pass to bounce_append() or
+ * defer_append().
+ */
+ va_start(ap, format);
+ why = vdsb_simple(dsb_create(), code, format, ap);
+ va_end(ap);
+ (void) DSN_FROM_DSN_BUF(why);
+ if (strchr("45", vstring_str(why->status)[0]) == 0)
+ msg_panic("%s: bad enhanced status code %s", myname, code);
+
+ /*
+ * Blindly bounce or defer all recipients.
+ */
+ for (n = 0; n < request->rcpt_list.len; n++) {
+ rcpt = request->rcpt_list.info + n;
+ status = (vstring_str(why->status)[0] != '4' ?
+ bounce_append : defer_append)
+ (DEL_REQ_TRACE_FLAGS(request->flags),
+ request->queue_id,
+ &request->msg_stats, rcpt,
+ service, &why->dsn);
+ if (status == 0)
+ deliver_completed(request->fp, rcpt->offset);
+ result |= status;
+ }
+ dsb_free(why);
+ return (result);
+}