nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c91e4f75fde4a5d5ba4bf0ceba1e9bef972f07f3
parent 612f784709e8c5a77cc48c6ba749eb1f92cf330c
Author: Flavio Curti <fcu-software@no-way.org>
Date:   Sat,  5 Dec 2020 19:23:02 +0100

Let QMAILQUEUE wrapper return custom error strings.

Original: qmail-queue-custom-error-v2.netqmail-1.05.patch

A common QMAILQUEUE use case is to prevent some messages from entering
the queue. We extend the qmail-queue(8) interface so that when rejecting
a message, a custom string can optionally be communicated to the caller
(for instance, qmail-smtpd). When this is desired, write to fd 6:

    "Dthis is a custom fatal error message"
      or
    "Zthis is a custom temporary failure message"

and exit 82.

An earlier version of this patch has been around since 2005. In 2007, it
switched from fd 4 to 6 in order to play well with qmail-qfilter.

Diffstat:
Mqmail.c | 28+++++++++++++++++++++++++++-
Mqmail.h | 1+
2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/qmail.c b/qmail.c @@ -24,22 +24,32 @@ struct qmail *qq; { int pim[2]; int pie[2]; + int pierr[2]; setup_qqargs(); if (pipe(pim) == -1) return -1; if (pipe(pie) == -1) { close(pim[0]); close(pim[1]); return -1; } + if (pipe(pierr) == -1) { + close(pim[0]); close(pim[1]); + close(pie[0]); close(pie[1]); + close(pierr[0]); close(pierr[1]); + return -1; + } switch(qq->pid = fork()) { case -1: + close(pierr[0]); close(pierr[1]); close(pim[0]); close(pim[1]); close(pie[0]); close(pie[1]); return -1; case 0: close(pim[1]); close(pie[1]); + close(pierr[0]); /* we want to receive data */ if (fd_move(0,pim[0]) == -1) _exit(120); if (fd_move(1,pie[0]) == -1) _exit(120); + if (fd_move(6,pierr[1]) == -1) _exit(120); if (chdir(auto_qmail) == -1) _exit(61); execv(*binqqargs,binqqargs); _exit(120); @@ -47,6 +57,7 @@ struct qmail *qq; qq->fdm = pim[1]; close(pim[0]); qq->fde = pie[1]; close(pie[0]); + qq->fderr = pierr[0]; close(pierr[1]); substdio_fdbuf(&qq->ss,write,qq->fdm,qq->buf,sizeof(qq->buf)); qq->flagerr = 0; return 0; @@ -89,10 +100,22 @@ struct qmail *qq; { int wstat; int exitcode; + int match; + char ch; + static char errstr[256]; + int len = 0; qmail_put(qq,"",1); if (!qq->flagerr) if (substdio_flush(&qq->ss) == -1) qq->flagerr = 1; close(qq->fde); + substdio_fdbuf(&qq->ss,read,qq->fderr,qq->buf,sizeof(qq->buf)); + while( substdio_bget(&qq->ss,&ch,1) && len < 255){ + errstr[len]=ch; + len++; + } + if (len > 0) errstr[len]='\0'; /* add str-term */ + + close(qq->fderr); if (wait_pid(&wstat,qq->pid) != qq->pid) return "Zqq waitpid surprise (#4.3.0)"; @@ -125,8 +148,11 @@ struct qmail *qq; case 81: return "Zqq internal bug (#4.3.0)"; case 120: return "Zunable to exec qq (#4.3.0)"; default: + if (exitcode == 82 && len > 2){ + return errstr; + } if ((exitcode >= 11) && (exitcode <= 40)) - return "Dqq permanent problem (#5.3.0)"; + return "Dqq permanent problem (#5.3.0)"; return "Zqq temporary problem (#4.3.0)"; } } diff --git a/qmail.h b/qmail.h @@ -10,6 +10,7 @@ struct qmail { unsigned long pid; int fdm; int fde; + int fderr; substdio ss; char buf[1024]; } ;