<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">2007-08-27 Version 2.0 of the patch (netqmail 1.05 version)
WARNING, NEW BEHAVIOUR: The patch is using descriptor 6 instead of 
fd 4 now!

fd 4 is also used by qmail-qfilter, so this patch is using fd 6.
Hopefully forever now :)

Thanks to Amitai Schlair for finding this and including the patch
the pkgsrc qmail package.

2005-05-27
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 &lt;frob-qmail webcentral.com.au&gt; 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 &lt;fcu-software at no-way.org&gt; 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,"&gt;&amp;6");
print FD "Ztemporary failure message";
close(FD);
exit(82);

Shell:
echo -n "Zpermanent failure after data" &gt;&amp;4
exit 82;

C (non-djb-style):
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/types.h&gt;

char    err[] = "Zpermanently refusing";

int main() {
        write(6,err,(strlen(err)+1));
        exit(82);
}


--- netqmail-1.05.orig/qmail.c	Mon Apr  4 03:54:50 2005
+++ netqmail-1.05/qmail.c	Mon Apr  4 03:57:59 2005
@@ -23,22 +23,32 @@
 {
   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-&gt;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(6,pierr[1]) == -1) _exit(120);
       if (chdir(auto_qmail) == -1) _exit(61);
       execv(*binqqargs,binqqargs);
       _exit(120);
@@ -46,6 +56,7 @@
 
   qq-&gt;fdm = pim[1]; close(pim[0]);
   qq-&gt;fde = pie[1]; close(pie[0]);
+  qq-&gt;fderr = pierr[0]; close(pierr[1]);
   substdio_fdbuf(&amp;qq-&gt;ss,write,qq-&gt;fdm,qq-&gt;buf,sizeof(qq-&gt;buf));
   qq-&gt;flagerr = 0;
   return 0;
@@ -93,10 +104,22 @@
 {
   int wstat;
   int exitcode;
+  int match;
+  char ch;
+  static char errstr[256];
+  int len = 0;
 
   qmail_put(qq,"",1);
   if (!qq-&gt;flagerr) if (substdio_flush(&amp;qq-&gt;ss) == -1) qq-&gt;flagerr = 1;
   close(qq-&gt;fde);
+  substdio_fdbuf(&amp;qq-&gt;ss,read,qq-&gt;fderr,qq-&gt;buf,sizeof(qq-&gt;buf));
+  while( substdio_bget(&amp;qq-&gt;ss,&amp;ch,1) &amp;&amp; len &lt; 255){
+    errstr[len]=ch;
+    len++;
+  }
+  if (len &gt; 0) errstr[len]='\0'; /* add str-term */
+
+  close(qq-&gt;fderr);
 
   if (wait_pid(&amp;wstat,qq-&gt;pid) != qq-&gt;pid)
     return "Zqq waitpid surprise (#4.3.0)";
@@ -129,8 +152,11 @@
     case 81: return "Zqq internal bug (#4.3.0)";
     case 120: return "Zunable to exec qq (#4.3.0)";
     default:
+      if (exitcode == 82 &amp;&amp; len &gt; 2){
+        return errstr;
+      }
       if ((exitcode &gt;= 11) &amp;&amp; (exitcode &lt;= 40))
-	return "Dqq permanent problem (#5.3.0)";
+        return "Dqq permanent problem (#5.3.0)";
       return "Zqq temporary problem (#4.3.0)";
   }
 }
--- netqmail-1.05.orig/qmail.h	Mon Jun 15 12:53:16 1998
+++ netqmail-1.05/qmail.h	Mon Apr  4 03:55:56 2005
@@ -8,6 +8,7 @@
   unsigned long pid;
   int fdm;
   int fde;
+  int fderr;
   substdio ss;
   char buf[1024];
 } ;
</pre></body></html>