WARNING, NEW BEHAVIOUR: The patch is using descriptor 4 instead of STDERR now! Adds the possibility for a qmail-queue-replacement to offer custom error (=bounce) messages. You have to write the error message to filedescriptor 4 and exit 82, in order to use the custom message. Format of the message: Dthis is a custom fatal error message Zthis is a custom temporary failure message Thanks to Richard Lyons for spotting a wrong errstr declaration. Thanks to Jeremy Hinton for noting that I forget to include the patch to qmail.h This patch has been made by Flavio Curti and is provided AS IS. Do with it as you wish, I'm not responsible for anything that breaks because of this patch. EXAMPLES Perl: open(FD,">&4"); print FD "Ztemporary failure message"; close(FD); exit(82); Shell: echo -n "Zpermanent failure after data" >&4 exit 82; C (non-djb-style): #include #include #include char err[] = "Zpermanently refusing"; int main() { write(4,err,(strlen(err)+1)); exit(82); } --- qmail.c 1998-06-15 12:53:16.000000000 +0200 +++ ../../qmail-1.03/qmail.c 2004-10-13 22:35:37.000000000 +0200 @@ -14,20 +14,30 @@ { int pim[2]; int pie[2]; + int pierr[2]; 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 = vfork()) { 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(4,pierr[1]) == -1) _exit(120); if (chdir(auto_qmail) == -1) _exit(61); execv(*binqqargs,binqqargs); _exit(120); @@ -35,6 +45,7 @@ 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; @@ -82,10 +93,22 @@ { 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)"; @@ -118,8 +141,11 @@ 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)"; } } --- qmail.h 1998-06-15 12:53:16.000000000 +0200 +++ ../../qmail-1.03/qmail.h 2004-05-26 14:48:23.000000000 +0200 @@ -8,6 +8,7 @@ unsigned long pid; int fdm; int fde; + int fderr; substdio ss; char buf[1024]; } ;