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 <frob-qmail webcentral.com.au> 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 <fcu-software at no-way.org> 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 <stdio.h>
#include <unistd.h>
#include <sys/types.h>
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];
} ;
syntax highlighted by Code2HTML, v. 0.9.1