If you set the environment variable QQEH before calling qmail-queue
(or anything that subsequently calls it), the contents of it will be
prepended to the email prior to the Received: header that qmail-queue
inserts.

diff -u orig/condredirect.c ./condredirect.c
--- orig/condredirect.c	1998-06-15 06:53:16.000000000 -0400
+++ ./condredirect.c	2004-07-15 12:19:42.000000000 -0400
@@ -34,6 +34,7 @@
 {
   char *sender;
   char *dtline;
+  char *qqeh;
   int pid;
   int wstat;
   char *qqx;
@@ -71,6 +72,11 @@
   if (qmail_open(&qqt) == -1)
     strerr_die2sys(111,FATAL,"unable to fork: ");
   qmail_puts(&qqt,dtline);
+
+  qqeh = env_get("QQEH");
+  if (qqeh)
+    qmail_puts(&qqt,qqeh);
+
   if (substdio_copy(&ssout,&ssin) != 0)
     strerr_die2sys(111,FATAL,"unable to read message: ");
   substdio_flush(&ssout);
diff -u orig/forward.c ./forward.c
--- orig/forward.c	1998-06-15 06:53:16.000000000 -0400
+++ ./forward.c	2004-07-15 12:18:22.000000000 -0400
@@ -32,6 +32,7 @@
 {
   char *sender;
   char *dtline;
+  char *qqeh;
   char *qqx;
  
   sig_pipeignore();
@@ -46,6 +47,11 @@
   if (qmail_open(&qqt) == -1)
     strerr_die2sys(111,FATAL,"unable to fork: ");
   qmail_puts(&qqt,dtline);
+
+  qqeh = env_get("QQEH");
+  if (qqeh)
+    qmail_puts(&qqt,qqeh);
+
   if (substdio_copy(&ssout,&ssin) != 0)
     strerr_die2sys(111,FATAL,"unable to read message: ");
   substdio_flush(&ssout);
diff -u orig/Makefile ./Makefile
--- orig/Makefile	1998-06-15 06:53:16.000000000 -0400
+++ ./Makefile	2004-07-14 16:20:51.000000000 -0400
@@ -1421,9 +1421,11 @@
 qmail-queue: \
 load qmail-queue.o triggerpull.o fmtqfn.o now.o date822fmt.o \
 datetime.a seek.a ndelay.a open.a sig.a alloc.a substdio.a error.a \
+env.a \
 str.a fs.a auto_qmail.o auto_split.o auto_uids.o
 	./load qmail-queue triggerpull.o fmtqfn.o now.o \
 	date822fmt.o datetime.a seek.a ndelay.a open.a sig.a \
+	env.a \
 	alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
 	auto_split.o auto_uids.o 
 
@@ -1434,6 +1436,7 @@
 qmail-queue.o: \
 compile qmail-queue.c readwrite.h sig.h exit.h open.h seek.h fmt.h \
 alloc.h substdio.h datetime.h now.h datetime.h triggerpull.h extra.h \
+env.h \
 auto_qmail.h auto_uids.h date822fmt.h fmtqfn.h
 	./compile qmail-queue.c
 
diff -u orig/preline.1 ./preline.1
--- orig/preline.1	1998-06-15 06:53:16.000000000 -0400
+++ ./preline.1	2004-07-15 12:23:03.000000000 -0400
@@ -39,6 +39,11 @@
 .B control/virtualdomains
 for manual routing.
 .TP
+.B \-e
+Do not include the
+.B QQEH
+contents.
+.TP
 .B \-f
 Do not include the
 .B From_
diff -u orig/preline.c ./preline.c
--- orig/preline.c	1998-06-15 06:53:16.000000000 -0400
+++ ./preline.c	2004-07-15 12:21:51.000000000 -0400
@@ -20,6 +20,7 @@
 int flagufline = 1; char *ufline;
 int flagrpline = 1; char *rpline;
 int flagdtline = 1; char *dtline;
+int flagqqeh = 1; char *qqeh;
 
 char outbuf[SUBSTDIO_OUTSIZE];
 char inbuf[SUBSTDIO_INSIZE];
@@ -46,9 +47,11 @@
       case 'f': flagufline = 0; break;
       case 'r': flagrpline = 0; break;
       case 'd': flagdtline = 0; break;
+      case 'e': flagqqeh   = 0; break;
       case 'F': flagufline = 1; break;
       case 'R': flagrpline = 1; break;
       case 'D': flagdtline = 1; break;
+      case 'E': flagqqeh   = 1; break;
       default: die_usage();
     }
   argc -= optind;
@@ -77,6 +80,7 @@
   if (flagufline) substdio_bputs(&ssout,ufline);
   if (flagrpline) substdio_bputs(&ssout,rpline);
   if (flagdtline) substdio_bputs(&ssout,dtline);
+  if (flagqqeh)   substdio_bputs(&ssout,qqeh);
   if (substdio_copy(&ssout,&ssin) != 0)
     strerr_die2sys(111,FATAL,"unable to copy input: ");
   substdio_flush(&ssout);
diff -u orig/qmail-command.8 ./qmail-command.8
--- orig/qmail-command.8	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-command.8	2004-07-15 11:41:31.000000000 -0400
@@ -143,6 +143,10 @@
 adds to
 .IR mbox -format
 files.
+.B QQEH
+is the same QQEH that was set when
+.B qmail-queue
+was invoked for this email.
 .SH "SEE ALSO"
 dot-qmail(5),
 envelopes(5),
diff -u orig/qmail-local.8 ./qmail-local.8
--- orig/qmail-local.8	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-local.8	2004-07-16 11:51:02.000000000 -0400
@@ -14,6 +14,7 @@
 .I domain
 .I sender
 .I defaultdelivery
+.I qqeh
 .SH DESCRIPTION
 .B qmail-local
 reads a mail message
@@ -70,6 +71,9 @@
 .BR .qmail\fIext :
 namely, following the delivery instructions in
 .IR defaultdelivery .
+Prepend the contents of
+.IR qqeh
+to the message on standard input.
 
 The standard input for
 .B qmail-local
diff -u orig/qmail-local.c ./qmail-local.c
--- orig/qmail-local.c	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-local.c	2004-07-15 11:53:46.000000000 -0400
@@ -52,6 +52,7 @@
 char *host;
 char *sender;
 char *aliasempty;
+char *qqeh;
 
 stralloc safeext = {0};
 stralloc ufline = {0};
@@ -116,6 +117,7 @@
  substdio_fdbuf(&ssout,write,fd,outbuf,sizeof(outbuf));
  if (substdio_put(&ssout,rpline.s,rpline.len) == -1) goto fail;
  if (substdio_put(&ssout,dtline.s,dtline.len) == -1) goto fail;
+ if (substdio_puts(&ssout,qqeh) == -1) goto fail;
 
  switch(substdio_copy(&ssout,&ss))
   {
@@ -196,6 +198,7 @@
  if (substdio_put(&ssout,ufline.s,ufline.len)) goto writeerrs;
  if (substdio_put(&ssout,rpline.s,rpline.len)) goto writeerrs;
  if (substdio_put(&ssout,dtline.s,dtline.len)) goto writeerrs;
+ if (substdio_puts(&ssout,qqeh) == -1) goto writeerrs;
  for (;;)
   {
    if (getln(&ss,&messline,&match,'\n') != 0) 
@@ -276,6 +279,7 @@
  if (qmail_open(&qqt) == -1) temp_fork();
  mailforward_qp = qmail_qp(&qqt);
  qmail_put(&qqt,dtline.s,dtline.len);
+ qmail_puts(&qqt,qqeh);
  do
   {
    if (getln(&ss,&messline,&match,'\n') != 0) { qmail_fail(&qqt); break; }
@@ -484,6 +488,7 @@
  if (!(host = *argv++)) usage();
  if (!(sender = *argv++)) usage();
  if (!(aliasempty = *argv++)) usage();
+ if (!(qqeh = *argv++)) usage();
  if (*argv) usage();
 
  if (homedir[0] != '/') usage();
@@ -495,6 +500,7 @@
  if (!env_put2("HOME",homedir)) temp_nomem();
  if (!env_put2("USER",user)) temp_nomem();
  if (!env_put2("LOCAL",local)) temp_nomem();
+ if (!env_put2("QQEH",qqeh)) temp_nomem();
 
  if (!stralloc_copys(&envrecip,local)) temp_nomem();
  if (!stralloc_cats(&envrecip,"@")) temp_nomem();
diff -u orig/qmail-lspawn.c ./qmail-lspawn.c
--- orig/qmail-lspawn.c	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-lspawn.c	2004-07-15 10:41:17.000000000 -0400
@@ -165,15 +165,15 @@
   }
 }
 
-int spawn(fdmess,fdout,s,r,at)
+int spawn(fdmess,fdout,s,qqeh,r,at)
 int fdmess; int fdout;
-char *s; char *r; int at;
+char *s; char *qqeh; char *r; int at;
 {
  int f;
 
  if (!(f = fork()))
   {
-   char *(args[11]);
+   char *(args[12]);
    unsigned long u;
    int n;
    int uid;
@@ -217,7 +217,8 @@
    args[7] = r + at + 1;
    args[8] = s;
    args[9] = aliasempty;
-   args[10] = 0;
+   args[10] = qqeh;
+   args[11] = 0;
 
    if (fd_move(0,fdmess) == -1) _exit(QLX_SYS);
    if (fd_move(1,fdout) == -1) _exit(QLX_SYS);
diff -u orig/qmail-queue.8 ./qmail-queue.8
--- orig/qmail-queue.8	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-queue.8	2004-07-16 11:53:50.000000000 -0400
@@ -33,6 +33,14 @@
 always adds a
 .B Received
 line to the top of the message.
+.B qmail-queue
+keeps a copy of the
+.B QQEH
+environment variable (if set), and passes it into the queue.
+.B qmail-local
+and
+.B qmail-remote
+will prepend it to the headers of the email when it is delivered.
 Other than this,
 .B qmail-queue
 does not inspect the message
diff -u orig/qmail-queue.c ./qmail-queue.c
--- orig/qmail-queue.c	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-queue.c	2004-07-14 16:23:52.000000000 -0400
@@ -16,6 +16,7 @@
 #include "auto_uids.h"
 #include "date822fmt.h"
 #include "fmtqfn.h"
+#include "env.h"
 
 #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */
 #define ADDR 1003
@@ -155,7 +156,9 @@
 {
  unsigned int len;
  char ch;
+ char *qqeh;
 
+ qqeh = env_get("QQEH");
  sig_blocknone();
  umask(033);
  if (chdir(auto_qmail) == -1) die(61);
@@ -216,6 +219,12 @@
  if (substdio_bput(&ssout,tmp,fmt_ulong(tmp,mypid)) == -1) die_write();
  if (substdio_bput(&ssout,"",1) == -1) die_write();
 
+ if (qqeh && *qqeh) {
+   if (substdio_bput(&ssout,"e",1) == -1) die_write();
+   if (substdio_bputs(&ssout,qqeh) == -1) die_write();
+   if (substdio_bput(&ssout,"",1) == -1) die_write();
+ }
+
  if (substdio_get(&ssin,&ch,1) < 1) die_read();
  if (ch != 'F') die(91);
  if (substdio_bput(&ssout,&ch,1) == -1) die_write();
diff -u orig/qmail-remote.8 ./qmail-remote.8
--- orig/qmail-remote.8	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-remote.8	2004-07-15 11:04:39.000000000 -0400
@@ -5,6 +5,7 @@
 .B qmail-remote
 .I host
 .I sender
+.I qqeh
 .I recip
 [
 .I recip ...
@@ -46,6 +47,8 @@
 .BR qmail-remote .
 The envelope sender address is listed as
 .I sender\fP.
+Any QQEH information passed to qmail-queue is passed in
+.I qqeh\fP.
 
 Note that
 .B qmail-remote
diff -u orig/qmail-remote.c ./qmail-remote.c
--- orig/qmail-remote.c	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-remote.c	2004-07-15 12:16:28.000000000 -0400
@@ -43,6 +43,7 @@
 struct constmap maproutes;
 stralloc host = {0};
 stralloc sender = {0};
+stralloc qqeh = {0};
 
 saa reciplist = {0};
 
@@ -193,7 +194,13 @@
 {
   int r;
   char ch;
+  int i;
 
+  for (i = 0; i < qqeh.len; i++) {
+    if (qqeh.s[i] == '\n')
+      substdio_put(&smtpto,"\r",1);
+    substdio_put(&smtpto,qqeh.s + i,1);
+  }
   for (;;) {
     r = substdio_get(&ssin,&ch,1);
     if (r == 0) break;
@@ -366,11 +373,13 @@
 
   addrmangle(&sender,argv[2],&flagalias,0);
  
+  if (!stralloc_copys(&qqeh,argv[3])) temp_nomem();
+
   if (!saa_readyplus(&reciplist,0)) temp_nomem();
   if (ipme_init() != 1) temp_oserr();
  
   flagallaliases = 1;
-  recips = argv + 3;
+  recips = argv + 4;
   while (*recips) {
     if (!saa_readyplus(&reciplist,1)) temp_nomem();
     reciplist.sa[reciplist.len] = sauninit;
diff -u orig/qmail-rspawn.c ./qmail-rspawn.c
--- orig/qmail-rspawn.c	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-rspawn.c	2004-07-15 10:43:19.000000000 -0400
@@ -77,18 +77,19 @@
     }
 }
 
-int spawn(fdmess,fdout,s,r,at)
+int spawn(fdmess,fdout,s,qqeh,r,at)
 int fdmess; int fdout;
-char *s; char *r; int at;
+char *s; char *qqeh; char *r; int at;
 {
  int f;
- char *(args[5]);
+ char *(args[6]);
 
  args[0] = "qmail-remote";
  args[1] = r + at + 1;
  args[2] = s;
- args[3] = r;
- args[4] = 0;
+ args[3] = qqeh;
+ args[4] = r;
+ args[5] = 0;
 
  if (!(f = vfork()))
   {
diff -u orig/qmail-send.c ./qmail-send.c
--- orig/qmail-send.c	1998-06-15 06:53:16.000000000 -0400
+++ ./qmail-send.c	2004-07-15 10:31:58.000000000 -0400
@@ -195,8 +195,9 @@
 
 /* this file is too long ---------------------------------------------- INFO */
 
-int getinfo(sa,dt,id)
+int getinfo(sa,eh,dt,id)
 stralloc *sa;
+stralloc *eh;
 datetime_sec *dt;
 unsigned long id;
 {
@@ -212,14 +213,22 @@
  if (fdinfo == -1) return 0;
  if (fstat(fdinfo,&st) == -1) { close(fdinfo); return 0; }
  substdio_fdbuf(&ss,read,fdinfo,buf,sizeof(buf));
- if (getln(&ss,&line,&match,'\0') == -1) { close(fdinfo); return 0; }
+ sa->len = eh->len = 0;
+ for (;;) {
+   if (getln(&ss,&line,&match,'\0') == -1) { close(fdinfo); return 0; }
+   if (!match) break;
+   if (line.s[0] == 'F') {
+     while (!stralloc_copys(sa,line.s + 1)) nomem();
+     while (!stralloc_0(sa)) nomem();
+   }
+   if (line.s[0] == 'e') {
+     while (!stralloc_copys(eh,line.s + 1)) nomem();
+     while (!stralloc_0(eh)) nomem();
+   }
+ }
  close(fdinfo);
- if (!match) return 0;
- if (line.s[0] != 'F') return 0;
 
  *dt = st.st_mtime;
- while (!stralloc_copys(sa,line.s + 1)) nomem();
- while (!stralloc_0(sa)) nomem();
  return 1;
 }
 
@@ -250,11 +259,12 @@
  return 1;
 }
 
-void comm_write(c,delnum,id,sender,recip)
+void comm_write(c,delnum,id,sender,qqeh,recip)
 int c;
 int delnum;
 unsigned long id;
 char *sender;
+char *qqeh;
 char *recip;
 {
  char ch;
@@ -267,6 +277,8 @@
  while (!stralloc_0(&comm_buf[c])) nomem();
  senderadd(&comm_buf[c],sender,recip);
  while (!stralloc_0(&comm_buf[c])) nomem();
+ while (!stralloc_cats(&comm_buf[c],qqeh)) nomem();
+ while (!stralloc_0(&comm_buf[c])) nomem();
  while (!stralloc_cats(&comm_buf[c],recip)) nomem();
  while (!stralloc_0(&comm_buf[c])) nomem();
  comm_pos[c] = 0;
@@ -486,6 +498,7 @@
   int channel;
   datetime_sec retry;
   stralloc sender;
+  stralloc qqeh;
   int numtodo;
   int flaghiteof;
   int flagdying;
@@ -503,6 +516,7 @@
   {
    jo[j].refs = 0;
    jo[j].sender.s = 0;
+   jo[j].qqeh.s = 0;
   }
 }
 
@@ -658,11 +672,12 @@
  char buf[128];
  char inbuf[128];
  static stralloc sender = {0};
+ static stralloc qqeh = {0};
  static stralloc quoted = {0};
  datetime_sec birth;
  unsigned long qp;
 
- if (!getinfo(&sender,&birth,id)) return 0; /* XXX: print warning */
+ if (!getinfo(&sender,&qqeh,&birth,id)) return 0; /* XXX: print warning */
 
  /* owner-@host-@[] -> owner-@host */
  if (sender.len >= 5)
@@ -855,7 +870,7 @@
  d[c][i].mpos = mpos;
  d[c][i].used = 1; ++concurrencyused[c];
 
- comm_write(c,i,jo[j].id,jo[j].sender.s,recip);
+ comm_write(c,i,jo[j].id,jo[j].sender.s,jo[j].qqeh.s,recip);
 
  strnum2[fmt_ulong(strnum2,d[c][i].delid)] = 0;
  strnum3[fmt_ulong(strnum3,jo[j].id)] = 0;
@@ -1059,6 +1074,7 @@
  datetime_sec birth;
  struct prioq_elt pe;
  static stralloc line = {0};
+ static stralloc qqeh = {0};
  int match;
 
  if (flagexitasap) return;
@@ -1074,13 +1090,14 @@
    pass[c].mpos = 0;
    pass[c].fd = open_read(fn.s);
    if (pass[c].fd == -1) goto trouble;
-   if (!getinfo(&line,&birth,pe.id)) { close(pass[c].fd); goto trouble; }
+   if (!getinfo(&line,&qqeh,&birth,pe.id)) { close(pass[c].fd); goto trouble; }
    pass[c].id = pe.id;
    substdio_fdbuf(&pass[c].ss,read,pass[c].fd,pass[c].buf,sizeof(pass[c].buf));
    pass[c].j = job_open(pe.id,c);
    jo[pass[c].j].retry = nextretry(birth,c);
    jo[pass[c].j].flagdying = (recent > birth + lifetime);
    while (!stralloc_copy(&jo[pass[c].j].sender,&line)) nomem();
+   while (!stralloc_copy(&jo[pass[c].j].qqeh,&qqeh)) nomem();
   }
 
  if (!del_avail(c)) return;
@@ -1346,8 +1363,15 @@
      case 'p':
        scan_ulong(todoline.s + 1,&pid);
        break;
+    case 'e':
+       if (substdio_put(&ssinfo,todoline.s,todoline.len) == -1)
+	{
+	 fnmake_info(id);
+         log3("warning: trouble writing to ",fn.s,"\n"); goto fail;
+	}
+       break;
      case 'F':
-       if (substdio_putflush(&ssinfo,todoline.s,todoline.len) == -1)
+       if (substdio_put(&ssinfo,todoline.s,todoline.len) == -1)
 	{
 	 fnmake_info(id);
          log3("warning: trouble writing to ",fn.s,"\n"); goto fail;
diff -u orig/spawn.c ./spawn.c
--- orig/spawn.c	1998-06-15 06:53:16.000000000 -0400
+++ ./spawn.c	2004-07-15 10:41:27.000000000 -0400
@@ -68,6 +68,7 @@
 int delnum;
 stralloc messid = {0};
 stralloc sender = {0};
+stralloc qqeh = {0};
 stralloc recip = {0};
 
 void err(s) char *s;
@@ -119,7 +120,7 @@
 
  coe(pi[0]);
 
- f = spawn(fdmess,pi[1],sender.s,recip.s,j);
+ f = spawn(fdmess,pi[1],sender.s,qqeh.s,recip.s,j);
  close(fdmess);
  if (f == -1)
   { close(pi[0]); close(pi[1]); err("Zqmail-spawn unable to fork. (#4.3.0)\n"); return; }
@@ -163,8 +164,12 @@
      case 2:
        if (!stralloc_append(&sender,&ch)) flagabort = 1;
        if (ch) break;
-       recip.len = 0; stage = 3; break;
+       qqeh.len = 0; stage = 3; break;
      case 3:
+       if (!stralloc_append(&qqeh,&ch)) flagabort = 1;
+       if (ch) break;
+       recip.len = 0; stage = 4; break;
+     case 4:
        if (!stralloc_append(&recip,&ch)) flagabort = 1;
        if (ch) break;
        docmd();

