diff options
Diffstat (limited to 'src/global/reject_deliver_request.c')
-rw-r--r-- | src/global/reject_deliver_request.c | 105 |
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); +} |