File qmailtoaster-1.3.1.patch of Package qmail-toaster

qmailtoaster-1.3.1.patch            May 10, 2006

Nick Hemmesch <nick@ndhsoft.com>
http://www.qmailtoaster.com

~~~~~~~~~~~~~ Patches Applied ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

qmail-1.03 patched to netqmail-1.05
-----------------------------------
QMAILQUEUE patch
qmail-local patch
local IP 0.0.0.0 patch
sendmail -f patch

Andrew St. Jean - qregex-starttls-2way-auth-20060305
http://www.arda.homeunix.net/store/qmail/

Frederik Vermeulen - qmail-tls 20060104
http://inoa.net/qmail-tls/

Erwin Hoffman - SMTP-AUTH Version 0.57
http://www.fehcom.de/qmail/

Robert Sander - qmail-remote-auth
http://www.ornl.gov/lists/mailing-lists/qmail/2002/03/msg00091.html

Antonio Nati - chkuser-2.0.8b
http://www.interazioni.it/opensource/chkuser/

Chris christophe@saout.de - qmail-spf.rc5 
http://www.saout.de/misc/spf/

Russ Nelson - qmail-1.03-dk-0.54 domainkeys patch
http://www.qmail.org/qmail-1.03-dk-0.54.patch

Jeremy Kister - qmail-dk-0.54-auth patch
http://jeremy.kister.net/code/qmail-dk-0.54-auth.patch

Erwin Hoffmann - warlord-1.3.11  
http://www.fehcom.de/qmail/

Bill Shupp - netqmail-maildir++.patch
http://shupp.org/patches/netqmail-maildir++.patch

Bill Shupp - custom-smtp-reject
http://www.shupp.org/patches/custom.patch

Johannes Erdfelt - big-concurrency patch
http://qmail.org/big-concurrency.patch

Inter7 - qmailtap-1.1 tap
http://www.inter7.com/qmailtap/qmail-tap-1.1.diff

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


diff -Naur ./badloadertypes ../qmail-1.03-build-10/badloadertypes
--- ./badloadertypes	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/badloadertypes	2005-01-29 06:08:50.000000000 -0600
@@ -0,0 +1,4 @@
+Mi5kb
+MzIuZ
+MyLmR
+MyLkR
diff -Naur ./badmimetypes ../qmail-1.03-build-10/badmimetypes
--- ./badmimetypes	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/badmimetypes	2005-01-29 06:09:25.000000000 -0600
@@ -0,0 +1,12 @@
+TVqQAAMAA
+TVpQAAIAA
+TVpAALQAc
+TVpyAXkAX
+TVrmAU4AA
+TVrhARwAk
+TVoFAQUAA
+TVoAAAQAA
+TVoIARMAA
+TVouARsAA
+TVrQAT8AA
+TVoAAAEAA
diff -Naur ./base64.c ../qmail-1.03-build-10/base64.c
--- ./base64.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/base64.c	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,122 @@
+#include "base64.h"
+#include "stralloc.h"
+#include "substdio.h"
+#include "str.h"
+
+static char *b64alpha =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#define B64PAD '='
+
+/* returns 0 ok, 1 illegal, -1 problem */
+
+int b64decode(in,l,out)
+const unsigned char *in;
+int l;
+stralloc *out; /* not null terminated */
+{
+  int p = 0;
+  int n;
+  unsigned int x;
+  int i, j;
+  char *s;
+  unsigned char b[3];
+
+  if (l == 0)
+  {
+    if (!stralloc_copys(out,"")) return -1;
+    return 0;
+  }
+
+  while(in[l-1] == B64PAD) {
+    p ++;
+    l--;
+  }
+
+  n = (l + p) / 4;
+  out->len = (n * 3) - p;
+  if (!stralloc_ready(out,out->len)) return -1;
+  s = out->s;
+
+  for(i = 0; i < n - 1 ; i++) {
+    x = 0;
+    for(j = 0; j < 4; j++) {
+      if(in[j] >= 'A' && in[j] <= 'Z')
+        x = (x << 6) + (unsigned int)(in[j] - 'A' + 0);
+      else if(in[j] >= 'a' && in[j] <= 'z')
+        x = (x << 6) + (unsigned int)(in[j] - 'a' + 26);
+      else if(in[j] >= '0' && in[j] <= '9')
+        x = (x << 6) + (unsigned int)(in[j] - '0' + 52);
+      else if(in[j] == '+')
+        x = (x << 6) + 62;
+      else if(in[j] == '/')
+        x = (x << 6) + 63;
+      else if(in[j] == '=')
+        x = (x << 6);
+    }
+
+    s[2] = (unsigned char)(x & 255); x >>= 8;
+    s[1] = (unsigned char)(x & 255); x >>= 8;
+    s[0] = (unsigned char)(x & 255); x >>= 8;
+    s += 3; in += 4;
+  }
+
+  x = 0;
+  for(j = 0; j < 4; j++) {
+    if(in[j] >= 'A' && in[j] <= 'Z')
+      x = (x << 6) + (unsigned int)(in[j] - 'A' + 0);
+    else if(in[j] >= 'a' && in[j] <= 'z')
+      x = (x << 6) + (unsigned int)(in[j] - 'a' + 26);
+    else if(in[j] >= '0' && in[j] <= '9')
+      x = (x << 6) + (unsigned int)(in[j] - '0' + 52);
+    else if(in[j] == '+')
+      x = (x << 6) + 62;
+    else if(in[j] == '/')
+      x = (x << 6) + 63;
+    else if(in[j] == '=')
+      x = (x << 6);
+  }
+
+  b[2] = (unsigned char)(x & 255); x >>= 8;
+  b[1] = (unsigned char)(x & 255); x >>= 8;
+  b[0] = (unsigned char)(x & 255); x >>= 8;
+
+  for(i = 0; i < 3 - p; i++)
+    s[i] = b[i];
+
+  return 0;
+}
+
+int b64encode(in,out)
+stralloc *in;
+stralloc *out; /* not null terminated */
+{
+  unsigned char a, b, c;
+  int i;
+  char *s;
+
+  if (in->len == 0)
+  {
+    if (!stralloc_copys(out,"")) return -1;
+    return 0;
+  }
+
+  if (!stralloc_ready(out,in->len / 3 * 4 + 4)) return -1;
+  s = out->s;
+
+  for (i = 0;i < in->len;i += 3) {
+    a = in->s[i];
+    b = i + 1 < in->len ? in->s[i + 1] : 0;
+    c = i + 2 < in->len ? in->s[i + 2] : 0;
+
+    *s++ = b64alpha[a >> 2];
+    *s++ = b64alpha[((a & 3 ) << 4) | (b >> 4)];
+
+    if (i + 1 >= in->len) *s++ = B64PAD;
+    else *s++ = b64alpha[((b & 15) << 2) | (c >> 6)];
+
+    if (i + 2 >= in->len) *s++ = B64PAD;
+    else *s++ = b64alpha[c & 63];
+  }
+  out->len = s - out->s;
+  return 0;
+}
diff -Naur ./base64.h ../qmail-1.03-build-10/base64.h
--- ./base64.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/base64.h	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,7 @@
+#ifndef BASE64_H
+#define BASE64_H
+
+extern int b64decode();
+extern int b64encode();
+
+#endif
diff -Naur ./byte_cspn.c ../qmail-1.03-build-10/byte_cspn.c
--- ./byte_cspn.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/byte_cspn.c	2006-05-05 21:22:33.000000000 -0500
@@ -0,0 +1,11 @@
+#include "byte.h"
+
+unsigned int byte_cspn(s,n,c)
+register char *s;
+register unsigned int n;
+register char *c;
+{
+  while(*c)
+    n = byte_chr(s,n,*c++);
+  return n;
+}
diff -Naur ./byte.h ../qmail-1.03-build-10/byte.h
--- ./byte.h	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/byte.h	2006-05-07 10:26:22.000000000 -0500
@@ -3,6 +3,8 @@
 
 extern unsigned int byte_chr();
 extern unsigned int byte_rchr();
+extern unsigned int byte_cspn();
+extern unsigned int byte_rcspn();
 extern void byte_copy();
 extern void byte_copyr();
 extern int byte_diff();
diff -Naur ./byte_rcspn.c ../qmail-1.03-build-10/byte_rcspn.c
--- ./byte_rcspn.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/byte_rcspn.c	2006-05-05 21:22:37.000000000 -0500
@@ -0,0 +1,17 @@
+#include "byte.h"
+
+unsigned int byte_rcspn(s,n,c)
+register char *s;
+register unsigned int n;
+register char *c;
+{
+  unsigned int ret,pos,i;
+
+  for(ret = n,pos = 0;*c;++c) {
+    i = byte_rchr(s + pos,n - pos,*c) + pos;
+    if (i < n) ret = pos = i;
+  }
+
+  return ret;
+}
+
diff -Naur ./case_startb.c ../qmail-1.03-build-10/case_startb.c
--- ./case_startb.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/case_startb.c	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,21 @@
+#include "case.h"
+
+int case_startb(s,len,t)
+register char *s;
+unsigned int len;
+register char *t;
+{
+  register unsigned char x;
+  register unsigned char y;
+
+  for (;;) {
+    y = *t++ - 'A';
+    if (y <= 'Z' - 'A') y += 'a'; else y += 'A';
+    if (!y) return 1;
+    if (!len) return 0;
+    --len;
+    x = *s++ - 'A';
+    if (x <= 'Z' - 'A') x += 'a'; else x += 'A';
+    if (x != y) return 0;
+  }
+}
diff -Naur ./cdbmake_add.c ../qmail-1.03-build-10/cdbmake_add.c
--- ./cdbmake_add.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/cdbmake_add.c	2006-04-24 21:24:32.000000000 -0500
@@ -1,3 +1,4 @@
+#include "alloc.h"
 #include "cdbmake.h"
 
 void cdbmake_init(cdbm)
diff -Naur ./cdb_seek.c ../qmail-1.03-build-10/cdb_seek.c
--- ./cdb_seek.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/cdb_seek.c	2006-04-24 21:24:32.000000000 -0500
@@ -1,6 +1,5 @@
 #include <sys/types.h>
 #include <errno.h>
-extern int errno;
 #include "cdb.h"
 
 #ifndef SEEK_SET
diff -Naur ./CHANGES ../qmail-1.03-build-10/CHANGES
--- ./CHANGES	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/CHANGES	2006-04-24 21:24:32.000000000 -0500
@@ -1,3 +1,24 @@
+20040121 version: netqmail 1.05
+20040121 code: qmail-smtpd is protected from exceedingly long (eg 2GB)
+         header lines
+20040121 code: qmail_lspawn, qmail-newmrh, qmail-newu, and qmail-rspawn
+         are protected from misbehaving on hosts where the size of an
+         integer is not the same as the size of a character pointer
+         (eg 64 bit hosts with 32 bit ints)
+20031027 version: netqmail 1.04.
+20031027 doc: INSTALL points to http://lifewithqmail.org/lwq.html
+20031027 doc: qmail.7 identifies installation as netqmail and points to
+         http://qmail.org/
+20031027 doc: qmail-queue.8 adds explanation of $QMAILQUEUE
+20031027 doc: qmail-log.5 adds reference to errors from $QMAILQUEUE script
+20031027 doc: FAQ also points to http://cr.yp.to/qmail/faq.html and
+         http://qmail.org/
+20031027 code: qmail-smtpd identifies itself as netqmail
+20031027 code: if $QMAILQUEUE is set, it's invoked instead of qmail-queue
+20031024 code: changed errno from int to #include.
+20031024 code: fixed .qmail parsing bug.
+20031024 code: recognize 0.0.0.0 as a local address.
+20031024 code: sendmail's -f flag now overrides environment variables.
 19980615 version: qmail 1.03.
 19980614 doc: eliminated BIN.setup in favor of a web page.
 19980614 code: added other auto* to qmail-showctl output.
diff -Naur ./chkspawn.c ../qmail-1.03-build-10/chkspawn.c
--- ./chkspawn.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/chkspawn.c	2006-05-05 19:36:34.000000000 -0500
@@ -22,8 +22,8 @@
     _exit(1);
   }
 
-  if (auto_spawn > 255) {
-    substdio_puts(subfderr,"Oops. You have set conf-spawn higher than 255.\n");
+  if (auto_spawn > 65000) {
+    substdio_puts(subfderr,"Oops. You have set conf-spawn higher than 65000.\n");
     substdio_flush(subfderr);
     _exit(1);
   }
diff -Naur ./chkuser.c ../qmail-1.03-build-10/chkuser.c
--- ./chkuser.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/chkuser.c	2006-04-25 13:54:57.000000000 -0500
@@ -0,0 +1,1156 @@
+
+/*
+ *
+ * 'chkuser.c' v.2.0.8
+ * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
+ *
+ * Author: Antonio Nati tonix@interazioni.it
+ * All rights on this software and
+ * the identifying words chkusr and chkuser kept by the author
+ *
+ * This software may be freely used, modified and distributed,
+ * but this lines must be kept in every original or derived version.
+ * Original author "Antonio Nati" and the web URL
+ * "http://www.interazioni.it/opensource"
+ * must be indicated in every related work or web page
+ *
+ */
+
+#include <pwd.h>
+
+/* required by vpopmail */
+#include <stdio.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "dns.h"
+#include "env.h"
+#include "ipme.h"
+#include "now.h"
+#include "open.h"
+#include "subfd.h"
+#include "substdio.h"
+#include "stralloc.h"
+
+#include "/home/vpopmail/include/vpopmail.h"
+#include "/home/vpopmail/include/vauth.h"
+#include "/home/vpopmail/include/vpopmail_config.h"
+
+#include "chkuser.h"
+#include "chkuser_settings.h"
+
+#if defined _exit
+#undef _exit
+#endif
+
+extern void flush();
+extern void out (char *s);
+
+extern char *remotehost;
+extern char *remoteip;
+extern char *remoteinfo;
+extern char *relayclient;
+extern char *fakehelo;
+
+extern void die_nomem();
+
+#define DIE_NOMEM() die_nomem()
+
+#if defined CHKUSER_DEBUG
+
+#if defined CHKUSER_DEBUG_STDERR
+
+#define CHKUSER_DBG(a) write (STDERR_FILENO, a, strlen (a))
+#define CHKUSER_DBG_INT(a) { int x; char str[30]; sprintf (str, "%d", a); write (STDERR_FILENO, str, strlen (str));}
+
+#else
+
+#define CHKUSER_DBG(a) write (STDOUT_FILENO, a, strlen (a))
+#define CHKUSER_DBG_INT(a) { int x; char str[30]; sprintf (str, "%d", a); write (STDOUT_FILENO, str, strlen (str));}
+
+#endif
+#else
+
+#define CHKUSER_DBG(a) /* DBG dummy */
+#define CHKUSER_DBG_INT(a) /* DBG dummy */
+
+#endif
+
+static int INTRUSION_threshold_reached = 0;
+static int first_time_init_flag = 1;
+
+static int recipients = 0;
+static int wrong_recipients = 0;
+
+static stralloc user = {0};
+static stralloc domain = {0};
+static stralloc domain_path = {0};
+static stralloc tmp_path = {0};
+static stralloc alias_path = {0};
+
+#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
+ static char *identify_remote;
+#endif
+
+#if defined CHKUSER_ENABLE_EXTENSIONS
+#define CHKUSER_ENABLE_USERS_EXTENSIONS
+#endif
+
+#if defined CHKUSER_ENABLE_LISTS
+#define CHKUSER_ENABLE_EZMLM_LISTS
+#endif
+
+#if defined CHKUSER_EXTENSION_DASH
+#define CHKUSER_USERS_DASH CHKUSER_EXTENSION_DASH
+#endif
+
+
+#if defined CHKUSER_ENABLE_VAUTH_OPEN
+ static int db_already_open = 0;
+#endif
+
+#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
+  static char *starting_string = 0;
+  static int starting_value = -1;
+#endif
+
+#if defined CHKUSER_RCPT_LIMIT_VARIABLE
+  static char *maxrcpt_string = 0;
+  static int maxrcpt_limit = 0;
+  static int maxrcpt_limit_reached = 0;
+#endif
+
+#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
+  static char *maxwrongrcpt_string = 0;
+  static int maxwrongrcpt_limit = 0;
+  static int maxwrongrcpt_limit_reached = 0;
+#endif
+
+#if defined CHKUSER_MBXQUOTA_VARIABLE
+  static char *maxmbxquota_string = 0;
+  static int maxmbxquota_limit = 0;
+#endif
+
+#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
+
+  static unsigned int sender_nocheck = 0;
+
+#endif
+
+#if defined CHKUSER_SENDER_FORMAT || defined CHKUSER_SENDER_MX
+static stralloc sender_user = {0};
+static stralloc sender_domain = {0};
+#endif
+
+
+#if defined CHKUSER_ERROR_DELAY
+
+  static int chkuser_delay_interval = CHKUSER_ERROR_DELAY * 1000;
+
+#define CHKUSER_DELAY()	chkuser_delay()
+
+void chkuser_delay (void) {
+
+        usleep (chkuser_delay_interval);
+
+#if defined CHKUSER_ERROR_DELAY_INCREASE
+        chkuser_delay_interval += CHKUSER_ERROR_DELAY_INCREASE * 1000;
+#endif
+}
+
+#if defined CHKUSER_RCPT_DELAY_ANYERROR
+#define CHKUSER_RCPT_DELAY_ANY() chkuser_delay()
+#else
+#define CHKUSER_RCPT_DELAY_ANY() /* no delay for any error */
+#endif
+
+#if defined CHKUSER_SENDER_DELAY_ANYERROR
+#define CHKUSER_SENDER_DELAY_ANY() chkuser_delay()
+#else
+#define CHKUSER_SENDER_DELAY_ANY() /* no delay for any error */
+#endif
+
+
+#else
+#define CHKUSER_DELAY() /* no delay */
+#define CHKUSER_RCPT_DELAY_ANY() /* no delay */
+#define CHKUSER_SENDER_DELAY_ANY() /* no delay */
+#endif
+
+#if defined CHKUSER_ENABLE_LOGGING
+
+static stralloc logstr = { 0 };
+
+static void chkuser_commonlog (char *sender, char *rcpt, char *title, char *description) {
+
+  substdio_puts (subfderr, "CHKUSER ");
+  substdio_puts (subfderr, title);
+  substdio_puts (subfderr, ": from <");
+  substdio_puts (subfderr, sender);
+  substdio_puts (subfderr, ":" );
+  if (remoteinfo) {
+	substdio_puts (subfderr, remoteinfo);
+  }
+  substdio_puts (subfderr, ":" );
+#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
+  if (identify_remote) substdio_puts (subfderr, identify_remote);
+#endif
+  substdio_puts (subfderr, "> remote <");
+  if (fakehelo) substdio_puts (subfderr, fakehelo);
+  substdio_puts (subfderr, ":" );
+  if (remotehost) substdio_puts (subfderr, remotehost);
+  substdio_puts (subfderr, ":" );
+  if (remoteip) substdio_puts (subfderr, remoteip);
+  substdio_puts (subfderr, "> rcpt <");
+  substdio_puts (subfderr, rcpt);
+  substdio_puts (subfderr, "> : ");
+  substdio_puts (subfderr, description);
+  substdio_puts (subfderr, "\n");
+  substdio_flush (subfderr);
+}
+
+#else
+#define chkuser_commonlog(a,b,c,d) /* no log */
+#endif
+
+#if defined CHKUSER_SENDER_FORMAT
+
+static int check_sender_address_format (stralloc *user, stralloc *domain) {
+
+        int x;
+
+        for (x = 0; x < (user->len -1); ++x) {
+                if ((!isalnum (user->s[x])) 
+
+#if defined CHKUSER_ALLOW_SENDER_SRS
+		&& (user->s[x] != '#')
+		&& (user->s[x] != '+')
+#endif
+#if defined CHKUSER_ALLOW_SENDER_CHAR_1
+		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_1)
+#endif
+#if defined CHKUSER_ALLOW_SENDER_CHAR_2
+		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_2)
+#endif
+#if defined CHKUSER_ALLOW_SENDER_CHAR_3
+		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_3)
+#endif
+#if defined CHKUSER_ALLOW_SENDER_CHAR_4
+		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_4)
+#endif
+#if defined CHKUSER_ALLOW_SENDER_CHAR_5
+		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_5)
+#endif
+		&& (user->s[x] != '_') && (user->s[x] != '-') && (user->s[x] != '.') && (user->s[x] != '=')) {
+                        return 0;
+                }
+        }
+
+/*
+ * Be careful, this is a base check
+ *      Minimum is x.xx + ending \0
+ *      Minimum characters needed are 5
+ */
+#if defined CHKUSER_MIN_DOMAIN_LEN
+        if (domain->len < (CHKUSER_MIN_DOMAIN_LEN +1)) {
+                return 0;
+        }
+#endif
+
+/*
+ *      This is a safety check
+ */
+#if defined CHKUSER_MIN_DOMAIN_LEN
+        if (domain->len < 2) {
+                return 0;
+        }
+#endif
+
+        for (x = 0; x < (domain->len -1); ++x) {
+                if ((!isalnum (domain->s[x])) && (domain->s[x] != '-') && (domain->s[x] != '.')) {
+                        return 0;
+                }
+        }
+
+        if ((domain->s[0] == '-') || (domain->s[domain->len -2] == '-') || (domain->s[0] == '.') || (domain->s[domain->len -2] == '.')) {
+                return 0;
+        }
+        if (strstr (domain->s, "..") != NULL) {
+                return 0;
+        }
+	if (strncmp (domain->s, "xn--", 4) == 0) {
+		if (strstr (&domain->s[4], "--") != NULL)
+			return 0;
+	} else {
+		if (strstr (domain->s, "--") != NULL)
+			return 0;
+	}
+        if (strstr (domain->s, ".-") != NULL) {
+                return 0;
+        }
+        if (strstr (domain->s, "-.") != NULL) {
+                return 0;
+        }
+        if (strchr (domain->s, '.') == NULL) {
+                return 0;
+        }
+
+        return 1;
+}
+
+#endif
+
+#if defined CHKUSER_RCPT_FORMAT
+
+static int check_rcpt_address_format (stralloc *user, stralloc *domain) {
+
+        int x;
+
+        for (x = 0; x < (user->len -1); ++x) {
+                if ((!isalnum (user->s[x])) 
+#if defined CHKUSER_ALLOW_RCPT_SRS
+                && (user->s[x] != '#')
+                && (user->s[x] != '+')
+#endif
+#if defined CHKUSER_ALLOW_RCPT_CHAR_1
+                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_1)
+#endif
+#if defined CHKUSER_ALLOW_RCPT_CHAR_2
+                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_2)
+#endif
+#if defined CHKUSER_ALLOW_RCPT_CHAR_3
+                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_3)
+#endif
+#if defined CHKUSER_ALLOW_RCPT_CHAR_4
+                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_4)
+#endif
+#if defined CHKUSER_ALLOW_RCPT_CHAR_5
+                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_5)
+#endif
+
+		&& (user->s[x] != '_') && (user->s[x] != '-') && (user->s[x] != '.') && (user->s[x] != '=')) {
+                        return 0;
+                }
+        }
+
+/*
+ * Be careful, this is a base check
+ *      Minimum is x.xx + ending \0
+ *      Minimum characters needed are 5
+ */
+#if defined CHKUSER_MIN_DOMAIN_LEN
+        if (domain->len < (CHKUSER_MIN_DOMAIN_LEN +1)) {
+                return 0;
+        }
+#endif
+
+/*
+ *      This is a safety check
+ */
+#if defined CHKUSER_MIN_DOMAIN_LEN
+        if (domain->len < 2) {
+                return 0;
+        }
+#endif
+        for (x = 0; x < (domain->len -1); ++x) {
+                if ((!isalnum (domain->s[x])) && (domain->s[x] != '-') && (domain->s[x] != '.')) {
+                        return 0;
+                }
+        }
+
+        if ((domain->s[0] == '-') || (domain->s[domain->len -2] == '-') || (domain->s[0] == '.') || (domain->s[domain->len -2] == '.')) {
+                return 0;
+        }
+        if (strstr (domain->s, "..") != NULL) {
+                return 0;
+        }
+	if (strncmp (domain->s, "xn--", 4) == 0) {
+		if (strstr (&domain->s[4], "--") != NULL)
+			return 0;
+	} else {
+		if (strstr (domain->s, "--") != NULL)
+			return 0;
+	}
+        if (strstr (domain->s, ".-") != NULL) {
+                return 0;
+        }
+        if (strstr (domain->s, "-.") != NULL) {
+                return 0;
+        }
+        if (strchr (domain->s, '.') == NULL) {
+                return 0;
+        }
+
+        return 1;
+}
+
+#endif
+
+#if defined CHKUSER_SENDER_MX || defined CHKUSER_RCPT_MX
+
+static   unsigned long mx_random;
+static  ipalloc mx_ip = {0};
+
+static int chkuser_mx_lookup (stralloc *domain) {
+
+  int status;
+
+	mx_random = now() + getpid();
+	dns_init(0);
+	status = dns_mxip (&mx_ip, domain, mx_random);
+
+	if (status == DNS_MEM) DIE_NOMEM();
+
+	return status;
+}
+
+#endif
+
+
+void chkuser_cleanup (int exit_value) {
+
+#if defined CHKUSER_DB_CLEANUP
+	vclose ();
+#endif
+	_exit (exit_value);
+}
+
+static void first_time_init (void) {
+
+  char * temp_string;
+
+#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
+        starting_string = env_get (CHKUSER_STARTING_VARIABLE);
+        if (starting_string) {
+                if (strcasecmp(starting_string, "ALWAYS") == 0) {
+                        starting_value = 1;
+                } else if (strcasecmp(starting_string, "DOMAIN") == 0) {
+                        starting_value = 0;
+                }
+        } else {
+                starting_string = "";
+        }
+#endif
+
+#if defined CHKUSER_RCPT_LIMIT_VARIABLE
+        maxrcpt_string = env_get (CHKUSER_RCPT_LIMIT_VARIABLE);
+        if (maxrcpt_string) {
+                maxrcpt_limit = atoi (maxrcpt_string);
+                if (maxrcpt_limit < 1) {
+                        maxrcpt_limit = 0;
+                }
+        } else {
+                maxrcpt_string = "";;
+        }
+#endif
+
+#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
+        maxwrongrcpt_string = env_get (CHKUSER_WRONGRCPT_LIMIT_VARIABLE);
+        if (maxwrongrcpt_string) {
+                maxwrongrcpt_limit = atoi (maxwrongrcpt_string);
+                if (maxwrongrcpt_limit < 1) {
+                        maxwrongrcpt_limit = 0;
+                }
+        } else {
+                maxwrongrcpt_string = "";
+        }
+#endif
+
+#if defined CHKUSER_MBXQUOTA_VARIABLE
+        maxmbxquota_string = env_get (CHKUSER_MBXQUOTA_VARIABLE);
+        if (maxmbxquota_string) {
+                maxmbxquota_limit = atoi (maxmbxquota_string);
+                if (maxmbxquota_limit < 1) {
+                	maxmbxquota_limit = 0;
+                }
+	} else {
+               	maxmbxquota_string = "";
+	}
+#endif
+
+#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
+
+        temp_string = env_get (CHKUSER_SENDER_NOCHECK_VARIABLE);
+        if (temp_string) {
+		sender_nocheck = 1;
+        } else {
+		sender_nocheck = 0;
+        }
+
+#endif
+
+#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
+
+        identify_remote = env_get (CHKUSER_IDENTIFY_REMOTE_VARIABLE);
+        if (identify_remote) {
+        }
+
+#endif
+
+        if (!stralloc_ready (&user, 300)) DIE_NOMEM();
+        if (!stralloc_ready (&domain, 500)) DIE_NOMEM();
+        if (!stralloc_ready (&domain_path, 1000)) DIE_NOMEM();
+        if (!stralloc_ready (&tmp_path, 1000)) DIE_NOMEM();
+        if (!stralloc_ready (&alias_path, 1000)) DIE_NOMEM();
+
+	first_time_init_flag = 0;
+
+}
+
+/*
+ * realrcpt ()
+ *
+ * Returns:
+ *
+ *	CHKUSER_OK = 1 = Ok, recipients does exists
+ *
+ *	0 = Not in rcpthosts
+ *
+ *	< 0 various errors
+ *
+ *
+ * Parameters:
+ *	stralloc *sender = sender address
+ *	stralloc *rcpt = rcpt address to check
+ *
+ *
+*/
+
+static int realrcpt (stralloc *sender, stralloc *rcpt)
+{
+  int count;
+  int retstat = CHKUSER_KO;
+  struct vqpasswd *user_passwd = NULL;
+  int fd_file = -1;
+  int read_char;
+  int offset;
+  char read_buf[1024];
+
+#if defined CHKUSER_ENABLE_UIDGID
+  uid_t eff_uid;
+  gid_t eff_gid;
+#endif
+
+#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
+  if (starting_value == -1) {
+                if (addrallowed()) {
+                        return CHKUSER_OK;
+                } else {
+                        if (relayclient) {
+                                return CHKUSER_RELAYING;
+                        }
+
+			return CHKUSER_NORCPTHOSTS;
+		}
+  }
+#endif
+
+  if (INTRUSION_threshold_reached == 1) {
+	return CHKUSER_ERR_INTRUSION_THRESHOLD;
+  }
+
+#if defined CHKUSER_RCPT_LIMIT_VARIABLE
+
+  ++recipients;
+  if ((maxrcpt_limit > 0) && (recipients >= maxrcpt_limit)) {
+	chkuser_commonlog (sender->s, rcpt->s, "intrusion threshold", "max number of allowed rcpt");
+	INTRUSION_threshold_reached = 1;
+        return CHKUSER_ERR_MAXRCPT;
+  }
+#endif
+
+/* Search the '@' character */
+  count = byte_rchr(rcpt->s,rcpt->len,'@');
+
+  if (count < rcpt->len) {
+    if (!stralloc_copyb (&user, rcpt->s, count)) DIE_NOMEM();
+    if (!stralloc_copys (&domain, rcpt->s + count + 1)) DIE_NOMEM();
+  }
+  else {
+    if (!stralloc_copys (&user, rcpt->s)) DIE_NOMEM();
+    domain.len = 0;
+  }
+  if (!stralloc_0 (&user)) DIE_NOMEM();
+  if (!stralloc_0 (&domain)) DIE_NOMEM();
+
+#if defined CHKUSER_ENABLE_UIDGID
+
+/* qmail-smtpd is running now as (effective) qmaild:nofiles */
+/* Save the effective UID & GID (qmaild:nofiles) */
+  eff_uid = geteuid ();
+  eff_gid = getegid ();
+
+/* Now set new effective UID & GID, getting it from real UID & GID (vpopmail:vchkpw) */
+  setegid (getgid());
+  seteuid (getuid());
+
+/* qmail-smtpd is running now as effective vpopmail:vchkpw */
+#endif
+
+
+/*
+ * 
+ * Now let's start the test/setting suite
+ *
+ **/
+
+	switch (0) {
+
+	case 0:
+/* These are some preliminary settings */
+  		case_lowers (user.s);
+  		case_lowers (domain.s);
+
+	case 1:
+
+                if (domain.len == 1) {
+#if defined CHKUSER_DOMAIN_WANTED
+                        retstat = CHKUSER_ERR_DOMAIN_MISSING;
+			break;
+#else
+                        if (!stralloc_copys (&domain, DEFAULT_DOMAIN)) DIE_NOMEM();
+  			if (!stralloc_0 (&domain)) DIE_NOMEM();
+#endif
+                }
+
+	case 2:
+
+#if defined CHKUSER_RCPT_FORMAT
+
+                if (check_rcpt_address_format (&user, &domain) == 0) {
+                        retstat = CHKUSER_ERR_RCPT_FORMAT;
+                        break;
+                }
+#endif
+
+	case 3:
+
+                if (!addrallowed()) {
+
+#if defined CHKUSER_RCPT_MX
+			switch (chkuser_mx_lookup(&domain)) {
+
+				case DNS_HARD:
+					retstat = CHKUSER_ERR_RCPT_MX;
+					break;
+
+				case DNS_SOFT:
+					retstat = CHKUSER_ERR_RCPT_MX_TMP;
+					break;
+			}
+
+			if (retstat != CHKUSER_KO) {
+				break;
+			}
+#endif
+
+  			if (relayclient) {
+				retstat = CHKUSER_RELAYING;
+				break;
+  			}
+
+                        retstat = CHKUSER_NORCPTHOSTS;
+                        break;
+                }
+
+	case 4:
+
+#if defined CHKUSER_ENABLE_VAUTH_OPEN
+                if (db_already_open != 1) {
+                        if (vauth_open () == 0) {
+                                db_already_open == 1;
+                        } else {
+                                retstat = CHKUSER_ERR_AUTH_RESOURCE;
+                        }
+                };
+#endif
+
+	case 5:
+
+#if defined CHKUSER_ENABLE_VGET_REAL_DOMAIN
+/* Check if domain is a real domain */
+
+                vget_real_domain(domain.s, domain.a);
+
+                domain.len = strlen (domain.s) +1;
+                if (domain.len > (domain.a - 1)) DIE_NOMEM();
+#endif
+
+/* Let's get domain's real path */
+                if (vget_assign(domain.s, domain_path.s, domain_path.a -1, NULL, NULL) == NULL) {
+			retstat = CHKUSER_OK;
+			break;
+		}
+	
+		domain_path.len = strlen (domain_path.s);
+
+	case 6:
+
+/* Check if domain has bouncing enabled */
+
+#if !defined CHKUSER_ALWAYS_ON
+
+#if defined CHKUSER_STARTING_VARIABLE
+		if (starting_value == 0) {
+#endif
+
+	                if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
+
+#if defined CHKUSER_SPECIFIC_BOUNCING
+	  		if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
+	  		if (!stralloc_cats (&tmp_path, CHKUSER_SPECIFIC_BOUNCING)) DIE_NOMEM();
+			if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
+	  		fd_file = open_read (tmp_path.s);	
+	  		if (fd_file != -1) {
+	      			close (fd_file);
+			} else {
+				retstat = CHKUSER_OK;
+				break;
+			}
+#else
+	  		if (!stralloc_cats (&tmp_path, "/.qmail-default")) DIE_NOMEM();
+			if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
+
+	  		read_char = 0;
+	  		fd_file = open_read (tmp_path.s);	
+	  		if (fd_file != -1) {
+	      			read_char = read (fd_file, read_buf, sizeof(read_buf) - 1);
+	      			close (fd_file);
+	      			if (read_char < 0) read_char = 0;
+	  			}
+	  		read_buf[read_char] = 0;
+
+	  		if ( strstr(read_buf, CHKUSER_BOUNCE_STRING) == NULL ) {
+				retstat = CHKUSER_OK;
+				break;
+	  		}
+#endif
+#if defined CHKUSER_STARTING_VARIABLE
+		}
+#endif
+#endif
+
+	case 7:
+#if defined VALIAS
+/* Check for aliases/forwards - valias*/
+
+		if (valias_select (user.s, domain.s) != NULL) {
+			retstat = CHKUSER_OK;
+			break;
+		}
+#endif
+
+	case 8:
+#if defined CHKUSER_ENABLE_ALIAS
+/* Check for aliases/forwards - .qmail.x files */
+
+		if (!stralloc_copy (&tmp_path, &user)) DIE_NOMEM();
+                /* Change all '.' in ':' before continuing on aliases */
+                for (count = 0; count < tmp_path.len; ++count)
+        	        if (*(tmp_path.s + count) == '.') *(tmp_path.s + count) = ':';
+
+                if (!stralloc_copy (&alias_path, &domain_path)) DIE_NOMEM();
+                if (!stralloc_cats (&alias_path, "/.qmail-")) DIE_NOMEM();
+                if (!stralloc_cats (&alias_path, tmp_path.s)) DIE_NOMEM();
+                if (!stralloc_0 (&alias_path)) DIE_NOMEM();
+
+		fd_file = open_read (alias_path.s);
+		if (fd_file != -1) {
+			close (fd_file);
+			retstat = CHKUSER_OK;
+			break;
+		}
+#endif
+
+	case 9:
+
+#if defined CHKUSER_ENABLE_ALIAS_DEFAULT
+
+		if (!stralloc_copy (&tmp_path, &user)) DIE_NOMEM();
+                /* Change all '.' in ':' before continuing on aliases */
+                for (count = 0; count < tmp_path.len; ++count)
+        	        if (*(tmp_path.s + count) == '.') *(tmp_path.s + count) = ':';
+
+                /* Search for the outer '-' character */
+                for (offset = user.len - 1; offset > 0; --offset)
+                        if (*(user.s + offset) == CHKUSER_USERS_DASH)  {
+                                if (!stralloc_copy (&alias_path, &domain_path)) die_nomem();
+                                if (!stralloc_cats (&alias_path, "/.qmail-")) die_nomem();
+                                if (!stralloc_catb (&alias_path, user.s, offset)) die_nomem();
+                                if (!stralloc_cats (&alias_path, "-default")) die_nomem();
+                                if (!stralloc_0 (&alias_path)) die_nomem();
+
+                                fd_file = open_read (alias_path.s);
+                                if (fd_file != -1) {
+                                        close (fd_file);
+                                        retstat = CHKUSER_OK;
+                                        break;
+                                }
+                        }
+
+                if (retstat != CHKUSER_KO) {
+                        break;
+                }
+
+#endif
+
+        case 10:
+#if defined CHKUSER_ENABLE_USERS
+/* User control: check the existance of a real user */
+
+                user_passwd = vauth_getpw (user.s, domain.s);
+
+#if defined CHKUSER_ENABLE_USERS_EXTENSIONS
+                if (user_passwd == NULL) {
+                       count = 0;
+                       while ((count < (user.len -1)) && (user_passwd == NULL)) {
+                               count += byte_chr(&user.s[count], user.len - count, CHKUSER_USERS_DASH);
+                               if (count < user.len) {
+                                       if (!stralloc_copyb (&tmp_path, user.s, count)) DIE_NOMEM();
+                                       if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
+                                       user_passwd = vauth_getpw (tmp_path.s, domain.s);
+                                         ++count;
+                               }
+                        }
+                }
+
+#endif
+                if (user_passwd != NULL) {
+
+                /* If user exists check if he has BOUNCE_MAIL flag set */
+
+                        if (user_passwd->pw_gid & BOUNCE_MAIL)
+                                retstat = CHKUSER_KO;
+                        else {
+                                retstat = CHKUSER_OK;
+#if defined CHKUSER_MBXQUOTA_VARIABLE
+                                if ((maxmbxquota_limit > 0) && (strcasecmp(user_passwd->pw_shell, "NOQUOTA") != 0)) {
+                                        if (!stralloc_copys (&tmp_path, user_passwd->pw_dir)) DIE_NOMEM();
+                                        if (!stralloc_cats (&tmp_path, "/Maildir")) DIE_NOMEM();
+                                        if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
+
+                                        if (vmaildir_readquota(tmp_path.s,format_maildirquota(user_passwd->pw_shell))
+                                                >= maxmbxquota_limit) {
+                                                retstat = CHKUSER_ERR_MBXFULL;
+                                        }
+                                }
+#endif
+                        }
+                        break;
+                }
+#endif
+
+	case 11:
+#if defined CHKUSER_ENABLE_EZMLM_LISTS
+/* Let's check for mailing lists */
+
+		/* Search for the outer CHKUSER_EZMLM_DASH character */
+	      	for (offset = user.len - 2; offset > 0; --offset) {
+			if (*(user.s + offset) == CHKUSER_EZMLM_DASH)  {
+				if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
+	      			if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
+	      			if (!stralloc_catb (&tmp_path, user.s, offset)) DIE_NOMEM();
+	      			if (!stralloc_cats (&tmp_path, "/mailinglist")) DIE_NOMEM();
+	      			if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
+				fd_file = open_read (tmp_path.s);
+				if (fd_file != -1) {
+					close (fd_file);
+					retstat = CHKUSER_OK;
+					break;
+				}
+	        	}
+		}
+		if (retstat != CHKUSER_KO) {
+			break;
+		}
+#endif
+
+        case 12:
+#if defined CHKUSER_ENABLE_MAILMAN_LISTS
+/* Let's check for mailing lists */
+
+                /* Search for the outer CHKUSER_MAILMAN_DASH character */
+                for (offset = user.len - 2; offset > 0; --offset) {
+                        if (*(user.s + offset) == CHKUSER_MAILMAN_DASH)  {
+                                if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
+                                if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
+				if (!stralloc_cats (&alias_path, "/.qmail-")) DIE_NOMEM();
+                                if (!stralloc_catb (&tmp_path, user.s, offset)) DIE_NOMEM();
+                                if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
+                                fd_file = open_read (tmp_path.s);
+	                        read_char = 0;
+        	                if (fd_file != -1) {
+                	                read_char = read (fd_file, read_buf, sizeof(read_buf) - 1);
+                        	        close (fd_file);
+                                	if (read_char < 0) read_char = 0;
+                                }
+	                        read_buf[read_char] = 0;
+
+        	                if ( strstr(read_buf, CHKUSER_MAILMAN_STRING) == NULL ) {
+	                                retstat = CHKUSER_OK;
+	                                break;
+	                        }
+
+                        }
+                }
+                if (retstat != CHKUSER_KO) {
+                        break;
+                }
+#endif
+
+/*
+ * Add this code if another case is following
+	case xx:
+		code ....
+		code ....
+		code ....
+		code ....
+
+		if (xxxxxxxx) {
+			retstat != CHKUSER_KO)
+			break;
+		}
+*/
+	    
+        default:
+                retstat = CHKUSER_KO;
+
+	} /* end switch */
+
+#if defined CHKUSER_ENABLE_UIDGID
+/* Now switch back effective to saved UID & GID (qmaild:nofiles) */
+
+  setegid (eff_gid);
+  seteuid (eff_uid);
+
+/* qmail-smtpd is running again as (effective) qmaild:nofiles */
+#endif
+
+  return retstat;
+
+}
+
+
+
+/*
+ * chkuser_realrcpt ()
+ *
+ * Returns a simple status:
+ *
+ *      CHKUSER_OK = 1 = Ok, recipients does exists
+ *
+ *      CHKUSER_NORCPTHOSTS = Not in rcpthosts
+ *
+ *      CHKUSER_KO = ERROR
+ *
+ *
+ * Parameters:
+ *      stralloc *sender = sender address
+ *      stralloc *rcpt = rcpt address to check
+ *
+ *
+*/
+
+int chkuser_realrcpt (stralloc *sender, stralloc *rcpt) {
+
+int retstat;
+
+  if (first_time_init_flag) {
+        first_time_init ();
+  }
+
+  retstat = realrcpt (sender, rcpt);
+
+	switch (retstat) {
+
+		case CHKUSER_OK:
+#if defined CHKUSER_LOG_VALID_RCPT
+			chkuser_commonlog (sender->s, rcpt->s, "accepted rcpt", "found existing recipient");
+#endif
+			return CHKUSER_OK;
+			break;
+
+                case CHKUSER_RELAYING:
+#if defined CHKUSER_LOG_VALID_RCPT
+                        chkuser_commonlog (sender->s, rcpt->s, "relaying rcpt", "client allowed to relay");
+#endif
+                        return CHKUSER_RELAYING;
+                        break;
+
+		case CHKUSER_NORCPTHOSTS:
+                        chkuser_commonlog (sender->s, rcpt->s, "rejected relaying", "client not allowed to relay");
+		        CHKUSER_RCPT_DELAY_ANY();
+			out(CHKUSER_NORELAY_STRING);
+			break;
+
+		case CHKUSER_KO:
+			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "not existing recipient");
+		        CHKUSER_DELAY();
+ 			out(CHKUSER_NORCPT_STRING);
+			break;
+
+		case CHKUSER_ERR_AUTH_RESOURCE:
+			chkuser_commonlog (sender->s, rcpt->s, "no auth resource", "no auth resource available");
+		        CHKUSER_RCPT_DELAY_ANY();
+			out(CHKUSER_RESOURCE_STRING);
+			break;
+
+		case CHKUSER_ERR_MBXFULL:
+			chkuser_commonlog (sender->s, rcpt->s, "mbx overquota", "rcpt mailbox is overquota");
+		        CHKUSER_RCPT_DELAY_ANY();
+			out(CHKUSER_MBXFULL_STRING);
+			break;
+
+		case CHKUSER_ERR_MAXRCPT:
+			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "max number of recipients");
+		        CHKUSER_DELAY ();
+			out(CHKUSER_MAXRCPT_STRING);
+			break;
+
+		case CHKUSER_ERR_MAXWRONGRCPT:
+			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "max number of invalid recipients");
+		        CHKUSER_DELAY ();
+			out(CHKUSER_MAXWRONGRCPT_STRING);
+			break;
+
+		case CHKUSER_ERR_INTRUSION_THRESHOLD:
+			chkuser_commonlog (sender->s, rcpt->s, "rejected intrusion", "rcpt ignored, session over INTRUSION threshold");
+			CHKUSER_DELAY ();
+			out(CHKUSER_INTRUSIONTHRESHOLD_STRING);
+			break;
+
+		case CHKUSER_ERR_DOMAIN_MISSING:
+		        CHKUSER_DELAY ();
+			out(CHKUSER_DOMAINMISSING_STRING);
+			break;
+
+                case CHKUSER_ERR_RCPT_FORMAT:
+                        chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "invalid rcpt address format");
+		        CHKUSER_RCPT_DELAY_ANY();
+			out(CHKUSER_RCPTFORMAT_STRING);
+                        break;
+
+                case CHKUSER_ERR_RCPT_MX:
+			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "invalid rcpt MX domain");
+		        CHKUSER_RCPT_DELAY_ANY();
+			out(CHKUSER_RCPTMX_STRING);
+                        break;
+
+                case CHKUSER_ERR_RCPT_MX_TMP:
+                        chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "temporary DNS problem");
+                        CHKUSER_RCPT_DELAY_ANY();
+                        out(CHKUSER_RCPTMX_TMP_STRING);
+                        break;
+	}
+
+
+
+#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
+	if ((retstat == CHKUSER_KO) || (retstat == CHKUSER_ERR_DOMAIN_MISSING)) {
+        	++wrong_recipients;
+        	if ((INTRUSION_threshold_reached == 0) && (maxwrongrcpt_limit > 0) && (wrong_recipients >= maxwrongrcpt_limit)) {
+        	        chkuser_commonlog (sender->s, rcpt->s, "intrusion threshold", "max number of allowed invalid rcpt");
+        	        INTRUSION_threshold_reached = 1;
+        	}
+	}
+#endif
+
+	return CHKUSER_KO;
+}
+
+
+/*
+ *
+ * This routine checks for sender format and MX
+ *
+ */
+
+
+int chkuser_sender (stralloc *sender) {
+
+int count;
+
+	if (first_time_init_flag) {
+		first_time_init ();
+	}
+
+#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
+	if (starting_value == -1) {
+		return CHKUSER_OK;
+	}
+#endif
+
+#if defined CHKUSER_SENDER_FORMAT || defined CHKUSER_SENDER_MX
+
+#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
+
+	if (sender_nocheck == 1) {
+		return CHKUSER_OK;
+	}
+#endif
+
+        if (sender->len <= 1) {
+#if defined CHKUSER_LOG_VALID_SENDER
+		chkuser_commonlog (sender->s, "", "accepted null sender", "accepted null sender always");
+#endif
+                return CHKUSER_OK;
+	}
+
+        count = byte_rchr(sender->s,sender->len,'@');
+        if (count < sender->len) {
+                if (!stralloc_copyb (&sender_user, sender->s, count)) DIE_NOMEM();
+                if (!stralloc_copys (&sender_domain, sender->s + count + 1)) DIE_NOMEM();
+        } else {
+                if (!stralloc_copys (&sender_user, sender->s)) DIE_NOMEM();
+                sender_domain.len = 0;
+        }
+        if (!stralloc_0 (&sender_user)) DIE_NOMEM();
+        if (!stralloc_0 (&sender_domain)) DIE_NOMEM();
+
+#if defined CHKUSER_SENDER_FORMAT
+        if (check_sender_address_format (&sender_user, &sender_domain) == 0) {
+                chkuser_commonlog (sender->s, "", "rejected sender", "invalid sender address format");
+		CHKUSER_SENDER_DELAY_ANY();
+		out(CHKUSER_SENDERFORMAT_STRING);
+	        return CHKUSER_ERR_SENDER_FORMAT;
+        }
+
+#endif
+
+#if defined CHKUSER_SENDER_MX
+
+	switch (chkuser_mx_lookup(&sender_domain)) {
+
+		case DNS_HARD:
+			CHKUSER_SENDER_DELAY_ANY();
+			out(CHKUSER_SENDERMX_STRING);
+			chkuser_commonlog (sender->s, "", "rejected sender", "invalid sender MX domain");
+			return CHKUSER_ERR_SENDER_MX;
+			break;
+
+		case DNS_SOFT:
+			CHKUSER_SENDER_DELAY_ANY();
+			out(CHKUSER_SENDERMX_TMP_STRING);
+			chkuser_commonlog (sender->s, "", "rejected sender", "temporary DNS problem");
+			return CHKUSER_ERR_SENDER_MX_TMP;
+			break;
+	}
+
+#if defined CHKUSER_LOG_VALID_SENDER
+                        chkuser_commonlog (sender->s, "", "accepted sender", "sender accepted");
+#endif
+
+	return CHKUSER_OK;
+#endif
+
+#else
+
+	return CHKUSER_OK;
+
+#endif
+
+}
+
+
diff -Naur ./CHKUSER.changelog ../qmail-1.03-build-10/CHKUSER.changelog
--- ./CHKUSER.changelog	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/CHKUSER.changelog	2004-12-08 19:10:36.000000000 -0600
@@ -0,0 +1,141 @@
+
+CHKUSER 2.0 change log
+
+V 2.0.8 - 7 december 2004
+	Features
+	Freeze of new features of 2.0.7, except null senders behaviour.
+	CHKUSER_ENABLE_NULL_SENDER_WITH_TCPREMOTEHOST is no more available
+	CHKUSER_ENABLE_NULL_SENDER is no more available
+	NULL SENDERS are now always accepted. No option is available to disable
+		this behaviour. Previous chkuser versions broke RFC compatibility on
+		null senders, and complicated real life e-mailing.
+	Logging of null senders <> is now available.
+	
+	Bugs corrected
+	Sender controls were not executed if CHKUSER_STARTING_VARIABLE was defined
+		(thanks to Charles Sprickman)
+	Domains not in control/virtualdomains are now explicitely excluded from
+		following cascade checks; in previous versions following cascade
+		checks were done using fake domains paths.
+	vget_assign is now handled correctly (a domain in rcpthosts but not
+		in virtualdomains could have an incorrect path in previous versions
+		(this bug is also in all chkusr versions)
+
+	Defaults changed
+	CHKUSER_RCPT_FORMAT is now undefined as default
+	CHKUSER_RCPT_MX is now undefined as default.
+	CHKUSER_SENDER_FORMAT is now undefined as default
+	CHKUSER_SENDER_MX is now undefined as default.
+	CHKUSER_ERROR_DELAY_INCREASE new default is 300 milliseconds
+	
+V 2.0.7 - 25 october 2004
+	Features
+	added vclose() of DB auth connection, overriding
+		qmail-smtpd _exit call
+	improved MX checking; now SOFT failure is handled as
+		temporary error.
+	added #define CHKUSER_RCPTMX_TMP_STRING
+	added #define CHKUSER_SENDERMX_TMP_STRING 
+	added handling of mailman mailing lists
+		(and related #define CHKUSER_ENABLE_MAILMAN_LISTS)
+	changed order of checking for recipients:
+		1 - valias
+		2 - alias
+		3 - alias extensions
+		4 - users
+		5 - users extensions
+		6 - lists
+	added #define CHKUSER_ACCEPT_NULL_SENDER (default defined)
+	added #define CHKUSER_ENABLE_ALIAS_DEFAULT (default not defined)
+		enables checking of .qmail-alias-default
+	added #define CHKUSER_IDENTIFY_REMOTE_VARIABLE "CHKUSER_IDENTIFY"
+		in order to allow a easy identification of remote IP
+		(substitutes RELAYCLIENT in chkuser logging)
+	added #define CHKUSER_ALLOW_RCPT_SRS
+		enable usage of "#" and "+" characters within rcpt address
+	added #define CHKUSER_ALLOW_RCPT_CHAR_1 '$'
+	added #define CHKUSER_ALLOW_RCPT_CHAR_2 '%'
+	added #define CHKUSER_ALLOW_RCPT_CHAR_3 ''
+	added #define CHKUSER_ALLOW_RCPT_CHAR_4 '?'
+	added #define CHKUSER_ALLOW_RCPT_CHAR_5 '*'
+	#define CHKUSER_ENABLE_USERS_EXTENSIONS
+		substitutes #define CHKUSER_ENABLE_EXTENSIONS
+	#define CHKUSER_ENABLE_EZMLM_LISTS
+		substitutes #define CHKUSER_ENABLE_LISTS
+	#define CHKUSER_USERS_DASH
+		substitutes #define CHKUSER_EXTENSION_DASH
+
+	Bugs
+	sender address "name@" could cause a crash. Corrected
+		(Thanks to Dmitry Petukhov)
+	Corrected Makefile: now qmail-smtpd.c recompiles if chkuser.h
+		changes
+	Corrected a bug in #endif sequence related to
+		#define CHKUSER_RCPT_FORMAT (thanks to Alex Plainer)
+	Corrected a bug in chkuser_sender; now is not executed when
+		chkuser is disabled
+	Corrected check of format for domains:
+		"xn--" admitted as leading string
+	Deleted correction over usage of RELAYCLIENT variable
+		Previous correction could affect a special
+		feature of RELAYCLIENT (thanks to Alex Pleiner)
+
+	Defaults changed
+	#define CHKUSER_ENABLE_NULL_SENDER_WITH_TCPREMOTEHOST (default undefined)
+
+
+V 2.0.6 - 25 september 2004
+	No bugs, just doc updates and an empty patch file corrected
+
+	#define CHKUSER_ENABLE_VGET_REAL_DOMAIN was existing and working in code,
+		but not reported both in docs and inside chkuser_settings.h
+			(default is commented, but this #define is important)	
+	patch for toaster-0.6-1 was empty. Now the correct one is provided
+
+V 2.0.5 - 23 september 2004
+	This is the first public release.
+
+	added #define CHKUSER_ALLOW_SENDER_CHAR_1 (default not defined) 
+	added #define CHKUSER_ALLOW_SENDER_CHAR_2 (default not defined) 
+	added #define CHKUSER_ALLOW_SENDER_CHAR_3 (default not defined) 
+	added #define CHKUSER_ALLOW_SENDER_CHAR_4 (default not defined) 
+	added #define CHKUSER_ALLOW_SENDER_CHAR_5 (default not defined) 
+	added #define CHKUSER_MIN_DOMAIN_LEN (default defined 4) -
+		Previously it was hard coded as 5. Juergen Kendzorra
+		showed me some existing names long only 4 chars. 
+	added #define CHKUSER_LOG_VALID_SENDER (default defined)
+
+V 2.0.4 - 15 september 2004
+
+	added #define CHKUSER_SENDER_NOCHECK_VARIABLE (default not defined) 
+	added #define CHKUSER_DEBUG_STDERR (default not defined) 
+	added #define CHKUSER_ALLOW_SENDER_SRS (default not defined) 
+	cleaned some typos in code and documentation (thanks to Juergen
+		Kendzorra - http://www.kendzorra.de) 
+
+
+V 2.0.3 - 8 september 2004
+	This is the first version released outside, for wider testing.
+
+	Tested Makefile for netqmail 1.05 
+	Added Makefiles for applying over other patches 
+
+V 2.0.0 - july 2004
+	chkuser 2.0.0 starts here, and is a private internal release.
+	Version 2.0 is much more modular than previous one (named chkusr),
+	and has been designed with the goal of enabling more features and
+	semplifying installations and upgrades of the patch himself. 
+
+	chkusr changes his name, to reflect a deep change of the patch. 
+
+	Chkusr 1.0 received a lot of feedbacks and suggestions.
+	The most of these suggestions are now inside version 2.0.
+
+		- Marcelo Coelho (marcelo at tpn.com.br), segnaled me some
+		unseen minor bugs of chkusr 1.0 (minor but very annoying to
+		my pride) and suggested some very interesting features
+		(some of them are now in chkuser 2.0). 
+		- Iulian Margarintescu (http:://www.erata.net) suggested a
+		workable way of introducing quota check on recipients
+		(now in chkuser 2.0). 
+
diff -Naur ./CHKUSER.copyright ../qmail-1.03-build-10/CHKUSER.copyright
--- ./CHKUSER.copyright	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/CHKUSER.copyright	2004-12-08 19:10:36.000000000 -0600
@@ -0,0 +1,15 @@
+
+chkuser for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
+
+Author: Antonio Nati tonix@interazioni.it
+
+All rights on this software and
+the identifying words chkusr and chkuser kept by the author
+
+This software may be freely used, modified and distributed,
+but this lines must be kept in every original or derived version.
+
+Original author "Antonio Nati" and the web URL
+"http://www.interazioni.it/opensource"
+must be indicated in every related work or web page
+
diff -Naur ./chkuser.h ../qmail-1.03-build-10/chkuser.h
--- ./chkuser.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/chkuser.h	2006-04-24 21:29:10.000000000 -0500
@@ -0,0 +1,51 @@
+
+/*
+ *
+ * 'chkuser.h' v.2.0.8
+ * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
+ *
+ * Author: Antonio Nati tonix@interazioni.it
+ * All rights on this software and
+ * the identifying words chkusr and chkuser kept by the author
+ *
+ * This software may be freely used, modified and distributed,
+ * but this lines must be kept in every original or derived version.
+ * Original author "Antonio Nati" and the web URL
+ * "http://www.interazioni.it/opensource"
+ * must be indicated in every related work or web page
+ *
+ */
+
+#define CHKUSER
+#define CHKUSER_VERSION		"2.0.8"
+#define CHKUSER_VERSION_RL	2
+#define CHKUSER_VERSION_MJ	0
+#define CHKUSER_VERSION_MN	8
+
+#define CHKUSER_OK			1
+#define CHKUSER_RELAYING		0
+#define CHKUSER_KO			-1
+#define CHKUSER_NORCPTHOSTS		-10
+#define CHKUSER_ERR_AUTH_RESOURCE	-20
+#define CHKUSER_ERR_MBXFULL		-30
+#define CHKUSER_ERR_MAXRCPT		-40
+#define CHKUSER_ERR_MAXWRONGRCPT	-50
+#define CHKUSER_ERR_DOMAIN_MISSING	-60
+#define CHKUSER_ERR_RCPT_FORMAT		-70
+#define CHKUSER_ERR_RCPT_MX		-75
+#define CHKUSER_ERR_RCPT_MX_TMP		-76
+#define CHKUSER_ERR_SENDER_FORMAT	-80
+#define CHKUSER_ERR_SENDER_MX		-85
+#define CHKUSER_ERR_SENDER_MX_TMP	-86
+#define CHKUSER_ERR_INTRUSION_THRESHOLD	-90
+
+void chkuser_cleanup (int exit_value);
+int chkuser_realrcpt (stralloc *sender, stralloc *rcpt);
+int chkuser_sender (stralloc *sender);
+
+#ifdef TLS_H
+#undef _exit
+#define _exit(value) { if (ssl) ssl_free(ssl); chkuser_cleanup(value); }
+#else
+#define _exit(value) chkuser_cleanup(value);
+#endif
diff -Naur ./CHKUSER.log_format ../qmail-1.03-build-10/CHKUSER.log_format
--- ./CHKUSER.log_format	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/CHKUSER.log_format	2004-12-08 19:10:36.000000000 -0600
@@ -0,0 +1,58 @@
+
+chkuser 2.0.8 logging format
+
+When #defines for logging are enabled, chkuser patch emits log informations
+on the same qmail-smtpd log destination
+
+This is the log format:
+
+    CHKUSER "brief message": \
+	    from <sender:remoteinfo:relayclient> \
+	    remote <helo:remotehostname:remotehostip> \
+	    rcpt <recipient> : "extended message"
+
+where
+	brief message 	
+		    * accepted rcpt
+		    * relaying rcpt
+		    * rejected relaying
+		    * rejected rcpt
+		    * no auth resource
+		    * mbx overquota
+		    * rejected intrusion
+		    * intrusion threshold
+		    * rejected sender
+
+	sender 	sender declared within "mail from"
+
+	remoteinfo	the value of "TCPREMOTEINFO" or the autenticated user
+
+	relayclient 	the value of RELAYCLIENT env variable (be careful to set it,
+			inside your tcp.cdb with a value that let you understand who is sending)
+
+	helo 		helo declared from remote system
+
+	hostname 	the value of "TCPREMOTEHOST"
+
+	remotehostip 	the value of "TCPREMOTEIP"
+
+	recipient 	recipient address
+
+	extended message 	this field has more wide description for
+				some generic "brief message":
+			accepted rcpt 	found existing recipient
+			relaying rcpt 	client allowed to relay
+			rejected relaying 	client not allowed to relay
+			rejected rcpt 	not existing recipient
+			rejected rcpt 	max number of recipients
+			rejected rcpt 	max number of invalid recipients
+			rejected rcpt 	invalid rcpt address format
+			rejected rcpt 	invalid rcpt MX domain
+			intrusion threshold 	max number of allowed rcpt
+			intrusion threshold 	max number of allowed invalid rcpt
+			rejected intrusion 	rcpt ignored, session over intrusion threshold
+			no auth resource 	no auth resource available
+			mbx overquota 	rcpt mailbox is overquota
+			rejected sender 	invalid sender address format
+			rejected sender 	invalid sender MX domain
+	
diff -Naur ./CHKUSER.readme ../qmail-1.03-build-10/CHKUSER.readme
--- ./CHKUSER.readme	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/CHKUSER.readme	2004-12-08 19:10:36.000000000 -0600
@@ -0,0 +1,54 @@
+chkuser 2.0 -README
+
+Description
+===========
+The original qmail-smtpd accepts by default all messages, checking later for
+the existence of the recipient. So, if the message is delivered to not existing
+recipients a lot of additional system work and network traffic are generated,
+with multiple expensive bouncing if the sender is a fake one.
+
+chkuser has been developed with the goal to improve the acceptance SMTP phase
+of qmail-smtpd. qmail-smtpd patched with chkuser may check the existance of
+e-mail recipients immediately in the SMTP acceptance phase of a message and
+rejects istantly all messages not directed to existing users, avoiding
+additional traffic, work and messages bounced more times.
+
+These goals are achieved enquirying the existing vpopmail archives (each
+format is supported: cdb, MySQL, LDAP, etc.) by using standard vpopmail calls,
+or using customized chkuser routines.
+
+Version 2.0 - From chkusr to chkuser
+====================================
+Version 2.0 is a lot different from previous versions, so it deserves a more
+evident change in the name.
+
+Version 2.0 has been designed with the goal to be modular, and to make more easy
+both adding new features to checkuser code and semplifing code update.
+
+Patching over original qmail files is done over a few points, while the most of
+chkuser code remains ouside, in dedicated chkuser's files.
+
+Same for settings, that are inside a dedicated chkuser_settings.h file.
+
+The intention is to semplify upgrading: for future chkuser releases, upgrading
+will require only to update chkuser specific files, leaving all the rest
+untouched, and changing chkuser_settings.h only if new features must be enabled.
+
+Logging and SPAM
+================
+chkuser 2.0 has detailed logging of accepted and refused recipients and senders,
+allowing a deep analysis of "who's sending to who". This can lead to more
+sophisticated future enhancements of anti-SPAM features.
+
+Intrusion rejection
+===================
+chkuser 2.0 can be tuned to reject sessions exceeding some recipients limits
+(limits can be set for max recipients and max not existing recipients). 
+
+URL Location
+============
+For any new release, support, FAQ, mailing lists, or other information, see:
+
+	http://www.interazioni.it/opensource
+
+
diff -Naur ./CHKUSER.running ../qmail-1.03-build-10/CHKUSER.running
--- ./CHKUSER.running	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/CHKUSER.running	2004-12-08 19:10:36.000000000 -0600
@@ -0,0 +1,103 @@
+
+CHKUSER 2.0.8 - Running instructions
+
+Chkuser may run using the most of security, following very strictly the sacurity
+model used By Dan Berstein. To achieve this goal, chkuser may switch between
+differents UID/GID, for differente purposes.
+
+However this is incompatible with TLS patches (like toaster-0.6-1), as these patches
+want to run under a unique UID/GID. Luckily, qmail is enought robust to let us
+run this way.
+
+To achieve both these goals, chkuser uses a #define (CHKUSER_ENABLE_UIDGID)
+that indicates if UID/GID switching is wanted, and running instructions must
+adapt to this way.
+
+Instead, when this define is not used, another way of running must be used.
+(Just for precision, even if the CHKUSER_ENABLE_UIDGID define is used, chkuser
+may be run without switching UID/GID).
+
+Running with UID/GID switch
+===========================
+
+If you want the most security when using chkuser, and you have enabled 
+CHKUSER_ENABLE_UIDGID within chkuser_settings.h (it's enabled by default), use
+these instructions.
+
+Description.
+	qmail-smtpd-chkusr must be installed (by default in /var/qmail/bin) with
+	setuid (user qmaild) and setgid (group qnofiles), and executed by tcpserver 
+	with -u vpopmail-user and -g vchkpw-group  parameters.
+
+	qmail-smtpd-chkusr starts running with the original qmail-smtpd uid and gid,
+	switching to needed uid and gid only for vpopmail checks on user existance,
+	turning back to the starting uid and gid.
+
+Instructions.
+	You have to set SUID (set-user-ID-on-execution) and SGID
+	(set-group-ID-on-execution) bits on qmail-smtpd-chkusr:
+		chown qmaild qmail-smtpd
+		chgrp nofiles qmail-smtpd
+		chmod 6555 qmail-smtpd
+
+	and the result you see should be like (different size and date, of course):
+		-r-sr-sr-x 1 qmaild nofiles 57056 Feb 14 18:18 qmail-smtpd-chkusr
+
+	Integrate qmail-smtpd in your start files:
+
+	As example, a real start command for qmail-smtpd-chkusr may be
+
+	#!/bin/sh -e
+	#
+	# Using splogger to send the log through syslog.
+
+	exec env - PATH="/var/qmail/bin:/usr/local/bin" \
+	tcpserver -t 5 -v -p -x <your.tcp.smtp.cdb> \
+	-u <vpopmail-user> -g <vchkpw-group> -l <your-host.domain> 0 smtp \
+	qmail-smtpd-chkusr splogger smtpd &
+
+	where
+		<vpopmail-user> = vpopmail uid
+		<vchkpw-group> = vchkpw gid
+		<your-host.domain> = your host.domain (!)
+		<your.tcp.smtp.cdb> = your tcp.permission.to.relay cdb
+
+	NOTE: if you are using more system users for your domains, the execution
+	uid (which I indicated as vpopmail) should be set to root.
+
+
+Running with fixed UID/GID
+==========================
+You may use these instructions if you've not defined CHKUSER_ENABLE_UIDGID, or if
+you want to run qmail-smtpd as unique user, despite of CHKUSER_ENABLE_UIDGID define.
+qmail-smtpd is well safe and robust, and there is no risk running it directly as
+vpopmail user, unless you use untrusted software layered down.
+
+Description.
+	qmail-smtpd must be installed normally (-r-xr-xr-x) and executed by tcpserver
+	with -u vpopmail-user and -g vchkpw-group parameters.
+
+Instructions.
+	Integrate qmail-smtpd-chkusr in your start files:
+
+	As example, a real start command for qmail-smtpd-chkusr may be
+
+	#!/bin/sh -e
+	#
+	# Using splogger to send the log through syslog.
+
+	exec env - PATH="/var/qmail/bin:/usr/local/bin" \
+	tcpserver -t 5 -v -p -x <your.tcp.smtp.cdb> \
+	-u <vpopmail-user> -g <vchkpw-group> -l <your-host.domain> 0 smtp \
+	qmail-smtpd-chkusr splogger smtpd &
+
+	where
+		<vpopmail-user> = vpopmail uid
+		<vchkpw-group> = vchkpw gid
+		<your-host.domain> = your host.domain (!)
+		<your.tcp.smtp.cdb> = your tcp.permission.to.relay cdb
+
+	NOTE: if you are using more system users for your domains, the execution user
+	(which I indicated as vpopmail) should be set to root.
+
+
diff -Naur ./chkuser_settings.h ../qmail-1.03-build-10/chkuser_settings.h
--- ./chkuser_settings.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/chkuser_settings.h	2006-05-05 19:22:07.000000000 -0500
@@ -0,0 +1,373 @@
+
+/*
+ *
+ * 'chkuser_settings.h' v.2.0.8
+ * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
+ *
+ * Author: Antonio Nati tonix@interazioni.it
+ * All rights on this software and
+ * the identifying words chkusr and chkuser kept by the author
+ *
+ * This software may be freely used, modified and distributed,
+ * but this lines must be kept in every original or derived version.
+ * Original author "Antonio Nati" and the web URL
+ * "http://www.interazioni.it/opensource"
+ * must be indicated in every related work or web page
+ *
+ */
+
+/*
+ * the following line enables debugging of chkuser
+ */
+/* #define CHKUSER_DEBUG */
+
+/*
+ * The following line moves DEBUG output from STDOUT (default) to STDERR
+ * Example of usage within sh: ./qmail-smtpd 2> /var/log/smtpd-debug.log
+ */
+/* #define CHKUSER_DEBUG_STDERR */
+
+/*
+ * Uncomment the following define if you want chkuser ALWAYS enabled.
+ * If uncommented, it will check for rcpt existance despite any .qmail-default
+ * setting.
+ * So, unsomments this if you are aware that ALL rcpt in all domains will be
+ * ALWAYS checked.
+ */
+/* #define CHKUSER_ALWAYS_ON */
+
+/*
+ * The following defines which virtual manager is used.
+ * Up to know, only vpopmail, but versions with pure qmail are in the mind.
+ */
+#define CHKUSER_VPOPMAIL
+
+/*
+ * Uncomment the following line if you want chkuser to work depending on a VARIABLE setting
+ * VALUE HERE DEFINED is the name of the variable
+ * Values admitted inside the variable: NONE | ALWAYS | DOMAIN
+ * 		NONE 	= chkuser will not work
+ *		ALWAYS	= chkuser will work always
+ *		DOMAIN	= chkuser will work depending by single domain settings
+ * if CHKUSER_ALWAYS_ON is defined, this define is useless
+ * if CHKUSER_STARTING_VARIABLE is defined, and no variable or no value is set, then chkuser is disabled
+ */
+/* #define CHKUSER_STARTING_VARIABLE "CHKUSER_START" */
+
+/*
+ * Uncomment this to enable uid/gid changing
+ * (switching UID/GID is NOT compatible with TLS; you may keep this commented if you have TLS)
+ */
+/* #define CHKUSER_ENABLE_UIDGID */
+
+/*
+ * Uncomment this to check if a domain is ALWAYS specified in rcpt addresses
+ */
+#define CHKUSER_DOMAIN_WANTED
+
+/*
+ * Uncomment this to check for vpopmail users
+ */
+#define CHKUSER_ENABLE_USERS
+
+/*
+ * Uncomment this to check for alias
+ */
+#define CHKUSER_ENABLE_ALIAS
+
+/*
+ * The following #define set the character used for lists extensions
+ * be careful: this is a  single char '-' definition, not a "string"
+ */
+#define CHKUSER_EZMLM_DASH '-'
+
+/*
+ * Uncomment this to set an alternative way to check for bouncing enabling;
+ * with this option enabled, the file here defined 
+ * will be searched, inside the domain dir, in order to check if bouncing is enabled
+ * The content of this file is not important, just it's existence is enough
+ */
+/* #define CHKUSER_SPECIFIC_BOUNCING ".qmailchkuser-bouncing" */
+
+/*
+ * This is the string to look for inside .qmail-default
+ * Be careful, chkuser looks within the first 1023 characters of .qmail-default for
+ * this string (despite the line containing the string is working or commented).
+ */
+#define CHKUSER_BOUNCE_STRING "bounce-no-mailbox"
+
+/*
+ * This is to enable auth open checking
+ * it is useful to avoid bouncing if MySQL/LDAP/PostGRES/etc are down or not reachable
+ */
+/* #define CHKUSER_ENABLE_VAUTH_OPEN */
+
+/*
+ * Uncomment to enable logging of rejected recipients and variuos limits reached
+ */
+#define CHKUSER_ENABLE_LOGGING
+
+/*
+ * Uncomment to enable logging of "good" rcpts
+ * valid only if CHKUSER_ENABLE_LOGGING is defined
+ */
+#define CHKUSER_LOG_VALID_RCPT
+
+/*
+ * Uncomment to enable usage of a variable escluding any check on the sender.
+ * The variable should be set in tcp.smtp for clients, with static IP, whose mailer
+ * is composing bad sender addresses
+ */
+/* #define CHKUSER_SENDER_NOCHECK_VARIABLE "SENDER_NOCHECK" */
+
+/*
+ * Uncomment to enable usage of "#" and "+" characters within sender address
+ * This is used by SRS (Sender Rewriting Scheme) products
+ */
+/* #define CHKUSER_ALLOW_SENDER_SRS */
+
+/*
+ * If you need more additional characters to be accepted within sender address
+ * uncomment one of the following #define and edit the character value.
+ * Be careful to use '*' (single hiphen) and NOT "*" (double hiphen) around the
+ * wanted char.
+ */
+/* #define CHKUSER_ALLOW_SENDER_CHAR_1 '$' */
+/* #define CHKUSER_ALLOW_SENDER_CHAR_2 '%' */
+/* #define CHKUSER_ALLOW_SENDER_CHAR_3 '' */
+/* #define CHKUSER_ALLOW_SENDER_CHAR_4 '?' */
+/* #define CHKUSER_ALLOW_SENDER_CHAR_5 '*' */
+
+/*
+ * The following #define sets the minimum length of a domain:
+ * as far as I know, "k.st" is the shortest domain, so 4 characters is the
+ * minimum length.
+ * This value is used to check formally a domain name validity.
+ * if CHKUSER_SENDER_FORMAT is undefined, no check on length is done.
+ * If you comment this define, no check on length is done.
+ */
+#define CHKUSER_MIN_DOMAIN_LEN 4
+
+/*
+ * Uncomment to enable logging of "good" senders
+ * valid only if CHKUSER_ENABLE_LOGGING is defined
+ */
+#define CHKUSER_LOG_VALID_SENDER
+
+/*
+ * Uncomment to define a variable which contains the max recipients number
+ * this will return always error if total recipients exceed this limit.
+ * The first reached, between CHKUSER_RCPT_LIMIT_VARIABLE and CHKUSER_WRONGRCPT_LIMIT_VARIABLE,
+ * makes chkuser rejecting everything else
+ */
+#define CHKUSER_RCPT_LIMIT_VARIABLE "CHKUSER_RCPTLIMIT"
+
+/*
+ * Uncomment to define a variable which contains the max unknown recipients number
+ * this will return always error if not existing recipients exceed this limit.
+ * The first reached, between CHKUSER_RCPT_LIMIT_VARIABLE and CHKUSER_WRONGRCPT_LIMIT_VARIABLE,
+ * makes chkuser rejecting everything else
+ */
+#define CHKUSER_WRONGRCPT_LIMIT_VARIABLE "CHKUSER_WRONGRCPTLIMIT"
+
+/*
+ * Uncomment to define the variable containing the percent to check for.
+ * Remember to define externally (i.e. in tcp.smtp) the environment variable containing
+ * the limit percent.
+ * If the variable is not defined, or it is <= 0, quota checking is not performed.
+ */
+#define CHKUSER_MBXQUOTA_VARIABLE "CHKUSER_MBXQUOTA"
+
+/*
+ * Delay to wait for each not existing recipient
+ * value is expressed in milliseconds
+ */
+#define CHKUSER_ERROR_DELAY 1000
+
+/*
+ * Uncomment to consider rcpt errors on address format and MX as intrusive
+ *
+ */
+#define CHKUSER_RCPT_DELAY_ANYERROR
+
+/*
+ * Uncomment to consider sender errors on address format and MX as intrusive
+ *
+ */
+#define CHKUSER_SENDER_DELAY_ANYERROR
+
+#define CHKUSER_NORCPT_STRING "511 sorry, no mailbox here by that name (#5.1.1 - chkuser)\r\n"
+#define CHKUSER_RESOURCE_STRING "430 system temporary unavailable, try again later (#4.3.0 - chkuser)\r\n"
+#define CHKUSER_MBXFULL_STRING "522 sorry, recipient mailbox is full (#5.2.2 - chkuser)\r\n"
+#define CHKUSER_MAXRCPT_STRING "571 sorry, reached maximum number of recipients for one session (#5.7.1 - chkuser)\r\n"
+#define CHKUSER_MAXWRONGRCPT_STRING "571 sorry, you are violating our security policies (#5.1.1 - chkuser)\r\n"
+#define CHKUSER_DOMAINMISSING_STRING "511 sorry, you must specify a domain (#5.1.1 - chkuser)\r\n"
+#define CHKUSER_RCPTFORMAT_STRING "511 sorry, recipient address has invalid format (#5.1.1 - chkuser)\r\n"
+#define CHKUSER_RCPTMX_STRING "511 sorry, can't find a valid MX for rcpt domain (#5.1.1 - chkuser)\r\n"
+#define CHKUSER_SENDERFORMAT_STRING "571 sorry, sender address has invalid format (#5.7.1 - chkuser)\r\n"
+#define CHKUSER_SENDERMX_STRING "511 sorry, can't find a valid MX for sender domain (#5.1.1 - chkuser)\r\n"
+#define CHKUSER_INTRUSIONTHRESHOLD_STRING "571 sorry, you are violating our security policies (#5.7.1 - chkuser)\r\n"
+#define CHKUSER_NORELAY_STRING "553 sorry, that domain isn't in my list of allowed rcpthosts (#5.5.3 - chkuser)\r\n"
+
+/***************************************************
+ *
+ *      new/modified defines in/from 2.0.6
+ *
+ **************************************************/
+
+/*
+ * Before version 5.3.25, vpopmail used the function vget_real_domain()
+ * to get the real name of a domain (useful if rcpt domain is aliasing
+ * another domain).
+ * From version 5.3.25, this call is not available and has been
+ * substituted by other calls.
+ *
+ *        must be enabled if vpopmail version< 5.3.5
+ *        must be disabled  if vpopmail version => 5.3.5 *
+ */
+/* #define CHKUSER_ENABLE_VGET_REAL_DOMAIN */
+
+/***************************************************
+ *
+ *      new/modified defines in/from 2.0.7
+ *
+ **************************************************/
+
+/*
+ * Uncomment next define to accept recipients for
+ * aliases that have a -default extension
+ */
+/* #define CHKUSER_ENABLE_ALIAS_DEFAULT */
+
+
+/*
+ * Uncomment to enable usage of "#" and "+" characters within rcpt address
+ * This is used by SRS (Sender Rewriting Scheme) products
+ */
+/* #define CHKUSER_ALLOW_RCPT_SRS */
+
+/*
+ * If you need more additional characters to be accepted within rcpt address
+ * uncomment one of the following #define and edit the character value.
+ * Be careful to use '*' (single hiphen) and NOT "*" (double hiphen) around the
+ * wanted char.
+ */
+/* #define CHKUSER_ALLOW_RCPT_CHAR_1 '$' */
+/* #define CHKUSER_ALLOW_RCPT_CHAR_2 '%' */
+/* #define CHKUSER_ALLOW_RCPT_CHAR_3 '' */
+/* #define CHKUSER_ALLOW_RCPT_CHAR_4 '?' */
+/* #define CHKUSER_ALLOW_RCPT_CHAR_5 '*' */
+
+/*
+ * This define has been eliminated.
+ * Turning it ON or OFF has no effect, as we consider the existence
+ * of #define VALIAS inside ~vpopmail/include/vpopmail_config.h
+ */
+/* #define CHKUSER_ENABLE_VALIAS */
+
+/*
+ * Uncomment this to enable user extension on names (i.e. TMDA)
+ * (for mailing lists this is done without checking this define)
+ * This define substitutes #define CHKUSER_ENABLE_EXTENSIONS
+ */
+#define CHKUSER_ENABLE_USERS_EXTENSIONS
+
+/*
+ * Enables checking for EZMLM lists
+ * this define substitutes #define CHKUSER_ENABLE_LISTS
+ *
+ */
+#define CHKUSER_ENABLE_EZMLM_LISTS
+
+/*
+ * Help identifying remote authorized IPs giving them a descriptive name
+ * Can be put in tcp.smtp, and will be displayed inside chkuser log
+ * Substitutes RELAYCLIENT in chkuser logging
+ */
+#define CHKUSER_IDENTIFY_REMOTE_VARIABLE "CHKUSER_IDENTIFY"
+
+/*
+ * The following #define set the character used for users extensions
+ * be careful: this is a  single char '-' definition, not a "string"
+ * this define substitutes #define CHKUSER_EXTENSION_DASH
+ * MUST be defined if CHKUSER_ENABLE_USERS_EXTENSIONS is defined
+ */
+#define CHKUSER_USERS_DASH '-'
+
+/*
+ * New error strings for SOFT DNS problems
+ */
+#define CHKUSER_RCPTMX_TMP_STRING "451 DNS temporary failure (#4.5.1 - chkuser)\r\n"
+#define CHKUSER_SENDERMX_TMP_STRING "451 DNS temporary failure (#4.5.1 - chkuser)\r\n"
+
+/*
+ * Enables checking for mailman lists
+ *
+ */
+/* #define CHKUSER_ENABLE_MAILMAN_LISTS */
+
+/*
+ * Identifies the pattern string to be searched within mailman aliases
+ *
+ */
+#define CHKUSER_MAILMAN_STRING "mailman"
+
+/*
+ * The following #define set the character used for mailman lists extensions
+ * be careful: this is a  single char '-' definition, not a "string"
+ */
+#define CHKUSER_MAILMAN_DASH '-'
+
+
+/*
+ * Enables final clean-up routine of chkuser
+ * This routine cleans open DB connections used for checking users and valiases
+ */
+#define CHKUSER_DB_CLEANUP
+
+/***************************************************
+ *
+ *      new/modified defines in/from 2.0.8
+ *
+ **************************************************/
+
+/*
+ * The following defines are NO MORE used. NULL SENDER rejecting breaks RFC
+ * compatibility, and makes harder to handle e-mail receipts.
+ * Please comment or delete them from your chkuser_settings.h.
+ */
+/* #define CHKUSER_ACCEPT_NULL_SENDER */
+/* #define CHKUSER_ENABLE_NULL_SENDER_WITH_TCPREMOTEHOST */
+
+/*
+ * Uncomment to enable checking of user and domain format for rcpt addresses
+ *      user    =       [a-z0-9_-]
+ *      domain  =       [a-z0-9-.] with not consecutive "-.", not leading or ending "-."
+ */
+#define CHKUSER_RCPT_FORMAT
+
+/*
+ * Uncomment to enable checking of domain MX for rcpt addresses
+ * It works on any rcpt address domain that is not inside rcpthosts
+ */
+#define CHKUSER_RCPT_MX
+
+/*
+ * Uncomment to enable checking of user and domain format for sender address
+ *      user    =       [a-z0-9_-]
+ *      domain  =       [a-z0-9-.] with not consecutive "-.", not leading or ending "-."
+ */
+#define CHKUSER_SENDER_FORMAT
+
+/*
+ * Uncomment to enable checking of domain MX for sender address
+ * it works on the first rcpt address, despite of any domain setting on chkuser
+ */
+#define CHKUSER_SENDER_MX
+
+/*
+ * Delay to add, for each not existing recipient, to the initial CHKUSER_ERROR_DELAY value
+ * value is expressed in milliseconds
+ */
+#define CHKUSER_ERROR_DELAY_INCREASE 300
+
diff -Naur ./conf-cc ../qmail-1.03-build-10/conf-cc
--- ./conf-cc	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/conf-cc	2006-04-27 13:03:27.000000000 -0500
@@ -1,3 +1,3 @@
-cc -O2
+cc -O2 -DTLS=20060104 -I/usr/include/openssl -I/home/vpopmail/include
 
 This will be used to compile .c files.
diff -Naur ./conf-spawn ../qmail-1.03-build-10/conf-spawn
--- ./conf-spawn	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/conf-spawn	2006-05-05 19:36:49.000000000 -0500
@@ -1,4 +1,4 @@
-120
+509
 
 This is a silent concurrency limit. You can't set it above 255. On some
 systems you can't set it above 125. qmail will refuse to compile if the
diff -Naur ./dns.c ../qmail-1.03-build-10/dns.c
--- ./dns.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/dns.c	2006-05-07 10:46:37.000000000 -0500
@@ -7,10 +7,9 @@
 #include <errno.h>
 extern int res_query();
 extern int res_search();
-extern int errno;
-extern int h_errno;
 #include "ip.h"
 #include "ipalloc.h"
+#include "strsalloc.h"
 #include "fmt.h"
 #include "alloc.h"
 #include "str.h"
@@ -29,6 +28,7 @@
 static int numanswers;
 static char name[MAXDNAME];
 static struct ip_address ip;
+static stralloc txt = {0};
 unsigned short pref;
 
 static stralloc glue = {0};
@@ -179,6 +179,49 @@
  return 0;
 }
 
+static int findtxt(wanttype)
+int wanttype;
+{
+ unsigned short rrtype;
+ unsigned short rrdlen;
+ int i;
+
+ if (numanswers <= 0) return 2;
+ --numanswers;
+ if (responsepos == responseend) return DNS_SOFT;
+
+ i = dn_expand(response.buf,responseend,responsepos,name,MAXDNAME);
+ if (i < 0) return DNS_SOFT;
+ responsepos += i;
+
+ i = responseend - responsepos;
+ if (i < 4 + 3 * 2) return DNS_SOFT;
+   
+ rrtype = getshort(responsepos);
+ rrdlen = getshort(responsepos + 8);
+ responsepos += 10;
+
+ if (rrtype == wanttype)
+  {
+   unsigned short txtpos;
+   unsigned char txtlen;
+
+   txt.len = 0;
+   for (txtpos = 0;txtpos < rrdlen;txtpos += txtlen)
+    {
+     txtlen = responsepos[txtpos++];
+     if (txtlen > rrdlen-txtpos) txtlen = rrdlen-txtpos;
+     if (!stralloc_catb(&txt,&responsepos[txtpos],txtlen)) return DNS_MEM;
+    }
+
+   responsepos += rrdlen;
+   return 1;
+ }
+
+ responsepos += rrdlen;
+ return 0;
+}
+
 void dns_init(flagsearch)
 int flagsearch;
 {
@@ -237,15 +280,18 @@
  return len;
 }
 
-int dns_ptr(sa,ip)
-stralloc *sa;
+static int dns_ptrplus(ssa,ip)
+strsalloc *ssa;
 struct ip_address *ip;
 {
+ stralloc sa = {0};
  int r;
 
- if (!stralloc_ready(sa,iaafmt((char *) 0,ip))) return DNS_MEM;
- sa->len = iaafmt(sa->s,ip);
- switch(resolve(sa,T_PTR))
+ if (!stralloc_ready(&sa,iaafmt((char *) 0,ip))) return DNS_MEM;
+ sa.len = iaafmt(sa.s,ip);
+ r = resolve(&sa,T_PTR);
+ alloc_free(sa.s);
+ switch(r)
   {
    case DNS_MEM: return DNS_MEM;
    case DNS_SOFT: return DNS_SOFT;
@@ -256,25 +302,46 @@
    if (r == DNS_SOFT) return DNS_SOFT;
    if (r == 1)
     {
-     if (!stralloc_copys(sa,name)) return DNS_MEM;
-     return 0;
+     stralloc sa2 = {0};
+     if (!stralloc_copys(&sa2,name)) return DNS_MEM;
+     if (!strsalloc_append(ssa,&sa2)) return DNS_MEM;
     }
   }
+ if (ssa->len) return 0;
  return DNS_HARD;
 }
 
+int dns_ptr(ssa,ip)
+strsalloc *ssa;
+struct ip_address *ip;
+{
+ int r;
+ int j;
+
+ if (!strsalloc_readyplus(ssa,0)) return DNS_MEM;
+ ssa->len = 0;
+ r = dns_ptrplus(ssa,ip);
+ if (r < 0)
+  {
+   for (j = 0;j < ssa->len;++j)
+    alloc_free(ssa->sa[j].s);
+   ssa->len = 0;
+  }
+ return r;
+}
+
+
 static int dns_ipplus(ia,sa,pref)
 ipalloc *ia;
 stralloc *sa;
 int pref;
 {
  int r;
- struct ip_mx ix;
+ struct ip_mx ix = {0};
 
  if (!stralloc_copy(&glue,sa)) return DNS_MEM;
  if (!stralloc_0(&glue)) return DNS_MEM;
  if (glue.s[0]) {
-   ix.pref = 0;
    if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)])
     {
      if (!ipalloc_append(ia,&ix)) return DNS_MEM;
@@ -293,9 +360,16 @@
    ix.ip = ip;
    ix.pref = pref;
    if (r == DNS_SOFT) return DNS_SOFT;
-   if (r == 1)
+   if (r == 1) {
+#ifdef IX_FQDN
+     ix.fqdn = glue.s;
+#endif
      if (!ipalloc_append(ia,&ix)) return DNS_MEM;
   }
+  }
+#ifdef IX_FQDN
+ glue.s = 0;
+#endif
  return 0;
 }
 
@@ -315,7 +389,7 @@
 {
  int r;
  struct mx { stralloc sa; unsigned short p; } *mx;
- struct ip_mx ix;
+ struct ip_mx ix = {0};
  int nummx;
  int i;
  int j;
@@ -327,7 +401,6 @@
  if (!stralloc_copy(&glue,sa)) return DNS_MEM;
  if (!stralloc_0(&glue)) return DNS_MEM;
  if (glue.s[0]) {
-   ix.pref = 0;
    if (!glue.s[ip_scan(glue.s,&ix.ip)] || !glue.s[ip_scanbracket(glue.s,&ix.ip)])
     {
      if (!ipalloc_append(ia,&ix)) return DNS_MEM;
@@ -398,3 +471,49 @@
  alloc_free(mx);
  return flagsoft;
 }
+
+
+static int dns_txtplus(ssa,sa)
+strsalloc *ssa;
+stralloc *sa;
+{
+ int r;
+
+ switch(resolve(sa,T_TXT)) 
+  {
+   case DNS_MEM: return DNS_MEM;
+   case DNS_SOFT: return DNS_SOFT;
+   case DNS_HARD: return DNS_HARD;
+  }
+ while ((r = findtxt(T_TXT)) != 2)
+  {
+   if (r == DNS_SOFT) return DNS_SOFT;
+   if (r == 1)
+    {
+     stralloc sa = {0};
+     if (!stralloc_copy(&sa,&txt)) return DNS_MEM;
+     if (!strsalloc_append(ssa,&sa)) return DNS_MEM;
+    }
+  }
+ if (ssa->len) return 0;
+ return DNS_HARD;
+}
+
+int dns_txt(ssa,sa)
+strsalloc *ssa;
+stralloc *sa;
+{
+ int r;
+ int j;
+
+ if (!strsalloc_readyplus(ssa,0)) return DNS_MEM;
+ ssa->len = 0;
+ r = dns_txtplus(ssa,sa);
+ if (r < 0)
+  {
+   for (j = 0;j < ssa->len;++j)
+    alloc_free(ssa->sa[j].s);
+   ssa->len = 0;
+  }
+ return r;
+}
diff -Naur ./dnsfq.c ../qmail-1.03-build-10/dnsfq.c
--- ./dnsfq.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/dnsfq.c	2006-05-07 10:48:57.000000000 -0500
@@ -5,15 +5,19 @@
 #include "dnsdoe.h"
 #include "ip.h"
 #include "ipalloc.h"
+#include "strsalloc.h"
 #include "exit.h"
 
 stralloc sa = {0};
+strsalloc ssa = {0};
 ipalloc ia = {0};
 
 void main(argc,argv)
 int argc;
 char **argv;
 {
+ int j;
+
  if (!argv[1]) _exit(100);
 
  if (!stralloc_copys(&sa,argv[1]))
@@ -25,8 +29,11 @@
   {
    substdio_putsflush(subfderr,"no IP addresses\n"); _exit(100);
   }
- dnsdoe(dns_ptr(&sa,&ia.ix[0].ip));
- substdio_putflush(subfdout,sa.s,sa.len);
- substdio_putsflush(subfdout,"\n");
+ dnsdoe(dns_ptr(&ssa,&ia.ix[0].ip));
+ for(j = 0;j < ssa.len;++j)
+  {
+   substdio_putflush(subfdout,ssa.sa[j].s,ssa.sa[j].len);
+   substdio_putsflush(subfdout,"\n");
+  }
  _exit(0);
 }
diff -Naur ./dns.h ../qmail-1.03-build-10/dns.h
--- ./dns.h	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/dns.h	2006-04-27 13:08:51.000000000 -0500
@@ -10,5 +10,6 @@
 int dns_mxip();
 int dns_ip();
 int dns_ptr();
+int dns_txt();
 
 #endif
diff -Naur ./dnsptr.c ../qmail-1.03-build-10/dnsptr.c
--- ./dnsptr.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/dnsptr.c	2006-05-07 10:52:39.000000000 -0500
@@ -6,22 +6,28 @@
 #include "dns.h"
 #include "dnsdoe.h"
 #include "ip.h"
+#include "strsalloc.h"
 #include "exit.h"
 
-stralloc sa = {0};
+strsalloc ssa = {0};
 struct ip_address ip;
 
 void main(argc,argv)
 int argc;
 char **argv;
 {
+ int j;
+
  if (!argv[1]) _exit(100);
 
  ip_scan(argv[1],&ip);
 
  dns_init(0);
- dnsdoe(dns_ptr(&sa,&ip));
- substdio_putflush(subfdout,sa.s,sa.len);
- substdio_putsflush(subfdout,"\n");
+ dnsdoe(dns_ptr(&ssa,&ip));
+ for(j = 0;j < ssa.len;++j)
+  {
+   substdio_putflush(subfdout,ssa.sa[j].s,ssa.sa[j].len);
+   substdio_putsflush(subfdout,"\n");
+  }
  _exit(0);
 }
diff -Naur ./dnstxt.c ../qmail-1.03-build-10/dnstxt.c
--- ./dnstxt.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/dnstxt.c	2006-05-05 21:22:43.000000000 -0500
@@ -0,0 +1,32 @@
+#include "substdio.h"
+#include "subfd.h"
+#include "stralloc.h"
+#include "str.h"
+#include "scan.h"
+#include "dns.h"
+#include "dnsdoe.h"
+#include "strsalloc.h"
+#include "exit.h"
+
+strsalloc ssa = {0};
+stralloc sa = {0};
+
+void main(argc,argv)
+int argc;
+char **argv;
+{
+ int j;
+
+ if (!argv[1]) _exit(100);
+
+ if (!stralloc_copys(&sa, argv[1]))
+  { substdio_putsflush(subfderr,"out of memory\n"); _exit(111); }
+ dns_init(0);
+ dnsdoe(dns_txt(&ssa,&sa));
+ for (j = 0;j < ssa.len;++j)
+  {
+   substdio_put(subfdout,ssa.sa[j].s,ssa.sa[j].len);
+   substdio_putsflush(subfdout,"\n");
+  }
+ _exit(0);
+}
diff -Naur ./error.3 ../qmail-1.03-build-10/error.3
--- ./error.3	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/error.3	2006-04-24 21:24:32.000000000 -0500
@@ -3,8 +3,8 @@
 error \- syscall error codes
 .SH SYNTAX
 .B #include <error.h>
-
-extern int \fBerrno\fP;
+.br
+.B #include <errno.h>
 
 extern int \fBerror_intr\fP;
 .br
diff -Naur ./error.h ../qmail-1.03-build-10/error.h
--- ./error.h	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/error.h	2006-04-24 21:24:32.000000000 -0500
@@ -1,7 +1,7 @@
 #ifndef ERROR_H
 #define ERROR_H
 
-extern int errno;
+#include <errno.h>
 
 extern int error_intr;
 extern int error_nomem;
diff -Naur ./FAQ ../qmail-1.03-build-10/FAQ
--- ./FAQ	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/FAQ	2006-04-24 21:24:32.000000000 -0500
@@ -1,3 +1,6 @@
+See http://cr.yp.to/qmail/faq.html for newer FAQs not included in this
+document, and http://qmail.org/ for qmail community contributions.
+
 1. Controlling the appearance of outgoing messages
 1.1. How do I set up host masquerading?
 1.2. How do I set up user masquerading?
diff -Naur ./FILES ../qmail-1.03-build-10/FILES
--- ./FILES	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/FILES	2006-05-07 10:55:27.000000000 -0500
@@ -10,6 +10,7 @@
 INSTALL.ids
 INSTALL.maildir
 INSTALL.mbox
+INSTALL-1.03
 INSTALL.vsm
 REMOVE.sendmail
 REMOVE.binmail
@@ -135,6 +136,8 @@
 dnsip.c
 dnsmxip.c
 dnsptr.c
+dnstxt.c
+spfquery.c
 hostname.c
 ipmeprint.c
 tcp-env.c
@@ -335,13 +338,16 @@
 byte.h
 byte_chr.c
 byte_copy.c
+byte_cspn.c
 byte_cr.c
 byte_diff.c
 byte_rchr.c
+byte_rcspn.c
 byte_zero.c
 str.h
 str_chr.c
 str_cpy.c
+str_cpyb.c
 str_diff.c
 str_diffn.c
 str_len.c
@@ -401,6 +407,8 @@
 date822fmt.c
 dns.h
 dns.c
+spf.h
+spf.c
 trylsock.c
 tryrsolv.c
 ip.h
diff -Naur ./FILES.warlord ../qmail-1.03-build-10/FILES.warlord
--- ./FILES.warlord	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/FILES.warlord	2005-01-29 06:08:25.000000000 -0600
@@ -0,0 +1,28 @@
+The WARLORD patch modifies the following QMAIL 1.03 files:
+
+Patched files:
+
+= Makefile
+= qmail-smtpd.c
+= qmail-smtpd.8
+= qmail-showctl.c
+= qmail-control.9
+= hier.c
+= install-big.c
+= cdb_seek.c
+= TARGETS
+
+Added files:
+
++ qmail-badloadertypes.c
++ qmail-badloadertypes.9
++ qmail-badmimetypes.c
++ qmail-badmimetypes.9
++ case_startb.c
+
+Informational files:
+
+% badloadertypes
+% badmimetypes
+% README.warlord
+% HISTORY.warlord
diff -Naur ./hier.c ../qmail-1.03-build-10/hier.c
--- ./hier.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/hier.c	2006-05-05 20:28:07.000000000 -0500
@@ -76,6 +76,10 @@
   c(auto_qmail,"boot","binm3+df",auto_uido,auto_gidq,0755);
 
   c(auto_qmail,"doc","FAQ",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.qregex",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.auth",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.remote-auth",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.starttls",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","UPGRADE",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","SENDMAIL",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","INSTALL",auto_uido,auto_gidq,0644);
@@ -109,6 +113,8 @@
   c(auto_qmail,"bin","qmail-clean",auto_uido,auto_gidq,0711);
   c(auto_qmail,"bin","qmail-send",auto_uido,auto_gidq,0711);
   c(auto_qmail,"bin","splogger",auto_uido,auto_gidq,0711);
+  c(auto_qmail,"bin","qmail-badmimetypes",auto_uido,auto_gidq,0700);
+  c(auto_qmail,"bin","qmail-badloadertypes",auto_uido,auto_gidq,0700);
   c(auto_qmail,"bin","qmail-newu",auto_uido,auto_gidq,0700);
   c(auto_qmail,"bin","qmail-newmrh",auto_uido,auto_gidq,0700);
   c(auto_qmail,"bin","qmail-pw2u",auto_uido,auto_gidq,0711);
@@ -143,6 +149,9 @@
   c(auto_qmail,"bin","qail",auto_uido,auto_gidq,0755);
   c(auto_qmail,"bin","elq",auto_uido,auto_gidq,0755);
   c(auto_qmail,"bin","pinq",auto_uido,auto_gidq,0755);
+#ifdef TLS
+  c(auto_qmail,"bin","update_tmprsadh",auto_uido,auto_gidq,0755);
+#endif
 
   c(auto_qmail,"man/man5","addresses.5",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/cat5","addresses.0",auto_uido,auto_gidq,0644);
@@ -221,6 +230,10 @@
   c(auto_qmail,"man/cat8","qmail-inject.0",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/man8","qmail-showctl.8",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/cat8","qmail-showctl.0",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/man8","qmail-badmimetypes.8",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/cat8","qmail-badmimetypes.0",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/man8","qmail-badloadertypes.8",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/cat8","qmail-badloadertypes.0",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/man8","qmail-newmrh.8",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/cat8","qmail-newmrh.0",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/man8","qmail-newu.8",auto_uido,auto_gidq,0644);
diff -Naur ./HISTORY.warlord ../qmail-1.03-build-10/HISTORY.warlord
--- ./HISTORY.warlord	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/HISTORY.warlord	2005-03-12 11:01:24.000000000 -0600
@@ -0,0 +1,22 @@
+HISTORY
+-------
+
+Convention: Version.Release.Fixlevel
+
+V.R.F	Description					Date
+--------------------------------------------------------------------
+1.2.1	Initial Release 				2003-09-09
+1.3.0  	Smarter base64 detection			2004-06-17
+1.3.1	Added badloadertype detection			2004-06-28
+1.3.4	Sync'ed with SPAMCONTROL 2.3			2004-09-14
+1.3.5	Sync'ed with SPAMCONTROL 2.3			2004-09-15
+1.3.6	Removed obsolete qhpsi defs.			2004-09-16
+1.3.7	Wrong length of MIME_LEN fixed.			2004-09-20
+1.3.8	Removed dependency on MIME_LEN.			2004-11-19
+1.3.9	Fixed 'status 11' aborts.			2004-12-09
+1.3.10	Removed function checkline in favour of a more 
+	generic multiple occurancee check 
+	badmimetype/badloadertyp stralloc now.		2005-01-29	
+1.3.11	FIXed false positive badladertype recognition
+	due to smarter base64 block identification.	2005-02-12
+	
diff -Naur ./INSTALL ../qmail-1.03-build-10/INSTALL
--- ./INSTALL	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/INSTALL	2006-04-24 21:24:32.000000000 -0500
@@ -1,84 +1 @@
-SAVE COPIES OF YOUR OUTGOING MAIL! Like any other piece of software (and
-information generally), the qmail system comes with NO WARRANTY. It's
-much more secure and reliable than sendmail, but that's not saying much.
-
-
-Things you have to decide before starting:
-
-* The qmail home directory, normally /var/qmail. To change this
-directory, edit conf-qmail now.
-
-* The names of the qmail users and the qmail groups. To change these
-names, edit conf-users and conf-groups now.
-
-
-To create /var/qmail and configure qmail (won't interfere with sendmail):
-
- 1. Create the qmail home directory:
-       # mkdir /var/qmail
-
- 2. Read INSTALL.ids. You must set up the qmail group and the qmail
-    users before compiling the programs.
-
- 3. Compile the programs and create the qmail directory tree:
-       # make setup check
-
- 4. Read INSTALL.ctl and FAQ. Minimal survival command:
-       # ./config
-
- 5. Read INSTALL.alias. Minimal survival command:
-       # (cd ~alias; touch .qmail-postmaster .qmail-mailer-daemon .qmail-root)
-       # chmod 644 ~alias/.qmail*
-
- 6. Read INSTALL.mbox and INSTALL.vsm.
-
- 7. Read INSTALL.maildir.
-
- 8. Copy /var/qmail/boot/home (or proc) to /var/qmail/rc.
-
-
-To test qmail deliveries (won't interfere with sendmail):
-
- 9. Enable deliveries of messages injected into qmail:
-       # csh -cf '/var/qmail/rc &'
-
-10. Read TEST.deliver.
-
-
-To upgrade from sendmail to qmail:
-
-11. Read SENDMAIL. This is what your users will want to know about the
-    switch from sendmail to qmail.
-
-12. Read REMOVE.sendmail. You must remove sendmail before installing
-    qmail.
-
-13. Read REMOVE.binmail.
-
-14. Add
-            csh -cf '/var/qmail/rc &'
-    to your boot scripts, so that the qmail daemons are restarted
-    whenever your system reboots. Make sure you include the &.
-
-15. Make qmail's ``sendmail'' wrapper available to MUAs:
-       # ln -s /var/qmail/bin/sendmail /usr/lib/sendmail
-       # ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
-    /usr/sbin might not exist on your system.
-
-16. Set up qmail-smtpd in /etc/inetd.conf (all on one line):
-            smtp stream tcp nowait qmaild /var/qmail/bin/tcp-env
-            tcp-env /var/qmail/bin/qmail-smtpd
-
-17. Reboot. (Or kill -HUP your inetd and make sure the qmail daemons
-    are running.)
-
-18. Read TEST.receive.
-
-
-
-That's it! To report success:
-       % ( echo 'First M. Last'; cat `cat SYSDEPS` ) | mail djb-qst@cr.yp.to
-Replace First M. Last with your name.
-
-If you have questions about qmail, join the qmail mailing list; see
-http://pobox.com/~djb/qmail.html.
+See http://lifewithqmail.org/lwq.html
diff -Naur ./install-big.c ../qmail-1.03-build-10/install-big.c
--- ./install-big.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/install-big.c	2006-05-05 20:29:22.000000000 -0500
@@ -76,6 +76,10 @@
   c(auto_qmail,"boot","binm3+df",auto_uido,auto_gidq,0755);
 
   c(auto_qmail,"doc","FAQ",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.qregex",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.auth",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.remote-auth",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"doc","README.starttls",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","UPGRADE",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","SENDMAIL",auto_uido,auto_gidq,0644);
   c(auto_qmail,"doc","INSTALL",auto_uido,auto_gidq,0644);
@@ -110,6 +114,8 @@
   c(auto_qmail,"bin","qmail-send",auto_uido,auto_gidq,0711);
   c(auto_qmail,"bin","splogger",auto_uido,auto_gidq,0711);
   c(auto_qmail,"bin","qmail-newu",auto_uido,auto_gidq,0700);
+  c(auto_qmail,"bin","qmail-badloadertypes",auto_uido,auto_gidq,0700);
+  c(auto_qmail,"bin","qmail-badmimetypes",auto_uido,auto_gidq,0700);
   c(auto_qmail,"bin","qmail-newmrh",auto_uido,auto_gidq,0700);
   c(auto_qmail,"bin","qmail-pw2u",auto_uido,auto_gidq,0711);
   c(auto_qmail,"bin","qmail-inject",auto_uido,auto_gidq,0755);
@@ -221,6 +227,10 @@
   c(auto_qmail,"man/cat8","qmail-inject.0",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/man8","qmail-showctl.8",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/cat8","qmail-showctl.0",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/man8","qmail-badloadertypes.8",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/cat8","qmail-badloadertypes.0",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/man8","qmail-badmimetypes.8",auto_uido,auto_gidq,0644);
+  c(auto_qmail,"man/cat8","qmail-badmimetypes.0",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/man8","qmail-newmrh.8",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/cat8","qmail-newmrh.0",auto_uido,auto_gidq,0644);
   c(auto_qmail,"man/man8","qmail-newu.8",auto_uido,auto_gidq,0644);
diff -Naur ./INSTALL.warlord ../qmail-1.03-build-10/INSTALL.warlord
--- ./INSTALL.warlord	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/INSTALL.warlord	2003-09-09 01:35:32.000000000 -0500
@@ -0,0 +1,26 @@
+Installation
+============
+
+1. Unpack/tar the Warlord archive in Qmail's source directory.
+2. Call ./warlord.sh.
+3. Verify the installation process; look into warlord.log.
+4. Re-make Qmail.
+
+Customization
+=============
+
+1. Copy the file badmimetypes from Qmail ./doc directory to ./control.
+2. Modifiy it to your needs.
+3. Execute qmail-newbmt.
+4. You need to define the environment variable $BADMIMETYPES in order
+   to let qmail-smtpd proceed with the badmime check.
+   You could do this globally in the qmail-smtpd start up script, 
+   or for individual senders/nets using tcpserver.
+
+Uninstallation
+==============
+
+1. Cd to the directory from where you installed Qmail/Warlord.
+2. Identify the current installed release of Warlord.
+3. Call ./warlord.sh -u Release.
+4. Re-make Qmail.
diff -Naur ./ipalloc.h ../qmail-1.03-build-10/ipalloc.h
--- ./ipalloc.h	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/ipalloc.h	2006-04-27 11:10:31.000000000 -0500
@@ -3,7 +3,15 @@
 
 #include "ip.h"
 
+#ifdef TLS
+# define IX_FQDN 1
+#endif
+
+#ifdef IX_FQDN
+struct ip_mx { struct ip_address ip; int pref; char *fqdn; } ;
+#else
 struct ip_mx { struct ip_address ip; int pref; } ;
+#endif
 
 #include "gen_alloc.h"
 
diff -Naur ./ipme.c ../qmail-1.03-build-10/ipme.c
--- ./ipme.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/ipme.c	2006-04-24 21:24:32.000000000 -0500
@@ -46,6 +46,11 @@
   ipme.len = 0;
   ix.pref = 0;
  
+  /* 0.0.0.0 is a special address which always refers to 
+   * "this host, this network", according to RFC 1122, Sec. 3.2.1.3a.
+  */
+  byte_copy(&ix.ip,4,"\0\0\0\0");
+  if (!ipalloc_append(&ipme,&ix)) { return 0; }
   if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1;
  
   len = 256;
diff -Naur ./maildirflags.c ../qmail-1.03-build-10/maildirflags.c
--- ./maildirflags.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirflags.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,23 @@
+/*
+** Copyright 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#include	<sys/types.h>
+#include	<string.h>
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+int maildir_hasflag(const char *filename, char flag)
+{
+	const char *p=strrchr(filename, '/');
+
+	if (p)
+		filename=p+1;
+
+	p=strrchr(p, ':');
+	if (p && strncmp(p, ":2,", 3) == 0 &&
+	    strchr(p+3, flag))
+		return (1);
+	return (0);
+}
diff -Naur ./maildirgetquota.c ../qmail-1.03-build-10/maildirgetquota.c
--- ./maildirgetquota.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirgetquota.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,50 @@
+/*
+** Copyright 1998 - 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#include	"maildirgetquota.h"
+#include	"maildirmisc.h"
+#if	HAVE_UNISTD_H
+#include	<unistd.h>
+#endif
+#include	<stdlib.h>
+#include	<string.h>
+#include	<fcntl.h>
+#include	<sys/types.h>
+#include	<sys/stat.h>
+
+int	maildir_getquota(const char *dir, char buf[QUOTABUFSIZE])
+{
+char	*p;
+struct	stat	stat_buf;
+int	n;
+int	l;
+
+	p=(char *)malloc(strlen(dir)+sizeof("/maildirfolder"));
+	if (!p)	return (-1);
+
+	strcat(strcpy(p, dir), "/maildirfolder");
+	if (stat(p, &stat_buf) == 0)
+	{
+		strcat(strcpy(p, dir), "/..");
+		n=maildir_getquota(p, buf);
+		free(p);
+		return (n);
+	}
+
+	strcat(strcpy(p, dir), "/maildirsize");
+	n=maildir_safeopen(p, O_RDONLY, 0);
+	free(p);
+	if (n < 0)	return (n);
+	if ((l=read(n, buf, QUOTABUFSIZE-1)) < 0)
+	{
+		close(n);
+		return (-1);
+	}
+	close(n);
+	for (n=0; n<l; n++)
+		if (buf[n] == '\n')	break;
+	buf[n]=0;
+	return (0);
+}
diff -Naur ./maildirgetquota.h ../qmail-1.03-build-10/maildirgetquota.h
--- ./maildirgetquota.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirgetquota.h	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,30 @@
+#ifndef	maildirgetquota_h
+#define	maildirgetquota_h
+
+/*
+** Copyright 1998 - 1999 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if	HAVE_CONFIG_H
+#include	"config.h"
+#endif
+
+#include	<sys/types.h>
+#include	<stdio.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+static const char maildirgetquota_h_rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+#define	QUOTABUFSIZE	256
+
+int maildir_getquota(const char *, char [QUOTABUFSIZE]);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff -Naur ./maildirmisc.h ../qmail-1.03-build-10/maildirmisc.h
--- ./maildirmisc.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirmisc.h	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,145 @@
+#ifndef	maildirmisc_h
+#define	maildirmisc_h
+
+/*
+** Copyright 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if	HAVE_CONFIG_H
+#include	"config.h"
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+static const char maildirmisc_h_rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+/*
+**
+** Miscellaneous maildir-related code
+**
+*/
+
+/* Some special folders */
+
+#define	INBOX	"INBOX"
+#define	DRAFTS	"Drafts"
+#define	SENT	"Sent"
+#define	TRASH	"Trash"
+
+#define	SHAREDSUBDIR	"shared-folders"
+
+char *maildir_folderdir(const char *,		/* maildir */
+	const char *);				/* folder name */
+	/* Returns the directory corresponding to foldername (foldername is
+	** checked to make sure that it's a valid name, else we set errno
+	** to EINVAL, and return (0).
+	*/
+
+char *maildir_filename(const char *,		/* maildir */
+	const char *,				/* folder */
+	const char *);				/* filename */
+	/*
+	** Builds the filename to this message, suitable for opening.
+	** If the file doesn't appear to be there, search the maildir to
+	** see if someone changed the flags, and return the current filename.
+	*/
+
+int maildir_safeopen(const char *,		/* filename */
+	int,				/* mode */
+	int);				/* perm */
+
+/*
+**	Same arguments as open().  When we're accessing a shared maildir,
+**	prevent someone from playing cute and dumping a bunch of symlinks
+**	in there.  This function will open the indicate file only if the
+**	last component is not a symlink.
+**	This is implemented by opening the file with O_NONBLOCK (to prevent
+**	a DOS attack of someone pointing the symlink to a pipe, causing
+**	the open to hang), clearing O_NONBLOCK, then stat-int the file
+**	descriptor, lstating the filename, and making sure that dev/ino
+**	match.
+*/
+
+int maildir_semisafeopen(const char *,	/* filename */
+	int,				/* mode */
+	int);				/* perm */
+
+/*
+** Same thing, except that we allow ONE level of soft link indirection,
+** because we're reading from our own maildir, which points to the
+** message in the sharable maildir.
+*/
+
+int maildir_mkdir(const char *);	/* directory */
+/*
+** Create maildir including all subdirectories in the path (like mkdir -p)
+*/
+
+void maildir_purgetmp(const char *);		/* maildir */
+	/* purges old stuff out of tmp */
+
+void maildir_purge(const char *,		/* directory */
+	unsigned);				/* time_t to purge */
+
+void maildir_getnew(const char *,		/* maildir */
+	const char *);				/* folder */
+	/* move messages from new to cur */
+
+int maildir_deletefolder(const char *,		/* maildir */
+	const char *);				/* folder */
+	/* deletes a folder */
+
+int maildir_mddelete(const char *);	/* delete a maildir folder by path */
+
+void maildir_list_sharable(const char *,	/* maildir */
+	void (*)(const char *, void *),		/* callback function */
+	void *);				/* 2nd arg to callback func */
+	/* list sharable folders */
+
+int maildir_shared_subscribe(const char *,	/* maildir */
+		const char *);			/* folder */
+	/* subscribe to a shared folder */
+
+void maildir_list_shared(const char *,		/* maildir */
+	void (*)(const char *, void *),		/* callback function */
+	void *);			/* 2nd arg to the callback func */
+	/* list subscribed folders */
+
+int maildir_shared_unsubscribe(const char *,	/* maildir */
+		const char *);			/* folder */
+	/* unsubscribe from a shared folder */
+
+char *maildir_shareddir(const char *,		/* maildir */
+	const char *);				/* folder */
+	/*
+	** Validate and return a path to a shared folder.  folderdir must be
+	** a name of a valid shared folder.
+	*/
+
+void maildir_shared_sync(const char *);		/* maildir */
+	/* "sync" the shared folder */
+
+int maildir_sharedisro(const char *);		/* maildir */
+	/* maildir is a shared read-only folder */
+
+int maildir_unlinksharedmsg(const char *);	/* filename */
+	/* Remove a message from a shared folder */
+
+/* Internal function that reads a symlink */
+
+char *maildir_getlink(const char *);
+
+	/* Determine whether the maildir filename has a certain flag */
+
+int maildir_hasflag(const char *filename, char);
+
+#define	MAILDIR_DELETED(f)	maildir_hasflag((f), 'T')
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff -Naur ./maildiropen.c ../qmail-1.03-build-10/maildiropen.c
--- ./maildiropen.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildiropen.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,133 @@
+/*
+** Copyright 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include	<sys/types.h>
+#include	<sys/stat.h>
+#include	<string.h>
+#include	<stdlib.h>
+#include	<time.h>
+#if	HAVE_UNISTD_H
+#include	<unistd.h>
+#endif
+#include	<stdio.h>
+#include	<ctype.h>
+#include	<errno.h>
+#include	<fcntl.h>
+
+#include	"maildirmisc.h"
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+char *maildir_getlink(const char *filename)
+{
+#if     HAVE_READLINK
+size_t	bufsiz;
+char	*buf;
+
+	bufsiz=0;
+	buf=0;
+
+	for (;;)
+	{
+	int	n;
+
+		if (buf)	free(buf);
+		bufsiz += 256;
+		if ((buf=malloc(bufsiz)) == 0)
+		{
+			perror("malloc");
+			return (0);
+		}
+		if ((n=readlink(filename, buf, bufsiz)) < 0)
+		{
+			free(buf);
+			return (0);
+		}
+		if (n < bufsiz)
+		{
+			buf[n]=0;
+			break;
+		}
+	}
+	return (buf);
+#else
+	return (0);
+#endif
+}
+
+int maildir_semisafeopen(const char *path, int mode, int perm)
+{
+
+#if	HAVE_READLINK
+
+char	*l=maildir_getlink(path);
+
+	if (l)
+	{
+	int	f;
+
+		if (*l != '/')
+		{
+		char	*q=malloc(strlen(path)+strlen(l)+2);
+		char	*s;
+
+			if (!q)
+			{
+				free(l);
+				return (-1);
+			}
+
+			strcpy(q, path);
+			if ((s=strchr(q, '/')) != 0)
+				s[1]=0;
+			else	*q=0;
+			strcat(q, l);
+			free(l);
+			l=q;
+		}
+
+		f=maildir_safeopen(l, mode, perm);
+
+		free(l);
+		return (f);
+	}
+#endif
+
+	return (maildir_safeopen(path, mode, perm));
+}
+		
+int maildir_safeopen(const char *path, int mode, int perm)
+{
+struct	stat	stat1, stat2;
+
+int	fd=open(path, mode
+#ifdef	O_NONBLOCK
+			| O_NONBLOCK
+#else
+			| O_NDELAY
+#endif
+				, perm);
+
+	if (fd < 0)	return (fd);
+	if (fcntl(fd, F_SETFL, (mode & O_APPEND)) || fstat(fd, &stat1)
+	    || lstat(path, &stat2))
+	{
+		close(fd);
+		return (-1);
+	}
+
+	if (stat1.st_dev != stat2.st_dev || stat1.st_ino != stat2.st_ino)
+	{
+		close(fd);
+		errno=ENOENT;
+		return (-1);
+	}
+
+	return (fd);
+}
diff -Naur ./maildirparsequota.c ../qmail-1.03-build-10/maildirparsequota.c
--- ./maildirparsequota.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirparsequota.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,44 @@
+/*
+** Copyright 1998 - 1999 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include	"maildirquota.h"
+#include	<stdlib.h>
+#include	<string.h>
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+int maildir_parsequota(const char *n, unsigned long *s)
+{
+const char *o;
+int	yes;
+
+	if ((o=strrchr(n, '/')) == 0)	o=n;
+
+	for (; *o; o++)
+		if (*o == ':')	break;
+	yes=0;
+	for ( ; o >= n; --o)
+	{
+		if (*o == '/')	break;
+
+		if (*o == ',' && o[1] == 'S' && o[2] == '=')
+		{
+			yes=1;
+			o += 3;
+			break;
+		}
+	}
+	if (yes)
+	{
+		*s=0;
+		while (*o >= '0' && *o <= '9')
+			*s= *s*10 + (*o++ - '0');
+		return (0);
+	}
+	return (-1);
+}
diff -Naur ./maildirquota.c ../qmail-1.03-build-10/maildirquota.c
--- ./maildirquota.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirquota.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,685 @@
+/*
+** Copyright 1998 - 2002 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+/* #if HAVE_DIRENT_H */
+#include <dirent.h>
+#define NAMLEN(dirent) strlen((dirent)->d_name)
+/* #else
+#define dirent direct
+#define NAMLEN(dirent) (dirent)->d_namlen
+#if HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#if HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#if HAVE_NDIR_H
+#include <ndir.h>
+#endif
+#endif */
+#include	<sys/types.h>
+/* #if	HAVE_SYS_STAT_H */
+#include	<sys/stat.h>
+/* #endif */
+#include	<sys/uio.h>
+
+#include	"maildirquota.h"
+#include	"maildirmisc.h"
+#include	<stdio.h>
+#include	<stdlib.h>
+#include	<string.h>
+#include	<errno.h>
+/* #if	HAVE_FCNTL_H */
+#include	<fcntl.h>
+/* #endif */
+#if	HAVE_UNISTD_H
+#include	<unistd.h>
+#endif
+#include	<time.h>
+#include	"numlib.h"
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+/* Read the maildirsize file */
+
+int maildirsize_read(const char *filename,	/* The filename */
+	int *fdptr,	/* Keep the file descriptor open */
+	off_t *sizeptr,	/* Grand total of maildir size */
+	unsigned *cntptr, /* Grand total of message count */
+	unsigned *nlines, /* # of lines in maildirsize */
+	struct stat *statptr)	/* The stats on maildirsize */
+{
+char buf[5120];
+int f;
+char *p;
+unsigned l;
+int n;
+int first;
+
+	if ((f=maildir_safeopen(filename, O_RDWR|O_APPEND, 0)) < 0)
+		return (-1);
+	p=buf;
+	l=sizeof(buf);
+
+	while (l)
+	{
+		n=read(f, p, l);
+		if (n < 0)
+		{
+			close(f);
+			return (-1);
+		}
+		if (n == 0)	break;
+		p += n;
+		l -= n;
+	}
+	if (l == 0 || fstat(f, statptr))	/* maildir too big */
+	{
+		close(f);
+		return (-1);
+	}
+
+	*sizeptr=0;
+	*cntptr=0;
+	*nlines=0;
+	*p=0;
+	p=buf;
+	first=1;
+	while (*p)
+	{
+	long n=0;
+	int c=0;
+	char	*q=p;
+
+		while (*p)
+			if (*p++ == '\n')
+			{
+				p[-1]=0;
+				break;
+			}
+
+		if (first)
+		{
+			first=0;
+			continue;
+		}
+		sscanf(q, "%ld %d", &n, &c);
+		*sizeptr += n;
+		*cntptr += c;
+		++ *nlines;
+	}
+	*fdptr=f;
+	return (0);
+}
+
+static char *makenewmaildirsizename(const char *, int *);
+static int countcurnew(const char *, time_t *, off_t *, unsigned *);
+static int countsubdir(const char *, const char *,
+		time_t *, off_t *, unsigned *);
+static int statcurnew(const char *, time_t *);
+static int statsubdir(const char *, const char *, time_t *);
+
+#define	MDQUOTA_SIZE	'S'	/* Total size of all messages in maildir */
+#define	MDQUOTA_BLOCKS	'B'	/* Total # of blocks for all messages in
+				maildir -- NOT IMPLEMENTED */
+#define	MDQUOTA_COUNT	'C'	/* Total number of messages in maildir */
+
+static int qcalc(off_t s, unsigned n, const char *quota, int *percentage)
+{
+off_t i;
+int	spercentage=0;
+int	npercentage=0;
+
+	errno=ENOSPC;
+	while (quota && *quota)
+	{
+		int x=1;
+
+		if (*quota < '0' || *quota > '9')
+		{
+			++quota;
+			continue;
+		}
+		i=0;
+		while (*quota >= '0' && *quota <= '9')
+			i=i*10 + (*quota++ - '0');
+		switch (*quota)	{
+		default:
+			if (i < s)
+			{
+				*percentage=100;
+				return (-1);
+			}
+
+			/*
+			** For huge quotas, over 20mb,
+			** divide numerator & denominator by 1024 to prevent
+			** an overflow when multiplying by 100
+			*/
+
+			x=1;
+			if (i > 20000000) x=1024;
+
+			spercentage = i ? (s/x) * 100 / (i/x):100;
+			break;
+		case 'C':
+
+			if (i < n)
+			{
+				*percentage=100;
+				return (-1);
+			}
+
+			/* Ditto */
+
+			x=1;
+			if (i > 20000000) x=1024;
+
+			npercentage = i ? ((off_t)n/x) * 100 / (i/x):100;
+			break;
+		}
+	}
+	*percentage = spercentage > npercentage ? spercentage:npercentage;
+	return (0);
+}
+
+static int	doaddquota(const char *, int, const char *, long, int, int);
+
+static int docheckquota(const char *dir,
+	int *maildirsize_fdptr,
+	const char *quota_type,
+	long xtra_size,
+	int xtra_cnt, int *percentage);
+
+
+int maildir_checkquota(const char *dir,
+	int *maildirsize_fdptr,
+	const char *quota_type,
+	long xtra_size,
+	int xtra_cnt)
+{
+int	dummy;
+
+	return (docheckquota(dir, maildirsize_fdptr, quota_type,
+		xtra_size, xtra_cnt, &dummy));
+}
+
+int maildir_readquota(const char *dir, const char *quota_type)
+{
+int	percentage=0;
+int	fd=-1;
+
+	(void)docheckquota(dir, &fd, quota_type, 0, 0, &percentage);
+	if (fd >= 0)
+		close(fd);
+	return (percentage);
+}
+
+static int docheckquota(const char *dir,
+	int *maildirsize_fdptr,
+	const char *quota_type,
+	long xtra_size,
+	int xtra_cnt,
+	int *percentage)
+{
+char	*checkfolder=(char *)malloc(strlen(dir)+sizeof("/maildirfolder"));
+char	*newmaildirsizename;
+struct stat stat_buf;
+int	maildirsize_fd;
+off_t	maildirsize_size;
+unsigned maildirsize_cnt;
+unsigned maildirsize_nlines;
+int	n;
+time_t	tm;
+time_t	maxtime;
+DIR	*dirp;
+struct dirent *de;
+
+	if (checkfolder == 0)	return (-1);
+	*maildirsize_fdptr= -1;
+	strcat(strcpy(checkfolder, dir), "/maildirfolder");
+	if (stat(checkfolder, &stat_buf) == 0)	/* Go to parent */
+	{
+		strcat(strcpy(checkfolder, dir), "/..");
+		n=docheckquota(checkfolder, maildirsize_fdptr,
+			quota_type, xtra_size, xtra_cnt, percentage);
+		free(checkfolder);
+		return (n);
+	}
+	if (!quota_type || !*quota_type)	return (0);
+
+	strcat(strcpy(checkfolder, dir), "/maildirsize");
+	time(&tm);
+	if (maildirsize_read(checkfolder, &maildirsize_fd,
+		&maildirsize_size, &maildirsize_cnt,
+		&maildirsize_nlines, &stat_buf) == 0)
+	{
+		n=qcalc(maildirsize_size+xtra_size, maildirsize_cnt+xtra_cnt,
+			quota_type, percentage);
+
+		if (n == 0)
+		{
+			free(checkfolder);
+			*maildirsize_fdptr=maildirsize_fd;
+			return (0);
+		}
+		close(maildirsize_fd);
+
+		if (maildirsize_nlines == 1 && tm < stat_buf.st_mtime + 15*60)
+			return (n);
+	}
+
+	maxtime=0;
+	maildirsize_size=0;
+	maildirsize_cnt=0;
+
+	if (countcurnew(dir, &maxtime, &maildirsize_size, &maildirsize_cnt))
+	{
+		free(checkfolder);
+		return (-1);
+	}
+
+	dirp=opendir(dir);
+	while (dirp && (de=readdir(dirp)) != 0)
+	{
+		if (countsubdir(dir, de->d_name, &maxtime, &maildirsize_size,
+			&maildirsize_cnt))
+		{
+			free(checkfolder);
+			closedir(dirp);
+			return (-1);
+		}
+	}
+	if (dirp)
+	{
+#if	CLOSEDIR_VOID
+		closedir(dirp);
+#else
+		if (closedir(dirp))
+		{
+			free(checkfolder);
+			return (-1);
+		}
+#endif
+	}
+
+	newmaildirsizename=makenewmaildirsizename(dir, &maildirsize_fd);
+	if (!newmaildirsizename)
+	{
+		free(checkfolder);
+		return (-1);
+	}
+
+	*maildirsize_fdptr=maildirsize_fd;
+
+	if (doaddquota(dir, maildirsize_fd, quota_type, maildirsize_size,
+		maildirsize_cnt, 1))
+	{
+		unlink(newmaildirsizename);
+		free(newmaildirsizename);
+		close(maildirsize_fd);
+		*maildirsize_fdptr= -1;
+		free(checkfolder);
+		return (-1);
+	}
+
+	strcat(strcpy(checkfolder, dir), "/maildirsize");
+
+	if (rename(newmaildirsizename, checkfolder))
+	{
+		/* free(checkfolder); */
+		unlink(newmaildirsizename);
+		close(maildirsize_fd);
+		*maildirsize_fdptr= -1;
+	}
+	free(checkfolder);
+	free(newmaildirsizename);
+
+	tm=0;
+
+	if (statcurnew(dir, &tm))
+	{
+		close(maildirsize_fd);
+		*maildirsize_fdptr= -1;
+		return (-1);
+	}
+
+	dirp=opendir(dir);
+	while (dirp && (de=readdir(dirp)) != 0)
+	{
+		if (statsubdir(dir, de->d_name, &tm))
+		{
+			close(maildirsize_fd);
+			*maildirsize_fdptr= -1;
+			closedir(dirp);
+			return (-1);
+		}
+	}
+	if (dirp)
+	{
+#if	CLOSEDIR_VOID
+		closedir(dirp);
+#else
+		if (closedir(dirp))
+		{
+			close(maildirsize_fd);
+			*maildirsize_fdptr= -1;
+			return (-1);
+		}
+#endif
+	}
+
+	if (tm != maxtime)	/* Race condition, someone changed something */
+	{
+		errno=EAGAIN;
+		return (-1);
+	}
+
+	return (qcalc(maildirsize_size+xtra_size, maildirsize_cnt+xtra_cnt,
+		quota_type, percentage));
+}
+
+int	maildir_addquota(const char *dir, int maildirsize_fd,
+	const char *quota_type, long maildirsize_size, int maildirsize_cnt)
+{
+	if (!quota_type || !*quota_type)	return (0);
+	return (doaddquota(dir, maildirsize_fd, quota_type, maildirsize_size,
+			maildirsize_cnt, 0));
+}
+
+static int doaddquota(const char *dir, int maildirsize_fd,
+	const char *quota_type, long maildirsize_size, int maildirsize_cnt,
+	int isnew)
+{
+union	{
+	char	buf[100];
+	struct stat stat_buf;
+	} u;				/* Scrooge */
+char	*newname2=0;
+char	*newmaildirsizename=0;
+struct	iovec	iov[3];
+int	niov;
+struct	iovec	*p;
+int	n;
+
+	niov=0;
+	if ( maildirsize_fd < 0)
+	{
+		newname2=(char *)malloc(strlen(dir)+sizeof("/maildirfolder"));
+		if (!newname2)	return (-1);
+		strcat(strcpy(newname2, dir), "/maildirfolder");
+		if (stat(newname2, &u.stat_buf) == 0)
+		{
+			strcat(strcpy(newname2, dir), "/..");
+			n=doaddquota(newname2, maildirsize_fd, quota_type,
+					maildirsize_size, maildirsize_cnt,
+					isnew);
+			free(newname2);
+			return (n);
+		}
+
+		strcat(strcpy(newname2, dir), "/maildirsize");
+
+		if ((maildirsize_fd=maildir_safeopen(newname2,
+			O_RDWR|O_APPEND, 0644)) < 0)
+		{
+			newmaildirsizename=makenewmaildirsizename(dir, &maildirsize_fd);
+			if (!newmaildirsizename)
+			{
+				free(newname2);
+				return (-1);
+			}
+
+			maildirsize_fd=maildir_safeopen(newmaildirsizename,
+				O_CREAT|O_RDWR|O_APPEND, 0644);
+
+			if (maildirsize_fd < 0)
+			{
+				free(newname2);
+				return (-1);
+			}
+			isnew=1;
+		}
+	}
+
+	if (isnew)
+	{
+		iov[0].iov_base=(caddr_t)quota_type;
+		iov[0].iov_len=strlen(quota_type);
+		iov[1].iov_base=(caddr_t)"\n";
+		iov[1].iov_len=1;
+		niov=2;
+	}
+
+
+	sprintf(u.buf, "%ld %d\n", maildirsize_size, maildirsize_cnt);
+	iov[niov].iov_base=(caddr_t)u.buf;
+	iov[niov].iov_len=strlen(u.buf);
+
+	p=iov;
+	++niov;
+	n=0;
+	while (niov)
+	{
+		if (n)
+		{
+			if (n < p->iov_len)
+			{
+				p->iov_base=
+					(caddr_t)((char *)p->iov_base + n);
+				p->iov_len -= n;
+			}
+			else
+			{
+				n -= p->iov_len;
+				++p;
+				--niov;
+				continue;
+			}
+		}
+
+		n=writev( maildirsize_fd, p, niov);
+
+		if (n <= 0)
+		{
+			if (newname2)
+			{
+				close(maildirsize_fd);
+				free(newname2);
+			}
+			return (-1);
+		}
+	}
+	if (newname2)
+	{
+		close(maildirsize_fd);
+
+		if (newmaildirsizename)
+		{
+			rename(newmaildirsizename, newname2);
+			free(newmaildirsizename);
+		}
+		free(newname2);
+	}
+	return (0);
+}
+
+/* New maildirsize is built in the tmp subdirectory */
+
+static char *makenewmaildirsizename(const char *dir, int *fd)
+{
+char	hostname[256];
+struct	stat stat_buf;
+time_t	t;
+char	*p;
+
+	hostname[0]=0;
+	hostname[sizeof(hostname)-1]=0;
+	gethostname(hostname, sizeof(hostname)-1);
+	p=(char *)malloc(strlen(dir)+strlen(hostname)+130);
+	if (!p)	return (0);
+
+	for (;;)
+	{
+	char	tbuf[NUMBUFSIZE];
+	char	pbuf[NUMBUFSIZE];
+
+		time(&t);
+		strcat(strcpy(p, dir), "/tmp/");
+		sprintf(p+strlen(p), "%s.%s_NeWmAiLdIrSiZe.%s",
+			str_time_t(t, tbuf),
+			str_pid_t(getpid(), pbuf), hostname);
+
+		if (stat( (const char *)p, &stat_buf) < 0 &&
+			(*fd=maildir_safeopen(p,
+				O_CREAT|O_RDWR|O_APPEND, 0644)) >= 0)
+			break;
+		sleep(3);
+	}
+	return (p);
+}
+
+static int statcurnew(const char *dir, time_t *maxtimestamp)
+{
+char	*p=(char *)malloc(strlen(dir)+5);
+struct	stat	stat_buf;
+
+	if (!p)	return (-1);
+	strcat(strcpy(p, dir), "/cur");
+	if ( stat(p, &stat_buf) == 0 && stat_buf.st_mtime > *maxtimestamp)
+		*maxtimestamp=stat_buf.st_mtime;
+	strcat(strcpy(p, dir), "/new");
+	if ( stat(p, &stat_buf) == 0 && stat_buf.st_mtime > *maxtimestamp)
+		*maxtimestamp=stat_buf.st_mtime;
+	free(p);
+	return (0);
+}
+
+static int statsubdir(const char *dir, const char *subdir, time_t *maxtime)
+{
+char	*p;
+int	n;
+
+	if ( *subdir != '.' || strcmp(subdir, ".") == 0 ||
+		strcmp(subdir, "..") == 0 || strcmp(subdir, "." TRASH) == 0)
+		return (0);
+
+	p=(char *)malloc(strlen(dir)+strlen(subdir)+2);
+	if (!p)	return (-1);
+	strcat(strcat(strcpy(p, dir), "/"), subdir);
+	n=statcurnew(p, maxtime);
+	free(p);
+	return (n);
+}
+
+static int docount(const char *, time_t *, off_t *, unsigned *);
+
+static int countcurnew(const char *dir, time_t *maxtime,
+	off_t *sizep, unsigned *cntp)
+{
+char	*p=(char *)malloc(strlen(dir)+5);
+int	n;
+
+	if (!p)	return (-1);
+	strcat(strcpy(p, dir), "/new");
+	n=docount(p, maxtime, sizep, cntp);
+	if (n == 0)
+	{
+		strcat(strcpy(p, dir), "/cur");
+		n=docount(p, maxtime, sizep, cntp);
+	}
+	free(p);
+	return (n);
+}
+
+static int countsubdir(const char *dir, const char *subdir, time_t *maxtime,
+	off_t *sizep, unsigned *cntp)
+{
+char	*p;
+int	n;
+
+	if ( *subdir != '.' || strcmp(subdir, ".") == 0 ||
+		strcmp(subdir, "..") == 0 || strcmp(subdir, "." TRASH) == 0)
+		return (0);
+
+	p=(char *)malloc(strlen(dir)+strlen(subdir)+2);
+	if (!p)	return (2);
+	strcat(strcat(strcpy(p, dir), "/"), subdir);
+	n=countcurnew(p, maxtime, sizep, cntp);
+	free(p);
+	return (n);
+}
+
+static int docount(const char *dir, time_t *dirstamp,
+	off_t *sizep, unsigned *cntp)
+{
+struct	stat	stat_buf;
+char	*p;
+DIR	*dirp;
+struct dirent *de;
+unsigned long	s;
+
+	if (stat(dir, &stat_buf))	return (0);	/* Ignore */
+	if (stat_buf.st_mtime > *dirstamp)	*dirstamp=stat_buf.st_mtime;
+	if ((dirp=opendir(dir)) == 0)	return (0);
+	while ((de=readdir(dirp)) != 0)
+	{
+	const char *n=de->d_name;
+
+		if (*n == '.')	continue;
+
+		/* PATCH - do not count msgs marked as deleted */
+
+		for ( ; *n; n++)
+		{
+			if (n[0] != ':' || n[1] != '2' ||
+				n[2] != ',')	continue;
+			n += 3;
+			while (*n >= 'A' && *n <= 'Z')
+			{
+				if (*n == 'T')	break;
+				++n;
+			}
+			break;
+		}
+		if (*n == 'T')	continue;
+		n=de->d_name;
+
+
+		if (maildir_parsequota(n, &s) == 0)
+			stat_buf.st_size=s;
+		else
+		{
+			p=(char *)malloc(strlen(dir)+strlen(n)+2);
+			if (!p)
+			{
+				closedir(dirp);
+				return (-1);
+			}
+			strcat(strcat(strcpy(p, dir), "/"), n);
+			if (stat(p, &stat_buf))
+			{
+				free(p);
+				continue;
+			}
+			free(p);
+		}
+		*sizep += stat_buf.st_size;
+		++*cntp;
+	}
+
+#if	CLOSEDIR_VOID
+	closedir(dirp);
+#else
+	if (closedir(dirp))
+		return (-1);
+#endif
+	return (0);
+}
diff -Naur ./maildirquota.h ../qmail-1.03-build-10/maildirquota.h
--- ./maildirquota.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/maildirquota.h	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,45 @@
+#ifndef	maildirquota_h
+#define	maildirquota_h
+
+/*
+** Copyright 1998 - 1999 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if	HAVE_CONFIG_H
+#include	"config.h"
+#endif
+
+#include	<sys/types.h>
+#include	<stdio.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+static const char maildirquota_h_rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+int maildir_checkquota(const char *,	/* Pointer to directory */
+	int *,	/* Initialized to -1, or opened descriptor for maildirsize */
+	const char *,	/* The quota */
+	long,		/* Extra bytes planning to add/remove from maildir */
+	int);		/* Extra messages planning to add/remove from maildir */
+
+int maildir_addquota(const char *,	/* Pointer to the maildir */
+	int,	/* Must be the int pointed to by 2nd arg to checkquota */
+	const char *,	/* The quota */
+	long,	/* +/- bytes */
+	int);	/* +/- files */
+
+int maildir_readquota(const char *,	/* Directory */
+	const char *);			/* Quota, from getquota */
+
+int maildir_parsequota(const char *, unsigned long *);
+	/* Attempt to parse file size encoded in filename.  Returns 0 if
+	** parsed, non-zero if we didn't parse. */
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff -Naur ./Makefile ../qmail-1.03-build-10/Makefile
--- ./Makefile	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/Makefile	2006-05-09 23:55:55.000000000 -0500
@@ -1,5 +1,10 @@
 # Don't edit Makefile! Use conf-* for configuration.
 
+VPOPMAIL_HOME=/home/vpopmail
+SMTPD_CHKUSER_OBJ=chkuser.o
+VPOPMAIL_LIBS=`head -1 $(VPOPMAIL_HOME)/etc/lib_deps` `cat dns.lib`
+LIB_DK=LDK_PATH
+
 SHELL=/bin/sh
 
 default: it
@@ -136,6 +141,10 @@
 compile auto_usera.c
 	./compile auto_usera.c
 
+base64.o: \
+compile base64.c base64.h stralloc.h substdio.h str.h
+	./compile base64.c
+
 binm1: \
 binm1.sh conf-qmail
 	cat binm1.sh \
@@ -203,6 +212,10 @@
 compile byte_cr.c byte.h
 	./compile byte_cr.c
 
+byte_cspn.o: \
+compile byte_cspn.c byte.h
+	./compile byte_cspn.c
+
 byte_diff.o: \
 compile byte_diff.c byte.h
 	./compile byte_diff.c
@@ -211,15 +224,19 @@
 compile byte_rchr.c byte.h
 	./compile byte_rchr.c
 
+byte_rcspn.o: \
+compile byte_rcspn.c byte.h
+	./compile byte_rcspn.c
+
 byte_zero.o: \
 compile byte_zero.c byte.h
 	./compile byte_zero.c
 
 case.a: \
 makelib case_diffb.o case_diffs.o case_lowerb.o case_lowers.o \
-case_starts.o
+case_starts.o case_startb.o
 	./makelib case.a case_diffb.o case_diffs.o case_lowerb.o \
-	case_lowers.o case_starts.o
+	case_lowers.o case_starts.o case_startb.o
 
 case_diffb.o: \
 compile case_diffb.c case.h
@@ -237,6 +254,10 @@
 compile case_lowers.c case.h
 	./compile case_lowers.c
 
+case_startb.o: \
+compile case_startb.c case.h
+	./compile case_startb.c
+
 case_starts.o: \
 compile case_starts.c case.h
 	./compile case_starts.c
@@ -263,7 +284,7 @@
 	cdbmake_add.o
 
 cdbmake_add.o: \
-compile cdbmake_add.c cdbmake.h uint32.h
+compile cdbmake_add.c cdbmake.h alloc.h uint32.h
 	./compile cdbmake_add.c
 
 cdbmake_hash.o: \
@@ -300,6 +321,10 @@
 exit.h auto_spawn.h
 	./compile chkspawn.c
 
+chkuser.o: \
+compile chkuser.c chkuser.h chkuser_settings.h
+	./compile chkuser.c
+
 clean: \
 TARGETS
 	rm -f `cat TARGETS`
@@ -393,84 +418,96 @@
 	rm -f trydrent.o
 
 dns.lib: \
-tryrsolv.c compile load socket.lib dns.o ipalloc.o ip.o stralloc.a \
+tryrsolv.c compile load socket.lib dns.o ipalloc.o strsalloc.o ip.o stralloc.a \
 alloc.a error.a fs.a str.a
 	( ( ./compile tryrsolv.c && ./load tryrsolv dns.o \
-	ipalloc.o ip.o stralloc.a alloc.a error.a fs.a str.a \
+	ipalloc.o strsalloc.o ip.o stralloc.a alloc.a error.a fs.a str.a \
 	-lresolv `cat socket.lib` ) >/dev/null 2>&1 \
 	&& echo -lresolv || exit 0 ) > dns.lib
 	rm -f tryrsolv.o tryrsolv
 
 dns.o: \
-compile dns.c ip.h ipalloc.h ip.h gen_alloc.h fmt.h alloc.h str.h \
+compile dns.c ip.h ipalloc.h ip.h strsalloc.h gen_alloc.h fmt.h alloc.h str.h \
 stralloc.h gen_alloc.h dns.h case.h
 	./compile dns.c
 
 dnscname: \
-load dnscname.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+load dnscname.o dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a \
 substdio.a error.a str.a fs.a dns.lib socket.lib
-	./load dnscname dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	./load dnscname dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a \
 	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
 	socket.lib`
 
 dnscname.o: \
-compile dnscname.c substdio.h subfd.h substdio.h stralloc.h \
+compile dnscname.c substdio.h subfd.h stralloc.h \
 gen_alloc.h dns.h dnsdoe.h readwrite.h exit.h
 	./compile dnscname.c
 
 dnsdoe.o: \
-compile dnsdoe.c substdio.h subfd.h substdio.h exit.h dns.h dnsdoe.h
+compile dnsdoe.c substdio.h subfd.h exit.h dns.h dnsdoe.h
 	./compile dnsdoe.c
 
 dnsfq: \
-load dnsfq.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+load dnsfq.o dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a \
 substdio.a error.a str.a fs.a dns.lib socket.lib
-	./load dnsfq dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	./load dnsfq dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a \
 	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
 	socket.lib`
 
 dnsfq.o: \
-compile dnsfq.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \
-dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h exit.h
+compile dnsfq.c substdio.h subfd.h stralloc.h gen_alloc.h \
+dns.h dnsdoe.h ip.h ipalloc.h strsalloc.h exit.h
 	./compile dnsfq.c
 
 dnsip: \
-load dnsip.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+load dnsip.o dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a \
 substdio.a error.a str.a fs.a dns.lib socket.lib
-	./load dnsip dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	./load dnsip dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a \
 	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
 	socket.lib`
 
 dnsip.o: \
-compile dnsip.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \
-dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h exit.h
+compile dnsip.c substdio.h subfd.h stralloc.h gen_alloc.h \
+dns.h dnsdoe.h ip.h ipalloc.h strsalloc.h exit.h
 	./compile dnsip.c
 
 dnsmxip: \
-load dnsmxip.o dns.o dnsdoe.o ip.o ipalloc.o now.o stralloc.a alloc.a \
+load dnsmxip.o dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o now.o stralloc.a alloc.a \
 substdio.a error.a str.a fs.a dns.lib socket.lib
-	./load dnsmxip dns.o dnsdoe.o ip.o ipalloc.o now.o \
+	./load dnsmxip dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o now.o \
 	stralloc.a alloc.a substdio.a error.a str.a fs.a  `cat \
 	dns.lib` `cat socket.lib`
 
 dnsmxip.o: \
-compile dnsmxip.c substdio.h subfd.h substdio.h stralloc.h \
-gen_alloc.h fmt.h dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h \
+compile dnsmxip.c substdio.h subfd.h stralloc.h \
+gen_alloc.h fmt.h dns.h dnsdoe.h ip.h ipalloc.h strsalloc.h \
 now.h datetime.h exit.h
 	./compile dnsmxip.c
 
 dnsptr: \
-load dnsptr.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+load dnsptr.o dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a \
 substdio.a error.a str.a fs.a dns.lib socket.lib
-	./load dnsptr dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	./load dnsptr dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a \
 	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
 	socket.lib`
 
 dnsptr.o: \
-compile dnsptr.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \
+compile dnsptr.c substdio.h subfd.h stralloc.h gen_alloc.h \
 str.h scan.h dns.h dnsdoe.h ip.h exit.h
 	./compile dnsptr.c
 
+dnstxt: \
+load dnstxt.o dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a \
+substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load dnstxt dns.o dnsdoe.o ip.o ipalloc.o strsalloc.o stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
+	socket.lib`
+
+dnstxt.o: \
+compile dnstxt.c substdio.h subfd.h stralloc.h gen_alloc.h \
+str.h scan.h dns.h dnsdoe.h ip.h exit.h
+	./compile dnstxt.c
+
 dot-qmail.0: \
 dot-qmail.5
 	nroff -man dot-qmail.5 > dot-qmail.0
@@ -777,24 +814,24 @@
 	./compile ip.c
 
 ipalloc.o: \
-compile ipalloc.c alloc.h gen_allocdefs.h ip.h ipalloc.h ip.h \
+compile ipalloc.c alloc.h gen_allocdefs.h ip.h ipalloc.h \
 gen_alloc.h
 	./compile ipalloc.c
 
 ipme.o: \
-compile ipme.c hassalen.h byte.h ip.h ipalloc.h ip.h gen_alloc.h \
-stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h
+compile ipme.c hassalen.h byte.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h \
+stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h strsalloc.h
 	./compile ipme.c
 
 ipmeprint: \
-load ipmeprint.o ipme.o ip.o ipalloc.o stralloc.a alloc.a substdio.a \
+load ipmeprint.o ipme.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a substdio.a \
 error.a str.a fs.a socket.lib
-	./load ipmeprint ipme.o ip.o ipalloc.o stralloc.a alloc.a \
+	./load ipmeprint ipme.o ip.o ipalloc.o strsalloc.o stralloc.a alloc.a \
 	substdio.a error.a str.a fs.a  `cat socket.lib`
 
 ipmeprint.o: \
 compile ipmeprint.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \
-ipalloc.h ip.h gen_alloc.h exit.h
+ipalloc.h strsalloc.h ip.h gen_alloc.h exit.h
 	./compile ipmeprint.c
 
 it: \
@@ -803,12 +840,13 @@
 predate datemail mailsubj qmail-upq qmail-showctl qmail-newu \
 qmail-pw2u qmail-qread qmail-qstat qmail-tcpto qmail-tcpok \
 qmail-pop3d qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd \
+qmail-badmimetypes qmail-badloadertypes \
 qmail-smtpd sendmail tcp-env qmail-newmrh config config-fast dnscname \
-dnsptr dnsip dnsmxip dnsfq hostname ipmeprint qreceipt qsmhook qbiff \
+dnsptr dnsip dnsmxip dnsfq dnstxt hostname ipmeprint qreceipt qsmhook qbiff \
 forward preline condredirect bouncesaying except maildirmake \
 maildir2mbox maildirwatch qail elq pinq idedit install-big install \
 instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \
-binm3 binm3+df
+binm3 binm3+df spfquery qmail-dk update_tmprsadh
 
 load: \
 make-load warn-auto.sh systype
@@ -890,6 +928,38 @@
 readwrite.h open.h headerbody.h maildir.h strerr.h
 	./compile maildirwatch.c
 
+maildirgetquota.o: \
+compile maildirgetquota.c maildirgetquota.h maildirmisc.h
+	./compile maildirgetquota.c
+
+maildirflags.o: \
+compile maildirflags.c
+	./compile maildirflags.c
+
+maildiropen.o: \
+compile maildiropen.c maildirmisc.h
+	./compile maildiropen.c
+
+maildirparsequota.o: \
+compile maildirparsequota.c
+	./compile maildirparsequota.c
+
+maildirquota.o: \
+compile maildirquota.c maildirquota.h maildirmisc.h numlib.h
+	./compile maildirquota.c
+
+overmaildirquota.o: \
+compile overmaildirquota.c 
+	./compile overmaildirquota.c
+
+strtimet.o: \
+compile strtimet.c 
+	./compile strtimet.c
+
+strpidt.o: \
+compile strpidt.c 
+	./compile strpidt.c
+
 mailsubj: \
 warn-auto.sh mailsubj.sh conf-qmail conf-break conf-split
 	cat warn-auto.sh mailsubj.sh \
@@ -927,6 +997,7 @@
 man: \
 qmail-local.0 qmail-lspawn.0 qmail-getpw.0 qmail-remote.0 \
 qmail-rspawn.0 qmail-clean.0 qmail-send.0 qmail-start.0 splogger.0 \
+qmail-badmimetypes.0 qmail-badloadertypes.0 \
 qmail-queue.0 qmail-inject.0 mailsubj.0 qmail-showctl.0 qmail-newu.0 \
 qmail-pw2u.0 qmail-qread.0 qmail-qstat.0 qmail-tcpto.0 qmail-tcpok.0 \
 qmail-pop3d.0 qmail-popup.0 qmail-qmqpc.0 qmail-qmqpd.0 qmail-qmtpd.0 \
@@ -1107,6 +1178,29 @@
 	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
 	> qmail-control.5
 
+qmail-dk: \
+load qmail-dk.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 \
+str.a fs.a auto_qmail.o auto_split.o auto_uids.o fd.a wait.a \
+$(LIB_DK) env.a getln.a control.o stralloc.a dns.lib
+	./load qmail-dk triggerpull.o fmtqfn.o now.o \
+	date822fmt.o datetime.a seek.a ndelay.a open.a sig.a \
+	substdio.a error.a fs.a auto_qmail.o \
+	auto_split.o auto_uids.o fd.a wait.a \
+	$(LIB_DK) -lcrypto env.a control.o open.a getln.a \
+	stralloc.a alloc.a  scan_ulong.o str.a `cat dns.lib`
+
+qmail-dk.0: \
+qmail-dk.8
+	nroff -man qmail-dk.8 > qmail-dk.0
+
+qmail-dk.o: \
+compile qmail-dk.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 wait.h fd.h fork.h str.h \
+auto_qmail.h auto_uids.h date822fmt.h fmtqfn.h
+	./compile qmail-dk.c
+
 qmail-getpw: \
 load qmail-getpw.o case.a substdio.a error.a str.a fs.a auto_break.o \
 auto_usera.o
@@ -1174,12 +1268,15 @@
 load qmail-local.o qmail.o quote.o now.o gfrom.o myctime.o \
 slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a lock.a fd.a \
 wait.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
-fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib
+fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib maildirquota.o \
+maildirgetquota.o maildiropen.o maildirparsequota.o overmaildirquota.o \
+strtimet.o strpidt.o
 	./load qmail-local qmail.o quote.o now.o gfrom.o myctime.o \
 	slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a \
 	lock.a fd.a wait.a env.a stralloc.a alloc.a strerr.a \
 	substdio.a error.a str.a fs.a datetime.a auto_qmail.o \
-	auto_patrn.o  `cat socket.lib`
+	auto_patrn.o  `cat socket.lib` maildirquota.o maildirgetquota.o \
+    maildiropen.o maildirparsequota.o overmaildirquota.o strtimet.o strpidt.o
 
 qmail-local.0: \
 qmail-local.8
@@ -1216,6 +1313,56 @@
 slurpclose.h auto_qmail.h auto_uids.h qlx.h
 	./compile qmail-lspawn.c
 
+qmail-badmimetypes: \
+load qmail-badmimetypes.o cdbmss.o getln.a open.a cdbmake.a seek.a case.a \
+stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o
+	./load qmail-badmimetypes cdbmss.o getln.a open.a cdbmake.a \
+	seek.a case.a stralloc.a alloc.a strerr.a substdio.a \
+	error.a str.a auto_qmail.o 
+
+qmail-badmimetypes.0: \
+qmail-badmimetypes.8
+	nroff -man qmail-badmimetypes.8 > qmail-badmimetypes.0
+
+qmail-badmimetypes.8: \
+qmail-badmimetypes.9 conf-break conf-spawn
+	cat qmail-badmimetypes.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-badmimetypes.8
+
+qmail-badmimetypes.o: \
+compile qmail-badmimetypes.c strerr.h stralloc.h gen_alloc.h substdio.h \
+getln.h exit.h readwrite.h open.h auto_qmail.h cdbmss.h cdbmake.h \
+uint32.h substdio.h
+	./compile qmail-badmimetypes.c
+
+qmail-badloadertypes: \
+load qmail-badloadertypes.o cdbmss.o getln.a open.a cdbmake.a seek.a case.a \
+stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o
+	./load qmail-badloadertypes cdbmss.o getln.a open.a cdbmake.a \
+	seek.a case.a stralloc.a alloc.a strerr.a substdio.a \
+	error.a str.a auto_qmail.o
+
+qmail-badloadertypes.0: \
+qmail-badloadertypes.8
+	nroff -man qmail-badloadertypes.8 > qmail-badloadertypes.0
+
+qmail-badloadertypes.8: \
+qmail-badloadertypes.9 conf-break conf-spawn
+	cat qmail-badloadertypes.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-badloadertypes.8
+
+qmail-badloadertypes.o: \
+compile qmail-badloadertypes.c strerr.h stralloc.h gen_alloc.h substdio.h \
+getln.h exit.h readwrite.h open.h auto_qmail.h cdbmss.h cdbmake.h \
+uint32.h substdio.h
+	./compile qmail-badloadertypes.c
+
 qmail-newmrh: \
 load qmail-newmrh.o cdbmss.o getln.a open.a cdbmake.a seek.a case.a \
 stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o
@@ -1269,11 +1416,13 @@
 qmail-pop3d: \
 load qmail-pop3d.o commands.o case.a timeoutread.o timeoutwrite.o \
 maildir.o prioq.o now.o env.a strerr.a sig.a open.a getln.a \
-stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib
+stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib maildirquota.o \
+maildirparsequota.o maildirflags.o maildiropen.o strtimet.o strpidt.o
 	./load qmail-pop3d commands.o case.a timeoutread.o \
 	timeoutwrite.o maildir.o prioq.o now.o env.a strerr.a sig.a \
 	open.a getln.a stralloc.a alloc.a substdio.a error.a str.a \
-	fs.a  `cat socket.lib`
+	fs.a  `cat socket.lib` maildirquota.o maildirgetquota.o \
+    maildirparsequota.o maildirflags.o maildiropen.o strtimet.o strpidt.o
 
 qmail-pop3d.0: \
 qmail-pop3d.8
@@ -1419,13 +1568,14 @@
 	nroff -man qmail-qstat.8 > qmail-qstat.0
 
 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 \
-str.a fs.a auto_qmail.o auto_split.o auto_uids.o
+load qmail-queue.o triggerpull.o fmtqfn.o now.o date822fmt.o qregex.o \
+datetime.a seek.a case.a ndelay.a open.a sig.a getln.a stralloc.a alloc.a \
+substdio.a error.a control.o constmap.o 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 \
-	alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
-	auto_split.o auto_uids.o 
+	date822fmt.o qregex.o control.o constmap.o datetime.a case.a seek.a \
+	ndelay.a open.a sig.a getln.a stralloc.a alloc.a substdio.a error.a \
+	str.a fs.a auto_qmail.o auto_split.o auto_uids.o 
 
 qmail-queue.0: \
 qmail-queue.8
@@ -1439,14 +1589,15 @@
 
 qmail-remote: \
 load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \
-timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o \
+timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o strsalloc.o ipme.o quote.o \
 ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \
-substdio.a error.a str.a fs.a auto_qmail.o dns.lib socket.lib
+substdio.a error.a str.a fs.a auto_qmail.o base64.o dns.lib socket.lib
 	./load qmail-remote control.o constmap.o timeoutread.o \
 	timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \
-	ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
+	tls.o ssl_timeoutio.o -L/usr/local/ssl/lib -lssl -lcrypto \
+	ipalloc.o strsalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
 	lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \
-	str.a fs.a auto_qmail.o  `cat dns.lib` `cat socket.lib`
+	str.a fs.a auto_qmail.o base64.o `cat dns.lib` `cat socket.lib`
 
 qmail-remote.0: \
 qmail-remote.8
@@ -1455,7 +1606,7 @@
 qmail-remote.o: \
 compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h \
 subfd.h substdio.h scan.h case.h error.h auto_qmail.h control.h dns.h \
-alloc.h quote.h ip.h ipalloc.h ip.h gen_alloc.h ipme.h ip.h ipalloc.h \
+alloc.h quote.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ipme.h ip.h ipalloc.h strsalloc.h \
 gen_alloc.h gen_allocdefs.h str.h now.h datetime.h exit.h constmap.h \
 tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h
 	./compile qmail-remote.c
@@ -1483,12 +1634,12 @@
 trigger.o fmtqfn.o quote.o now.o readsubdir.o qmail.o date822fmt.o \
 datetime.a case.a ndelay.a getln.a wait.a seek.a fd.a sig.a open.a \
 lock.a stralloc.a alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
-auto_split.o
+auto_split.o env.a
 	./load qmail-send qsutil.o control.o constmap.o newfield.o \
 	prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \
 	qmail.o date822fmt.o datetime.a case.a ndelay.a getln.a \
 	wait.a seek.a fd.a sig.a open.a lock.a stralloc.a alloc.a \
-	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o 
+	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a
 
 qmail-send.0: \
 qmail-send.8
@@ -1528,32 +1679,33 @@
 compile qmail-showctl.c substdio.h subfd.h substdio.h exit.h fmt.h \
 str.h control.h constmap.h stralloc.h gen_alloc.h direntry.h \
 auto_uids.h auto_qmail.h auto_break.h auto_patrn.h auto_spawn.h \
-auto_split.h
+auto_split.h spf.h
 	./compile qmail-showctl.c
 
 qmail-smtpd: \
-load qmail-smtpd.o rcpthosts.o commands.o timeoutread.o \
-timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
-date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
-open.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a str.a \
-fs.a auto_qmail.o socket.lib
-	./load qmail-smtpd rcpthosts.o commands.o timeoutread.o \
-	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
-	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
+load qmail-smtpd.o rcpthosts.o qregex.o commands.o timeoutread.o \
+timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o constmap.o received.o \
+date822fmt.o now.o qmail.o spf.o dns.o cdb.a fd.a wait.a datetime.a getln.a \
+open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
+fs.a lock.a auto_qmail.o base64.o socket.lib $(SMTPD_CHKUSER_OBJ) dns.lib
+	./load qmail-smtpd $(SMTPD_CHKUSER_OBJ) qregex.o rcpthosts.o commands.o timeoutread.o \
+	timeoutwrite.o ip.o ipme.o ipalloc.o strsalloc.o control.o constmap.o \
+	tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
+	received.o date822fmt.o now.o qmail.o spf.o cdb.a fd.a wait.a \
 	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
-	alloc.a substdio.a error.a str.a fs.a auto_qmail.o  `cat \
-	socket.lib`
+	alloc.a strerr.a substdio.a error.a fs.a auto_qmail.o str.a base64.o \
+	`cat socket.lib dns.lib` dns.o lock.a $(VPOPMAIL_LIBS)
 
 qmail-smtpd.0: \
 qmail-smtpd.8
 	nroff -man qmail-smtpd.8 > qmail-smtpd.0
 
 qmail-smtpd.o: \
-compile qmail-smtpd.c sig.h readwrite.h stralloc.h gen_alloc.h \
+compile qmail-smtpd.c chkuser.h sig.h readwrite.h stralloc.h gen_alloc.h \
 substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
-error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \
+error.h ipme.h ip.h ipalloc.h strsalloc.h ip.h gen_alloc.h ip.h qmail.h \
 substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
-exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h
+exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h spf.h base64.h
 	./compile qmail-smtpd.c
 
 qmail-start: \
@@ -1681,6 +1833,10 @@
 constmap.h stralloc.h gen_alloc.h rcpthosts.h
 	./compile rcpthosts.c
 
+qregex.o: \
+compile qregex.c qregex.h
+	./compile qregex.c
+
 readsubdir.o: \
 compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \
 auto_split.h
@@ -1767,6 +1923,7 @@
 maildirwatch.1 mailsubj.1 mbox.5 preline.1 qbiff.1 qmail-clean.8 \
 qmail-command.8 qmail-control.9 qmail-getpw.9 qmail-header.5 \
 qmail-inject.8 qmail-limits.9 qmail-local.8 qmail-log.5 \
+qmail-badmimetypes.9 qmail-badloadertypes.9 \
 qmail-lspawn.8 qmail-newmrh.9 qmail-newu.9 qmail-pop3d.8 \
 qmail-popup.8 qmail-pw2u.9 qmail-qmqpc.8 qmail-qmqpd.8 qmail-qmtpd.8 \
 qmail-qread.8 qmail-qstat.8 qmail-queue.8 qmail-remote.8 \
@@ -1774,12 +1931,13 @@
 qmail-start.9 qmail-tcpok.8 qmail-tcpto.8 qmail-users.9 qmail.7 \
 qreceipt.1 splogger.8 tcp-env.1 config.sh config-fast.sh \
 qmail-clean.c qmail-getpw.c qmail-inject.c qmail-local.c \
+qmail-badmimetypes.c qmail-badloadertypes.c \
 qmail-lspawn.c qmail-newmrh.c qmail-newu.c qmail-pop3d.c \
 qmail-popup.c qmail-pw2u.c qmail-qmqpc.c qmail-qmqpd.c qmail-qmtpd.c \
 qmail-qread.c qmail-qstat.sh qmail-queue.c qmail-remote.c \
 qmail-rspawn.c qmail-send.c qmail-showctl.c qmail-smtpd.c \
 qmail-start.c qmail-tcpok.c qmail-tcpto.c spawn.c dnscname.c dnsfq.c \
-dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c tcp-env.c \
+dnsip.c dnsmxip.c dnsptr.c dnstxt.c hostname.c ipmeprint.c tcp-env.c \
 sendmail.c qreceipt.c qsmhook.c qbiff.c forward.c preline.c predate.c \
 except.c bouncesaying.c condredirect.c maildirmake.c maildir2mbox.c \
 maildirwatch.c splogger.c qail.sh elq.sh pinq.sh qmail-upq.sh \
@@ -1813,8 +1971,9 @@
 trywaitp.c sig.h sig_alarm.c sig_block.c sig_catch.c sig_pause.c \
 sig_pipe.c sig_child.c sig_term.c sig_hup.c sig_misc.c sig_bug.c \
 trysgact.c trysgprm.c env.3 env.h env.c envread.c byte.h byte_chr.c \
-byte_copy.c byte_cr.c byte_diff.c byte_rchr.c byte_zero.c str.h \
-str_chr.c str_cpy.c str_diff.c str_diffn.c str_len.c str_rchr.c \
+byte_copy.c byte_cr.c byte_cspn.c byte_diff.c byte_rchr.c byte_rcspn.c \
+byte_zero.c str.h spf.c spf.h spfquery.c \
+str_chr.c str_cpy.c str_cpyb.c str_diff.c str_diffn.c str_len.c str_rchr.c \
 str_start.c lock.h lock_ex.c lock_exnb.c lock_un.c tryflock.c getln.3 \
 getln.h getln.c getln2.3 getln2.c sgetopt.3 sgetopt.h sgetopt.c \
 subgetopt.3 subgetopt.h subgetopt.c error.3 error_str.3 error_temp.3 \
@@ -1824,10 +1983,11 @@
 headerbody.h headerbody.c token822.h token822.c control.h control.c \
 datetime.3 datetime.h datetime.c datetime_un.c prioq.h prioq.c \
 date822fmt.h date822fmt.c dns.h dns.c trylsock.c tryrsolv.c ip.h ip.c \
-ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \
+ipalloc.h strsalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \
 ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \
 prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \
-maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c
+maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c \
+update_tmprsadh
 	shar -m `cat FILES` > shar
 	chmod 400 shar
 
@@ -1892,11 +2052,28 @@
 
 spawn.o: \
 compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \
-stralloc.h gen_alloc.h select.h exit.h coe.h open.h error.h \
+stralloc.h gen_alloc.h select.h exit.h alloc.h coe.h open.h error.h \
 auto_qmail.h auto_uids.h auto_spawn.h
 	./chkspawn
 	./compile spawn.c
 
+spf.o: \
+compile spf.c stralloc.h gen_alloc.h alloc.h ipme.h ip.h ipalloc.h \
+strsalloc.h str.h fmt.h scan.h byte.h now.h case.h
+	./compile spf.c
+
+spfquery: \
+load spfquery.o spf.o ip.o ipme.o ipalloc.o strsalloc.o now.o dns.o \
+datetime.a stralloc.a alloc.a str.a substdio.a error.a fs.a case.a dns.lib
+	./load spfquery spf.o ip.o ipme.o ipalloc.o strsalloc.o \
+	now.o dns.o datetime.a stralloc.a alloc.a str.a substdio.a \
+	case.a error.a fs.a `cat dns.lib` `cat socket.lib`
+
+spfquery.o: \
+compile spfquery.c substdio.h subfd.h stralloc.h gen_alloc.h alloc.h \
+spf.h exit.h
+	./compile spfquery.c
+
 splogger: \
 load splogger.o substdio.a error.a str.a fs.a syslog.lib socket.lib
 	./load splogger substdio.a error.a str.a fs.a  `cat \
@@ -1912,12 +2089,12 @@
 	./compile splogger.c
 
 str.a: \
-makelib str_len.o str_diff.o str_diffn.o str_cpy.o str_chr.o \
-str_rchr.o str_start.o byte_chr.o byte_rchr.o byte_diff.o byte_copy.o \
+makelib str_len.o str_diff.o str_diffn.o str_cpy.o str_cpyb.o str_chr.o \
+str_rchr.o str_start.o byte_chr.o byte_rchr.o byte_diff.o byte_copy.o byte_cspn.o byte_rcspn.o \
 byte_cr.o byte_zero.o
-	./makelib str.a str_len.o str_diff.o str_diffn.o str_cpy.o \
-	str_chr.o str_rchr.o str_start.o byte_chr.o byte_rchr.o \
-	byte_diff.o byte_copy.o byte_cr.o byte_zero.o
+	./makelib str.a str_len.o str_diff.o str_diffn.o str_cpy.o str_cpyb.o \
+	str_chr.o str_rchr.o str_start.o byte_chr.o byte_rchr.o byte_cspn.o \
+	byte_rcspn.o byte_diff.o byte_copy.o byte_cr.o byte_zero.o
 
 str_chr.o: \
 compile str_chr.c str.h
@@ -1927,6 +2104,10 @@
 compile str_cpy.c str.h
 	./compile str_cpy.c
 
+str_cpyb.o: \
+compile str_cpyb.c str.h
+	./compile str_cpyb.c
+
 str_diff.o: \
 compile str_diff.c str.h
 	./compile str_diff.c
@@ -2006,6 +2187,11 @@
 compile strerr_sys.c error.h strerr.h
 	./compile strerr_sys.c
 
+strsalloc.o: \
+compile strsalloc.c alloc.h gen_allocdefs.h stralloc.h strsalloc.h \
+gen_alloc.h
+	./compile strsalloc.c
+
 subfderr.o: \
 compile subfderr.c readwrite.h substdio.h subfd.h substdio.h
 	./compile subfderr.c
@@ -2066,10 +2252,10 @@
 
 tcp-env: \
 load tcp-env.o dns.o remoteinfo.o timeoutread.o timeoutwrite.o \
-timeoutconn.o ip.o ipalloc.o case.a ndelay.a sig.a env.a getopt.a \
+timeoutconn.o ip.o ipalloc.o strsalloc.o case.a ndelay.a sig.a env.a getopt.a \
 stralloc.a alloc.a substdio.a error.a str.a fs.a dns.lib socket.lib
 	./load tcp-env dns.o remoteinfo.o timeoutread.o \
-	timeoutwrite.o timeoutconn.o ip.o ipalloc.o case.a ndelay.a \
+	timeoutwrite.o timeoutconn.o ip.o ipalloc.o strsalloc.o case.a ndelay.a \
 	sig.a env.a getopt.a stralloc.a alloc.a substdio.a error.a \
 	str.a fs.a  `cat dns.lib` `cat socket.lib`
 
@@ -2108,6 +2294,19 @@
 compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h
 	./compile timeoutwrite.c
 
+qmail-smtpd: tls.o ssl_timeoutio.o ndelay.a
+qmail-remote: tls.o ssl_timeoutio.o
+qmail-smtpd.o: tls.h ssl_timeoutio.h
+qmail-remote.o: tls.h ssl_timeoutio.h
+
+tls.o: \
+compile tls.c exit.h error.h
+	./compile tls.c
+
+ssl_timeoutio.o: \
+compile ssl_timeoutio.c ssl_timeoutio.h select.h error.h ndelay.h
+	./compile ssl_timeoutio.c
+
 token822.o: \
 compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \
 gen_alloc.h gen_allocdefs.h
@@ -2139,3 +2338,26 @@
 wait_pid.o: \
 compile wait_pid.c error.h haswaitp.h
 	./compile wait_pid.c
+
+cert cert-req: \
+Makefile-cert
+	@$(MAKE) -sf $< $@
+
+Makefile-cert: \
+conf-qmail conf-users conf-groups Makefile-cert.mk
+	@cat Makefile-cert.mk \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> $@
+
+update_tmprsadh: \
+conf-qmail conf-users conf-groups update_tmprsadh.sh
+	@cat update_tmprsadh.sh\
+	| sed s}UGQMAILD}"`head -2 conf-users|tail -1`:`head -1 conf-groups`"}g \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> $@
+	chmod 755 update_tmprsadh 
+
+tmprsadh: \
+update_tmprsadh
+	echo "Creating new temporary RSA and DH parameters"
+	./update_tmprsadh
diff -Naur ./Makefile-cert.mk ../qmail-1.03-build-10/Makefile-cert.mk
--- ./Makefile-cert.mk	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/Makefile-cert.mk	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,21 @@
+cert-req: req.pem
+cert cert-req: QMAIL/control/clientcert.pem
+	@:
+
+QMAIL/control/clientcert.pem: QMAIL/control/servercert.pem
+	ln -s $< $@
+
+QMAIL/control/servercert.pem:
+	PATH=$$PATH:/usr/local/ssl/bin \
+		openssl req -new -x509 -nodes -days 366 -out $@ -keyout $@
+	chmod 640 $@
+	chown `head -2 conf-users | tail -1`:`head -1 conf-groups` $@
+
+req.pem:
+	PATH=$$PATH:/usr/local/ssl/bin openssl req \
+		-new -nodes -out $@ -keyout QMAIL/control/servercert.pem
+	chmod 640 QMAIL/control/servercert.pem
+	chown `head -2 conf-users | tail -1`:`head -1 conf-groups` QMAIL/control/servercert.pem
+	@echo
+	@echo "Send req.pem to your CA to obtain signed_req.pem, and do:"
+	@echo "cat signed_req.pem >> QMAIL/control/servercert.pem"
diff -Naur ./Makefile.orig ../qmail-1.03-build-10/Makefile.orig
--- ./Makefile.orig	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/Makefile.orig	2006-04-27 13:19:48.000000000 -0500
@@ -0,0 +1,2197 @@
+# Don't edit Makefile! Use conf-* for configuration.
+
+VPOPMAIL_HOME=/home/vpopmail
+SMTPD_CHKUSER_OBJ=chkuser.o dns.o
+VPOPMAIL_LIBS=`head -1 $(VPOPMAIL_HOME)/etc/lib_deps` `cat dns.lib`
+
+SHELL=/bin/sh
+
+default: it
+
+addresses.0: \
+addresses.5
+	nroff -man addresses.5 > addresses.0
+
+alloc.a: \
+makelib alloc.o alloc_re.o
+	./makelib alloc.a alloc.o alloc_re.o
+
+alloc.o: \
+compile alloc.c alloc.h error.h
+	./compile alloc.c
+
+alloc_re.o: \
+compile alloc_re.c alloc.h byte.h
+	./compile alloc_re.c
+
+auto-ccld.sh: \
+conf-cc conf-ld warn-auto.sh
+	( cat warn-auto.sh; \
+	echo CC=\'`head -1 conf-cc`\'; \
+	echo LD=\'`head -1 conf-ld`\' \
+	) > auto-ccld.sh
+
+auto-gid: \
+load auto-gid.o substdio.a error.a str.a fs.a
+	./load auto-gid substdio.a error.a str.a fs.a 
+
+auto-gid.o: \
+compile auto-gid.c subfd.h substdio.h substdio.h readwrite.h exit.h \
+scan.h fmt.h
+	./compile auto-gid.c
+
+auto-int: \
+load auto-int.o substdio.a error.a str.a fs.a
+	./load auto-int substdio.a error.a str.a fs.a 
+
+auto-int.o: \
+compile auto-int.c substdio.h readwrite.h exit.h scan.h fmt.h
+	./compile auto-int.c
+
+auto-int8: \
+load auto-int8.o substdio.a error.a str.a fs.a
+	./load auto-int8 substdio.a error.a str.a fs.a 
+
+auto-int8.o: \
+compile auto-int8.c substdio.h readwrite.h exit.h scan.h fmt.h
+	./compile auto-int8.c
+
+auto-str: \
+load auto-str.o substdio.a error.a str.a
+	./load auto-str substdio.a error.a str.a 
+
+auto-str.o: \
+compile auto-str.c substdio.h readwrite.h exit.h
+	./compile auto-str.c
+
+auto-uid: \
+load auto-uid.o substdio.a error.a str.a fs.a
+	./load auto-uid substdio.a error.a str.a fs.a 
+
+auto-uid.o: \
+compile auto-uid.c subfd.h substdio.h substdio.h readwrite.h exit.h \
+scan.h fmt.h
+	./compile auto-uid.c
+
+auto_break.c: \
+auto-str conf-break
+	./auto-str auto_break \
+	"`head -1 conf-break`" > auto_break.c
+
+auto_break.o: \
+compile auto_break.c
+	./compile auto_break.c
+
+auto_patrn.c: \
+auto-int8 conf-patrn
+	./auto-int8 auto_patrn `head -1 conf-patrn` > auto_patrn.c
+
+auto_patrn.o: \
+compile auto_patrn.c
+	./compile auto_patrn.c
+
+auto_qmail.c: \
+auto-str conf-qmail
+	./auto-str auto_qmail `head -1 conf-qmail` > auto_qmail.c
+
+auto_qmail.o: \
+compile auto_qmail.c
+	./compile auto_qmail.c
+
+auto_spawn.c: \
+auto-int conf-spawn
+	./auto-int auto_spawn `head -1 conf-spawn` > auto_spawn.c
+
+auto_spawn.o: \
+compile auto_spawn.c
+	./compile auto_spawn.c
+
+auto_split.c: \
+auto-int conf-split
+	./auto-int auto_split `head -1 conf-split` > auto_split.c
+
+auto_split.o: \
+compile auto_split.c
+	./compile auto_split.c
+
+auto_uids.c: \
+auto-uid auto-gid conf-users conf-groups
+	( ./auto-uid auto_uida `head -1 conf-users` \
+	&&./auto-uid auto_uidd `head -2 conf-users | tail -1` \
+	&&./auto-uid auto_uidl `head -3 conf-users | tail -1` \
+	&&./auto-uid auto_uido `head -4 conf-users | tail -1` \
+	&&./auto-uid auto_uidp `head -5 conf-users | tail -1` \
+	&&./auto-uid auto_uidq `head -6 conf-users | tail -1` \
+	&&./auto-uid auto_uidr `head -7 conf-users | tail -1` \
+	&&./auto-uid auto_uids `head -8 conf-users | tail -1` \
+	&&./auto-gid auto_gidq `head -1 conf-groups` \
+	&&./auto-gid auto_gidn `head -2 conf-groups | tail -1` \
+	) > auto_uids.c.tmp && mv auto_uids.c.tmp auto_uids.c
+
+auto_uids.o: \
+compile auto_uids.c
+	./compile auto_uids.c
+
+auto_usera.c: \
+auto-str conf-users
+	./auto-str auto_usera `head -1 conf-users` > auto_usera.c
+
+auto_usera.o: \
+compile auto_usera.c
+	./compile auto_usera.c
+
+base64.o: \
+compile base64.c base64.h stralloc.h substdio.h str.h
+	./compile base64.c
+
+binm1: \
+binm1.sh conf-qmail
+	cat binm1.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> binm1
+	chmod 755 binm1
+
+binm1+df: \
+binm1+df.sh conf-qmail
+	cat binm1+df.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> binm1+df
+	chmod 755 binm1+df
+
+binm2: \
+binm2.sh conf-qmail
+	cat binm2.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> binm2
+	chmod 755 binm2
+
+binm2+df: \
+binm2+df.sh conf-qmail
+	cat binm2+df.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> binm2+df
+	chmod 755 binm2+df
+
+binm3: \
+binm3.sh conf-qmail
+	cat binm3.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> binm3
+	chmod 755 binm3
+
+binm3+df: \
+binm3+df.sh conf-qmail
+	cat binm3+df.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> binm3+df
+	chmod 755 binm3+df
+
+bouncesaying: \
+load bouncesaying.o strerr.a error.a substdio.a str.a wait.a
+	./load bouncesaying strerr.a error.a substdio.a str.a \
+	wait.a 
+
+bouncesaying.0: \
+bouncesaying.1
+	nroff -man bouncesaying.1 > bouncesaying.0
+
+bouncesaying.o: \
+compile bouncesaying.c fork.h strerr.h error.h wait.h sig.h exit.h
+	./compile bouncesaying.c
+
+byte_chr.o: \
+compile byte_chr.c byte.h
+	./compile byte_chr.c
+
+byte_copy.o: \
+compile byte_copy.c byte.h
+	./compile byte_copy.c
+
+byte_cr.o: \
+compile byte_cr.c byte.h
+	./compile byte_cr.c
+
+byte_diff.o: \
+compile byte_diff.c byte.h
+	./compile byte_diff.c
+
+byte_rchr.o: \
+compile byte_rchr.c byte.h
+	./compile byte_rchr.c
+
+byte_zero.o: \
+compile byte_zero.c byte.h
+	./compile byte_zero.c
+
+case.a: \
+makelib case_diffb.o case_diffs.o case_lowerb.o case_lowers.o \
+case_starts.o
+	./makelib case.a case_diffb.o case_diffs.o case_lowerb.o \
+	case_lowers.o case_starts.o
+
+case_diffb.o: \
+compile case_diffb.c case.h
+	./compile case_diffb.c
+
+case_diffs.o: \
+compile case_diffs.c case.h
+	./compile case_diffs.c
+
+case_lowerb.o: \
+compile case_lowerb.c case.h
+	./compile case_lowerb.c
+
+case_lowers.o: \
+compile case_lowers.c case.h
+	./compile case_lowers.c
+
+case_starts.o: \
+compile case_starts.c case.h
+	./compile case_starts.c
+
+cdb.a: \
+makelib cdb_hash.o cdb_unpack.o cdb_seek.o
+	./makelib cdb.a cdb_hash.o cdb_unpack.o cdb_seek.o
+
+cdb_hash.o: \
+compile cdb_hash.c cdb.h uint32.h
+	./compile cdb_hash.c
+
+cdb_seek.o: \
+compile cdb_seek.c cdb.h uint32.h
+	./compile cdb_seek.c
+
+cdb_unpack.o: \
+compile cdb_unpack.c cdb.h uint32.h
+	./compile cdb_unpack.c
+
+cdbmake.a: \
+makelib cdbmake_pack.o cdbmake_hash.o cdbmake_add.o
+	./makelib cdbmake.a cdbmake_pack.o cdbmake_hash.o \
+	cdbmake_add.o
+
+cdbmake_add.o: \
+compile cdbmake_add.c cdbmake.h alloc.h uint32.h
+	./compile cdbmake_add.c
+
+cdbmake_hash.o: \
+compile cdbmake_hash.c cdbmake.h uint32.h
+	./compile cdbmake_hash.c
+
+cdbmake_pack.o: \
+compile cdbmake_pack.c cdbmake.h uint32.h
+	./compile cdbmake_pack.c
+
+cdbmss.o: \
+compile cdbmss.c readwrite.h seek.h alloc.h cdbmss.h cdbmake.h \
+uint32.h substdio.h
+	./compile cdbmss.c
+
+check: \
+it man
+	./instcheck
+
+chkshsgr: \
+load chkshsgr.o
+	./load chkshsgr 
+
+chkshsgr.o: \
+compile chkshsgr.c exit.h
+	./compile chkshsgr.c
+
+chkspawn: \
+load chkspawn.o substdio.a error.a str.a fs.a auto_spawn.o
+	./load chkspawn substdio.a error.a str.a fs.a auto_spawn.o 
+
+chkspawn.o: \
+compile chkspawn.c substdio.h subfd.h substdio.h fmt.h select.h \
+exit.h auto_spawn.h
+	./compile chkspawn.c
+
+chkuser.o: \
+compile chkuser.c chkuser.h chkuser_settings.h
+	./compile chkuser.c
+
+clean: \
+TARGETS
+	rm -f `cat TARGETS`
+
+coe.o: \
+compile coe.c coe.h
+	./compile coe.c
+
+commands.o: \
+compile commands.c commands.h substdio.h stralloc.h gen_alloc.h str.h \
+case.h
+	./compile commands.c
+
+compile: \
+make-compile warn-auto.sh systype
+	( cat warn-auto.sh; ./make-compile "`cat systype`" ) > \
+	compile
+	chmod 755 compile
+
+condredirect: \
+load condredirect.o qmail.o strerr.a fd.a sig.a wait.a seek.a env.a \
+substdio.a error.a str.a fs.a auto_qmail.o
+	./load condredirect qmail.o strerr.a fd.a sig.a wait.a \
+	seek.a env.a substdio.a error.a str.a fs.a auto_qmail.o 
+
+condredirect.0: \
+condredirect.1
+	nroff -man condredirect.1 > condredirect.0
+
+condredirect.o: \
+compile condredirect.c sig.h readwrite.h exit.h env.h error.h fork.h \
+wait.h seek.h qmail.h substdio.h strerr.h substdio.h fmt.h
+	./compile condredirect.c
+
+config: \
+warn-auto.sh config.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh config.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> config
+	chmod 755 config
+
+config-fast: \
+warn-auto.sh config-fast.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh config-fast.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> config-fast
+	chmod 755 config-fast
+
+constmap.o: \
+compile constmap.c constmap.h alloc.h case.h
+	./compile constmap.c
+
+control.o: \
+compile control.c readwrite.h open.h getln.h stralloc.h gen_alloc.h \
+substdio.h error.h control.h alloc.h scan.h
+	./compile control.c
+
+date822fmt.o: \
+compile date822fmt.c datetime.h fmt.h date822fmt.h
+	./compile date822fmt.c
+
+datemail: \
+warn-auto.sh datemail.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh datemail.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> datemail
+	chmod 755 datemail
+
+datetime.a: \
+makelib datetime.o datetime_un.o
+	./makelib datetime.a datetime.o datetime_un.o
+
+datetime.o: \
+compile datetime.c datetime.h
+	./compile datetime.c
+
+datetime_un.o: \
+compile datetime_un.c datetime.h
+	./compile datetime_un.c
+
+direntry.h: \
+compile trydrent.c direntry.h1 direntry.h2
+	( ./compile trydrent.c >/dev/null 2>&1 \
+	&& cat direntry.h2 || cat direntry.h1 ) > direntry.h
+	rm -f trydrent.o
+
+dns.lib: \
+tryrsolv.c compile load socket.lib dns.o ipalloc.o ip.o stralloc.a \
+alloc.a error.a fs.a str.a
+	( ( ./compile tryrsolv.c && ./load tryrsolv dns.o \
+	ipalloc.o ip.o stralloc.a alloc.a error.a fs.a str.a \
+	-lresolv `cat socket.lib` ) >/dev/null 2>&1 \
+	&& echo -lresolv || exit 0 ) > dns.lib
+	rm -f tryrsolv.o tryrsolv
+
+dns.o: \
+compile dns.c ip.h ipalloc.h ip.h gen_alloc.h fmt.h alloc.h str.h \
+stralloc.h gen_alloc.h dns.h case.h
+	./compile dns.c
+
+dnscname: \
+load dnscname.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load dnscname dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
+	socket.lib`
+
+dnscname.o: \
+compile dnscname.c substdio.h subfd.h substdio.h stralloc.h \
+gen_alloc.h dns.h dnsdoe.h readwrite.h exit.h
+	./compile dnscname.c
+
+dnsdoe.o: \
+compile dnsdoe.c substdio.h subfd.h substdio.h exit.h dns.h dnsdoe.h
+	./compile dnsdoe.c
+
+dnsfq: \
+load dnsfq.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load dnsfq dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
+	socket.lib`
+
+dnsfq.o: \
+compile dnsfq.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \
+dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h exit.h
+	./compile dnsfq.c
+
+dnsip: \
+load dnsip.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load dnsip dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
+	socket.lib`
+
+dnsip.o: \
+compile dnsip.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \
+dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h exit.h
+	./compile dnsip.c
+
+dnsmxip: \
+load dnsmxip.o dns.o dnsdoe.o ip.o ipalloc.o now.o stralloc.a alloc.a \
+substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load dnsmxip dns.o dnsdoe.o ip.o ipalloc.o now.o \
+	stralloc.a alloc.a substdio.a error.a str.a fs.a  `cat \
+	dns.lib` `cat socket.lib`
+
+dnsmxip.o: \
+compile dnsmxip.c substdio.h subfd.h substdio.h stralloc.h \
+gen_alloc.h fmt.h dns.h dnsdoe.h ip.h ipalloc.h ip.h gen_alloc.h \
+now.h datetime.h exit.h
+	./compile dnsmxip.c
+
+dnsptr: \
+load dnsptr.o dns.o dnsdoe.o ip.o ipalloc.o stralloc.a alloc.a \
+substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load dnsptr dns.o dnsdoe.o ip.o ipalloc.o stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a  `cat dns.lib` `cat \
+	socket.lib`
+
+dnsptr.o: \
+compile dnsptr.c substdio.h subfd.h substdio.h stralloc.h gen_alloc.h \
+str.h scan.h dns.h dnsdoe.h ip.h exit.h
+	./compile dnsptr.c
+
+dot-qmail.0: \
+dot-qmail.5
+	nroff -man dot-qmail.5 > dot-qmail.0
+
+dot-qmail.5: \
+dot-qmail.9 conf-break conf-spawn
+	cat dot-qmail.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> dot-qmail.5
+
+elq: \
+warn-auto.sh elq.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh elq.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> elq
+	chmod 755 elq
+
+env.a: \
+makelib env.o envread.o
+	./makelib env.a env.o envread.o
+
+env.o: \
+compile env.c str.h alloc.h env.h
+	./compile env.c
+
+envelopes.0: \
+envelopes.5
+	nroff -man envelopes.5 > envelopes.0
+
+envread.o: \
+compile envread.c env.h str.h
+	./compile envread.c
+
+error.a: \
+makelib error.o error_str.o error_temp.o
+	./makelib error.a error.o error_str.o error_temp.o
+
+error.o: \
+compile error.c error.h
+	./compile error.c
+
+error_str.o: \
+compile error_str.c error.h
+	./compile error_str.c
+
+error_temp.o: \
+compile error_temp.c error.h
+	./compile error_temp.c
+
+except: \
+load except.o strerr.a error.a substdio.a str.a wait.a
+	./load except strerr.a error.a substdio.a str.a wait.a 
+
+except.0: \
+except.1
+	nroff -man except.1 > except.0
+
+except.o: \
+compile except.c fork.h strerr.h wait.h error.h exit.h
+	./compile except.c
+
+fd.a: \
+makelib fd_copy.o fd_move.o
+	./makelib fd.a fd_copy.o fd_move.o
+
+fd_copy.o: \
+compile fd_copy.c fd.h
+	./compile fd_copy.c
+
+fd_move.o: \
+compile fd_move.c fd.h
+	./compile fd_move.c
+
+fifo.o: \
+compile fifo.c hasmkffo.h fifo.h
+	./compile fifo.c
+
+find-systype: \
+find-systype.sh auto-ccld.sh
+	cat auto-ccld.sh find-systype.sh > find-systype
+	chmod 755 find-systype
+
+fmt_str.o: \
+compile fmt_str.c fmt.h
+	./compile fmt_str.c
+
+fmt_strn.o: \
+compile fmt_strn.c fmt.h
+	./compile fmt_strn.c
+
+fmt_uint.o: \
+compile fmt_uint.c fmt.h
+	./compile fmt_uint.c
+
+fmt_uint0.o: \
+compile fmt_uint0.c fmt.h
+	./compile fmt_uint0.c
+
+fmt_ulong.o: \
+compile fmt_ulong.c fmt.h
+	./compile fmt_ulong.c
+
+fmtqfn.o: \
+compile fmtqfn.c fmtqfn.h fmt.h auto_split.h
+	./compile fmtqfn.c
+
+forgeries.0: \
+forgeries.7
+	nroff -man forgeries.7 > forgeries.0
+
+fork.h: \
+compile load tryvfork.c fork.h1 fork.h2
+	( ( ./compile tryvfork.c && ./load tryvfork ) >/dev/null \
+	2>&1 \
+	&& cat fork.h2 || cat fork.h1 ) > fork.h
+	rm -f tryvfork.o tryvfork
+
+forward: \
+load forward.o qmail.o strerr.a alloc.a fd.a wait.a sig.a env.a \
+substdio.a error.a str.a fs.a auto_qmail.o
+	./load forward qmail.o strerr.a alloc.a fd.a wait.a sig.a \
+	env.a substdio.a error.a str.a fs.a auto_qmail.o 
+
+forward.0: \
+forward.1
+	nroff -man forward.1 > forward.0
+
+forward.o: \
+compile forward.c sig.h readwrite.h exit.h env.h qmail.h substdio.h \
+strerr.h substdio.h fmt.h
+	./compile forward.c
+
+fs.a: \
+makelib fmt_str.o fmt_strn.o fmt_uint.o fmt_uint0.o fmt_ulong.o \
+scan_ulong.o scan_8long.o
+	./makelib fs.a fmt_str.o fmt_strn.o fmt_uint.o fmt_uint0.o \
+	fmt_ulong.o scan_ulong.o scan_8long.o
+
+getln.a: \
+makelib getln.o getln2.o
+	./makelib getln.a getln.o getln2.o
+
+getln.o: \
+compile getln.c substdio.h byte.h stralloc.h gen_alloc.h getln.h
+	./compile getln.c
+
+getln2.o: \
+compile getln2.c substdio.h stralloc.h gen_alloc.h byte.h getln.h
+	./compile getln2.c
+
+getopt.a: \
+makelib subgetopt.o sgetopt.o
+	./makelib getopt.a subgetopt.o sgetopt.o
+
+gfrom.o: \
+compile gfrom.c str.h gfrom.h
+	./compile gfrom.c
+
+hasflock.h: \
+tryflock.c compile load
+	( ( ./compile tryflock.c && ./load tryflock ) >/dev/null \
+	2>&1 \
+	&& echo \#define HASFLOCK 1 || exit 0 ) > hasflock.h
+	rm -f tryflock.o tryflock
+
+hasmkffo.h: \
+trymkffo.c compile load
+	( ( ./compile trymkffo.c && ./load trymkffo ) >/dev/null \
+	2>&1 \
+	&& echo \#define HASMKFIFO 1 || exit 0 ) > hasmkffo.h
+	rm -f trymkffo.o trymkffo
+
+hasnpbg1.h: \
+trynpbg1.c compile load open.h open.a fifo.h fifo.o select.h
+	( ( ./compile trynpbg1.c \
+	&& ./load trynpbg1 fifo.o open.a && ./trynpbg1 ) \
+	>/dev/null 2>&1 \
+	&& echo \#define HASNAMEDPIPEBUG1 1 || exit 0 ) > \
+	hasnpbg1.h
+	rm -f trynpbg1.o trynpbg1
+
+hassalen.h: \
+trysalen.c compile
+	( ./compile trysalen.c >/dev/null 2>&1 \
+	&& echo \#define HASSALEN 1 || exit 0 ) > hassalen.h
+	rm -f trysalen.o
+
+hassgact.h: \
+trysgact.c compile load
+	( ( ./compile trysgact.c && ./load trysgact ) >/dev/null \
+	2>&1 \
+	&& echo \#define HASSIGACTION 1 || exit 0 ) > hassgact.h
+	rm -f trysgact.o trysgact
+
+hassgprm.h: \
+trysgprm.c compile load
+	( ( ./compile trysgprm.c && ./load trysgprm ) >/dev/null \
+	2>&1 \
+	&& echo \#define HASSIGPROCMASK 1 || exit 0 ) > hassgprm.h
+	rm -f trysgprm.o trysgprm
+
+hasshsgr.h: \
+chkshsgr warn-shsgr tryshsgr.c compile load
+	./chkshsgr || ( cat warn-shsgr; exit 1 )
+	( ( ./compile tryshsgr.c \
+	&& ./load tryshsgr && ./tryshsgr ) >/dev/null 2>&1 \
+	&& echo \#define HASSHORTSETGROUPS 1 || exit 0 ) > \
+	hasshsgr.h
+	rm -f tryshsgr.o tryshsgr
+
+haswaitp.h: \
+trywaitp.c compile load
+	( ( ./compile trywaitp.c && ./load trywaitp ) >/dev/null \
+	2>&1 \
+	&& echo \#define HASWAITPID 1 || exit 0 ) > haswaitp.h
+	rm -f trywaitp.o trywaitp
+
+headerbody.o: \
+compile headerbody.c stralloc.h gen_alloc.h substdio.h getln.h \
+hfield.h headerbody.h
+	./compile headerbody.c
+
+hfield.o: \
+compile hfield.c hfield.h
+	./compile hfield.c
+
+hier.o: \
+compile hier.c auto_qmail.h auto_split.h auto_uids.h fmt.h fifo.h
+	./compile hier.c
+
+home: \
+home.sh conf-qmail
+	cat home.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> home
+	chmod 755 home
+
+home+df: \
+home+df.sh conf-qmail
+	cat home+df.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> home+df
+	chmod 755 home+df
+
+hostname: \
+load hostname.o substdio.a error.a str.a dns.lib socket.lib
+	./load hostname substdio.a error.a str.a  `cat dns.lib` \
+	`cat socket.lib`
+
+hostname.o: \
+compile hostname.c substdio.h subfd.h substdio.h readwrite.h exit.h
+	./compile hostname.c
+
+idedit: \
+load idedit.o strerr.a substdio.a error.a str.a fs.a wait.a open.a \
+seek.a
+	./load idedit strerr.a substdio.a error.a str.a fs.a \
+	wait.a open.a seek.a 
+
+idedit.o: \
+compile idedit.c readwrite.h exit.h scan.h fmt.h strerr.h open.h \
+seek.h fork.h
+	./compile idedit.c
+
+install: \
+load install.o fifo.o hier.o auto_qmail.o auto_split.o auto_uids.o \
+strerr.a substdio.a open.a error.a str.a fs.a
+	./load install fifo.o hier.o auto_qmail.o auto_split.o \
+	auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a 
+
+install-big: \
+load install-big.o fifo.o install.o auto_qmail.o auto_split.o \
+auto_uids.o strerr.a substdio.a open.a error.a str.a fs.a
+	./load install-big fifo.o install.o auto_qmail.o \
+	auto_split.o auto_uids.o strerr.a substdio.a open.a error.a \
+	str.a fs.a 
+
+install-big.o: \
+compile install-big.c auto_qmail.h auto_split.h auto_uids.h fmt.h \
+fifo.h
+	./compile install-big.c
+
+install.o: \
+compile install.c substdio.h strerr.h error.h open.h readwrite.h \
+exit.h
+	./compile install.c
+
+instcheck: \
+load instcheck.o fifo.o hier.o auto_qmail.o auto_split.o auto_uids.o \
+strerr.a substdio.a error.a str.a fs.a
+	./load instcheck fifo.o hier.o auto_qmail.o auto_split.o \
+	auto_uids.o strerr.a substdio.a error.a str.a fs.a 
+
+instcheck.o: \
+compile instcheck.c strerr.h error.h readwrite.h exit.h
+	./compile instcheck.c
+
+ip.o: \
+compile ip.c fmt.h scan.h ip.h
+	./compile ip.c
+
+ipalloc.o: \
+compile ipalloc.c alloc.h gen_allocdefs.h ip.h ipalloc.h ip.h \
+gen_alloc.h
+	./compile ipalloc.c
+
+ipme.o: \
+compile ipme.c hassalen.h byte.h ip.h ipalloc.h ip.h gen_alloc.h \
+stralloc.h gen_alloc.h ipme.h ip.h ipalloc.h
+	./compile ipme.c
+
+ipmeprint: \
+load ipmeprint.o ipme.o ip.o ipalloc.o stralloc.a alloc.a substdio.a \
+error.a str.a fs.a socket.lib
+	./load ipmeprint ipme.o ip.o ipalloc.o stralloc.a alloc.a \
+	substdio.a error.a str.a fs.a  `cat socket.lib`
+
+ipmeprint.o: \
+compile ipmeprint.c subfd.h substdio.h substdio.h ip.h ipme.h ip.h \
+ipalloc.h ip.h gen_alloc.h exit.h
+	./compile ipmeprint.c
+
+it: \
+qmail-local qmail-lspawn qmail-getpw qmail-remote qmail-rspawn \
+qmail-clean qmail-send qmail-start splogger qmail-queue qmail-inject \
+predate datemail mailsubj qmail-upq qmail-showctl qmail-newu \
+qmail-pw2u qmail-qread qmail-qstat qmail-tcpto qmail-tcpok \
+qmail-pop3d qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd \
+qmail-smtpd sendmail tcp-env qmail-newmrh config config-fast dnscname \
+dnsptr dnsip dnsmxip dnsfq hostname ipmeprint qreceipt qsmhook qbiff \
+forward preline condredirect bouncesaying except maildirmake \
+maildir2mbox maildirwatch qail elq pinq idedit install-big install \
+instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \
+binm3 binm3+df update_tmprsadh
+
+load: \
+make-load warn-auto.sh systype
+	( cat warn-auto.sh; ./make-load "`cat systype`" ) > load
+	chmod 755 load
+
+lock.a: \
+makelib lock_ex.o lock_exnb.o lock_un.o
+	./makelib lock.a lock_ex.o lock_exnb.o lock_un.o
+
+lock_ex.o: \
+compile lock_ex.c hasflock.h lock.h
+	./compile lock_ex.c
+
+lock_exnb.o: \
+compile lock_exnb.c hasflock.h lock.h
+	./compile lock_exnb.c
+
+lock_un.o: \
+compile lock_un.c hasflock.h lock.h
+	./compile lock_un.c
+
+maildir.0: \
+maildir.5
+	nroff -man maildir.5 > maildir.0
+
+maildir.o: \
+compile maildir.c prioq.h datetime.h gen_alloc.h env.h stralloc.h \
+gen_alloc.h direntry.h datetime.h now.h datetime.h str.h maildir.h \
+strerr.h
+	./compile maildir.c
+
+maildir2mbox: \
+load maildir2mbox.o maildir.o prioq.o now.o myctime.o gfrom.o lock.a \
+getln.a env.a open.a strerr.a stralloc.a alloc.a substdio.a error.a \
+str.a fs.a datetime.a
+	./load maildir2mbox maildir.o prioq.o now.o myctime.o \
+	gfrom.o lock.a getln.a env.a open.a strerr.a stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a datetime.a 
+
+maildir2mbox.0: \
+maildir2mbox.1
+	nroff -man maildir2mbox.1 > maildir2mbox.0
+
+maildir2mbox.o: \
+compile maildir2mbox.c readwrite.h prioq.h datetime.h gen_alloc.h \
+env.h stralloc.h gen_alloc.h subfd.h substdio.h substdio.h getln.h \
+error.h open.h lock.h gfrom.h str.h exit.h myctime.h maildir.h \
+strerr.h
+	./compile maildir2mbox.c
+
+maildirmake: \
+load maildirmake.o strerr.a substdio.a error.a str.a
+	./load maildirmake strerr.a substdio.a error.a str.a 
+
+maildirmake.0: \
+maildirmake.1
+	nroff -man maildirmake.1 > maildirmake.0
+
+maildirmake.o: \
+compile maildirmake.c strerr.h exit.h
+	./compile maildirmake.c
+
+maildirwatch: \
+load maildirwatch.o hfield.o headerbody.o maildir.o prioq.o now.o \
+getln.a env.a open.a strerr.a stralloc.a alloc.a substdio.a error.a \
+str.a
+	./load maildirwatch hfield.o headerbody.o maildir.o \
+	prioq.o now.o getln.a env.a open.a strerr.a stralloc.a \
+	alloc.a substdio.a error.a str.a 
+
+maildirwatch.0: \
+maildirwatch.1
+	nroff -man maildirwatch.1 > maildirwatch.0
+
+maildirwatch.o: \
+compile maildirwatch.c getln.h substdio.h subfd.h substdio.h prioq.h \
+datetime.h gen_alloc.h stralloc.h gen_alloc.h str.h exit.h hfield.h \
+readwrite.h open.h headerbody.h maildir.h strerr.h
+	./compile maildirwatch.c
+
+mailsubj: \
+warn-auto.sh mailsubj.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh mailsubj.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> mailsubj
+	chmod 755 mailsubj
+
+mailsubj.0: \
+mailsubj.1
+	nroff -man mailsubj.1 > mailsubj.0
+
+make-compile: \
+make-compile.sh auto-ccld.sh
+	cat auto-ccld.sh make-compile.sh > make-compile
+	chmod 755 make-compile
+
+make-load: \
+make-load.sh auto-ccld.sh
+	cat auto-ccld.sh make-load.sh > make-load
+	chmod 755 make-load
+
+make-makelib: \
+make-makelib.sh auto-ccld.sh
+	cat auto-ccld.sh make-makelib.sh > make-makelib
+	chmod 755 make-makelib
+
+makelib: \
+make-makelib warn-auto.sh systype
+	( cat warn-auto.sh; ./make-makelib "`cat systype`" ) > \
+	makelib
+	chmod 755 makelib
+
+man: \
+qmail-local.0 qmail-lspawn.0 qmail-getpw.0 qmail-remote.0 \
+qmail-rspawn.0 qmail-clean.0 qmail-send.0 qmail-start.0 splogger.0 \
+qmail-queue.0 qmail-inject.0 mailsubj.0 qmail-showctl.0 qmail-newu.0 \
+qmail-pw2u.0 qmail-qread.0 qmail-qstat.0 qmail-tcpto.0 qmail-tcpok.0 \
+qmail-pop3d.0 qmail-popup.0 qmail-qmqpc.0 qmail-qmqpd.0 qmail-qmtpd.0 \
+qmail-smtpd.0 tcp-env.0 qmail-newmrh.0 qreceipt.0 qbiff.0 forward.0 \
+preline.0 condredirect.0 bouncesaying.0 except.0 maildirmake.0 \
+maildir2mbox.0 maildirwatch.0 qmail.0 qmail-limits.0 qmail-log.0 \
+qmail-control.0 qmail-header.0 qmail-users.0 dot-qmail.0 \
+qmail-command.0 tcp-environ.0 maildir.0 mbox.0 addresses.0 \
+envelopes.0 forgeries.0
+
+mbox.0: \
+mbox.5
+	nroff -man mbox.5 > mbox.0
+
+myctime.o: \
+compile myctime.c datetime.h fmt.h myctime.h
+	./compile myctime.c
+
+ndelay.a: \
+makelib ndelay.o ndelay_off.o
+	./makelib ndelay.a ndelay.o ndelay_off.o
+
+ndelay.o: \
+compile ndelay.c ndelay.h
+	./compile ndelay.c
+
+ndelay_off.o: \
+compile ndelay_off.c ndelay.h
+	./compile ndelay_off.c
+
+newfield.o: \
+compile newfield.c fmt.h datetime.h stralloc.h gen_alloc.h \
+date822fmt.h newfield.h stralloc.h
+	./compile newfield.c
+
+now.o: \
+compile now.c datetime.h now.h datetime.h
+	./compile now.c
+
+open.a: \
+makelib open_append.o open_excl.o open_read.o open_trunc.o \
+open_write.o
+	./makelib open.a open_append.o open_excl.o open_read.o \
+	open_trunc.o open_write.o
+
+open_append.o: \
+compile open_append.c open.h
+	./compile open_append.c
+
+open_excl.o: \
+compile open_excl.c open.h
+	./compile open_excl.c
+
+open_read.o: \
+compile open_read.c open.h
+	./compile open_read.c
+
+open_trunc.o: \
+compile open_trunc.c open.h
+	./compile open_trunc.c
+
+open_write.o: \
+compile open_write.c open.h
+	./compile open_write.c
+
+pinq: \
+warn-auto.sh pinq.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh pinq.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> pinq
+	chmod 755 pinq
+
+predate: \
+load predate.o datetime.a strerr.a sig.a fd.a wait.a substdio.a \
+error.a str.a fs.a
+	./load predate datetime.a strerr.a sig.a fd.a wait.a \
+	substdio.a error.a str.a fs.a 
+
+predate.o: \
+compile predate.c datetime.h fork.h wait.h fd.h fmt.h strerr.h \
+substdio.h subfd.h substdio.h readwrite.h exit.h
+	./compile predate.c
+
+preline: \
+load preline.o strerr.a fd.a wait.a sig.a env.a getopt.a substdio.a \
+error.a str.a
+	./load preline strerr.a fd.a wait.a sig.a env.a getopt.a \
+	substdio.a error.a str.a 
+
+preline.0: \
+preline.1
+	nroff -man preline.1 > preline.0
+
+preline.o: \
+compile preline.c fd.h sgetopt.h subgetopt.h readwrite.h strerr.h \
+substdio.h exit.h fork.h wait.h env.h sig.h error.h
+	./compile preline.c
+
+prioq.o: \
+compile prioq.c alloc.h gen_allocdefs.h prioq.h datetime.h \
+gen_alloc.h
+	./compile prioq.c
+
+proc: \
+proc.sh conf-qmail
+	cat proc.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> proc
+	chmod 755 proc
+
+proc+df: \
+proc+df.sh conf-qmail
+	cat proc+df.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> proc+df
+	chmod 755 proc+df
+
+prot.o: \
+compile prot.c hasshsgr.h prot.h
+	./compile prot.c
+
+qail: \
+warn-auto.sh qail.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh qail.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> qail
+	chmod 755 qail
+
+qbiff: \
+load qbiff.o headerbody.o hfield.o getln.a env.a open.a stralloc.a \
+alloc.a substdio.a error.a str.a
+	./load qbiff headerbody.o hfield.o getln.a env.a open.a \
+	stralloc.a alloc.a substdio.a error.a str.a 
+
+qbiff.0: \
+qbiff.1
+	nroff -man qbiff.1 > qbiff.0
+
+qbiff.o: \
+compile qbiff.c readwrite.h stralloc.h gen_alloc.h substdio.h subfd.h \
+substdio.h open.h byte.h str.h headerbody.h hfield.h env.h exit.h
+	./compile qbiff.c
+
+qmail-clean: \
+load qmail-clean.o fmtqfn.o now.o getln.a sig.a stralloc.a alloc.a \
+substdio.a error.a str.a fs.a auto_qmail.o auto_split.o
+	./load qmail-clean fmtqfn.o now.o getln.a sig.a stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
+	auto_split.o 
+
+qmail-clean.0: \
+qmail-clean.8
+	nroff -man qmail-clean.8 > qmail-clean.0
+
+qmail-clean.o: \
+compile qmail-clean.c readwrite.h sig.h now.h datetime.h str.h \
+direntry.h getln.h stralloc.h gen_alloc.h substdio.h subfd.h \
+substdio.h byte.h scan.h fmt.h error.h exit.h fmtqfn.h auto_qmail.h
+	./compile qmail-clean.c
+
+qmail-command.0: \
+qmail-command.8
+	nroff -man qmail-command.8 > qmail-command.0
+
+qmail-control.0: \
+qmail-control.5
+	nroff -man qmail-control.5 > qmail-control.0
+
+qmail-control.5: \
+qmail-control.9 conf-break conf-spawn
+	cat qmail-control.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-control.5
+
+qmail-getpw: \
+load qmail-getpw.o case.a substdio.a error.a str.a fs.a auto_break.o \
+auto_usera.o
+	./load qmail-getpw case.a substdio.a error.a str.a fs.a \
+	auto_break.o auto_usera.o 
+
+qmail-getpw.0: \
+qmail-getpw.8
+	nroff -man qmail-getpw.8 > qmail-getpw.0
+
+qmail-getpw.8: \
+qmail-getpw.9 conf-break conf-spawn
+	cat qmail-getpw.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-getpw.8
+
+qmail-getpw.o: \
+compile qmail-getpw.c readwrite.h substdio.h subfd.h substdio.h \
+error.h exit.h byte.h str.h case.h fmt.h auto_usera.h auto_break.h \
+qlx.h
+	./compile qmail-getpw.c
+
+qmail-header.0: \
+qmail-header.5
+	nroff -man qmail-header.5 > qmail-header.0
+
+qmail-inject: \
+load qmail-inject.o headerbody.o hfield.o newfield.o quote.o now.o \
+control.o date822fmt.o constmap.o qmail.o case.a fd.a wait.a open.a \
+getln.a sig.a getopt.a datetime.a token822.o env.a stralloc.a alloc.a \
+substdio.a error.a str.a fs.a auto_qmail.o
+	./load qmail-inject headerbody.o hfield.o newfield.o \
+	quote.o now.o control.o date822fmt.o constmap.o qmail.o \
+	case.a fd.a wait.a open.a getln.a sig.a getopt.a datetime.a \
+	token822.o env.a stralloc.a alloc.a substdio.a error.a \
+	str.a fs.a auto_qmail.o 
+
+qmail-inject.0: \
+qmail-inject.8
+	nroff -man qmail-inject.8 > qmail-inject.0
+
+qmail-inject.o: \
+compile qmail-inject.c sig.h substdio.h stralloc.h gen_alloc.h \
+subfd.h substdio.h sgetopt.h subgetopt.h getln.h alloc.h str.h fmt.h \
+hfield.h token822.h gen_alloc.h control.h env.h gen_alloc.h \
+gen_allocdefs.h error.h qmail.h substdio.h now.h datetime.h exit.h \
+quote.h headerbody.h auto_qmail.h newfield.h stralloc.h constmap.h
+	./compile qmail-inject.c
+
+qmail-limits.0: \
+qmail-limits.7
+	nroff -man qmail-limits.7 > qmail-limits.0
+
+qmail-limits.7: \
+qmail-limits.9 conf-break conf-spawn
+	cat qmail-limits.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-limits.7
+
+qmail-local: \
+load qmail-local.o qmail.o quote.o now.o gfrom.o myctime.o \
+slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a lock.a fd.a \
+wait.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
+fs.a datetime.a auto_qmail.o auto_patrn.o socket.lib
+	./load qmail-local qmail.o quote.o now.o gfrom.o myctime.o \
+	slurpclose.o case.a getln.a getopt.a sig.a open.a seek.a \
+	lock.a fd.a wait.a env.a stralloc.a alloc.a strerr.a \
+	substdio.a error.a str.a fs.a datetime.a auto_qmail.o \
+	auto_patrn.o  `cat socket.lib`
+
+qmail-local.0: \
+qmail-local.8
+	nroff -man qmail-local.8 > qmail-local.0
+
+qmail-local.o: \
+compile qmail-local.c readwrite.h sig.h env.h byte.h exit.h fork.h \
+open.h wait.h lock.h seek.h substdio.h getln.h strerr.h subfd.h \
+substdio.h sgetopt.h subgetopt.h alloc.h error.h stralloc.h \
+gen_alloc.h fmt.h str.h now.h datetime.h case.h quote.h qmail.h \
+substdio.h slurpclose.h myctime.h gfrom.h auto_patrn.h
+	./compile qmail-local.c
+
+qmail-log.0: \
+qmail-log.5
+	nroff -man qmail-log.5 > qmail-log.0
+
+qmail-lspawn: \
+load qmail-lspawn.o spawn.o prot.o slurpclose.o coe.o sig.a wait.a \
+case.a cdb.a fd.a open.a stralloc.a alloc.a substdio.a error.a str.a \
+fs.a auto_qmail.o auto_uids.o auto_spawn.o
+	./load qmail-lspawn spawn.o prot.o slurpclose.o coe.o \
+	sig.a wait.a case.a cdb.a fd.a open.a stralloc.a alloc.a \
+	substdio.a error.a str.a fs.a auto_qmail.o auto_uids.o \
+	auto_spawn.o 
+
+qmail-lspawn.0: \
+qmail-lspawn.8
+	nroff -man qmail-lspawn.8 > qmail-lspawn.0
+
+qmail-lspawn.o: \
+compile qmail-lspawn.c fd.h wait.h prot.h substdio.h stralloc.h \
+gen_alloc.h scan.h exit.h fork.h error.h cdb.h uint32.h case.h \
+slurpclose.h auto_qmail.h auto_uids.h qlx.h
+	./compile qmail-lspawn.c
+
+qmail-newmrh: \
+load qmail-newmrh.o cdbmss.o getln.a open.a cdbmake.a seek.a case.a \
+stralloc.a alloc.a strerr.a substdio.a error.a str.a auto_qmail.o
+	./load qmail-newmrh cdbmss.o getln.a open.a cdbmake.a \
+	seek.a case.a stralloc.a alloc.a strerr.a substdio.a \
+	error.a str.a auto_qmail.o 
+
+qmail-newmrh.0: \
+qmail-newmrh.8
+	nroff -man qmail-newmrh.8 > qmail-newmrh.0
+
+qmail-newmrh.8: \
+qmail-newmrh.9 conf-break conf-spawn
+	cat qmail-newmrh.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-newmrh.8
+
+qmail-newmrh.o: \
+compile qmail-newmrh.c strerr.h stralloc.h gen_alloc.h substdio.h \
+getln.h exit.h readwrite.h open.h auto_qmail.h cdbmss.h cdbmake.h \
+uint32.h substdio.h
+	./compile qmail-newmrh.c
+
+qmail-newu: \
+load qmail-newu.o cdbmss.o getln.a open.a seek.a cdbmake.a case.a \
+stralloc.a alloc.a substdio.a error.a str.a auto_qmail.o
+	./load qmail-newu cdbmss.o getln.a open.a seek.a cdbmake.a \
+	case.a stralloc.a alloc.a substdio.a error.a str.a \
+	auto_qmail.o 
+
+qmail-newu.0: \
+qmail-newu.8
+	nroff -man qmail-newu.8 > qmail-newu.0
+
+qmail-newu.8: \
+qmail-newu.9 conf-break conf-spawn
+	cat qmail-newu.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-newu.8
+
+qmail-newu.o: \
+compile qmail-newu.c stralloc.h gen_alloc.h subfd.h substdio.h \
+getln.h substdio.h cdbmss.h cdbmake.h uint32.h substdio.h exit.h \
+readwrite.h open.h error.h case.h auto_qmail.h
+	./compile qmail-newu.c
+
+qmail-pop3d: \
+load qmail-pop3d.o commands.o case.a timeoutread.o timeoutwrite.o \
+maildir.o prioq.o now.o env.a strerr.a sig.a open.a getln.a \
+stralloc.a alloc.a substdio.a error.a str.a fs.a socket.lib
+	./load qmail-pop3d commands.o case.a timeoutread.o \
+	timeoutwrite.o maildir.o prioq.o now.o env.a strerr.a sig.a \
+	open.a getln.a stralloc.a alloc.a substdio.a error.a str.a \
+	fs.a  `cat socket.lib`
+
+qmail-pop3d.0: \
+qmail-pop3d.8
+	nroff -man qmail-pop3d.8 > qmail-pop3d.0
+
+qmail-pop3d.o: \
+compile qmail-pop3d.c commands.h sig.h getln.h stralloc.h gen_alloc.h \
+substdio.h alloc.h open.h prioq.h datetime.h gen_alloc.h scan.h fmt.h \
+str.h exit.h maildir.h strerr.h readwrite.h timeoutread.h \
+timeoutwrite.h
+	./compile qmail-pop3d.c
+
+qmail-popup: \
+load qmail-popup.o commands.o timeoutread.o timeoutwrite.o now.o \
+case.a fd.a sig.a wait.a stralloc.a alloc.a substdio.a error.a str.a \
+fs.a socket.lib
+	./load qmail-popup commands.o timeoutread.o timeoutwrite.o \
+	now.o case.a fd.a sig.a wait.a stralloc.a alloc.a \
+	substdio.a error.a str.a fs.a  `cat socket.lib`
+
+qmail-popup.0: \
+qmail-popup.8
+	nroff -man qmail-popup.8 > qmail-popup.0
+
+qmail-popup.o: \
+compile qmail-popup.c commands.h fd.h sig.h stralloc.h gen_alloc.h \
+substdio.h alloc.h wait.h str.h byte.h now.h datetime.h fmt.h exit.h \
+readwrite.h timeoutread.h timeoutwrite.h
+	./compile qmail-popup.c
+
+qmail-pw2u: \
+load qmail-pw2u.o constmap.o control.o open.a getln.a case.a getopt.a \
+stralloc.a alloc.a substdio.a error.a str.a fs.a auto_usera.o \
+auto_break.o auto_qmail.o
+	./load qmail-pw2u constmap.o control.o open.a getln.a \
+	case.a getopt.a stralloc.a alloc.a substdio.a error.a str.a \
+	fs.a auto_usera.o auto_break.o auto_qmail.o 
+
+qmail-pw2u.0: \
+qmail-pw2u.8
+	nroff -man qmail-pw2u.8 > qmail-pw2u.0
+
+qmail-pw2u.8: \
+qmail-pw2u.9 conf-break conf-spawn
+	cat qmail-pw2u.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-pw2u.8
+
+qmail-pw2u.o: \
+compile qmail-pw2u.c substdio.h readwrite.h subfd.h substdio.h \
+sgetopt.h subgetopt.h control.h constmap.h stralloc.h gen_alloc.h \
+fmt.h str.h scan.h open.h error.h getln.h auto_break.h auto_qmail.h \
+auto_usera.h
+	./compile qmail-pw2u.c
+
+qmail-qmqpc: \
+load qmail-qmqpc.o slurpclose.o timeoutread.o timeoutwrite.o \
+timeoutconn.o ip.o control.o auto_qmail.o sig.a ndelay.a open.a \
+getln.a substdio.a stralloc.a alloc.a error.a str.a fs.a socket.lib
+	./load qmail-qmqpc slurpclose.o timeoutread.o \
+	timeoutwrite.o timeoutconn.o ip.o control.o auto_qmail.o \
+	sig.a ndelay.a open.a getln.a substdio.a stralloc.a alloc.a \
+	error.a str.a fs.a  `cat socket.lib`
+
+qmail-qmqpc.0: \
+qmail-qmqpc.8
+	nroff -man qmail-qmqpc.8 > qmail-qmqpc.0
+
+qmail-qmqpc.o: \
+compile qmail-qmqpc.c substdio.h getln.h readwrite.h exit.h \
+stralloc.h gen_alloc.h slurpclose.h error.h sig.h ip.h timeoutconn.h \
+timeoutread.h timeoutwrite.h auto_qmail.h control.h fmt.h
+	./compile qmail-qmqpc.c
+
+qmail-qmqpd: \
+load qmail-qmqpd.o received.o now.o date822fmt.o qmail.o auto_qmail.o \
+env.a substdio.a sig.a error.a wait.a fd.a str.a datetime.a fs.a
+	./load qmail-qmqpd received.o now.o date822fmt.o qmail.o \
+	auto_qmail.o env.a substdio.a sig.a error.a wait.a fd.a \
+	str.a datetime.a fs.a 
+
+qmail-qmqpd.0: \
+qmail-qmqpd.8
+	nroff -man qmail-qmqpd.8 > qmail-qmqpd.0
+
+qmail-qmqpd.o: \
+compile qmail-qmqpd.c auto_qmail.h qmail.h substdio.h received.h \
+sig.h substdio.h readwrite.h exit.h now.h datetime.h fmt.h env.h
+	./compile qmail-qmqpd.c
+
+qmail-qmtpd: \
+load qmail-qmtpd.o rcpthosts.o control.o constmap.o received.o \
+date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a open.a \
+getln.a sig.a case.a env.a stralloc.a alloc.a substdio.a error.a \
+str.a fs.a auto_qmail.o
+	./load qmail-qmtpd rcpthosts.o control.o constmap.o \
+	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
+	datetime.a open.a getln.a sig.a case.a env.a stralloc.a \
+	alloc.a substdio.a error.a str.a fs.a auto_qmail.o 
+
+qmail-qmtpd.0: \
+qmail-qmtpd.8
+	nroff -man qmail-qmtpd.8 > qmail-qmtpd.0
+
+qmail-qmtpd.o: \
+compile qmail-qmtpd.c stralloc.h gen_alloc.h substdio.h qmail.h \
+substdio.h now.h datetime.h str.h fmt.h env.h sig.h rcpthosts.h \
+auto_qmail.h readwrite.h control.h received.h
+	./compile qmail-qmtpd.c
+
+qmail-qread: \
+load qmail-qread.o fmtqfn.o readsubdir.o date822fmt.o datetime.a \
+open.a getln.a stralloc.a alloc.a substdio.a error.a str.a fs.a \
+auto_qmail.o auto_split.o
+	./load qmail-qread fmtqfn.o readsubdir.o date822fmt.o \
+	datetime.a open.a getln.a stralloc.a alloc.a substdio.a \
+	error.a str.a fs.a auto_qmail.o auto_split.o 
+
+qmail-qread.0: \
+qmail-qread.8
+	nroff -man qmail-qread.8 > qmail-qread.0
+
+qmail-qread.o: \
+compile qmail-qread.c stralloc.h gen_alloc.h substdio.h subfd.h \
+substdio.h fmt.h str.h getln.h fmtqfn.h readsubdir.h direntry.h \
+auto_qmail.h open.h datetime.h date822fmt.h readwrite.h error.h \
+exit.h
+	./compile qmail-qread.c
+
+qmail-qstat: \
+warn-auto.sh qmail-qstat.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh qmail-qstat.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> qmail-qstat
+	chmod 755 qmail-qstat
+
+qmail-qstat.0: \
+qmail-qstat.8
+	nroff -man qmail-qstat.8 > qmail-qstat.0
+
+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 \
+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 \
+	alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
+	auto_split.o auto_uids.o 
+
+qmail-queue.0: \
+qmail-queue.8
+	nroff -man qmail-queue.8 > qmail-queue.0
+
+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 \
+auto_qmail.h auto_uids.h date822fmt.h fmtqfn.h
+	./compile qmail-queue.c
+
+qmail-remote: \
+load qmail-remote.o control.o constmap.o timeoutread.o timeoutwrite.o \
+timeoutconn.o tcpto.o now.o dns.o ip.o ipalloc.o ipme.o quote.o \
+ndelay.a case.a sig.a open.a lock.a seek.a getln.a stralloc.a alloc.a \
+substdio.a error.a str.a fs.a auto_qmail.o base64.o dns.lib socket.lib
+	./load qmail-remote control.o constmap.o timeoutread.o \
+	timeoutwrite.o timeoutconn.o tcpto.o now.o dns.o ip.o \
+	tls.o ssl_timeoutio.o -L/usr/local/ssl/lib -lssl -lcrypto \
+	ipalloc.o ipme.o quote.o ndelay.a case.a sig.a open.a \
+	lock.a seek.a getln.a stralloc.a alloc.a substdio.a error.a \
+	str.a fs.a auto_qmail.o base64.o `cat dns.lib` `cat socket.lib`
+
+qmail-remote.0: \
+qmail-remote.8
+	nroff -man qmail-remote.8 > qmail-remote.0
+
+qmail-remote.o: \
+compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h \
+subfd.h substdio.h scan.h case.h error.h auto_qmail.h control.h dns.h \
+alloc.h quote.h ip.h ipalloc.h ip.h gen_alloc.h ipme.h ip.h ipalloc.h \
+gen_alloc.h gen_allocdefs.h str.h now.h datetime.h exit.h constmap.h \
+tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h
+	./compile qmail-remote.c
+
+qmail-rspawn: \
+load qmail-rspawn.o spawn.o tcpto_clean.o now.o coe.o sig.a open.a \
+seek.a lock.a wait.a fd.a stralloc.a alloc.a substdio.a error.a str.a \
+auto_qmail.o auto_uids.o auto_spawn.o
+	./load qmail-rspawn spawn.o tcpto_clean.o now.o coe.o \
+	sig.a open.a seek.a lock.a wait.a fd.a stralloc.a alloc.a \
+	substdio.a error.a str.a auto_qmail.o auto_uids.o \
+	auto_spawn.o 
+
+qmail-rspawn.0: \
+qmail-rspawn.8
+	nroff -man qmail-rspawn.8 > qmail-rspawn.0
+
+qmail-rspawn.o: \
+compile qmail-rspawn.c fd.h wait.h substdio.h exit.h fork.h error.h \
+tcpto.h
+	./compile qmail-rspawn.c
+
+qmail-send: \
+load qmail-send.o qsutil.o control.o constmap.o newfield.o prioq.o \
+trigger.o fmtqfn.o quote.o now.o readsubdir.o qmail.o date822fmt.o \
+datetime.a case.a ndelay.a getln.a wait.a seek.a fd.a sig.a open.a \
+lock.a stralloc.a alloc.a substdio.a error.a str.a fs.a auto_qmail.o \
+auto_split.o env.a
+	./load qmail-send qsutil.o control.o constmap.o newfield.o \
+	prioq.o trigger.o fmtqfn.o quote.o now.o readsubdir.o \
+	qmail.o date822fmt.o datetime.a case.a ndelay.a getln.a \
+	wait.a seek.a fd.a sig.a open.a lock.a stralloc.a alloc.a \
+	substdio.a error.a str.a fs.a auto_qmail.o auto_split.o env.a
+
+qmail-send.0: \
+qmail-send.8
+	nroff -man qmail-send.8 > qmail-send.0
+
+qmail-send.8: \
+qmail-send.9 conf-break conf-spawn
+	cat qmail-send.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-send.8
+
+qmail-send.o: \
+compile qmail-send.c readwrite.h sig.h direntry.h control.h select.h \
+open.h seek.h exit.h lock.h ndelay.h now.h datetime.h getln.h \
+substdio.h alloc.h error.h stralloc.h gen_alloc.h str.h byte.h fmt.h \
+scan.h case.h auto_qmail.h trigger.h newfield.h stralloc.h quote.h \
+qmail.h substdio.h qsutil.h prioq.h datetime.h gen_alloc.h constmap.h \
+fmtqfn.h readsubdir.h direntry.h
+	./compile qmail-send.c
+
+qmail-showctl: \
+load qmail-showctl.o auto_uids.o control.o open.a getln.a stralloc.a \
+alloc.a substdio.a error.a str.a fs.a auto_qmail.o auto_break.o \
+auto_patrn.o auto_spawn.o auto_split.o
+	./load qmail-showctl auto_uids.o control.o open.a getln.a \
+	stralloc.a alloc.a substdio.a error.a str.a fs.a \
+	auto_qmail.o auto_break.o auto_patrn.o auto_spawn.o \
+	auto_split.o 
+
+qmail-showctl.0: \
+qmail-showctl.8
+	nroff -man qmail-showctl.8 > qmail-showctl.0
+
+qmail-showctl.o: \
+compile qmail-showctl.c substdio.h subfd.h substdio.h exit.h fmt.h \
+str.h control.h constmap.h stralloc.h gen_alloc.h direntry.h \
+auto_uids.h auto_qmail.h auto_break.h auto_patrn.h auto_spawn.h \
+auto_split.h
+	./compile qmail-showctl.c
+
+qmail-smtpd: \
+load qmail-smtpd.o rcpthosts.o qregex.o commands.o timeoutread.o \
+timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
+date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
+open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
+fs.a auto_qmail.o base64.o socket.lib $(SMTPD_CHKUSER_OBJ) dns.lib
+	./load qmail-smtpd $(SMTPD_CHKUSER_OBJ) qregex.o rcpthosts.o commands.o timeoutread.o \
+	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
+	tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
+	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
+	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
+	alloc.a strerr.a substdio.a error.a str.a fs.a auto_qmail.o base64.o \
+	 $(VPOPMAIL_LIBS) \
+	`cat socket.lib`
+
+qmail-smtpd.0: \
+qmail-smtpd.8
+	nroff -man qmail-smtpd.8 > qmail-smtpd.0
+
+qmail-smtpd.o: \
+compile qmail-smtpd.c chkuser.h sig.h readwrite.h stralloc.h gen_alloc.h \
+substdio.h alloc.h auto_qmail.h control.h received.h constmap.h \
+error.h ipme.h ip.h ipalloc.h ip.h gen_alloc.h ip.h qmail.h \
+substdio.h str.h fmt.h scan.h byte.h case.h env.h now.h datetime.h \
+exit.h rcpthosts.h timeoutread.h timeoutwrite.h commands.h base64.h
+	./compile qmail-smtpd.c
+
+qmail-start: \
+load qmail-start.o prot.o fd.a auto_uids.o
+	./load qmail-start prot.o fd.a auto_uids.o 
+
+qmail-start.0: \
+qmail-start.8
+	nroff -man qmail-start.8 > qmail-start.0
+
+qmail-start.8: \
+qmail-start.9 conf-break conf-spawn
+	cat qmail-start.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-start.8
+
+qmail-start.o: \
+compile qmail-start.c fd.h prot.h exit.h fork.h auto_uids.h
+	./compile qmail-start.c
+
+qmail-tcpok: \
+load qmail-tcpok.o open.a lock.a strerr.a substdio.a error.a str.a \
+auto_qmail.o
+	./load qmail-tcpok open.a lock.a strerr.a substdio.a \
+	error.a str.a auto_qmail.o 
+
+qmail-tcpok.0: \
+qmail-tcpok.8
+	nroff -man qmail-tcpok.8 > qmail-tcpok.0
+
+qmail-tcpok.o: \
+compile qmail-tcpok.c strerr.h substdio.h lock.h open.h readwrite.h \
+auto_qmail.h exit.h
+	./compile qmail-tcpok.c
+
+qmail-tcpto: \
+load qmail-tcpto.o ip.o now.o open.a lock.a substdio.a error.a str.a \
+fs.a auto_qmail.o
+	./load qmail-tcpto ip.o now.o open.a lock.a substdio.a \
+	error.a str.a fs.a auto_qmail.o 
+
+qmail-tcpto.0: \
+qmail-tcpto.8
+	nroff -man qmail-tcpto.8 > qmail-tcpto.0
+
+qmail-tcpto.o: \
+compile qmail-tcpto.c substdio.h subfd.h substdio.h auto_qmail.h \
+fmt.h ip.h lock.h error.h exit.h datetime.h now.h datetime.h
+	./compile qmail-tcpto.c
+
+qmail-upq: \
+warn-auto.sh qmail-upq.sh conf-qmail conf-break conf-split
+	cat warn-auto.sh qmail-upq.sh \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPLIT}"`head -1 conf-split`"}g \
+	> qmail-upq
+	chmod 755 qmail-upq
+
+qmail-users.0: \
+qmail-users.5
+	nroff -man qmail-users.5 > qmail-users.0
+
+qmail-users.5: \
+qmail-users.9 conf-break conf-spawn
+	cat qmail-users.9 \
+	| sed s}QMAILHOME}"`head -1 conf-qmail`"}g \
+	| sed s}BREAK}"`head -1 conf-break`"}g \
+	| sed s}SPAWN}"`head -1 conf-spawn`"}g \
+	> qmail-users.5
+
+qmail.0: \
+qmail.7
+	nroff -man qmail.7 > qmail.0
+
+qmail.o: \
+compile qmail.c substdio.h readwrite.h wait.h exit.h fork.h fd.h \
+qmail.h substdio.h auto_qmail.h
+	./compile qmail.c
+
+qreceipt: \
+load qreceipt.o headerbody.o hfield.o quote.o token822.o qmail.o \
+getln.a fd.a wait.a sig.a env.a stralloc.a alloc.a substdio.a error.a \
+str.a auto_qmail.o
+	./load qreceipt headerbody.o hfield.o quote.o token822.o \
+	qmail.o getln.a fd.a wait.a sig.a env.a stralloc.a alloc.a \
+	substdio.a error.a str.a auto_qmail.o 
+
+qreceipt.0: \
+qreceipt.1
+	nroff -man qreceipt.1 > qreceipt.0
+
+qreceipt.o: \
+compile qreceipt.c sig.h env.h substdio.h stralloc.h gen_alloc.h \
+subfd.h substdio.h getln.h alloc.h str.h hfield.h token822.h \
+gen_alloc.h error.h gen_alloc.h gen_allocdefs.h headerbody.h exit.h \
+open.h quote.h qmail.h substdio.h
+	./compile qreceipt.c
+
+qsmhook: \
+load qsmhook.o sig.a case.a fd.a wait.a getopt.a env.a stralloc.a \
+alloc.a substdio.a error.a str.a
+	./load qsmhook sig.a case.a fd.a wait.a getopt.a env.a \
+	stralloc.a alloc.a substdio.a error.a str.a 
+
+qsmhook.o: \
+compile qsmhook.c fd.h stralloc.h gen_alloc.h readwrite.h sgetopt.h \
+subgetopt.h wait.h env.h byte.h str.h alloc.h exit.h fork.h case.h \
+subfd.h substdio.h error.h substdio.h sig.h
+	./compile qsmhook.c
+
+qsutil.o: \
+compile qsutil.c stralloc.h gen_alloc.h readwrite.h substdio.h \
+qsutil.h
+	./compile qsutil.c
+
+quote.o: \
+compile quote.c stralloc.h gen_alloc.h str.h quote.h
+	./compile quote.c
+
+rcpthosts.o: \
+compile rcpthosts.c cdb.h uint32.h byte.h open.h error.h control.h \
+constmap.h stralloc.h gen_alloc.h rcpthosts.h
+	./compile rcpthosts.c
+
+qregex.o: \
+compile qregex.c qregex.h
+	./compile qregex.c
+
+readsubdir.o: \
+compile readsubdir.c readsubdir.h direntry.h fmt.h scan.h str.h \
+auto_split.h
+	./compile readsubdir.c
+
+received.o: \
+compile received.c fmt.h qmail.h substdio.h now.h datetime.h \
+datetime.h date822fmt.h received.h
+	./compile received.c
+
+remoteinfo.o: \
+compile remoteinfo.c byte.h substdio.h ip.h fmt.h timeoutconn.h \
+timeoutread.h timeoutwrite.h remoteinfo.h
+	./compile remoteinfo.c
+
+scan_8long.o: \
+compile scan_8long.c scan.h
+	./compile scan_8long.c
+
+scan_ulong.o: \
+compile scan_ulong.c scan.h
+	./compile scan_ulong.c
+
+seek.a: \
+makelib seek_cur.o seek_end.o seek_set.o seek_trunc.o
+	./makelib seek.a seek_cur.o seek_end.o seek_set.o \
+	seek_trunc.o
+
+seek_cur.o: \
+compile seek_cur.c seek.h
+	./compile seek_cur.c
+
+seek_end.o: \
+compile seek_end.c seek.h
+	./compile seek_end.c
+
+seek_set.o: \
+compile seek_set.c seek.h
+	./compile seek_set.c
+
+seek_trunc.o: \
+compile seek_trunc.c seek.h
+	./compile seek_trunc.c
+
+select.h: \
+compile trysysel.c select.h1 select.h2
+	( ./compile trysysel.c >/dev/null 2>&1 \
+	&& cat select.h2 || cat select.h1 ) > select.h
+	rm -f trysysel.o trysysel
+
+sendmail: \
+load sendmail.o env.a getopt.a alloc.a substdio.a error.a str.a \
+auto_qmail.o
+	./load sendmail env.a getopt.a alloc.a substdio.a error.a \
+	str.a auto_qmail.o 
+
+sendmail.o: \
+compile sendmail.c sgetopt.h subgetopt.h substdio.h subfd.h \
+substdio.h alloc.h auto_qmail.h exit.h env.h str.h
+	./compile sendmail.c
+
+setup: \
+it man
+	./install
+
+sgetopt.o: \
+compile sgetopt.c substdio.h subfd.h substdio.h sgetopt.h subgetopt.h \
+subgetopt.h
+	./compile sgetopt.c
+
+shar: \
+FILES BLURB BLURB2 BLURB3 BLURB4 README FAQ INSTALL INSTALL.alias \
+INSTALL.ctl INSTALL.ids INSTALL.maildir INSTALL.mbox INSTALL.vsm \
+REMOVE.sendmail REMOVE.binmail TEST.deliver TEST.receive UPGRADE \
+THOUGHTS TODO THANKS CHANGES SECURITY INTERNALS SENDMAIL \
+PIC.local2alias PIC.local2ext PIC.local2local PIC.local2rem \
+PIC.local2virt PIC.nullclient PIC.relaybad PIC.relaygood \
+PIC.rem2local FILES VERSION SYSDEPS TARGETS Makefile BIN.README \
+BIN.Makefile BIN.setup idedit.c conf-break auto_break.h conf-spawn \
+auto_spawn.h chkspawn.c conf-split auto_split.h conf-patrn \
+auto_patrn.h conf-users conf-groups auto_uids.h auto_usera.h extra.h \
+addresses.5 except.1 bouncesaying.1 condredirect.1 dot-qmail.9 \
+envelopes.5 forgeries.7 forward.1 maildir2mbox.1 maildirmake.1 \
+maildirwatch.1 mailsubj.1 mbox.5 preline.1 qbiff.1 qmail-clean.8 \
+qmail-command.8 qmail-control.9 qmail-getpw.9 qmail-header.5 \
+qmail-inject.8 qmail-limits.9 qmail-local.8 qmail-log.5 \
+qmail-lspawn.8 qmail-newmrh.9 qmail-newu.9 qmail-pop3d.8 \
+qmail-popup.8 qmail-pw2u.9 qmail-qmqpc.8 qmail-qmqpd.8 qmail-qmtpd.8 \
+qmail-qread.8 qmail-qstat.8 qmail-queue.8 qmail-remote.8 \
+qmail-rspawn.8 qmail-send.9 qmail-showctl.8 qmail-smtpd.8 \
+qmail-start.9 qmail-tcpok.8 qmail-tcpto.8 qmail-users.9 qmail.7 \
+qreceipt.1 splogger.8 tcp-env.1 config.sh config-fast.sh \
+qmail-clean.c qmail-getpw.c qmail-inject.c qmail-local.c \
+qmail-lspawn.c qmail-newmrh.c qmail-newu.c qmail-pop3d.c \
+qmail-popup.c qmail-pw2u.c qmail-qmqpc.c qmail-qmqpd.c qmail-qmtpd.c \
+qmail-qread.c qmail-qstat.sh qmail-queue.c qmail-remote.c \
+qmail-rspawn.c qmail-send.c qmail-showctl.c qmail-smtpd.c \
+qmail-start.c qmail-tcpok.c qmail-tcpto.c spawn.c dnscname.c dnsfq.c \
+dnsip.c dnsmxip.c dnsptr.c hostname.c ipmeprint.c tcp-env.c \
+sendmail.c qreceipt.c qsmhook.c qbiff.c forward.c preline.c predate.c \
+except.c bouncesaying.c condredirect.c maildirmake.c maildir2mbox.c \
+maildirwatch.c splogger.c qail.sh elq.sh pinq.sh qmail-upq.sh \
+datemail.sh mailsubj.sh qlx.h rcpthosts.h rcpthosts.c commands.h \
+commands.c dnsdoe.h dnsdoe.c fmtqfn.h fmtqfn.c gfrom.h gfrom.c \
+myctime.h myctime.c newfield.h newfield.c qsutil.h qsutil.c \
+readsubdir.h readsubdir.c received.h received.c tcpto.h tcpto.c \
+tcpto_clean.c trigger.h trigger.c triggerpull.h triggerpull.c \
+trynpbg1.c trysyslog.c conf-cc conf-ld home.sh home+df.sh proc.sh \
+proc+df.sh binm1.sh binm2.sh binm3.sh binm1+df.sh binm2+df.sh \
+binm3+df.sh find-systype.sh make-compile.sh make-load.sh \
+make-makelib.sh trycpp.c warn-auto.sh auto-str.c auto-int.c \
+auto-int8.c auto-gid.c auto-uid.c hier.c install.c instcheck.c \
+install-big.c alloc.3 alloc.h alloc.c alloc_re.c case.3 case.h \
+case_diffb.c case_diffs.c case_lowerb.c case_lowers.c case_starts.c \
+cdb.3 cdb.h cdb_hash.c cdb_seek.c cdb_unpack.c cdbmake.h \
+cdbmake_add.c cdbmake_hash.c cdbmake_pack.c cdbmss.h cdbmss.c coe.3 \
+coe.h coe.c fd.h fd_copy.3 fd_copy.c fd_move.3 fd_move.c fifo_make.3 \
+fifo.h fifo.c trymkffo.c fork.h1 fork.h2 tryvfork.c now.3 now.h now.c \
+open.h open_append.c open_excl.c open_read.c open_trunc.c \
+open_write.c seek.h seek_cur.c seek_end.c seek_set.c seek_trunc.c \
+conf-qmail auto_qmail.h qmail.h qmail.c gen_alloc.h gen_allocdefs.h \
+stralloc.3 stralloc.h stralloc_eady.c stralloc_pend.c stralloc_copy.c \
+stralloc_opyb.c stralloc_opys.c stralloc_cat.c stralloc_catb.c \
+stralloc_cats.c stralloc_arts.c strerr.h strerr_sys.c strerr_die.c \
+substdio.h substdio.c substdi.c substdo.c substdio_copy.c subfd.h \
+subfderr.c subfdouts.c subfdout.c subfdins.c subfdin.c readwrite.h \
+exit.h timeoutconn.h timeoutconn.c timeoutread.h timeoutread.c \
+timeoutwrite.h timeoutwrite.c remoteinfo.h remoteinfo.c uint32.h1 \
+uint32.h2 tryulong32.c wait.3 wait.h wait_pid.c wait_nohang.c \
+trywaitp.c sig.h sig_alarm.c sig_block.c sig_catch.c sig_pause.c \
+sig_pipe.c sig_child.c sig_term.c sig_hup.c sig_misc.c sig_bug.c \
+trysgact.c trysgprm.c env.3 env.h env.c envread.c byte.h byte_chr.c \
+byte_copy.c byte_cr.c byte_diff.c byte_rchr.c byte_zero.c str.h \
+str_chr.c str_cpy.c str_diff.c str_diffn.c str_len.c str_rchr.c \
+str_start.c lock.h lock_ex.c lock_exnb.c lock_un.c tryflock.c getln.3 \
+getln.h getln.c getln2.3 getln2.c sgetopt.3 sgetopt.h sgetopt.c \
+subgetopt.3 subgetopt.h subgetopt.c error.3 error_str.3 error_temp.3 \
+error.h error.c error_str.c error_temp.c fmt.h fmt_str.c fmt_strn.c \
+fmt_uint.c fmt_uint0.c fmt_ulong.c scan.h scan_ulong.c scan_8long.c \
+slurpclose.h slurpclose.c quote.h quote.c hfield.h hfield.c \
+headerbody.h headerbody.c token822.h token822.c control.h control.c \
+datetime.3 datetime.h datetime.c datetime_un.c prioq.h prioq.c \
+date822fmt.h date822fmt.c dns.h dns.c trylsock.c tryrsolv.c ip.h ip.c \
+ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \
+ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \
+prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \
+maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c \
+update_tmprsadh
+	shar -m `cat FILES` > shar
+	chmod 400 shar
+
+sig.a: \
+makelib sig_alarm.o sig_block.o sig_catch.o sig_pause.o sig_pipe.o \
+sig_child.o sig_hup.o sig_term.o sig_bug.o sig_misc.o
+	./makelib sig.a sig_alarm.o sig_block.o sig_catch.o \
+	sig_pause.o sig_pipe.o sig_child.o sig_hup.o sig_term.o \
+	sig_bug.o sig_misc.o
+
+sig_alarm.o: \
+compile sig_alarm.c sig.h
+	./compile sig_alarm.c
+
+sig_block.o: \
+compile sig_block.c sig.h hassgprm.h
+	./compile sig_block.c
+
+sig_bug.o: \
+compile sig_bug.c sig.h
+	./compile sig_bug.c
+
+sig_catch.o: \
+compile sig_catch.c sig.h hassgact.h
+	./compile sig_catch.c
+
+sig_child.o: \
+compile sig_child.c sig.h
+	./compile sig_child.c
+
+sig_hup.o: \
+compile sig_hup.c sig.h
+	./compile sig_hup.c
+
+sig_misc.o: \
+compile sig_misc.c sig.h
+	./compile sig_misc.c
+
+sig_pause.o: \
+compile sig_pause.c sig.h hassgprm.h
+	./compile sig_pause.c
+
+sig_pipe.o: \
+compile sig_pipe.c sig.h
+	./compile sig_pipe.c
+
+sig_term.o: \
+compile sig_term.c sig.h
+	./compile sig_term.c
+
+slurpclose.o: \
+compile slurpclose.c stralloc.h gen_alloc.h readwrite.h slurpclose.h \
+error.h
+	./compile slurpclose.c
+
+socket.lib: \
+trylsock.c compile load
+	( ( ./compile trylsock.c && \
+	./load trylsock -lsocket -lnsl ) >/dev/null 2>&1 \
+	&& echo -lsocket -lnsl || exit 0 ) > socket.lib
+	rm -f trylsock.o trylsock
+
+spawn.o: \
+compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \
+stralloc.h gen_alloc.h select.h exit.h alloc.h coe.h open.h error.h \
+auto_qmail.h auto_uids.h auto_spawn.h
+	./chkspawn
+	./compile spawn.c
+
+splogger: \
+load splogger.o substdio.a error.a str.a fs.a syslog.lib socket.lib
+	./load splogger substdio.a error.a str.a fs.a  `cat \
+	syslog.lib` `cat socket.lib`
+
+splogger.0: \
+splogger.8
+	nroff -man splogger.8 > splogger.0
+
+splogger.o: \
+compile splogger.c error.h substdio.h subfd.h substdio.h exit.h str.h \
+scan.h fmt.h
+	./compile splogger.c
+
+str.a: \
+makelib str_len.o str_diff.o str_diffn.o str_cpy.o str_chr.o \
+str_rchr.o str_start.o byte_chr.o byte_rchr.o byte_diff.o byte_copy.o \
+byte_cr.o byte_zero.o
+	./makelib str.a str_len.o str_diff.o str_diffn.o str_cpy.o \
+	str_chr.o str_rchr.o str_start.o byte_chr.o byte_rchr.o \
+	byte_diff.o byte_copy.o byte_cr.o byte_zero.o
+
+str_chr.o: \
+compile str_chr.c str.h
+	./compile str_chr.c
+
+str_cpy.o: \
+compile str_cpy.c str.h
+	./compile str_cpy.c
+
+str_diff.o: \
+compile str_diff.c str.h
+	./compile str_diff.c
+
+str_diffn.o: \
+compile str_diffn.c str.h
+	./compile str_diffn.c
+
+str_len.o: \
+compile str_len.c str.h
+	./compile str_len.c
+
+str_rchr.o: \
+compile str_rchr.c str.h
+	./compile str_rchr.c
+
+str_start.o: \
+compile str_start.c str.h
+	./compile str_start.c
+
+stralloc.a: \
+makelib stralloc_eady.o stralloc_pend.o stralloc_copy.o \
+stralloc_opys.o stralloc_opyb.o stralloc_cat.o stralloc_cats.o \
+stralloc_catb.o stralloc_arts.o
+	./makelib stralloc.a stralloc_eady.o stralloc_pend.o \
+	stralloc_copy.o stralloc_opys.o stralloc_opyb.o \
+	stralloc_cat.o stralloc_cats.o stralloc_catb.o \
+	stralloc_arts.o
+
+stralloc_arts.o: \
+compile stralloc_arts.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_arts.c
+
+stralloc_cat.o: \
+compile stralloc_cat.c byte.h stralloc.h gen_alloc.h
+	./compile stralloc_cat.c
+
+stralloc_catb.o: \
+compile stralloc_catb.c stralloc.h gen_alloc.h byte.h
+	./compile stralloc_catb.c
+
+stralloc_cats.o: \
+compile stralloc_cats.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_cats.c
+
+stralloc_copy.o: \
+compile stralloc_copy.c byte.h stralloc.h gen_alloc.h
+	./compile stralloc_copy.c
+
+stralloc_eady.o: \
+compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \
+gen_allocdefs.h
+	./compile stralloc_eady.c
+
+stralloc_opyb.o: \
+compile stralloc_opyb.c stralloc.h gen_alloc.h byte.h
+	./compile stralloc_opyb.c
+
+stralloc_opys.o: \
+compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h
+	./compile stralloc_opys.c
+
+stralloc_pend.o: \
+compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \
+gen_allocdefs.h
+	./compile stralloc_pend.c
+
+strerr.a: \
+makelib strerr_sys.o strerr_die.o
+	./makelib strerr.a strerr_sys.o strerr_die.o
+
+strerr_die.o: \
+compile strerr_die.c substdio.h subfd.h substdio.h exit.h strerr.h
+	./compile strerr_die.c
+
+strerr_sys.o: \
+compile strerr_sys.c error.h strerr.h
+	./compile strerr_sys.c
+
+subfderr.o: \
+compile subfderr.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfderr.c
+
+subfdin.o: \
+compile subfdin.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdin.c
+
+subfdins.o: \
+compile subfdins.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdins.c
+
+subfdout.o: \
+compile subfdout.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdout.c
+
+subfdouts.o: \
+compile subfdouts.c readwrite.h substdio.h subfd.h substdio.h
+	./compile subfdouts.c
+
+subgetopt.o: \
+compile subgetopt.c subgetopt.h
+	./compile subgetopt.c
+
+substdi.o: \
+compile substdi.c substdio.h byte.h error.h
+	./compile substdi.c
+
+substdio.a: \
+makelib substdio.o substdi.o substdo.o subfderr.o subfdout.o \
+subfdouts.o subfdin.o subfdins.o substdio_copy.o
+	./makelib substdio.a substdio.o substdi.o substdo.o \
+	subfderr.o subfdout.o subfdouts.o subfdin.o subfdins.o \
+	substdio_copy.o
+
+substdio.o: \
+compile substdio.c substdio.h
+	./compile substdio.c
+
+substdio_copy.o: \
+compile substdio_copy.c substdio.h
+	./compile substdio_copy.c
+
+substdo.o: \
+compile substdo.c substdio.h str.h byte.h error.h
+	./compile substdo.c
+
+syslog.lib: \
+trysyslog.c compile load
+	( ( ./compile trysyslog.c && \
+	./load trysyslog -lgen ) >/dev/null 2>&1 \
+	&& echo -lgen || exit 0 ) > syslog.lib
+	rm -f trysyslog.o trysyslog
+
+systype: \
+find-systype trycpp.c
+	./find-systype > systype
+
+tcp-env: \
+load tcp-env.o dns.o remoteinfo.o timeoutread.o timeoutwrite.o \
+timeoutconn.o ip.o ipalloc.o case.a ndelay.a sig.a env.a getopt.a \
+stralloc.a alloc.a substdio.a error.a str.a fs.a dns.lib socket.lib
+	./load tcp-env dns.o remoteinfo.o timeoutread.o \
+	timeoutwrite.o timeoutconn.o ip.o ipalloc.o case.a ndelay.a \
+	sig.a env.a getopt.a stralloc.a alloc.a substdio.a error.a \
+	str.a fs.a  `cat dns.lib` `cat socket.lib`
+
+tcp-env.0: \
+tcp-env.1
+	nroff -man tcp-env.1 > tcp-env.0
+
+tcp-env.o: \
+compile tcp-env.c sig.h stralloc.h gen_alloc.h str.h env.h fmt.h \
+scan.h subgetopt.h ip.h dns.h byte.h remoteinfo.h exit.h case.h
+	./compile tcp-env.c
+
+tcp-environ.0: \
+tcp-environ.5
+	nroff -man tcp-environ.5 > tcp-environ.0
+
+tcpto.o: \
+compile tcpto.c tcpto.h open.h lock.h seek.h now.h datetime.h ip.h \
+byte.h datetime.h readwrite.h
+	./compile tcpto.c
+
+tcpto_clean.o: \
+compile tcpto_clean.c tcpto.h open.h substdio.h readwrite.h
+	./compile tcpto_clean.c
+
+timeoutconn.o: \
+compile timeoutconn.c ndelay.h select.h error.h readwrite.h ip.h \
+byte.h timeoutconn.h
+	./compile timeoutconn.c
+
+timeoutread.o: \
+compile timeoutread.c timeoutread.h select.h error.h readwrite.h
+	./compile timeoutread.c
+
+timeoutwrite.o: \
+compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h
+	./compile timeoutwrite.c
+
+qmail-smtpd: tls.o ssl_timeoutio.o ndelay.a
+qmail-remote: tls.o ssl_timeoutio.o
+qmail-smtpd.o: tls.h ssl_timeoutio.h
+qmail-remote.o: tls.h ssl_timeoutio.h
+
+tls.o: \
+compile tls.c exit.h error.h
+	./compile tls.c
+
+ssl_timeoutio.o: \
+compile ssl_timeoutio.c ssl_timeoutio.h select.h error.h ndelay.h
+	./compile ssl_timeoutio.c
+
+token822.o: \
+compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \
+gen_alloc.h gen_allocdefs.h
+	./compile token822.c
+
+trigger.o: \
+compile trigger.c select.h open.h trigger.h hasnpbg1.h
+	./compile trigger.c
+
+triggerpull.o: \
+compile triggerpull.c ndelay.h open.h triggerpull.h
+	./compile triggerpull.c
+
+uint32.h: \
+tryulong32.c compile load uint32.h1 uint32.h2
+	( ( ./compile tryulong32.c && ./load tryulong32 && \
+	./tryulong32 ) >/dev/null 2>&1 \
+	&& cat uint32.h2 || cat uint32.h1 ) > uint32.h
+	rm -f tryulong32.o tryulong32
+
+wait.a: \
+makelib wait_pid.o wait_nohang.o
+	./makelib wait.a wait_pid.o wait_nohang.o
+
+wait_nohang.o: \
+compile wait_nohang.c haswaitp.h
+	./compile wait_nohang.c
+
+wait_pid.o: \
+compile wait_pid.c error.h haswaitp.h
+	./compile wait_pid.c
+
+cert cert-req: \
+Makefile-cert
+	@$(MAKE) -sf $< $@
+
+Makefile-cert: \
+conf-qmail conf-users conf-groups Makefile-cert.mk
+	@cat Makefile-cert.mk \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> $@
+
+update_tmprsadh: \
+conf-qmail conf-users conf-groups update_tmprsadh.sh
+	@cat update_tmprsadh.sh\
+	| sed s}UGQMAILD}"`head -2 conf-users|tail -1`:`head -1 conf-groups`"}g \
+	| sed s}QMAIL}"`head -1 conf-qmail`"}g \
+	> $@
+	chmod 755 update_tmprsadh 
+
+tmprsadh: \
+update_tmprsadh
+	echo "Creating new temporary RSA and DH parameters"
+	./update_tmprsadh
diff -Naur ./numlib.h ../qmail-1.03-build-10/numlib.h
--- ./numlib.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/numlib.h	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,45 @@
+#ifndef	numlib_h
+#define	numlib_h
+
+/*
+** Copyright 1998 - 1999 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+static const char numlib_h_rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+#if	HAVE_CONFIG_H
+#include	"config.h"
+#endif
+
+#include	<sys/types.h>
+#include	<time.h>
+
+#define	NUMBUFSIZE	60
+
+/* Convert various system types to decimal */
+
+char	*str_time_t(time_t, char *);
+char	*str_off_t(off_t, char *);
+char	*str_pid_t(pid_t, char *);
+char	*str_ino_t(ino_t, char *);
+char	*str_uid_t(uid_t, char *);
+char	*str_gid_t(gid_t, char *);
+char	*str_size_t(size_t, char *);
+
+char	*str_sizekb(unsigned long, char *);	/* X Kb or X Mb */
+
+/* Convert selected system types to hex */
+
+char	*strh_time_t(time_t, char *);
+char	*strh_pid_t(pid_t, char *);
+char	*strh_ino_t(ino_t, char *);
+
+#ifdef	__cplusplus
+}
+#endif
+#endif
diff -Naur ./overmaildirquota.c ../qmail-1.03-build-10/overmaildirquota.c
--- ./overmaildirquota.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/overmaildirquota.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,41 @@
+/*
+** Copyright 1998 - 1999 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include        "maildirquota.h"
+#include        <stdlib.h>
+#include        <string.h>
+#include        <errno.h>
+#include        <sys/stat.h>
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+int user_over_maildirquota( const char *dir, const char *q)
+{
+struct  stat    stat_buf;
+int     quotafd;
+int     ret_value;
+
+        if (fstat(0, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode) &&
+                stat_buf.st_size > 0 && *q)
+        {
+                if (maildir_checkquota(dir, &quotafd, q, stat_buf.st_size, 1)
+                        && errno != EAGAIN)
+                {
+                        if (quotafd >= 0)       close(quotafd);
+                        ret_value = 1;
+                } else {
+                        maildir_addquota(dir, quotafd, q, stat_buf.st_size, 1);
+                        if (quotafd >= 0)       close(quotafd);
+                        ret_value = 0;
+                }
+        } else {
+                ret_value = 0;
+        }
+
+        return(ret_value);
+}
diff -Naur ./qmail.7 ../qmail-1.03-build-10/qmail.7
--- ./qmail.7	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail.7	2006-04-24 21:24:32.000000000 -0500
@@ -55,12 +55,14 @@
 and
 .BR qmail-pop3d (8).
 
-This documentation describes version
-1.03
+This documentation describes netqmail version
+1.05
 of
 .BR qmail .
 See
 .B http://pobox.com/~djb/qmail.html
 for other
 .BR qmail -related
-software.
+software, and
+.B http://qmail.org/
+for other qmail community contributions.
diff -Naur ./qmail-badloadertypes.9 ../qmail-1.03-build-10/qmail-badloadertypes.9
--- ./qmail-badloadertypes.9	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qmail-badloadertypes.9	2005-03-12 11:01:36.000000000 -0600
@@ -0,0 +1,46 @@
+.TH qmail-badloadertype 8
+.SH NAME
+qmail-badloadertype \- prepare badloadertypes for qmail-smtpd
+.SH SYNOPSIS
+.B qmail-badloadertype
+.SH DESCRIPTION
+.B qmail-badloadertype
+reads the instructions in
+.B QMAILHOME/control/badloadertypes
+and writes them into
+.B QMAILHOME/control/badloadertypes.cdb
+in a binary format suited
+for quick access by
+.BR qmail-smtpd .
+
+If there is a problem with
+.BR control/badloadertypes ,
+.B qmail-badloadertype
+complains and leaves
+.B control/badloadertypes.cdb
+alone.
+
+.B qmail-badloadertype
+ensures that
+.B control/badloadertypes.cdb
+is updated atomically,
+so
+.B qmail-smtpd
+never has to wait for
+.B qmail-badloadertype
+to finish.
+However,
+.B qmail-badloadertype
+makes no attempt to protect against two simultaneous updates of
+.BR control/badloadertypes.cdb .
+For convenience,
+.B qmail-badloadertype
+allows comments (lines starting with '#') and 
+copies only the significant leading characters to
+.BR control/badloadertypes.cdb .
+
+The binary
+.B control/badloadertypes.cdb
+format is portable across machines.
+.SH "SEE ALSO"
+qmail-smtpd(8)
diff -Naur ./qmail-badloadertypes.c ../qmail-1.03-build-10/qmail-badloadertypes.c
--- ./qmail-badloadertypes.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qmail-badloadertypes.c	2005-03-12 11:01:36.000000000 -0600
@@ -0,0 +1,64 @@
+#include "strerr.h"
+#include "stralloc.h"
+#include "substdio.h"
+#include "getln.h"
+#include "exit.h"
+#include "readwrite.h"
+#include "open.h"
+#include "auto_qmail.h"
+#include "cdbmss.h"
+
+#define FATAL "qmail-badloadertypes: fatal: "
+#define LOADER_LEN 5
+
+void die_read()
+{
+  strerr_die2sys(111,FATAL,"unable to read control/badloadertypes: ");
+}
+void die_write()
+{
+  strerr_die2sys(111,FATAL,"unable to write to control/badloadertypes.tmp: ");
+}
+
+char inbuf[1024];
+substdio ssin;
+
+int fd;
+int fdtemp;
+
+struct cdbmss cdbmss;
+stralloc line = {0};
+int match;
+
+void main()
+{
+  umask(033);
+  if (chdir(auto_qmail) == -1)
+    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");
+
+  fd = open_read("control/badloadertypes");
+  if (fd == -1) die_read();
+
+  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof inbuf);
+
+  fdtemp = open_trunc("control/badloadertypes.tmp");
+  if (fdtemp == -1) die_write();
+
+  if (cdbmss_start(&cdbmss,fdtemp) == -1) die_write();
+
+  for (;;) {
+    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
+    if (line.s[0] != '#' && line.len > LOADER_LEN)
+      if (cdbmss_add(&cdbmss,line.s,LOADER_LEN,"",0) == -1)
+	die_write();
+    if (!match) break;
+  }
+
+  if (cdbmss_finish(&cdbmss) == -1) die_write();
+  if (fsync(fdtemp) == -1) die_write();
+  if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
+  if (rename("control/badloadertypes.tmp","control/badloadertypes.cdb") == -1)
+    strerr_die2sys(111,FATAL,"unable to move control/badloadertypes.tmp to control/badloadertypes.cdb");
+
+  _exit(0);
+}
diff -Naur ./qmail-badmimetypes.9 ../qmail-1.03-build-10/qmail-badmimetypes.9
--- ./qmail-badmimetypes.9	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qmail-badmimetypes.9	2005-03-12 11:01:36.000000000 -0600
@@ -0,0 +1,46 @@
+.TH qmail-badmimetype 8
+.SH NAME
+qmail-badmimetype \- prepare badmimetypes for qmail-smtpd
+.SH SYNOPSIS
+.B qmail-badmimetype
+.SH DESCRIPTION
+.B qmail-badmimetype
+reads the instructions in
+.B QMAILHOME/control/badmimetypes
+and writes them into
+.B QMAILHOME/control/badmimetypes.cdb
+in a binary format suited
+for quick access by
+.BR qmail-smtpd .
+
+If there is a problem with
+.BR control/badmimetypes ,
+.B qmail-badmimetype
+complains and leaves
+.B control/badmimetypes.cdb
+alone.
+
+.B qmail-badmimetype
+ensures that
+.B control/badmimetypes.cdb
+is updated atomically,
+so
+.B qmail-smtpd
+never has to wait for
+.B qmail-badmimetype
+to finish.
+However,
+.B qmail-badmimetype
+makes no attempt to protect against two simultaneous updates of
+.BR control/badmimetypes.cdb .
+For convenience,
+.B qmail-badmimetype
+allows comments (lines starting with '#') and 
+copies only the significant leading characters to
+.BR control/badmimetypes.cdb .
+
+The binary
+.B control/badmimetypes.cdb
+format is portable across machines.
+.SH "SEE ALSO"
+qmail-smtpd(8)
diff -Naur ./qmail-badmimetypes.c ../qmail-1.03-build-10/qmail-badmimetypes.c
--- ./qmail-badmimetypes.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qmail-badmimetypes.c	2005-03-12 11:01:36.000000000 -0600
@@ -0,0 +1,64 @@
+#include "strerr.h"
+#include "stralloc.h"
+#include "substdio.h"
+#include "getln.h"
+#include "exit.h"
+#include "readwrite.h"
+#include "open.h"
+#include "auto_qmail.h"
+#include "cdbmss.h"
+
+#define FATAL "qmail-badmimetypes: fatal: "
+#define MIMETYPE_LEN 9
+
+void die_read()
+{
+  strerr_die2sys(111,FATAL,"unable to read control/badmimetypes: ");
+}
+void die_write()
+{
+  strerr_die2sys(111,FATAL,"unable to write to control/badmimetypes.tmp: ");
+}
+
+char inbuf[1024];
+substdio ssin;
+
+int fd;
+int fdtemp;
+
+struct cdbmss cdbmss;
+stralloc line = {0};
+int match;
+
+void main()
+{
+  umask(033);
+  if (chdir(auto_qmail) == -1)
+    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");
+
+  fd = open_read("control/badmimetypes");
+  if (fd == -1) die_read();
+
+  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof inbuf);
+
+  fdtemp = open_trunc("control/badmimetypes.tmp");
+  if (fdtemp == -1) die_write();
+
+  if (cdbmss_start(&cdbmss,fdtemp) == -1) die_write();
+
+  for (;;) {
+    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
+    if (line.s[0] != '#' && line.len > MIMETYPE_LEN)
+      if (cdbmss_add(&cdbmss,line.s,MIMETYPE_LEN,"",0) == -1)
+	die_write();
+    if (!match) break;
+  }
+
+  if (cdbmss_finish(&cdbmss) == -1) die_write();
+  if (fsync(fdtemp) == -1) die_write();
+  if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
+  if (rename("control/badmimetypes.tmp","control/badmimetypes.cdb") == -1)
+    strerr_die2sys(111,FATAL,"unable to move control/badmimetypes.tmp to control/badmimetypes.cdb");
+
+  _exit(0);
+}
diff -Naur ./qmail.c ../qmail-1.03-build-10/qmail.c
--- ./qmail.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail.c	2006-05-05 19:25:27.000000000 -0500
@@ -6,28 +6,49 @@
 #include "fd.h"
 #include "qmail.h"
 #include "auto_qmail.h"
+#include "env.h"
 
-static char *binqqargs[2] = { "bin/qmail-queue", 0 } ;
+static char *binqqargs[2] = { 0, 0 } ;
+
+static void setup_qqargs()
+{
+  if(!binqqargs[0])
+    binqqargs[0] = env_get("QMAILQUEUE");
+  if(!binqqargs[0])
+    binqqargs[0] = "bin/qmail-queue";
+}
 
 int qmail_open(qq)
 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 = 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 +56,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 +104,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 +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 && 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 -Naur ./qmail-control.9 ../qmail-1.03-build-10/qmail-control.9
--- ./qmail-control.9	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-control.9	2006-05-09 23:44:10.000000000 -0500
@@ -20,7 +20,11 @@
 
 Comments are allowed
 in
+.IR badhelo ,
 .IR badmailfrom ,
+.IR badmailfromnorelay ,
+.IR badmailto ,
+.IR badmailtonorelay ,
 .IR locals ,
 .IR percenthack ,
 .IR qmqpservers ,
@@ -40,14 +44,24 @@
 .ta 5c 10c
 control	default	used by
 
+.I badhelo	\fR(none)	\fRqmail-smtpd
+.I badloadertypes.cdb	\fR(none)	\fRqmail-smtpd
 .I badmailfrom	\fR(none)	\fRqmail-smtpd
+.I badmailfromnorelay	\fR(none)	\fRqmail-smtpd
+.I badmailto	\fR(none)	\fRqmail-smtpd
+.I badmailtonorelay	\fR(none)	\fRqmail-smtpd
+.I badmimetypes.cdb	\fR(none)	\fRqmail-smtpd
 .I bouncefrom	\fRMAILER-DAEMON	\fRqmail-send
 .I bouncehost	\fIme	\fRqmail-send
+.I clientca.pem	\fR(none)	\fRqmail-smtpd
+.I clientcert.pem	\fR(none)	\fRqmail-remote
 .I concurrencylocal	\fR10	\fRqmail-send
 .I concurrencyremote	\fR20	\fRqmail-send
 .I defaultdomain	\fIme	\fRqmail-inject
 .I defaulthost	\fIme	\fRqmail-inject
 .I databytes	\fR0	\fRqmail-smtpd
+.I dh1024.pem	\fR(none)	\fRqmail-smtpd
+.I dh512.pem	\fR(none)	\fRqmail-smtpd
 .I doublebouncehost	\fIme	\fRqmail-send
 .I doublebounceto	\fRpostmaster	\fRqmail-send
 .I envnoathost	\fIme	\fRqmail-send
@@ -61,18 +75,33 @@
 .I qmqpservers	\fR(none)	\fRqmail-qmqpc
 .I queuelifetime	\fR604800	\fRqmail-send
 .I rcpthosts	\fR(none)	\fRqmail-smtpd
+.I rsa512.pem	\fR(none)	\fRqmail-smtpd
+.I servercert.pem	\fR(none)	\fRqmail-smtpd
 .I smtpgreeting	\fIme	\fRqmail-smtpd
 .I smtproutes	\fR(none)	\fRqmail-remote
+.I spfbehavior	\fR0	\fRqmail-smtpd
+.I spfexp	\fR(default)	\fRqmail-smtpd
+.I spfguess	\fR(none)	\fRqmail-smtpd
+.I spfrules	\fR(none)	\fRqmail-smtpd
+.I taps	\fR(none)	\fRqmail-queue
 .I timeoutconnect	\fR60	\fRqmail-remote
 .I timeoutremote	\fR1200	\fRqmail-remote
 .I timeoutsmtpd	\fR1200	\fRqmail-smtpd
+.I tlsclients	\fR(none)	\fRqmail-smtpd
+.I tlsclientciphers	\fR(none)	\fRqmail-remote
+.I tlshosts/FQDN.pem	\fR(none)	\fRqmail-remote
+.I tlsserverciphers	\fR(none)	\fRqmail-smtpd
 .I virtualdomains	\fR(none)	\fRqmail-send
 .fi
 .RE
 .SH "SEE ALSO"
 qmail-inject(8),
 qmail-qmqpc(8),
+qmail-queue(8),
 qmail-remote(8),
 qmail-send(8),
 qmail-showctl(8),
-qmail-smtpd(8)
+qmail-smtpd(8),
+qmail-badloadertype(8),
+qmail-badmimetype(8),
+qmail-newmrh(8)
diff -Naur ./qmail-dk.8 ../qmail-1.03-build-10/qmail-dk.8
--- ./qmail-dk.8	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qmail-dk.8	2006-05-12 19:23:30.000000000 -0500
@@ -0,0 +1,125 @@
+.TH qmail-dk 8
+.SH NAME
+qmail-dk \- sign/verify and queue a mail message for delivery
+.SH SYNOPSIS
+.B qmail-dk
+.SH DESCRIPTION
+.B qmail-dk
+has the same interface as
+.B qmail-queue
+except that it inserts an appropriate DomainKeys header before it
+queues the message.  There are two separate ways to invoke
+.BR qmail-dk .
+For one way, you can patch qmail with the http://qmail.org/qmailqueue
+patch and set QMAILQUEUE to point to qmail-dk in the environment when
+you send or receive email.
+For another way, you can rename qmail-queue to qmail-queue.orig, and 
+set DKQUEUE=bin/qmail-queue.orig.
+
+.B qmail-dk
+has been patched with
+.BR qmail-dk-0.54-auth.patch ,
+which sets up a bit of automatic behavior.  If RELAYCLIENT is found in
+the environment, qmail-dk imports the DKSIGN environment variable and
+tries to sign the mail.  If RELAYCLIENT is not found in the environment,
+DKVERIFY is imported, and we attempt to verify the mail.
+
+.B qmail-dk
+supports DomainKey signing and verification.  It uses the libdomainkey
+and OpenSSL libraries.  To sign a message, set the
+.B DKSIGN
+environment variable to the pathname to the private key that will be
+used to sign the message.  If there is a % character in the environment
+variable, it is removed and replaced by the domain name in the From: header.
+If, after substituting the %, that file does not exist, the message will not be signed.
+If there is no % and the file does not exist, the message will be rejected with error 32.
+The selector will be taken from the
+basename of the file.  The private key should be created by 
+.BR dknewkey ,
+which comes with libdomainkey.
+
+To verify a message, set the
+.B DKVERIFY
+environment variable to a desired set of letters.  Precisely, if you
+want a libdomainkey return status to generate an error, include that
+letter, where A is the first return status (DK_STAT_OK), B is the
+second (DK_STAT_BADSIG), etc.  The letter should be uppercase if you
+want a permanent error to be returned (exit code 13), and lowercase if
+you want a temporary error to be returned (exit code 82).
+
+For example, if you want to permanently reject messages that have a
+signature that has been revoked, include the letter 'K' in the
+.B DKVERIFY
+environment variable.  A conservative set of letters is
+.BR DEGIJKfh .
+Reject permanently BADSIG, NOKEY, BADKEY, SYNTAX, ARGS, REVOKED, and
+INTERNAL errors, and temporarily CANTVRFY and NORESOURCE.  Add in
+.B B
+if you want to reject messages that have a signature that doesn't
+verify (presumably because the message is a forgery or has been
+damaged in transit.  Note that
+.B qmail-dk
+always inserts the 
+.B DomainKey-Status
+header, so that messages can be
+rejected at delivery time, or in the mail reader.
+
+Typically, you would sign messages generated on-host by setting
+.B DKSIGN
+in the environment before running an email program.  DKSIGN will be carried
+through qmail's sendmail emulation through 
+.B qmail-inject
+to
+.BR qmail-dk .
+You would also set it for
+.B qmail-smtpd
+at the same time
+.B RELAYCLIENT
+is set, most often in the tcpserver cdb file.  If a host is authorized
+to relay, you probably want to sign messages sent by that host.
+.B DKVERIFY
+should be set for all other hosts.
+
+If neither
+.B DKSIGN
+nor
+.B DKVERIFY
+are set, then
+.B DKSIGN
+will be set to /var/qmail/control/domainkeys/%/default.  If such a private 
+key exists, it will be used to sign the domain.
+
+.B qmail-dk
+will ordinarily spawn qmail-queue, but if DKQUEUE is set in the environment,
+the program that it points to will be executed instead.  If DKQUEUE is not set, and
+.B qmail-dk
+has been invoked as
+.B qmail-queue
+then
+.B qmail-queue.orig
+is spawned instead.
+
+.SH "EXIT CODES"
+.B qmail-dk
+returns the same exit codes as qmail-queue with these additions:
+.TP 5
+.B 32
+The private key file does not exist.
+.TP 5
+.B 57
+Trouble waiting for qmail-queue to exit.
+.TP 5
+.B 58
+Unable to vfork.
+.TP 5
+.B 59
+Unable to create a pipe to qmail-queue.
+.SH "SEE ALSO"
+addresses(5),
+envelopes(5),
+qmail-header(5),
+qmail-inject(8),
+qmail-qmqpc(8),
+qmail-queue(8),
+qmail-send(8),
+qmail-smtpd(8)
diff -Naur ./qmail-dk.c ../qmail-1.03-build-10/qmail-dk.c
--- ./qmail-dk.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qmail-dk.c	2006-05-12 19:26:10.000000000 -0500
@@ -0,0 +1,303 @@
+#include <sys/types.h>
+#include "readwrite.h"
+#include "sig.h"
+#include "exit.h"
+#include "open.h"
+#include "seek.h"
+#include "fmt.h"
+#include "alloc.h"
+#include "str.h"
+#include "stralloc.h"
+#include "substdio.h"
+#include "datetime.h"
+#include "now.h"
+#include "fork.h"
+#include "wait.h"
+#include "extra.h"
+#include "auto_qmail.h"
+#include "auto_uids.h"
+#include "date822fmt.h"
+#include "fmtqfn.h"
+#include "env.h"
+#include "control.h"
+#include <domainkeys.h>
+
+#define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */
+#define ADDR 1003
+
+char inbuf[2048];
+struct substdio ssin;
+char outbuf[256];
+struct substdio ssout;
+
+datetime_sec starttime;
+struct datetime dt;
+unsigned long mypid;
+unsigned long uid;
+char *pidfn;
+int messfd;
+int readfd;
+
+void die(e) int e; { _exit(e); }
+void die_write() { die(53); }
+void die_read() { die(54); }
+void sigalrm() { /* thou shalt not clean up here */ die(52); }
+void sigbug() { die(81); }
+void maybe_die_dk(e) DK_STAT e; {
+  switch(e) {
+  case DK_STAT_BADKEY: _exit(55);
+  case DK_STAT_CANTVRFY: _exit(74);
+  case DK_STAT_NORESOURCE: _exit(51);
+  case DK_STAT_ARGS: _exit(12);
+  case DK_STAT_SYNTAX: _exit(31);
+  case DK_STAT_INTERNAL: _exit(81);
+  }
+}
+
+unsigned int pidfmt(s,seq)
+char *s;
+unsigned long seq;
+{
+ unsigned int i;
+ unsigned int len;
+
+ len = 0;
+ i = fmt_str(s,"/tmp/qmail-dk."); len += i; if (s) s += i;
+ i = fmt_ulong(s,mypid); len += i; if (s) s += i;
+ i = fmt_str(s,"."); len += i; if (s) s += i;
+ i = fmt_ulong(s,starttime); len += i; if (s) s += i;
+ i = fmt_str(s,"."); len += i; if (s) s += i;
+ i = fmt_ulong(s,seq); len += i; if (s) s += i;
+ ++len; if (s) *s++ = 0;
+
+ return len;
+}
+
+void pidopen()
+{
+ unsigned int len;
+ unsigned long seq;
+
+ seq = 1;
+ len = pidfmt((char *) 0,seq);
+ pidfn = alloc(len);
+ if (!pidfn) die(51);
+
+ for (seq = 1;seq < 10;++seq)
+  {
+   if (pidfmt((char *) 0,seq) > len) die(81); /* paranoia */
+   pidfmt(pidfn,seq);
+   messfd = open_excl(pidfn);
+   if (messfd != -1) return;
+  }
+
+ die(63);
+}
+
+char tmp[FMT_ULONG];
+
+char *relayclient;
+char *dksign = 0;
+stralloc dksignature = {0};
+stralloc dkoutput = {0};
+char *dkverify = 0;
+char *dkqueue = 0;
+DK_LIB *dklib;
+DK *dk;
+DK_STAT st;
+
+static void write_signature(DK *dk, char *keyfn)
+{
+ char advice[2048];
+ char *selector;
+ char *from;
+ static stralloc keyfnfrom = {0};
+ int i;
+
+ from = dk_from(dk);
+ i = str_chr(keyfn, '%');
+ if (keyfn[i]) {
+   if (!stralloc_copyb(&keyfnfrom,keyfn,i)) die(51);
+   if (!stralloc_cats(&keyfnfrom,from)) die(51);
+   if (!stralloc_cats(&keyfnfrom,keyfn + i + 1)) die(51);
+ } else {
+   if (!stralloc_copys(&keyfnfrom,keyfn)) die(51);
+ }
+ if (!stralloc_0(&keyfnfrom)) die(51);
+
+ switch(control_readfile(&dksignature,keyfnfrom.s,0)) {
+ case 0:
+   if (keyfn[i]) return;
+   die(32);
+ case 1: break;
+ default: die(31);
+ }
+ for(i=0; i < dksignature.len; i++)
+   if (dksignature.s[i] == '\0') dksignature.s[i] = '\n';
+ if (!stralloc_0(&dksignature)) die(51);
+
+ st = dk_getsig(dk, dksignature.s, advice, sizeof(advice));
+ maybe_die_dk(st);
+
+ if (!stralloc_cats(&dkoutput,
+   "Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys\n"
+	   "DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;\n"
+	   "  s=")) die(51);
+ selector = keyfn;
+ while (*keyfn) {
+   if (*keyfn == '/') selector = keyfn+1;
+    keyfn++;
+ }
+ if (!stralloc_cats(&dkoutput,selector)) die(51);
+ if (!stralloc_cats(&dkoutput,"; d=")) die(51);
+ if (from) {
+   if (!stralloc_cats(&dkoutput,from)) die(51);
+ } else if (!stralloc_cats(&dkoutput,"unknown")) die(51);
+ if (!stralloc_cats(&dkoutput,";\n  b=")) die(51);
+ if (!stralloc_cats(&dkoutput,advice)) die(51);
+ if (!stralloc_cats(&dkoutput,"  ;\n")) die(51);
+}
+
+static char *binqqargs[2] = { "bin/qmail-queue", 0 } ;
+
+void main(int argc, char *argv[])
+{
+ unsigned int len;
+ char ch;
+ int pim[2];
+ int wstat;
+ unsigned long pid;
+
+ sig_blocknone();
+ umask(033);
+
+ relayclient = env_get("RELAYCLIENT");
+ if(relayclient){
+  dksign = env_get("DKSIGN");
+  if(! dksign)
+   dksign = "/var/qmail/control/domainkeys/%/default";
+ }else{
+  dkverify = env_get("DKVERIFY");
+ }
+
+ dkqueue = env_get("DKQUEUE");
+ if (dkqueue && *dkqueue) binqqargs[0] = dkqueue;
+ else if (str_equal(argv[0]+str_rchr(argv[0], '/'), "/qmail-queue"))
+   binqqargs[0] = "bin/qmail-queue.orig";
+
+ if (dksign || dkverify) {
+   dklib = dk_init(0);
+   if (!dklib) die(51);
+ }
+ if (dksign) {
+    dk = dk_sign(dklib, &st, DK_CANON_NOFWS);
+    if (!dk) die(31);
+ } else if (dkverify) {
+    dk = dk_verify(dklib, &st);
+    if (!dk) die(31);
+ }
+
+ mypid = getpid();
+ uid = getuid();
+ starttime = now();
+ datetime_tai(&dt,starttime);
+
+ sig_pipeignore();
+ sig_miscignore();
+ sig_alarmcatch(sigalrm);
+ sig_bugcatch(sigbug);
+
+ alarm(DEATH);
+
+ pidopen();
+ readfd = open_read(pidfn);
+ if (unlink(pidfn) == -1) die(63);
+
+ substdio_fdbuf(&ssout,write,messfd,outbuf,sizeof(outbuf));
+ substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
+
+ for (;;) {
+   register int n;
+   register char *x;
+   int i;
+
+   n = substdio_feed(&ssin);
+   if (n < 0) die_read();
+   if (!n) break;
+   x = substdio_PEEK(&ssin);
+   if (dksign || dkverify)
+     for(i=0; i < n; i++) {
+       if (x[i] == '\n') st = dk_message(dk, "\r\n", 2);
+       else st = dk_message(dk, x+i, 1);
+       maybe_die_dk(st);
+      }
+   if (substdio_put(&ssout,x,n) == -1) die_write();
+   substdio_SEEK(&ssin,n);
+ }
+
+ if (substdio_flush(&ssout) == -1) die_write();
+
+ if (dksign || dkverify) {
+   st = dk_eom(dk, (void *)0);
+   maybe_die_dk(st);
+   if (dksign) {
+     write_signature(dk, dksign);
+   } else if (dkverify) {
+     char *status;
+     if (!stralloc_copys(&dkoutput,"DomainKey-Status: ")) die(51);
+     switch(st) {
+     case DK_STAT_OK:         status = "good        "; break;
+     case DK_STAT_BADSIG:     status = "bad         "; break;
+     case DK_STAT_NOSIG:      status = "no signature"; break;
+     case DK_STAT_NOKEY:
+     case DK_STAT_CANTVRFY:   status = "no key      "; break;
+     case DK_STAT_BADKEY:     status = "bad key     "; break;
+     case DK_STAT_INTERNAL:
+     case DK_STAT_ARGS:
+     case DK_STAT_SYNTAX:     status = "bad format  "; break;
+     case DK_STAT_NORESOURCE: status = "no resources"; break;
+     case DK_STAT_REVOKED:    status = "revoked     "; break;
+     }
+     if (!stralloc_cats(&dkoutput,status)) die(51);
+     if (!stralloc_cats(&dkoutput,"\n")) die(51);
+     if (dkverify[str_chr(dkverify, 'A'+st)]) die(13);
+     if (dkverify[str_chr(dkverify, 'a'+st)]) die(82);
+   }
+ }
+
+ if (pipe(pim) == -1) die(59);
+ 
+ switch(pid = vfork()) {
+ case -1:
+   close(pim[0]); close(pim[1]);
+   die(58);
+ case 0:
+   close(pim[1]);
+   if (fd_move(0,pim[0]) == -1) die(120);
+   if (chdir(auto_qmail) == -1) die(61);
+   execv(*binqqargs,binqqargs);
+   die(120);
+ }
+
+ close(pim[0]);
+
+ substdio_fdbuf(&ssin,read,readfd,inbuf,sizeof(inbuf));
+ substdio_fdbuf(&ssout,write,pim[1],outbuf,sizeof(outbuf));
+
+ if (substdio_bput(&ssout,dkoutput.s,dkoutput.len) == -1) die_write();
+ switch(substdio_copy(&ssout,&ssin))
+  {
+   case -2: die_read();
+   case -3: die_write();
+  }
+
+ if (substdio_flush(&ssout) == -1) die_write();
+ close(pim[1]);
+
+ if (wait_pid(&wstat,pid) != pid)
+   die(57);
+ if (wait_crashed(wstat))
+   die(57);
+ die(wait_exitcode(wstat));
+
+}
diff -Naur ./qmail.h ../qmail-1.03-build-10/qmail.h
--- ./qmail.h	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail.h	2006-05-05 19:25:27.000000000 -0500
@@ -8,6 +8,7 @@
   unsigned long pid;
   int fdm;
   int fde;
+  int fderr;
   substdio ss;
   char buf[1024];
 } ;
diff -Naur ./qmail-local.c ../qmail-1.03-build-10/qmail-local.c
--- ./qmail-local.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-local.c	2006-05-03 17:44:55.000000000 -0500
@@ -66,6 +66,7 @@
 
 char buf[1024];
 char outbuf[1024];
+#define QUOTABUFSIZE    256
 
 /* child process */
 
@@ -86,9 +87,15 @@
  int fd;
  substdio ss;
  substdio ssout;
+ char quotabuf[QUOTABUFSIZE];
 
  sig_alarmcatch(sigalrm);
  if (chdir(dir) == -1) { if (error_temp(errno)) _exit(1); _exit(2); }
+ if (maildir_getquota(dir, quotabuf) == 0) {
+  if (user_over_maildirquota(dir,quotabuf)==1) {
+   _exit(1);
+  }
+ }
  pid = getpid();
  host[0] = 0;
  gethostname(host,sizeof(host));
@@ -99,7 +106,10 @@
    s += fmt_str(s,"tmp/");
    s += fmt_ulong(s,time); *s++ = '.';
    s += fmt_ulong(s,pid); *s++ = '.';
-   s += fmt_strn(s,host,sizeof(host)); *s++ = 0;
+   s += fmt_strn(s,host,sizeof(host));
+   s += fmt_strn(s,",S=",sizeof(",S="));
+   if (fstat(0,&st) == -1) if (errno == error_noent) break;
+   s += fmt_ulong(s,st.st_size); *s++ = 0;
    if (stat(fntmptph,&st) == -1) if (errno == error_noent) break;
    /* really should never get to this point */
    if (loop == 2) _exit(1);
@@ -159,6 +169,7 @@
  switch(wait_exitcode(wstat))
   {
    case 0: break;
+   case 1: strerr_die1x(1, "User over quota. (#5.1.1)");
    case 2: strerr_die1x(111,"Unable to chdir to maildir. (#4.2.1)");
    case 3: strerr_die1x(111,"Timeout on maildir delivery. (#4.3.0)");
    case 4: strerr_die1x(111,"Unable to read message. (#4.3.0)");
@@ -645,7 +656,7 @@
     {
      cmds.s[j] = 0;
      k = j;
-     while ((k > i) && (cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t'))
+     while ((k > i) && ((cmds.s[k - 1] == ' ') || (cmds.s[k - 1] == '\t')))
        cmds.s[--k] = 0;
      switch(cmds.s[i])
       {
diff -Naur ./qmail-log.5 ../qmail-1.03-build-10/qmail-log.5
--- ./qmail-log.5	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-log.5	2006-04-24 21:24:32.000000000 -0500
@@ -232,6 +232,11 @@
 is unable to queue a bounce message,
 usually because the machine is almost out of memory.
 It will try again later.
+This can also be caused by incorrect settings of
+.B $QMAILQUEUE
+or errors in a program or script which
+.B $QMAILQUEUE
+points to.
 .TP
 .B unable to stat ...
 .B qmail-send
diff -Naur ./qmail-pop3d.c ../qmail-1.03-build-10/qmail-pop3d.c
--- ./qmail-pop3d.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-pop3d.c	2006-05-03 17:44:55.000000000 -0500
@@ -16,6 +16,11 @@
 #include "readwrite.h"
 #include "timeoutread.h"
 #include "timeoutwrite.h"
+#include <errno.h>
+#include "maildirquota.h"
+#include "maildirmisc.h"
+
+#define QUOTABUFSIZE 256
 
 void die() { _exit(0); }
 
@@ -45,19 +50,15 @@
 {
   substdio_put(&ssout,buf,len);
 }
-void puts(s) char *s;
-{
-  substdio_puts(&ssout,s);
-}
 void flush()
 {
   substdio_flush(&ssout);
 }
 void err(s) char *s;
 {
-  puts("-ERR ");
-  puts(s);
-  puts("\r\n");
+  substdio_puts(&ssout,"-ERR ");
+  substdio_puts(&ssout,s);
+  substdio_puts(&ssout,"\r\n");
   flush();
 }
 
@@ -66,14 +67,14 @@
 void die_scan() { err("unable to scan $HOME/Maildir"); die(); }
 
 void err_syntax() { err("syntax error"); }
-void err_unimpl() { err("unimplemented"); }
+void err_unimpl(arg) char *arg; { err("unimplemented"); }
 void err_deleted() { err("already deleted"); }
 void err_nozero() { err("messages are counted from 1"); }
 void err_toobig() { err("not that many messages"); }
 void err_nosuch() { err("unable to open that message"); }
 void err_nounlink() { err("unable to unlink all deleted messages"); }
 
-void okay() { puts("+OK \r\n"); flush(); }
+void okay() { substdio_puts(&ssout,"+OK \r\n"); flush(); }
 
 void printfn(fn) char *fn;
 {
@@ -146,43 +147,66 @@
   }
 }
 
-void pop3_stat()
+void pop3_stat(arg) char *arg;
 {
   int i;
   unsigned long total;
  
   total = 0;
   for (i = 0;i < numm;++i) if (!m[i].flagdeleted) total += m[i].size;
-  puts("+OK ");
+  substdio_puts(&ssout,"+OK ");
   put(strnum,fmt_uint(strnum,numm));
-  puts(" ");
+  substdio_puts(&ssout," ");
   put(strnum,fmt_ulong(strnum,total));
-  puts("\r\n");
+  substdio_puts(&ssout,"\r\n");
   flush();
 }
 
-void pop3_rset()
+void pop3_rset(arg) char *arg;
 {
   int i;
   for (i = 0;i < numm;++i) m[i].flagdeleted = 0;
   last = 0;
-  okay();
+  okay(0);
 }
 
-void pop3_last()
+void pop3_last(arg) char *arg;
 {
-  puts("+OK ");
+  substdio_puts(&ssout,"+OK ");
   put(strnum,fmt_uint(strnum,last));
-  puts("\r\n");
+  substdio_puts(&ssout,"\r\n");
   flush();
 }
 
-void pop3_quit()
+void pop3_quit(arg) char *arg;
 {
   int i;
+  char quotabuf[QUOTABUFSIZE];
+  int has_quota=maildir_getquota(".", quotabuf);
+
+  long deleted_bytes=0;
+  long deleted_messages=0;
+
   for (i = 0;i < numm;++i)
     if (m[i].flagdeleted) {
-      if (unlink(m[i].fn) == -1) err_nounlink();
+      unsigned long un=0;
+      const char *filename=m[i].fn;
+      if (has_quota == 0 && !MAILDIR_DELETED(filename)) {
+          if (maildir_parsequota(filename, &un)) {
+              struct stat stat_buf;
+
+              if (stat(filename, &stat_buf) == 0)
+                  un=stat_buf.st_size;
+          }
+      }
+      if (unlink(m[i].fn) == -1) {
+          err_nounlink();
+          un=0;
+      }
+      if (un) {
+          deleted_bytes -= un;
+          deleted_messages -= 1;
+      }
     }
     else
       if (str_start(m[i].fn,"new/")) {
@@ -192,7 +216,22 @@
 	if (!stralloc_0(&line)) die_nomem();
 	rename(m[i].fn,line.s); /* if it fails, bummer */
       }
-  okay();
+
+    if (deleted_messages < 0) {
+        int quotafd;
+
+        if (maildir_checkquota(".", &quotafd, quotabuf, deleted_bytes,
+                               deleted_messages) && errno != EAGAIN &&
+                               deleted_bytes >= 0)
+            {
+                if (quotafd >= 0) close (quotafd);
+            } else {
+                 maildir_addquota(".", quotafd, quotabuf,
+                                 deleted_bytes, deleted_messages);
+                 if (quotafd >= 0) close(quotafd);
+            }
+        }
+  okay(0);
   die();
 }
 
@@ -214,7 +253,7 @@
   if (i == -1) return;
   m[i].flagdeleted = 1;
   if (i + 1 > last) last = i + 1;
-  okay();
+  okay(0);
 }
 
 void list(i,flaguidl)
@@ -222,10 +261,10 @@
 int flaguidl;
 {
   put(strnum,fmt_uint(strnum,i + 1));
-  puts(" ");
+  substdio_puts(&ssout," ");
   if (flaguidl) printfn(m[i].fn);
   else put(strnum,fmt_ulong(strnum,m[i].size));
-  puts("\r\n");
+  substdio_puts(&ssout,"\r\n");
 }
 
 void dolisting(arg,flaguidl) char *arg; int flaguidl;
@@ -234,15 +273,15 @@
   if (*arg) {
     i = msgno(arg);
     if (i == -1) return;
-    puts("+OK ");
+    substdio_puts(&ssout,"+OK ");
     list(i,flaguidl);
   }
   else {
-    okay();
+    okay(0);
     for (i = 0;i < numm;++i)
       if (!m[i].flagdeleted)
 	list(i,flaguidl);
-    puts(".\r\n");
+    substdio_puts(&ssout,".\r\n");
   }
   flush();
 }
@@ -267,7 +306,7 @@
  
   fd = open_read(m[i].fn);
   if (fd == -1) { err_nosuch(); return; }
-  okay();
+  okay(0);
   substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf));
   blast(&ssmsg,limit);
   close(fd);
@@ -299,7 +338,7 @@
  
   getlist();
 
-  okay();
+  okay(0);
   commands(&ssin,pop3commands);
   die();
 }
diff -Naur ./qmail-popup.c ../qmail-1.03-build-10/qmail-popup.c
--- ./qmail-popup.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-popup.c	2006-04-24 21:24:32.000000000 -0500
@@ -64,10 +64,10 @@
 
 void err_syntax() { err("syntax error"); }
 void err_wantuser() { err("USER first"); }
-void err_authoriz() { err("authorization first"); }
+void err_authoriz(arg) char *arg; { err("authorization first"); }
 
-void okay() { puts("+OK \r\n"); flush(); }
-void pop3_quit() { okay(); die(); }
+void okay(arg) char *arg; { puts("+OK \r\n"); flush(); }
+void pop3_quit(arg) char *arg; { okay(0); die(); }
 
 
 char unique[FMT_ULONG + FMT_ULONG + 3];
@@ -136,7 +136,7 @@
 void pop3_user(arg) char *arg;
 {
   if (!*arg) { err_syntax(); return; }
-  okay();
+  okay(0);
   seenuser = 1;
   if (!stralloc_copys(&username,arg)) die_nomem(); 
   if (!stralloc_0(&username)) die_nomem(); 
diff -Naur ./qmail-queue.8 ../qmail-1.03-build-10/qmail-queue.8
--- ./qmail-queue.8	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-queue.8	2006-05-09 23:45:45.000000000 -0500
@@ -40,6 +40,17 @@
 However, the recipients probably expect to see a proper header,
 as described in
 .BR qmail-header(5) .
+.SH "CONTROL FILES"
+.TP 5
+.I taps
+Should contain regex syntax of email addresses to tap and
+the associated email address to send the copy to. The two
+fields should be separated by a colon.
+Programs included with qmail which invoke
+.B qmail-queue
+will invoke the contents of
+.B $QMAILQUEUE
+instead, if that environment variable is set.
 .SH "FILESYSTEM RESTRICTIONS"
 .B qmail-queue
 imposes two constraints on the queue structure:
diff -Naur ./qmail-queue.c ../qmail-1.03-build-10/qmail-queue.c
--- ./qmail-queue.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-queue.c	2006-05-09 23:51:14.000000000 -0500
@@ -16,6 +16,8 @@
 #include "auto_uids.h"
 #include "date822fmt.h"
 #include "fmtqfn.h"
+#include "stralloc.h"
+#include "constmap.h"
 
 #define DEATH 86400 /* 24 hours; _must_ be below q-s's OSSIFIED (36 hours) */
 #define ADDR 1003
@@ -25,6 +27,14 @@
 char outbuf[256];
 struct substdio ssout;
 
+int tapok = 0;
+stralloc tap = {0};
+struct constmap maptap;
+stralloc chkaddr = {0};
+int tapped;
+stralloc tapaddr = {0};
+stralloc controlfile = {0};
+
 datetime_sec starttime;
 struct datetime dt;
 unsigned long mypid;
@@ -175,7 +185,14 @@
 
  alarm(DEATH);
 
- pidopen();
+ stralloc_copys( &controlfile, auto_qmail);
+ stralloc_cats( &controlfile, "/control/taps");
+ stralloc_0( &controlfile);
+ tapok = control_readfile(&tap,controlfile.s,0);
+ if (tapok == -1) die(65);
+ if (!constmap_init(&maptap,tap.s,tap.len,0)) die(65);
+
+pidopen();
  if (fstat(messfd,&pidst) == -1) die(63);
 
  messnum = pidst.st_ino;
@@ -219,14 +236,28 @@
  if (substdio_get(&ssin,&ch,1) < 1) die_read();
  if (ch != 'F') die(91);
  if (substdio_bput(&ssout,&ch,1) == -1) die_write();
+ stralloc_0(&chkaddr);
  for (len = 0;len < ADDR;++len)
   {
+   if ( len == 1 ) stralloc_copyb(&chkaddr, &ch,1);
+   else if ( len > 1 ) stralloc_catb(&chkaddr, &ch,1);
    if (substdio_get(&ssin,&ch,1) < 1) die_read();
    if (substdio_put(&ssout,&ch,1) == -1) die_write();
    if (!ch) break;
   }
  if (len >= ADDR) die(11);
 
+ /* check the from address */
+ stralloc_0(&chkaddr);
+ if (tapped == 0 && tapcheck()==1 ) {
+   tapped = 1;
+   if ( tapaddr.len > 0 ) {
+     if (substdio_bput(&ssout,"T",1) == -1) die_write();
+     if (substdio_bput(&ssout,tapaddr.s,tapaddr.len) == -1) die_write();
+     if (substdio_bput(&ssout,"",1) == -1) die_write();
+   }
+ }
+
  if (substdio_bput(&ssout,QUEUE_EXTRA,QUEUE_EXTRALEN) == -1) die_write();
 
  for (;;)
@@ -237,10 +268,24 @@
    if (substdio_bput(&ssout,&ch,1) == -1) die_write();
    for (len = 0;len < ADDR;++len)
     {
+     if ( len == 1 ) stralloc_copyb(&chkaddr, &ch,1);
+     else if ( len > 1 ) stralloc_catb(&chkaddr, &ch,1);
      if (substdio_get(&ssin,&ch,1) < 1) die_read();
      if (substdio_bput(&ssout,&ch,1) == -1) die_write();
      if (!ch) break;
     }
+
+    /* check the to address */
+    stralloc_0(&chkaddr);
+    if (tapped == 0 && tapcheck()==1 ) {
+      tapped = 1;
+      if ( tapaddr.len > 0 ) {
+        if (substdio_bput(&ssout,"T",1) == -1) die_write();
+        if (substdio_bput(&ssout,tapaddr.s,tapaddr.len) == -1) die_write();
+        if (substdio_bput(&ssout,"",1) == -1) die_write();
+       }
+     }
+
    if (len >= ADDR) die(11);
   }
 
@@ -252,3 +297,42 @@
  triggerpull();
  die(0);
 }
+
+int tapcheck()
+{
+  int i = 0;
+  int j = 0;
+  int x = 0;
+  int negate = 0;
+  stralloc curregex = {0};
+  char tmpbuf[200];
+
+  while (j < tap.len) {
+    i = j;
+    while ((tap.s[i] != ':') && (i < tap.len)) i++;
+    if (tap.s[j] == '!') {
+      negate = 1;
+      j++;
+    }
+    stralloc_copys(&tapaddr, &tap.s[i+1]);
+
+    stralloc_copyb(&curregex,tap.s + j,(i - j));
+    stralloc_0(&curregex);
+    x = matchregex(chkaddr.s, curregex.s, tmpbuf);
+
+    while ((tap.s[i] != '\0') && (i < tap.len)) i++;
+  
+    if ((negate) && (x == 0)) {
+      return 1;
+    }
+    if (!(negate) && (x > 0)) {
+      return 1;
+    }
+    j = i + 1;
+    negate = 0;
+
+
+  }
+  return 0;
+}
+
diff -Naur ./qmail-remote.8 ../qmail-1.03-build-10/qmail-remote.8
--- ./qmail-remote.8	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-remote.8	2006-04-27 11:10:31.000000000 -0500
@@ -114,6 +114,10 @@
 always exits zero.
 .SH "CONTROL FILES"
 .TP 5
+.I clientcert.pem
+SSL certificate that is used to authenticate with the remote server
+during a TLS session.
+.TP 5
 .I helohost
 Current host name,
 for use solely in saying hello to the remote SMTP server.
@@ -123,6 +127,16 @@
 otherwise
 .B qmail-remote
 refuses to run.
+
+.TP 5
+.I notlshosts/<FQDN>
+.B qmail-remote
+will not try TLS on servers for which this file exists
+.RB ( <FQDN>
+is the fully-qualified domain name of the server).
+.IR (tlshosts/<FQDN>.pem
+takes precedence over this file however).
+
 .TP 5
 .I smtproutes
 Artificial SMTP routes.
@@ -156,6 +170,8 @@
 this tells
 .B qmail-remote
 to look up MX records as usual.
+.I port 
+value of 465 (deprecated smtps port) causes TLS session to be started.
 .I smtproutes
 may include wildcards:
 
@@ -195,6 +211,33 @@
 .B qmail-remote
 will wait for each response from the remote SMTP server.
 Default: 1200.
+
+.TP 5
+.I tlsclientciphers
+A set of OpenSSL client cipher strings. Multiple ciphers
+contained in a string should be separated by a colon.
+
+.TP 5
+.I tlshosts/<FQDN>.pem
+.B qmail-remote
+requires TLS authentication from servers for which this certificate exists
+.RB ( <FQDN>
+is the fully-qualified domain name of the server). One of the
+.I dNSName
+or the
+.I CommonName
+attributes have to match.
+
+.B WARNING:
+this option may cause mail to be delayed, bounced, doublebounced, or lost.
+
+.TP 5
+.I tlshosts/exhaustivelist
+if this file exists
+no TLS will be tried on hosts other than those for which a file
+.B tlshosts/<FQDN>.pem
+exists.
+
 .SH "SEE ALSO"
 addresses(5),
 envelopes(5),
diff -Naur ./qmail-remote.c ../qmail-1.03-build-10/qmail-remote.c
--- ./qmail-remote.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-remote.c	2006-04-27 11:10:31.000000000 -0500
@@ -28,6 +28,7 @@
 #include "timeoutconn.h"
 #include "timeoutread.h"
 #include "timeoutwrite.h"
+#include "base64.h"
 
 #define HUGESMTPTEXT 5000
 
@@ -43,11 +44,27 @@
 struct constmap maproutes;
 stralloc host = {0};
 stralloc sender = {0};
+stralloc auth_smtp_user = {0};
+stralloc auth_smtp_pass = {0};
+stralloc auth_b64_user = {0};
+stralloc auth_b64_pass = {0};
+stralloc auth_status = {0};
 
 saa reciplist = {0};
 
 struct ip_address partner;
 
+#ifdef TLS
+# include <sys/stat.h>
+# include "tls.h"
+# include "ssl_timeoutio.h"
+# include <openssl/x509v3.h>
+# define EHLO 1
+
+int tls_init();
+const char *ssl_err_str = 0;
+#endif 
+
 void out(s) char *s; { if (substdio_puts(subfdoutsmall,s) == -1) _exit(0); }
 void zero() { if (substdio_put(subfdoutsmall,"\0",1) == -1) _exit(0); }
 void zerodie() { zero(); substdio_flush(subfdoutsmall); _exit(0); }
@@ -85,6 +102,18 @@
 Sorry. Although I'm listed as a best-preference MX or A for that host,\n\
 it isn't in my control/locals file, so I don't treat it as local. (#5.4.6)\n");
 zerodie(); }
+void auth_user_not_set() {
+  if(!stralloc_copys(&auth_status, \
+    "User and password not set, continuing without authentication.\n"))
+    temp_nomem();
+  if(!stralloc_0(&auth_status)) temp_nomem();
+}
+void no_supported_auth() {
+  if(!stralloc_copys(&auth_status, \
+    "No supported AUTH method found, continuing without authentication.\n"))
+    temp_nomem();
+  if(!stralloc_0(&auth_status)) temp_nomem();
+}
 
 void outhost()
 {
@@ -99,6 +128,9 @@
   outhost();
   out(" but connection died. ");
   if (flagcritical) out("Possible duplicate! ");
+#ifdef TLS
+  if (ssl_err_str) { out(ssl_err_str); out(" "); }
+#endif
   out("(#4.4.2)\n");
   zerodie();
 }
@@ -110,6 +142,12 @@
 int saferead(fd,buf,len) int fd; char *buf; int len;
 {
   int r;
+#ifdef TLS
+  if (ssl) {
+    r = ssl_timeoutread(timeout, smtpfd, smtpfd, ssl, buf, len);
+    if (r < 0) ssl_err_str = ssl_error_str();
+  } else
+#endif
   r = timeoutread(timeout,smtpfd,buf,len);
   if (r <= 0) dropped();
   return r;
@@ -117,6 +155,12 @@
 int safewrite(fd,buf,len) int fd; char *buf; int len;
 {
   int r;
+#ifdef TLS
+  if (ssl) {
+    r = ssl_timeoutwrite(timeout, smtpfd, smtpfd, ssl, buf, len);
+    if (r < 0) ssl_err_str = ssl_error_str();
+  } else
+#endif 
   r = timeoutwrite(timeout,smtpfd,buf,len);
   if (r <= 0) dropped();
   return r;
@@ -163,6 +207,65 @@
   return code;
 }
 
+#ifdef EHLO
+saa ehlokw = {0}; /* list of EHLO keywords and parameters */
+int maxehlokwlen = 0;
+
+unsigned long ehlo()
+{
+  stralloc *sa;
+  char *s, *e, *p;
+  unsigned long code;
+
+  if (ehlokw.len > maxehlokwlen) maxehlokwlen = ehlokw.len;
+  ehlokw.len = 0;
+
+# ifdef MXPS
+  if (type == 's') return 0;
+# endif
+
+  substdio_puts(&smtpto, "EHLO ");
+  substdio_put(&smtpto, helohost.s, helohost.len);
+  substdio_puts(&smtpto, "\r\n");
+  substdio_flush(&smtpto);
+
+  code = smtpcode();
+  if (code != 250) return code;
+
+  s = smtptext.s;
+  while (*s++ != '\n') ; /* skip the first line: contains the domain */
+
+  e = smtptext.s + smtptext.len - 6; /* 250-?\n */
+  while (s <= e)
+  {
+    int wasspace = 0;
+
+    if (!saa_readyplus(&ehlokw, 1)) temp_nomem();
+    sa = ehlokw.sa + ehlokw.len++;
+    if (ehlokw.len > maxehlokwlen) *sa = sauninit; else sa->len = 0;
+
+     /* smtptext is known to end in a '\n' */
+     for (p = (s += 4); ; ++p)
+       if (*p == '\n' || *p == ' ' || *p == '\t') {
+         if (!wasspace)
+           if (!stralloc_catb(sa, s, p - s) || !stralloc_0(sa)) temp_nomem();
+         if (*p == '\n') break;
+         wasspace = 1;
+       } else if (wasspace == 1) {
+         wasspace = 0;
+         s = p;
+       }
+    s = ++p;
+
+    /* keyword should consist of alpha-num and '-'
+     * broken AUTH might use '=' instead of space */
+    for (p = sa->s; *p; ++p) if (*p == '=') { *p = 0; break; }
+  }
+
+  return 250;
+}
+#endif
+
 void outsmtptext()
 {
   int i; 
@@ -179,6 +282,11 @@
 char *prepend;
 char *append;
 {
+#ifdef TLS
+  /* shouldn't talk to the client unless in an appropriate state */
+  int state = ssl ? ssl->state : SSL_ST_BEFORE;
+  if (state & SSL_ST_OK || (!smtps && state & SSL_ST_BEFORE))
+#endif
   substdio_putsflush(&smtpto,"QUIT\r\n");
   /* waiting for remote side is just too ridiculous */
   out(prepend);
@@ -186,6 +294,30 @@
   out(append);
   out(".\n");
   outsmtptext();
+
+#if defined(TLS) && defined(DEBUG)
+  if (ssl) {
+    X509 *peercert;
+
+    out("STARTTLS proto="); out(SSL_get_version(ssl));
+    out("; cipher="); out(SSL_get_cipher(ssl));
+
+    /* we want certificate details */
+    if (peercert = SSL_get_peer_certificate(ssl)) {
+      char *str;
+
+      str = X509_NAME_oneline(X509_get_subject_name(peercert), NULL, 0);
+      out("; subject="); out(str); OPENSSL_free(str);
+
+      str = X509_NAME_oneline(X509_get_issuer_name(peercert), NULL, 0);
+      out("; issuer="); out(str); OPENSSL_free(str);
+
+      X509_free(peercert);
+    }
+    out(";\n");
+  }
+#endif
+
   zerodie();
 }
 
@@ -214,26 +346,297 @@
   substdio_flush(&smtpto);
 }
 
+#ifdef TLS
+char *partner_fqdn = 0;
+
+# define TLS_QUIT quit(ssl ? "; connected to " : "; connecting to ", "")
+void tls_quit(const char *s1, const char *s2)
+{
+  out(s1); if (s2) { out(": "); out(s2); } TLS_QUIT;
+}
+# define tls_quit_error(s) tls_quit(s, ssl_error())
+
+int match_partner(const char *s, int len)
+{
+  if (!case_diffb(partner_fqdn, len, s) && !partner_fqdn[len]) return 1;
+  /* we also match if the name is *.domainname */
+  if (*s == '*') {
+    const char *domain = partner_fqdn + str_chr(partner_fqdn, '.');
+    if (!case_diffb(domain, --len, ++s) && !domain[len]) return 1;
+  }
+  return 0;
+}
+
+/* don't want to fail handshake if certificate can't be verified */
+int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
+
+int tls_init()
+{
+  int i;
+  SSL *myssl;
+  SSL_CTX *ctx;
+  stralloc saciphers = {0};
+  const char *ciphers, *servercert = 0;
+
+  if (partner_fqdn) {
+    struct stat st;
+    stralloc tmp = {0};
+    if (!stralloc_copys(&tmp, "control/tlshosts/")
+      || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn))
+      || !stralloc_catb(&tmp, ".pem", 5)) temp_nomem();
+    if (stat(tmp.s, &st) == 0)
+      servercert = tmp.s;
+    else {
+      if (!stralloc_copys(&tmp, "control/notlshosts/")
+        || !stralloc_catb(&tmp, partner_fqdn, str_len(partner_fqdn)+1))
+        temp_nomem();
+      if ((stat("control/tlshosts/exhaustivelist", &st) == 0) ||
+        (stat(tmp.s, &st) == 0)) {
+         alloc_free(tmp.s);
+         return 0;
+      }
+      alloc_free(tmp.s);
+    }
+  }
+ 
+  if (!smtps) {
+    stralloc *sa = ehlokw.sa;
+    unsigned int len = ehlokw.len;
+    /* look for STARTTLS among EHLO keywords */
+    for ( ; len && case_diffs(sa->s, "STARTTLS"); ++sa, --len) ;
+    if (!len) {
+      if (!servercert) return 0;
+      out("ZNo TLS achieved while "); out(servercert);
+      out(" exists"); smtptext.len = 0; TLS_QUIT;
+    }
+  }
+
+  SSL_library_init();
+  ctx = SSL_CTX_new(SSLv23_client_method());
+  if (!ctx) {
+    if (!smtps && !servercert) return 0;
+    smtptext.len = 0;
+    tls_quit_error("ZTLS error initializing ctx");
+  }
+
+  if (servercert) {
+    if (!SSL_CTX_load_verify_locations(ctx, servercert, NULL)) {
+      SSL_CTX_free(ctx);
+      smtptext.len = 0;
+      out("ZTLS unable to load "); tls_quit_error(servercert);
+    }
+    /* set the callback here; SSL_set_verify didn't work before 0.9.6c */
+    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
+  }
+
+  /* let the other side complain if it needs a cert and we don't have one */
+# define CLIENTCERT "control/clientcert.pem"
+  if (SSL_CTX_use_certificate_chain_file(ctx, CLIENTCERT))
+    SSL_CTX_use_RSAPrivateKey_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM);
+# undef CLIENTCERT
+
+  myssl = SSL_new(ctx);
+  SSL_CTX_free(ctx);
+  if (!myssl) {
+    if (!smtps && !servercert) return 0;
+    smtptext.len = 0;
+    tls_quit_error("ZTLS error initializing ssl");
+  }
+
+  if (!smtps) substdio_putsflush(&smtpto, "STARTTLS\r\n");
+
+  /* while the server is preparing a responce, do something else */
+  if (control_readfile(&saciphers, "control/tlsclientciphers", 0) == -1)
+    { SSL_free(myssl); temp_control(); }
+  if (saciphers.len) {
+    for (i = 0; i < saciphers.len - 1; ++i)
+      if (!saciphers.s[i]) saciphers.s[i] = ':';
+    ciphers = saciphers.s;
+  }
+  else ciphers = "DEFAULT";
+  SSL_set_cipher_list(myssl, ciphers);
+  alloc_free(saciphers.s);
+
+  /* SSL_set_options(myssl, SSL_OP_NO_TLSv1); */
+  SSL_set_fd(myssl, smtpfd);
+
+  /* read the responce to STARTTLS */
+  if (!smtps) {
+    if (smtpcode() != 220) {
+      SSL_free(myssl);
+      if (!servercert) return 0;
+      out("ZSTARTTLS rejected while ");
+      out(servercert); out(" exists"); TLS_QUIT;
+    }
+    smtptext.len = 0;
+  }
+
+  ssl = myssl;
+  if (ssl_timeoutconn(timeout, smtpfd, smtpfd, ssl) <= 0)
+    tls_quit("ZTLS connect failed", ssl_error_str());
+
+  if (servercert) {
+    X509 *peercert;
+    STACK_OF(GENERAL_NAME) *gens;
+
+    int r = SSL_get_verify_result(ssl);
+    if (r != X509_V_OK) {
+      out("ZTLS unable to verify server with ");
+      tls_quit(servercert, X509_verify_cert_error_string(r));
+    }
+    alloc_free(servercert);
+
+    peercert = SSL_get_peer_certificate(ssl);
+    if (!peercert) {
+      out("ZTLS unable to verify server ");
+      tls_quit(partner_fqdn, "no certificate provided");
+    }
+
+    /* RFC 2595 section 2.4: find a matching name
+     * first find a match among alternative names */
+    gens = X509_get_ext_d2i(peercert, NID_subject_alt_name, 0, 0);
+    if (gens) {
+      for (i = 0, r = sk_GENERAL_NAME_num(gens); i < r; ++i)
+      {
+        const GENERAL_NAME *gn = sk_GENERAL_NAME_value(gens, i);
+        if (gn->type == GEN_DNS)
+          if (match_partner(gn->d.ia5->data, gn->d.ia5->length)) break;
+      }
+      sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
+    }
+
+    /* no alternative name matched, look up commonName */
+    if (!gens || i >= r) {
+      stralloc peer = {0};
+      X509_NAME *subj = X509_get_subject_name(peercert);
+      i = X509_NAME_get_index_by_NID(subj, NID_commonName, -1);
+      if (i >= 0) {
+        const ASN1_STRING *s = X509_NAME_get_entry(subj, i)->value;
+        if (s) { peer.len = s->length; peer.s = s->data; }
+      }
+      if (peer.len <= 0) {
+        out("ZTLS unable to verify server ");
+        tls_quit(partner_fqdn, "certificate contains no valid commonName");
+      }
+      if (!match_partner(peer.s, peer.len)) {
+        out("ZTLS unable to verify server "); out(partner_fqdn);
+        out(": received certificate for "); outsafe(&peer); TLS_QUIT;
+      }
+    }
+
+    X509_free(peercert);
+  }
+
+  if (smtps) if (smtpcode() != 220)
+    quit("ZTLS Connected to "," but greeting failed");
+
+  return 1;
+}
+#endif
+
 stralloc recip = {0};
 
+void mail_without_auth()
+{
+  substdio_puts(&smtpto,"MAIL FROM:<");
+  substdio_put(&smtpto,sender.s,sender.len);
+  substdio_puts(&smtpto,">\r\n");
+  substdio_flush(&smtpto);
+}
+
 void smtp()
 {
   unsigned long code;
   int flagbother;
-  int i;
+  int i, j;
+
+#ifndef PORT_SMTP
+  /* the qmtpc patch uses smtp_port and undefines PORT_SMTP */
+# define port smtp_port
+#endif
+
+#ifdef TLS
+# ifdef MXPS
+  if (type == 'S') smtps = 1;
+  else if (type != 's')
+# endif
+    if (port == 465) smtps = 1;
+  if (!smtps)
+#endif
  
   if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
  
+#ifdef EHLO
+# ifdef TLS
+  if (!smtps)
+# endif
+  code = ehlo();
+
+# ifdef TLS
+  if (tls_init())
+    /* RFC2487 says we should issue EHLO (even if we might not need
+     * extensions); at the same time, it does not prohibit a server
+     * to reject the EHLO and make us fallback to HELO */
+    code = ehlo();
+# endif
+
+  if (code == 250) {
+    /* add EHLO response checks here */
+
+    /* and if EHLO failed, use HELO */
+  } else {
+#endif
+ 
   substdio_puts(&smtpto,"HELO ");
   substdio_put(&smtpto,helohost.s,helohost.len);
   substdio_puts(&smtpto,"\r\n");
   substdio_flush(&smtpto);
   if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
  
-  substdio_puts(&smtpto,"MAIL FROM:<");
-  substdio_put(&smtpto,sender.s,sender.len);
-  substdio_puts(&smtpto,">\r\n");
-  substdio_flush(&smtpto);
+#ifdef EHLO
+  }
+#endif
+  i = 0;
+  if (auth_smtp_user.len && auth_smtp_pass.len)  {
+    while((i += str_chr(smtptext.s+i,'\n') + 1) &&
+         (i+8 < smtptext.len) &&
+         str_diffn(smtptext.s+i+4,"AUTH",4));
+    if (((i+9 < smtptext.len) &&
+        (str_diffn(smtptext.s+i+9," ",1) ||
+         str_diffn(smtptext.s+i+9,"=",1))) &&
+       ( i += str_chr(smtptext.s+i,'L') + 1 ) &&
+       str_diffn(smtptext.s+i+1,"OGIN",4)) {
+
+      if (b64encode(&auth_smtp_user,&auth_b64_user)) quit("ZConnected to "," but unable to base64encode user");
+      if (b64encode(&auth_smtp_pass,&auth_b64_pass)) quit("ZConnected to "," but unable to base64encode pass");
+
+      substdio_puts(&smtpto,"AUTH LOGIN\r\n");
+      substdio_flush(&smtpto);
+      if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (AUTH LOGIN)");
+      substdio_put(&smtpto,auth_b64_user.s,auth_b64_user.len);
+      substdio_puts(&smtpto,"\r\n");
+      substdio_flush(&smtpto);
+      if (smtpcode() != 334) quit("ZConnected to "," but authentication was rejected (username)");
+      substdio_put(&smtpto,auth_b64_pass.s,auth_b64_pass.len);
+      substdio_puts(&smtpto,"\r\n");
+      substdio_flush(&smtpto);
+      if (smtpcode() != 235) quit("ZConnected to "," but authentication was rejected (password)");
+      substdio_puts(&smtpto,"MAIL FROM:<");
+      substdio_put(&smtpto,sender.s,sender.len);
+      substdio_puts(&smtpto,"> AUTH=<");
+      substdio_put(&smtpto,sender.s,sender.len);
+      substdio_puts(&smtpto,">\r\n");
+      substdio_flush(&smtpto);
+      if(!stralloc_copys(&auth_status, "Delivered with authenticated connection to \n")) temp_nomem();
+      if(!stralloc_0(&auth_status)) temp_nomem();
+    } else {
+      no_supported_auth();
+      mail_without_auth();
+    }
+  } else {
+    auth_user_not_set();
+    mail_without_auth();
+  }
   code = smtpcode();
   if (code >= 500) quit("DConnected to "," but sender was rejected");
   if (code >= 400) quit("ZConnected to "," but sender was rejected");
@@ -246,15 +649,22 @@
     substdio_flush(&smtpto);
     code = smtpcode();
     if (code >= 500) {
-      out("h"); outhost(); out(" does not like recipient.\n");
+      out("h"); out(auth_status.s); outhost();
+      out(" does not like recipient.\n");
       outsmtptext(); zero();
     }
     else if (code >= 400) {
-      out("s"); outhost(); out(" does not like recipient.\n");
+      out("s"); out(auth_status.s); outhost();
+      out(" does not like recipient.\n");
       outsmtptext(); zero();
     }
     else {
-      out("r"); zero();
+      /*
+       * James Raftery <james@now.ie>
+       * Log _real_ envelope recipient, post canonicalisation.
+       */
+      out("r"); out(auth_status.s);
+      out("<"); outsafe(&reciplist.sa[i]); out("> "); zero();
       flagbother = 1;
     }
   }
@@ -331,7 +741,7 @@
 char **argv;
 {
   static ipalloc ip = {0};
-  int i;
+  int i,j;
   unsigned long random;
   char **recips;
   unsigned long prefme;
@@ -347,6 +757,9 @@
  
   if (!stralloc_copys(&host,argv[1])) temp_nomem();
  
+  if (!stralloc_copys(&auth_smtp_user,"")) temp_nomem();
+  if (!stralloc_copys(&auth_smtp_pass,"")) temp_nomem();
+
   relayhost = 0;
   for (i = 0;i <= host.len;++i)
     if ((i == 0) || (i == host.len) || (host.s[i] == '.'))
@@ -355,6 +768,16 @@
   if (relayhost && !*relayhost) relayhost = 0;
  
   if (relayhost) {
+    i = str_chr(relayhost,' ');
+    if (relayhost[i]) {
+      j = str_chr(relayhost + i + 1,' ');
+      if (relayhost[j]) {
+	relayhost[i] = 0;
+	relayhost[i + j + 1] = 0;
+	if (!stralloc_copys(&auth_smtp_user,relayhost + i + 1)) temp_nomem();
+	if (!stralloc_copys(&auth_smtp_pass,relayhost + i + j + 2)) temp_nomem();
+      }
+    }
     i = str_chr(relayhost,':');
     if (relayhost[i]) {
       scan_ulong(relayhost + i + 1,&port);
@@ -417,6 +840,9 @@
     if (timeoutconn(smtpfd,&ip.ix[i].ip,(unsigned int) port,timeoutconnect) == 0) {
       tcpto_err(&ip.ix[i].ip,0);
       partner = ip.ix[i].ip;
+#ifdef TLS
+      partner_fqdn = ip.ix[i].fqdn;
+#endif
       smtp(); /* does not return */
     }
     tcpto_err(&ip.ix[i].ip,errno == error_timeout);
diff -Naur ./qmail-send.c ../qmail-1.03-build-10/qmail-send.c
--- ./qmail-send.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-send.c	2006-05-05 19:42:35.000000000 -0500
@@ -262,6 +262,8 @@
  while (!stralloc_copys(&comm_buf[c],"")) nomem();
  ch = delnum;
  while (!stralloc_append(&comm_buf[c],&ch)) nomem();
+ ch = delnum >> 8;
+ while (!stralloc_append(&comm_buf[c],&ch)) nomem();
  fnmake_split(id);
  while (!stralloc_cats(&comm_buf[c],fn.s)) nomem();
  while (!stralloc_0(&comm_buf[c])) nomem();
@@ -906,41 +908,42 @@
      dline[c].len = REPORTMAX;
      /* qmail-lspawn and qmail-rspawn are responsible for keeping it short */
      /* but from a security point of view, we don't trust rspawn */
-   if (!ch && (dline[c].len > 1))
+   if (!ch && (dline[c].len > 2))
     {
      delnum = (unsigned int) (unsigned char) dline[c].s[0];
+     delnum += (unsigned int) ((unsigned int) dline[c].s[1]) << 8;
      if ((delnum < 0) || (delnum >= concurrency[c]) || !d[c][delnum].used)
        log1("warning: internal error: delivery report out of range\n");
      else
       {
        strnum3[fmt_ulong(strnum3,d[c][delnum].delid)] = 0;
-       if (dline[c].s[1] == 'Z')
+       if (dline[c].s[2] == 'Z')
 	 if (jo[d[c][delnum].j].flagdying)
 	  {
-	   dline[c].s[1] = 'D';
+	   dline[c].s[2] = 'D';
 	   --dline[c].len;
 	   while (!stralloc_cats(&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem();
 	   while (!stralloc_0(&dline[c])) nomem();
 	  }
-       switch(dline[c].s[1])
+       switch(dline[c].s[2])
 	{
 	 case 'K':
 	   log3("delivery ",strnum3,": success: ");
-	   logsafe(dline[c].s + 2);
+	   logsafe(dline[c].s + 3);
 	   log1("\n");
 	   markdone(c,jo[d[c][delnum].j].id,d[c][delnum].mpos);
 	   --jo[d[c][delnum].j].numtodo;
 	   break;
 	 case 'Z':
 	   log3("delivery ",strnum3,": deferral: ");
-	   logsafe(dline[c].s + 2);
+	   logsafe(dline[c].s + 3);
 	   log1("\n");
 	   break;
 	 case 'D':
 	   log3("delivery ",strnum3,": failure: ");
-	   logsafe(dline[c].s + 2);
+	   logsafe(dline[c].s + 3);
 	   log1("\n");
-	   addbounce(jo[d[c][delnum].j].id,d[c][delnum].recip.s,dline[c].s + 2);
+	   addbounce(jo[d[c][delnum].j].id,d[c][delnum].recip.s,dline[c].s + 3);
 	   markdone(c,jo[d[c][delnum].j].id,d[c][delnum].mpos);
 	   --jo[d[c][delnum].j].numtodo;
 	   break;
@@ -1544,7 +1547,7 @@
  numjobs = 0;
  for (c = 0;c < CHANNELS;++c)
   {
-   char ch;
+   char ch, ch1;
    int u;
    int r;
    do
@@ -1552,7 +1555,13 @@
    while ((r == -1) && (errno == error_intr));
    if (r < 1)
     { log1("alert: cannot start: hath the daemon spawn no fire?\n"); _exit(111); }
+   do
+     r = read(chanfdin[c],&ch1,1);
+   while ((r == -1) && (errno == error_intr));
+   if (r < 1)
+    { log1("alert: cannot start: hath the daemon spawn no fire?\n"); _exit(111); }
    u = (unsigned int) (unsigned char) ch;
+   u += (unsigned int) ((unsigned char) ch1) << 8;
    if (concurrency[c] > u) concurrency[c] = u;
    numjobs += concurrency[c];
   }
diff -Naur ./qmail-showctl.c ../qmail-1.03-build-10/qmail-showctl.c
--- ./qmail-showctl.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-showctl.c	2006-05-07 11:43:00.000000000 -0500
@@ -15,6 +15,7 @@
 #include "auto_patrn.h"
 #include "auto_spawn.h"
 #include "auto_split.h"
+#include "spf.h"
 
 stralloc me = {0};
 int meok;
@@ -140,7 +141,7 @@
 {
   DIR *dir;
   direntry *d;
-  struct stat stmrh;
+  struct stat stmrh;	/* multiple use */ 
   struct stat stmrhcdb;
 
   substdio_puts(subfdout,"qmail home directory: ");
@@ -214,7 +215,46 @@
     _exit(111);
   }
 
-  do_lst("badmailfrom","Any MAIL FROM is allowed.",""," not accepted in MAIL FROM.");
+  do_lst("badhelo","Any HELO host name is allowed.",""," HELO host name denied if it matches this pattern.");
+  do_lst("badmailfrom","Any MAIL FROM is allowed.",""," MAIL FROM denied if it matches this pattern.");
+  do_lst("badmailfromnorelay","Any MAIL FROM is allowed.",""," MAIL FROM denied if it matches this pattern and RELAYCLIENT is not set.");
+  do_lst("badmailto","No RCPT TO are specifically denied.",""," RCPT TO denied if it matches this pattern.");
+  do_lst("badmailtonorelay","No RCPT TO are specifically denied.",""," RCPT TO denied if it matches this pattern and RELAYCLIENT is not set.");
+
+  do_lst("badloadertypes","Any LOADER types are accepted.",""," not accepted as LOADER type.");
+  /* XXX: check badloadertypes.cdb contents */
+  substdio_puts(subfdout,"\nbadloadertypes.cdb: ");
+  if (stat("badloadertypes",&stmrh) == -1)
+    if (stat("badloadertypes.cdb",&stmrhcdb) == -1)
+      substdio_puts(subfdout,"(Default.) No effect.\n");
+    else
+      substdio_puts(subfdout,"Oops! badloadertypes.cdb exists but badloadertypes doesn't.\n");
+  else
+    if (stat("badloadertypes.cdb",&stmrhcdb) == -1)
+      substdio_puts(subfdout,"Oops! badloadertypes exists but badloadertypes.cdb doesn't.\n");
+    else
+      if (stmrh.st_mtime > stmrhcdb.st_mtime)
+        substdio_puts(subfdout,"Oops! badloadertypes.cdb is older than badloadertypes.\n");
+      else
+        substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
+
+  do_lst("badmimetypes","Any MIME types are accepted.",""," not accepted as MIME type.");
+  /* XXX: check badmimetypes.cdb contents */
+  substdio_puts(subfdout,"\nbadmimetypes.cdb: ");
+  if (stat("badmimetypes",&stmrh) == -1)
+    if (stat("badmimetypes.cdb",&stmrhcdb) == -1)
+      substdio_puts(subfdout,"(Default.) No effect.\n");
+    else
+      substdio_puts(subfdout,"Oops! badmimetypes.cdb exists but badmimetypes doesn't.\n");
+  else
+    if (stat("badmimetypes.cdb",&stmrhcdb) == -1)
+      substdio_puts(subfdout,"Oops! badmimetypes exists but badmimetypes.cdb doesn't.\n");
+    else
+      if (stmrh.st_mtime > stmrhcdb.st_mtime)
+        substdio_puts(subfdout,"Oops! badmimetypes.cdb is older than badmimetypes.\n");
+      else
+        substdio_puts(subfdout,"Modified recently enough; hopefully up to date.\n");
+
   do_str("bouncefrom",0,"MAILER-DAEMON","Bounce user name is ");
   do_str("bouncehost",1,"bouncehost","Bounce host name is ");
   do_int("concurrencylocal","10","Local concurrency is ","");
@@ -257,6 +297,10 @@
 
   do_str("smtpgreeting",1,"smtpgreeting","SMTP greeting: 220 ");
   do_lst("smtproutes","No artificial SMTP routes.","SMTP route: ","");
+  do_int("spfbehavior","0","The SPF behavior is ","");
+  do_str("spfexp",0,SPF_DEFEXP,"The SPF default explanation is: 550 ");
+  do_str("spfguess",0,"","The guess SPF rules are: ");
+  do_str("spfrules",0,"","The local SPF rules are: ");
   do_int("timeoutconnect","60","SMTP client connection timeout is "," seconds");
   do_int("timeoutremote","1200","SMTP client data timeout is "," seconds");
   do_int("timeoutsmtpd","1200","SMTP server data timeout is "," seconds");
@@ -267,7 +311,15 @@
     if (str_equal(d->d_name,"..")) continue;
     if (str_equal(d->d_name,"bouncefrom")) continue;
     if (str_equal(d->d_name,"bouncehost")) continue;
+    if (str_equal(d->d_name,"badhelo")) continue;
+    if (str_equal(d->d_name,"badloadertypes")) continue;
+    if (str_equal(d->d_name,"badloadertypes.cdb")) continue;
+    if (str_equal(d->d_name,"badmimetypes")) continue;
+    if (str_equal(d->d_name,"badmimetypes.cdb")) continue;
     if (str_equal(d->d_name,"badmailfrom")) continue;
+    if (str_equal(d->d_name,"badmailfromnorelay")) continue;
+    if (str_equal(d->d_name,"badmailto")) continue;
+    if (str_equal(d->d_name,"badmailtonorelay")) continue;
     if (str_equal(d->d_name,"bouncefrom")) continue;
     if (str_equal(d->d_name,"bouncehost")) continue;
     if (str_equal(d->d_name,"concurrencylocal")) continue;
@@ -292,6 +344,10 @@
     if (str_equal(d->d_name,"rcpthosts")) continue;
     if (str_equal(d->d_name,"smtpgreeting")) continue;
     if (str_equal(d->d_name,"smtproutes")) continue;
+    if (str_equal(d->d_name,"spfbehavior")) continue;
+    if (str_equal(d->d_name,"spfexp")) continue;
+    if (str_equal(d->d_name,"spfguess")) continue;
+    if (str_equal(d->d_name,"spfrules")) continue;
     if (str_equal(d->d_name,"timeoutconnect")) continue;
     if (str_equal(d->d_name,"timeoutremote")) continue;
     if (str_equal(d->d_name,"timeoutsmtpd")) continue;
diff -Naur ./qmail-smtpd.8 ../qmail-1.03-build-10/qmail-smtpd.8
--- ./qmail-smtpd.8	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-smtpd.8	2006-05-07 11:43:58.000000000 -0500
@@ -14,6 +14,15 @@
 see
 .BR tcp-environ(5) .
 
+If the environment variable
+.B SMTPS
+is non-empty,
+.B qmail-smtpd
+starts a TLS session (to support the deprecated SMTPS protocol,
+normally on port 465). Otherwise,
+.B qmail-smtpd
+offers the STARTTLS extension to ESMTP.
+
 .B qmail-smtpd
 is responsible for counting hops.
 It rejects any message with 100 or more 
@@ -23,7 +32,30 @@
 header fields.
 
 .B qmail-smtpd
-supports ESMTP, including the 8BITMIME and PIPELINING options.
+supports ESMTP, including the 8BITMIME, DATA, PIPELINING, SIZE, and AUTH options.
+.B qmail-smtpd
+includes a \'MAIL FROM:\' parameter parser and obeys \'Auth\' and \'Size\' advertisements.
+.B qmail-smtpd
+can accept LOGIN, PLAIN, and CRAM-MD5 AUTH types. It invokes
+.IR checkprogram ,
+which reads on file descriptor 3 the username, a 0 byte, the password
+or CRAM-MD5 digest/response derived from the SMTP client,
+another 0 byte, a CRAM-MD5 challenge (if applicable to the AUTH type),
+and a final 0 byte.
+.I checkprogram
+invokes
+.I subprogram
+upon successful authentication, which should in turn return 0 to
+.BR qmail-smtpd ,
+effectively setting the environment variables $RELAYCLIENT and $TCPREMOTEINFO
+(any supplied value replaced with the authenticated username).
+.B qmail-smtpd
+will reject the authentication attempt if it receives a nonzero return
+value from
+.I checkprogram
+or
+.IR subprogram .
+
 .SH TRANSPARENCY
 .B qmail-smtpd
 converts the SMTP newline convention into the UNIX newline convention
@@ -37,11 +69,48 @@
 even though such messages violate the SMTP protocol.
 .SH "CONTROL FILES"
 .TP 5
+.I badhelo
+Unacceptable HELO/EHLO host names.
+.B qmail-smtpd
+will reject every recipient address for a message if
+the host name is listed in, 
+or matches a POSIX regular expression pattern listed in,
+.IR badhelo .
+If the 
+.B NOBADHELO 
+environment variable is set, then the contents of 
+.IR badhelo 
+will be ignored.
+For more information, please have a look at doc/README.qregex.
+.TP 5
+.I badloadertypes.cdb
+Unacceptable base64 encoded LOADER types in message.
+.B qmail-smtpd
+will reject every message if 5 significant
+characters (eg.
+.BR Mi5kb )
+in any of it's embedded base64 attachments is identical with one
+compiled into
+.IR badloadertypes.cdb .
+Use
+.B qmail-badloadertypes
+to derive
+.I badloadertypes.cdb
+from
+.IR badloadertypes .
+The control file
+.I badloadertypes.cdb
+is evaluated if the environment variable
+.I $BADLOADERTYPE='M'
+is set and the provided character matches the first character in
+.IR badloadertypes.cdb .
+.TP 5
 .I badmailfrom
 Unacceptable envelope sender addresses.
 .B qmail-smtpd
 will reject every recipient address for a message
-if the envelope sender address is listed in
+if the envelope sender address is listed in, or matches a POSIX regular expression
+pattern listed in,
 .IR badmailfrom .
 A line in
 .I badmailfrom
@@ -49,6 +118,66 @@
 .BR @\fIhost ,
 meaning every address at
 .IR host .
+For more information, please have a look at doc/README.qregex.
+.TP 5
+.I badmimetypes.cdb
+Unacceptable base64 encoded MIME types in message.
+.B qmail-smtpd
+will reject every message if the first 9 significant 
+characters (eg.
+.BR TVqQAAMAA )
+of any of it's embedded base64 attachments types is identical with one
+compiled into
+.IR badmimetypes.cdb .
+Use 
+.B qmail-badmimetypes
+to derive
+.I badmimetypes.cdb
+from
+.IR badmimetypes .
+The control file
+.I badmimetypes.cdb
+is evaluated if the environment variable
+.I $BADMIMETYPE
+is set.
+.TP 5
+.I badmailfromnorelay
+Functions the same as the
+.IR badmailfrom
+control file but is read only if the 
+.B RELAYCLIENT 
+environment variable is not set.
+For more information, please have a look at doc/README.qregex.
+.TP 5
+.I badmailto
+Unacceptable envelope recipient addresses.
+.B qmail-smtpd
+will reject every recipient address for a message if the recipient address
+is listed in,
+or matches a POSIX regular expression pattern listed in,
+.IR badmailto .
+For more information, please have a look at doc/README.qregex.
+.TP 5
+.I badmailtonorelay
+Functions the same as the
+.IR badmailto
+control file but is read only if the
+.B RELAYCLIENT
+environment variable is not set.
+For more information, please have a look at doc/README.qregex.
+
+.TP 5
+.I clientca.pem
+A list of Certifying Authority (CA) certificates that are used to verify
+the client-presented certificates during a TLS-encrypted session.
+
+.TP 5
+.I clientcrl.pem
+A list of Certificate Revocation Lists (CRLs). If present it
+should contain the CRLs of the CAs in 
+.I clientca.pem 
+and client certs will be checked for revocation.
+
 .TP 5
 .I databytes
 Maximum number of bytes allowed in a message,
@@ -76,6 +205,18 @@
 .B DATABYTES
 is set, it overrides
 .IR databytes .
+
+.TP 5
+.I dh1024.pem
+If these 1024 bit DH parameters are provided,
+.B qmail-smtpd
+will use them for TLS sessions instead of generating one on-the-fly 
+(which is very timeconsuming).
+.TP 5
+.I dh512.pem
+512 bit counterpart for 
+.B dh1024.pem. 
+
 .TP 5
 .I localiphost
 Replacement host name for local IP addresses.
@@ -151,6 +292,19 @@
 
 Envelope recipient addresses without @ signs are
 always allowed through.
+
+.TP 5
+.I rsa512.pem
+If this 512 bit RSA key is provided,
+.B qmail-smtpd
+will use it for TLS sessions instead of generating one on-the-fly.
+
+.TP 5
+.I servercert.pem
+SSL certificate to be presented to clients in TLS-encrypted sessions.
+Should contain both the certificate and the private key. Certifying Authority
+(CA) and intermediate certificates can be added at the end of the file.
+
 .TP 5
 .I smtpgreeting
 SMTP greeting message.
@@ -169,6 +323,58 @@
 .B qmail-smtpd
 will wait for each new buffer of data from the remote SMTP client.
 Default: 1200.
+
+.TP 5
+.I tlsclients
+A list of email addresses. When relay rules would reject an incoming message,
+.B qmail-smtpd
+can allow it if the client presents a certificate that can be verified against
+the CA list in
+.I clientca.pem
+and the certificate email address is in
+.IR tlsclients .
+
+.TP 5
+.I tlsserverciphers
+A set of OpenSSL cipher strings. Multiple ciphers contained in a
+string should be separated by a colon. If the environment variable
+.B TLSCIPHERS
+is set to such a string, it takes precedence.
+.TP 5
+.I spfbehavior
+Set to a value between 1 and 6 to enable SPF checks; 0 to disable.
+1 selects 'annotate-only' mode, where
+.B qmail-smtpd
+will annotate incoming email with
+.B Received-SPF
+fields, but will not reject any messages.  2 will produce temporary
+failures on DNS lookup problems so you can make sure you always have
+meaningful Received-SPF headers.  3 selects 'reject' mode,
+where incoming mail will be rejected if the SPF record says 'fail'.  4
+selects a more stricter rejection mode, which is like 'reject' mode,
+except that incoming mail will also be rejected when the SPF record
+says 'softfail'.  5 will also reject when the SPF record says 'neutral',
+and 6 if no SPF records are available at all (or a syntax error was
+encountered). The contents of this file are overridden by the value of
+the
+.B SPFBEHAVIOR
+environment variable, if set.
+Default: 0.
+.TP 5
+.I spfexp
+You can add a line with a an SPF explanation that will be shown to the
+sender in case of a reject. It will override the default one. You can
+use SPF macro expansion.
+.TP 5
+.I spfguess
+You can add a line with SPF rules that will be checked if a sender
+domain doesn't have a SPF record. The local rules will also be used
+in this case.
+.TP 5
+.I spfrules
+You can add a line with SPF rules that will be checked before other SPF
+rules would fail.  This can be used to always allow certain machines to
+send certain mails.
 .SH "SEE ALSO"
 tcp-env(1),
 tcp-environ(5),
diff -Naur ./qmail-smtpd.c ../qmail-1.03-build-10/qmail-smtpd.c
--- ./qmail-smtpd.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/qmail-smtpd.c	2006-05-07 12:50:24.000000000 -0500
@@ -1,3 +1,13 @@
+/*
+ *
+ * includes chkuser v.2.0.8
+ * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
+ *
+ * Author: Antonio Nati tonix@interazioni.it
+ * www.interazioni.it/opensource
+ *
+ */
+
 #include "sig.h"
 #include "readwrite.h"
 #include "stralloc.h"
@@ -23,14 +33,61 @@
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 #include "commands.h"
+#include "spf.h"
+#include "qregex.h"
+#include "strerr.h"
+#include "cdb.h"
+
+/* start chkuser code */
+#include "chkuser.h"
+/* end chkuser code */
+
+#define BMCHECK_BMF 0
+#define BMCHECK_BMFNR 1
+#define BMCHECK_BMT 2
+#define BMCHECK_BMTNR 3
+#define BMCHECK_BHELO 4
+    
+#include "wait.h"
+
+#define CRAM_MD5
+#define AUTHSLEEP 5
 
 #define MAXHOPS 100
 unsigned int databytes = 0;
 int timeout = 1200;
+unsigned int spfbehavior = 0;
+
+const char *protocol = "SMTP";
+
+#ifdef TLS
+#include <sys/stat.h>
+#include "tls.h"
+#include "ssl_timeoutio.h"
+
+void tls_init();
+int tls_verify();
+void tls_nogateway();
+int ssl_rfd = -1, ssl_wfd = -1; /* SSL_get_Xfd() are broken */
+#endif
+
+#define MIMETYPE_LEN 9
+#define LOADER_LEN 5
+
+static int fdbmt;
+int flagmimetype = 0;
+static int fdblt;
+int flagloadertype = 0;
+char *badloaderinit;
 
 int safewrite(fd,buf,len) int fd; char *buf; int len;
 {
   int r;
+#ifdef TLS
+  if (ssl && fd == ssl_wfd)
+    r = ssl_timeoutwrite(timeout, ssl_rfd, ssl_wfd, ssl, buf, len);
+  else
+#endif
   r = timeoutwrite(timeout,fd,buf,len);
   if (r <= 0) _exit(1);
   return r;
@@ -49,29 +106,54 @@
 void die_ipme() { out("421 unable to figure out my IP addresses (#4.3.0)\r\n"); flush(); _exit(1); }
 void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n"); flush(); _exit(1); }
 
-void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
+void err_size() { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); }
+void err_bmf() { out("553 sorry, your envelope sender has been denied (#5.7.1)\r\n"); }
+void err_bmt() { out("553 sorry, your envelope recipient has been denied (#5.7.1)\r\n"); }
+void err_bhelo() { out("553 sorry, your HELO host name has been denied (#5.7.1)\r\n"); }
+#ifndef TLS
 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); }
-void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); }
+#else
+void err_nogateway()
+{
+  out("553 sorry, that domain isn't in my list of allowed rcpthosts");
+  tls_nogateway();
+  out(" (#5.7.1)\r\n");
+}
+#endif
+void err_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); }
 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
 void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); }
 void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); }
-void err_noop() { out("250 ok\r\n"); }
-void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); }
+void err_noop(arg) char *arg; { out("250 ok\r\n"); }
+void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); }
 void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
 
+int err_child() { out("454 oops, problem with child and I can't auth (#4.3.0)\r\n"); return -1; }
+int err_fork() { out("454 oops, child won't start and I can't auth (#4.3.0)\r\n"); return -1; }
+int err_pipe() { out("454 oops, unable to open pipe and I can't auth (#4.3.0)\r\n"); return -1; }
+int err_write() { out("454 oops, unable to write pipe and I can't auth (#4.3.0)\r\n"); return -1; }
+void err_authd() { out("503 you're already authenticated (#5.5.0)\r\n"); }
+void err_authmail() { out("503 no auth during mail transaction (#5.5.0)\r\n"); }
+int err_noauth() { out("504 auth type unimplemented (#5.5.1)\r\n"); return -1; }
+int err_authabrt() { out("501 auth exchange canceled (#5.0.0)\r\n"); return -1; }
+int err_input() { out("501 malformed auth input (#5.5.4)\r\n"); return -1; }
+void err_authfail() { out("535 authentication failed (#5.7.1)\r\n"); }
 
 stralloc greeting = {0};
+stralloc spflocal = {0};
+stralloc spfguess = {0};
+stralloc spfexp = {0};
 
 void smtp_greet(code) char *code;
 {
   substdio_puts(&ssout,code);
   substdio_put(&ssout,greeting.s,greeting.len);
 }
-void smtp_help()
+void smtp_help(arg) char *arg;
 {
-  out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n");
+  out("214 netqmail home page: http://qmail.org/netqmail\r\n");
 }
-void smtp_quit()
+void smtp_quit(arg) char *arg;
 {
   smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
 }
@@ -81,6 +163,7 @@
 char *remoteinfo;
 char *local;
 char *relayclient;
+char *reply554;
 
 stralloc helohost = {0};
 char *fakehelo; /* pointer into helohost, or 0 */
@@ -93,9 +176,21 @@
 
 int liphostok = 0;
 stralloc liphost = {0};
+
 int bmfok = 0;
 stralloc bmf = {0};
-struct constmap mapbmf;
+
+int bmfnrok = 0;
+stralloc bmfnr = {0};
+
+int bmtok = 0;
+stralloc bmt = {0};
+
+int bmtnrok = 0;
+stralloc bmtnr = {0};
+
+int bhelook = 0;
+stralloc bhelo = {0};
 
 void setup()
 {
@@ -109,20 +204,43 @@
   if (liphostok == -1) die_control();
   if (control_readint(&timeout,"control/timeoutsmtpd") == -1) die_control();
   if (timeout <= 0) timeout = 1;
-
   if (rcpthosts_init() == -1) die_control();
 
   bmfok = control_readfile(&bmf,"control/badmailfrom",0);
   if (bmfok == -1) die_control();
-  if (bmfok)
-    if (!constmap_init(&mapbmf,bmf.s,bmf.len,0)) die_nomem();
+
+  bmfnrok = control_readfile(&bmfnr,"control/badmailfromnorelay",0);
+  if (bmfnrok == -1) die_control();
+
+  bmtok = control_readfile(&bmt,"control/badmailto",0);
+  if (bmtok == -1) die_control();
+
+  bmtnrok = control_readfile(&bmtnr,"control/badmailtonorelay",0);
+  if (bmtnrok == -1) die_control();
+
+  bhelook = control_readfile(&bhelo, "control/badhelo",0);
+  if (bhelook == -1) die_control();
+  if (env_get("NOBADHELO")) bhelook = 0;
  
   if (control_readint(&databytes,"control/databytes") == -1) die_control();
   x = env_get("DATABYTES");
   if (x) { scan_ulong(x,&u); databytes = u; }
   if (!(databytes + 1)) --databytes;
  
-  remoteip = env_get("TCPREMOTEIP");
+  if (control_readint(&spfbehavior,"control/spfbehavior") == -1)
+    die_control();
+  x = env_get("SPFBEHAVIOR");
+  if (x) { scan_ulong(x,&u); spfbehavior = u; }
+
+  if (control_readline(&spflocal,"control/spfrules") == -1) die_control();
+  if (spflocal.len && !stralloc_0(&spflocal)) die_nomem();
+  if (control_readline(&spfguess,"control/spfguess") == -1) die_control();
+  if (spfguess.len && !stralloc_0(&spfguess)) die_nomem();
+  if (control_rldef(&spfexp,"control/spfexp",0,SPF_DEFEXP) == -1)
+    die_control();
+  if (!stralloc_0(&spfexp)) die_nomem();
+
+remoteip = env_get("TCPREMOTEIP");
   if (!remoteip) remoteip = "unknown";
   local = env_get("TCPLOCALHOST");
   if (!local) local = env_get("TCPLOCALIP");
@@ -131,6 +249,28 @@
   if (!remotehost) remotehost = "unknown";
   remoteinfo = env_get("TCPREMOTEINFO");
   relayclient = env_get("RELAYCLIENT");
+
+  if (env_get("BADMIMETYPE")) {
+    flagmimetype = 1;
+    fdbmt = open_read("control/badmimetypes.cdb");
+    if (fdbmt == -1 ) flagmimetype = 0;
+  }
+
+  badloaderinit = env_get("BADLOADERTYPE");
+  if (badloaderinit) {
+    if (str_len(badloaderinit) == 1) {
+      flagloadertype = 1;
+      fdblt = open_read("control/badloadertypes.cdb");
+      if (fdblt == -1 ) flagloadertype = 0;
+    }
+  }
+
+  reply554 = env_get("REPLY554"); 
+
+#ifdef TLS
+  if (env_get("SMTPS")) { smtps = 1; tls_init(); }
+  else
+#endif
   dohelo(remotehost);
 }
 
@@ -197,14 +337,48 @@
   return 1;
 }
 
-int bmfcheck()
+int bmcheck(which) int which;
 {
-  int j;
-  if (!bmfok) return 0;
-  if (constmap(&mapbmf,addr.s,addr.len - 1)) return 1;
-  j = byte_rchr(addr.s,addr.len,'@');
-  if (j < addr.len)
-    if (constmap(&mapbmf,addr.s + j,addr.len - j - 1)) return 1;
+  int i = 0;
+  int j = 0;
+  int x = 0;
+  int negate = 0;
+  static stralloc bmb = {0};
+  static stralloc curregex = {0};
+
+  if (which == BMCHECK_BMF) {
+    if (!stralloc_copy(&bmb,&bmf)) die_nomem();
+  } else if (which == BMCHECK_BMFNR) {
+    if (!stralloc_copy(&bmb,&bmfnr)) die_nomem();
+  } else if (which == BMCHECK_BMT) {
+    if (!stralloc_copy(&bmb,&bmt)) die_nomem();
+  } else if (which == BMCHECK_BMTNR) {
+    if (!stralloc_copy(&bmb,&bmtnr)) die_nomem();
+  } else if (which == BMCHECK_BHELO) {
+    if (!stralloc_copy(&bmb,&bhelo)) die_nomem();
+  } else {
+    die_control();
+  }
+
+  while (j < bmb.len) {
+    i = j;
+    while ((bmb.s[i] != '\0') && (i < bmb.len)) i++;
+    if (bmb.s[j] == '!') {
+      negate = 1;
+      j++;
+    }
+    if (!stralloc_copyb(&curregex,bmb.s + j,(i - j))) die_nomem();
+    if (!stralloc_0(&curregex)) die_nomem();
+    if (which == BMCHECK_BHELO) {
+      x = matchregex(helohost.s, curregex.s);
+    } else {
+      x = matchregex(addr.s, curregex.s);
+    }
+    if ((negate) && (x == 0)) return 1;
+    if (!(negate) && (x > 0)) return 1;
+    j = i + 1;
+    negate = 0;
+  }
   return 0;
 }
 
@@ -213,62 +387,289 @@
   int r;
   r = rcpthosts(addr.s,str_len(addr.s));
   if (r == -1) die_control();
+#ifdef TLS
+  if (r == 0) if (tls_verify()) r = -2;
+#endif
   return r;
 }
 
 
 int seenmail = 0;
-int flagbarf; /* defined if seenmail */
+int flagbarfbmf; /* defined if seenmail */
+int flagbarfbmt;
+int flagbarfbhelo;
+int flagsize;
+int flagbarfspf;
+stralloc spfbarfmsg = {0};
 stralloc mailfrom = {0};
 stralloc rcptto = {0};
+stralloc fuser = {0};
+stralloc mfparms = {0};
+
+int mailfrom_size(arg) char *arg;
+{
+  long r;
+  unsigned long sizebytes = 0;
+
+  scan_ulong(arg,&r);
+  sizebytes = r;
+  if (databytes) if (sizebytes > databytes) return 1;
+  return 0;
+}
+
+void mailfrom_auth(arg,len) 
+char *arg; 
+int len;
+{
+  int j;
+
+  if (!stralloc_copys(&fuser,"")) die_nomem();
+  if (case_starts(arg,"<>")) { if (!stralloc_cats(&fuser,"unknown")) die_nomem(); }
+  else 
+    while (len) {
+      if (*arg == '+') {
+        if (case_starts(arg,"+3D")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"=")) die_nomem(); }
+        if (case_starts(arg,"+2B")) { arg=arg+2; len=len-2; if (!stralloc_cats(&fuser,"+")) die_nomem(); }
+      }
+      else
+        if (!stralloc_catb(&fuser,arg,1)) die_nomem();
+      arg++; len--;
+    }
+  if(!stralloc_0(&fuser)) die_nomem();
+  if (!remoteinfo) {
+    remoteinfo = fuser.s;
+    if (!env_unset("TCPREMOTEINFO")) die_read();
+    if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem();
+  }
+}
+
+void mailfrom_parms(arg) char *arg;
+{
+  int i;
+  int len;
+
+    len = str_len(arg);
+    if (!stralloc_copys(&mfparms,"")) die_nomem;
+    i = byte_chr(arg,len,'>');
+    if (i > 4 && i < len) {
+      while (len) {
+        arg++; len--; 
+        if (*arg == ' ' || *arg == '\0' ) {
+           if (case_starts(mfparms.s,"SIZE=")) if (mailfrom_size(mfparms.s+5)) { flagsize = 1; return; }
+           if (case_starts(mfparms.s,"AUTH=")) mailfrom_auth(mfparms.s+5,mfparms.len-5);  
+           if (!stralloc_copys(&mfparms,"")) die_nomem;
+        }
+        else
+          if (!stralloc_catb(&mfparms,arg,1)) die_nomem; 
+      }
+    }
+}
 
 void smtp_helo(arg) char *arg;
 {
   smtp_greet("250 "); out("\r\n");
   seenmail = 0; dohelo(arg);
+  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
 }
+/* ESMTP extensions are published here */
 void smtp_ehlo(arg) char *arg;
 {
-  smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
+#ifdef TLS
+  struct stat st;
+#endif
+  char size[FMT_ULONG];
+  size[fmt_ulong(size,(unsigned int) databytes)] = 0;
+  smtp_greet("250-");
+#ifdef TLS
+  if (!ssl && (stat("control/servercert.pem",&st) == 0))
+    out("\r\n250-STARTTLS");
+#endif
+  out("\r\n250-PIPELINING\r\n250-8BITMIME\r\n");
+  out("250-SIZE "); out(size); out("\r\n");
+#ifdef CRAM_MD5
+  out("250 AUTH LOGIN PLAIN CRAM-MD5\r\n");
+#else
+  out("250 AUTH LOGIN PLAIN\r\n");
+#endif
   seenmail = 0; dohelo(arg);
+  if (bhelook) flagbarfbhelo = bmcheck(BMCHECK_BHELO);
 }
-void smtp_rset()
+void smtp_rset(arg) char *arg;
 {
   seenmail = 0;
   out("250 flushed\r\n");
 }
 void smtp_mail(arg) char *arg;
 {
+  int r;
+
   if (!addrparse(arg)) { err_syntax(); return; }
-  flagbarf = bmfcheck();
+/* start chkuser code */
+  if (chkuser_sender (&addr) != CHKUSER_OK) { return; }
+/* end chkuser code */
+  
+  flagsize = 0;
+  flagbarfspf = 0;
+  mailfrom_parms(arg);
+  if (flagsize) { err_size(); return; }
+  flagbarfbmf = 0; /* bmcheck is skipped for empty envelope senders */
+  if ((bmfok) && (addr.len != 1)) flagbarfbmf = bmcheck(BMCHECK_BMF);
+  if ((!flagbarfbmf) && (bmfnrok) && (addr.len != 1) && (!relayclient)) {
+    flagbarfbmf = bmcheck(BMCHECK_BMFNR);
+  }
+/* start spf code */  
+  if (spfbehavior && !relayclient)
+   { 
+    switch(r = spfcheck()) {
+    case SPF_OK: env_put2("SPFRESULT","pass"); break;
+    case SPF_NONE: env_put2("SPFRESULT","none"); break;
+    case SPF_UNKNOWN: env_put2("SPFRESULT","unknown"); break;
+    case SPF_NEUTRAL: env_put2("SPFRESULT","neutral"); break;
+    case SPF_SOFTFAIL: env_put2("SPFRESULT","softfail"); break;
+    case SPF_FAIL: env_put2("SPFRESULT","fail"); break;
+    case SPF_ERROR: env_put2("SPFRESULT","error"); break;
+    }
+    switch (r) {
+    case SPF_NOMEM:
+      die_nomem();
+    case SPF_ERROR:
+      if (spfbehavior < 2) break;
+      out("451 SPF lookup failure (#4.3.0)\r\n");
+      return;
+    case SPF_NONE:
+    case SPF_UNKNOWN:
+      if (spfbehavior < 6) break;
+    case SPF_NEUTRAL:
+      if (spfbehavior < 5) break;
+    case SPF_SOFTFAIL:
+      if (spfbehavior < 4) break;
+    case SPF_FAIL:
+      if (spfbehavior < 3) break;
+      if (!spfexplanation(&spfbarfmsg)) die_nomem();
+      if (!stralloc_0(&spfbarfmsg)) die_nomem();
+      flagbarfspf = 1;
+    }
+   } 
+  else
+   env_unset("SPFRESULT");
+/* end spf code */  
   seenmail = 1;
   if (!stralloc_copys(&rcptto,"")) die_nomem();
   if (!stralloc_copys(&mailfrom,addr.s)) die_nomem();
   if (!stralloc_0(&mailfrom)) die_nomem();
   out("250 ok\r\n");
 }
+
+void err_spf() {
+  int i,j;
+
+  for(i = 0; i < spfbarfmsg.len; i = j + 1) {
+    j = byte_chr(spfbarfmsg.s + i, spfbarfmsg.len - i, '\n') + i;
+    if (j < spfbarfmsg.len) {
+      out("550-");
+      spfbarfmsg.s[j] = 0;
+      out(spfbarfmsg.s);
+      spfbarfmsg.s[j] = '\n';
+      out("\r\n");
+    } else {
+      out("550 ");
+      out(spfbarfmsg.s);
+      out(" (#5.7.1)\r\n");
+    }
+  }
+}
+
 void smtp_rcpt(arg) char *arg; {
   if (!seenmail) { err_wantmail(); return; }
   if (!addrparse(arg)) { err_syntax(); return; }
-  if (flagbarf) { err_bmf(); return; }
-  if (relayclient) {
+  if (flagbarfspf) { err_spf(); return; }
+  if (flagbarfbhelo) {
+    strerr_warn4("qmail-smtpd: badhelo: <",helohost.s,"> at ",remoteip,0);
+    err_bhelo();
+    return;
+  }
+  if (flagbarfbmf) {
+    strerr_warn4("qmail-smtpd: badmailfrom: <",mailfrom.s,"> at ",remoteip,0);
+    err_bmf();
+    return;
+  }
+  if (bmtok) flagbarfbmt = bmcheck(BMCHECK_BMT);
+  if ((!flagbarfbmt) && (bmtnrok) && (!relayclient)) {
+    flagbarfbmt = bmcheck(BMCHECK_BMTNR);
+  }
+  if (flagbarfbmt) {
+    strerr_warn4("qmail-smtpd: badmailto: <",addr.s,"> at ",remoteip,0);
+    err_bmt();
+    return;
+  }
+
+/*
+ * Original code substituted by chkuser code
+
+if (relayclient) {
     --addr.len;
     if (!stralloc_cats(&addr,relayclient)) die_nomem();
     if (!stralloc_0(&addr)) die_nomem();
   }
   else
     if (!addrallowed()) { err_nogateway(); return; }
+  
+
+ * end of substituted code
+ */
+
+/* start chkuser code */
+  switch (chkuser_realrcpt (&mailfrom, &addr)) {
+
+        case CHKUSER_KO:
+                return;
+                break;
+
+        case CHKUSER_RELAYING:
+                --addr.len;
+                if (!stralloc_cats(&addr,relayclient)) die_nomem();
+                if (!stralloc_0(&addr)) die_nomem();
+                break;
+
+  }
+/* end chkuser code */
+
   if (!stralloc_cats(&rcptto,"T")) die_nomem();
   if (!stralloc_cats(&rcptto,addr.s)) die_nomem();
   if (!stralloc_0(&rcptto)) die_nomem();
   out("250 ok\r\n");
 }
 
+struct qmail qqt;
+unsigned int bytestooverflow = 0;
+
+void spfreceived()
+{
+  stralloc sa = {0};
+  stralloc rcvd_spf = {0};
+
+  if (!spfbehavior || relayclient) return;
+
+  if (!stralloc_copys(&rcvd_spf, "Received-SPF: ")) die_nomem();
+  if (!spfinfo(&sa)) die_nomem();
+  if (!stralloc_cat(&rcvd_spf, &sa)) die_nomem();
+  if (!stralloc_append(&rcvd_spf, "\n")) die_nomem();
+  if (bytestooverflow) {
+    bytestooverflow -= rcvd_spf.len;
+    if (bytestooverflow <= 0) qmail_fail(&qqt);
+  }
+  qmail_put(&qqt,rcvd_spf.s,rcvd_spf.len);
+}
 
 int saferead(fd,buf,len) int fd; char *buf; int len;
 {
   int r;
   flush();
+#ifdef TLS
+  if (ssl && fd == ssl_rfd)
+    r = ssl_timeoutread(timeout, ssl_rfd, ssl_wfd, ssl, buf, len);
+  else
+#endif
   r = timeoutread(timeout,fd,buf,len);
   if (r == -1) if (errno == error_timeout) die_alarm();
   if (r <= 0) die_read();
@@ -278,12 +679,63 @@
 char ssinbuf[1024];
 substdio ssin = SUBSTDIO_FDBUF(saferead,0,ssinbuf,sizeof ssinbuf);
 
-struct qmail qqt;
-unsigned int bytestooverflow = 0;
+
+stralloc line = {0};
+stralloc base64types = {0};
+stralloc badmimetype = {0};
+stralloc badloadertype = {0};
+
+unsigned int nolines = 0;
+unsigned int flag64 = 0;
+unsigned int flagbase = 0;
+unsigned int flagblank = 0;
 
 void put(ch)
 char *ch;
 {
+  uint32 dlen;
+  int i;
+ 
+  if (line.len < 1025)
+    if (!stralloc_catb(&line,ch,1)) die_nomem(); 	/* Reassamble chars to line; prepend with 'L' */
+
+  if (*ch == '\n') {
+     nolines++;
+  
+    if (line.len == 2) { flagblank = nolines; flagbase = 0; }	/* trigger */
+    if (*(line.s+1) == 'C' || *(line.s+1) == 'c')
+      if (case_startb(line.s+1,line.len-2,"content-transfer-encoding: base64")) flag64 = nolines;	/* base64 attachments */
+    if (flag64 && nolines == flagblank+1 && line.len > MIMETYPE_LEN+2) {
+      flagbase = nolines;
+      if (!stralloc_catb(&base64types,line.s+1,MIMETYPE_LEN)) die_nomem();
+      if (!stralloc_0(&base64types)) die_nomem(); 
+      if (flagmimetype == 1) {
+        if (cdb_seek(fdbmt,line.s+1,MIMETYPE_LEN,&dlen)) {
+          if (!stralloc_copyb(&badmimetype,line.s+1,MIMETYPE_LEN)) die_nomem();
+          if (!stralloc_0(&badmimetype)) die_nomem(); 
+          qmail_fail(&qqt);
+          flagmimetype = -1;
+        }
+      }
+    }
+    if (flagloadertype == 1 && flagmimetype != -1) {
+      if (line.len > MIMETYPE_LEN + 2 && flagbase > flagblank) {
+        for ( i = 0; i < line.len - LOADER_LEN; ++i ) {
+          if (*(line.s+i) == *badloaderinit) {
+            if (cdb_seek(fdblt,line.s+i,LOADER_LEN,&dlen)) {
+              if (!stralloc_copyb(&badloadertype,line.s+i,LOADER_LEN)) die_nomem();
+              if (!stralloc_0(&badloadertype)) die_nomem(); 
+              qmail_fail(&qqt);
+              flagloadertype = -1;
+            }
+          }
+        }
+      }
+    }
+    line.len = 0;
+    stralloc_copys(&line,"L");
+  }
+
   if (bytestooverflow)
     if (!--bytestooverflow)
       qmail_fail(&qqt);
@@ -316,8 +768,8 @@
         if (flagmaybex) if (pos == 7) ++*hops;
         if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
         if (flagmaybey) if (pos == 1) flaginheader = 0;
+	++pos;
       }
-      ++pos;
       if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
     }
     switch(state) {
@@ -365,7 +817,7 @@
   out("\r\n");
 }
 
-void smtp_data() {
+void smtp_data(arg) char *arg; {
   int hops;
   unsigned long qp;
   char *qqx;
@@ -374,11 +826,13 @@
   if (!rcptto.len) { err_wantrcpt(); return; }
   seenmail = 0;
   if (databytes) bytestooverflow = databytes + 1;
+  if (base64types.len == 1 ) if (!env_unset("QHPSI")) die_nomem();
   if (qmail_open(&qqt) == -1) { err_qqt(); return; }
   qp = qmail_qp(&qqt);
   out("354 go ahead\r\n");
  
-  received(&qqt,"SMTP",local,remoteip,remotehost,remoteinfo,fakehelo);
+  received(&qqt,protocol,local,remoteip,remotehost,remoteinfo,fakehelo);
+  spfreceived();
   blast(&hops);
   hops = (hops >= MAXHOPS);
   if (hops) qmail_fail(&qqt);
@@ -388,28 +842,506 @@
   qqx = qmail_close(&qqt);
   if (!*qqx) { acceptmessage(qp); return; }
   if (hops) { out("554 too many hops, this message is looping (#5.4.6)\r\n"); return; }
-  if (databytes) if (!bytestooverflow) { out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return; }
+  if (databytes) if (!bytestooverflow) { err_size(); return; }
+  if (flagmimetype == -1) { 
+    out("554 invalid message content "); 
+    if (reply554) out(reply554); 
+    out(" (#5.3.2)\r\n"); 
+    return; 
+  }
+  if (flagloadertype == -1) { 
+    out("554 invalid message content "); 
+    if (reply554) out(reply554); 
+    out(" (#5.3.2)\r\n"); 
+    return; 
+  }
   if (*qqx == 'D') out("554 "); else out("451 ");
   out(qqx + 1);
   out("\r\n");
 }
 
+/* this file is too long ----------------------------------------- SMTP AUTH */
+
+char unique[FMT_ULONG + FMT_ULONG + 3];
+static stralloc authin = {0};   /* input from SMTP client */
+static stralloc user = {0};     /* authorization user-id */
+static stralloc pass = {0};     /* plain passwd or digest */
+static stralloc resp = {0};     /* b64 response */
+#ifdef CRAM_MD5
+static stralloc chal = {0};     /* plain challenge */
+static stralloc slop = {0};     /* b64 challenge */
+#endif
+
+int flagauth = 0;
+char **childargs;
+char ssauthbuf[512];
+substdio ssauth = SUBSTDIO_FDBUF(safewrite,3,ssauthbuf,sizeof(ssauthbuf));
+
+int authgetl(void) {
+  int i;
+
+  if (!stralloc_copys(&authin,"")) die_nomem();
+  for (;;) {
+    if (!stralloc_readyplus(&authin,1)) die_nomem(); /* XXX */
+    i = substdio_get(&ssin,authin.s + authin.len,1);
+    if (i != 1) die_read();
+    if (authin.s[authin.len] == '\n') break;
+    ++authin.len;
+  }
+
+  if (authin.len > 0) if (authin.s[authin.len - 1] == '\r') --authin.len;
+  authin.s[authin.len] = 0;
+  if (*authin.s == '*' && *(authin.s + 1) == 0) { return err_authabrt(); }
+  if (authin.len == 0) { return err_input(); }
+  return authin.len;
+}
+
+int authenticate(void)
+{
+  int child;
+  int wstat;
+  int pi[2];
+
+  if (!stralloc_0(&user)) die_nomem();
+  if (!stralloc_0(&pass)) die_nomem();
+#ifdef CRAM_MD5
+  if (!stralloc_0(&chal)) die_nomem();
+#endif
+
+  if (pipe(pi) == -1) return err_pipe();
+  switch(child = fork()) {
+    case -1:
+      return err_fork();
+    case 0:
+      close(pi[1]);
+      if(fd_copy(3,pi[0]) == -1) return err_pipe();
+      sig_pipedefault();
+        execvp(*childargs, childargs);
+      _exit(1);
+  }
+  close(pi[0]);
+
+  substdio_fdbuf(&ssauth,write,pi[1],ssauthbuf,sizeof ssauthbuf);
+  if (substdio_put(&ssauth,user.s,user.len) == -1) return err_write();
+  if (substdio_put(&ssauth,pass.s,pass.len) == -1) return err_write();
+#ifdef CRAM_MD5
+  if (substdio_put(&ssauth,chal.s,chal.len) == -1) return err_write();
+#endif
+  if (substdio_flush(&ssauth) == -1) return err_write();
+
+  close(pi[1]);
+#ifdef CRAM_MD5
+  if (!stralloc_copys(&chal,"")) die_nomem();
+  if (!stralloc_copys(&slop,"")) die_nomem();
+#endif
+  byte_zero(ssauthbuf,sizeof ssauthbuf);
+  if (wait_pid(&wstat,child) == -1) return err_child();
+  if (wait_crashed(wstat)) return err_child();
+  if (wait_exitcode(wstat)) { sleep(AUTHSLEEP); return 1; } /* no */
+  return 0; /* yes */
+}
+
+int auth_login(arg) char *arg;
+{
+  int r;
+
+  if (*arg) {
+    if (r = b64decode(arg,str_len(arg),&user) == 1) return err_input();
+  }
+  else {
+    out("334 VXNlcm5hbWU6\r\n"); flush();       /* Username: */
+    if (authgetl() < 0) return -1;
+    if (r = b64decode(authin.s,authin.len,&user) == 1) return err_input();
+  }
+  if (r == -1) die_nomem();
+
+  out("334 UGFzc3dvcmQ6\r\n"); flush();         /* Password: */
+
+  if (authgetl() < 0) return -1;
+  if (r = b64decode(authin.s,authin.len,&pass) == 1) return err_input();
+  if (r == -1) die_nomem();
+
+  if (!user.len || !pass.len) return err_input();
+  return authenticate();
+}
+
+int auth_plain(arg) char *arg;
+{
+  int r, id = 0;
+
+  if (*arg) {
+    if (r = b64decode(arg,str_len(arg),&resp) == 1) return err_input();
+  }
+  else {
+    out("334 \r\n"); flush();
+    if (authgetl() < 0) return -1;
+    if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input();
+  }
+  if (r == -1 || !stralloc_0(&resp)) die_nomem();
+  while (resp.s[id]) id++;                       /* "authorize-id\0userid\0passwd\0" */
+
+  if (resp.len > id + 1)
+    if (!stralloc_copys(&user,resp.s + id + 1)) die_nomem();
+  if (resp.len > id + user.len + 2)
+    if (!stralloc_copys(&pass,resp.s + id + user.len + 2)) die_nomem();
+
+  if (!user.len || !pass.len) return err_input();
+  return authenticate();
+}
+
+#ifdef CRAM_MD5
+int auth_cram()
+{
+  int i, r;
+  char *s;
+
+  s = unique;                                           /* generate challenge */
+  s += fmt_uint(s,getpid());
+  *s++ = '.';
+  s += fmt_ulong(s,(unsigned long) now());
+  *s++ = '@';
+  *s++ = 0;
+  if (!stralloc_copys(&chal,"<")) die_nomem();
+  if (!stralloc_cats(&chal,unique)) die_nomem();
+  if (!stralloc_cats(&chal,local)) die_nomem();
+  if (!stralloc_cats(&chal,">")) die_nomem();
+  if (b64encode(&chal,&slop) < 0) die_nomem();
+  if (!stralloc_0(&slop)) die_nomem();
+
+  out("334 ");                                          /* "334 base64_challenge \r\n" */
+  out(slop.s);
+  out("\r\n");
+  flush();
+
+  if (authgetl() < 0) return -1;                        /* got response */
+  if (r = b64decode(authin.s,authin.len,&resp) == 1) return err_input();
+  if (r == -1 || !stralloc_0(&resp)) die_nomem();
+
+  i = str_chr(resp.s,' ');
+  s = resp.s + i;
+  while (*s == ' ') ++s;
+  resp.s[i] = 0;
+  if (!stralloc_copys(&user,resp.s)) die_nomem();       /* userid */
+  if (!stralloc_copys(&pass,s)) die_nomem();            /* digest */
+
+  if (!user.len || !pass.len) return err_input();
+  return authenticate();
+}
+#endif
+
+struct authcmd {
+  char *text;
+  int (*fun)();
+} authcmds[] = {
+  { "login",auth_login }
+,  { "plain",auth_plain }
+#ifdef CRAM_MD5
+, { "cram-md5",auth_cram }
+#endif
+, { 0,err_noauth }
+};
+
+void smtp_auth(arg)
+char *arg;
+{
+  int i;
+  char *cmd = arg;
+
+  if (!*childargs) { out("503 auth not available (#5.3.3)\r\n"); return; }
+  if (flagauth) { err_authd(); return; }
+  if (seenmail) { err_authmail(); return; }
+
+  if (!stralloc_copys(&user,"")) die_nomem();
+  if (!stralloc_copys(&pass,"")) die_nomem();
+  if (!stralloc_copys(&resp,"")) die_nomem();
+#ifdef CRAM_MD5
+  if (!stralloc_copys(&chal,"")) die_nomem();
+#endif
+
+  i = str_chr(cmd,' ');
+  arg = cmd + i;
+  while (*arg == ' ') ++arg;
+  cmd[i] = 0;
+
+  for (i = 0;authcmds[i].text;++i)
+    if (case_equals(authcmds[i].text,cmd)) break;
+
+  switch (authcmds[i].fun(arg)) {
+    case 0:
+      flagauth = 1;
+      protocol = "ESMTPA";
+      relayclient = "";
+      remoteinfo = user.s;
+      if (!env_unset("TCPREMOTEINFO")) die_read();
+      if (!env_put2("TCPREMOTEINFO",remoteinfo)) die_nomem();
+      if (!env_put2("RELAYCLIENT",relayclient)) die_nomem();
+      out("235 ok, go ahead (#2.0.0)\r\n");
+      break;
+    case 1:
+      err_authfail(user.s,authcmds[i].text);
+  }
+}
+
+
+/* this file is too long --------------------------------------------- GO ON */
+
+#ifdef TLS
+stralloc proto = {0};
+int ssl_verified = 0;
+const char *ssl_verify_err = 0;
+
+void smtp_tls(char *arg)
+{
+  if (ssl) err_unimpl();
+  else if (*arg) out("501 Syntax error (no parameters allowed) (#5.5.4)\r\n");
+  else tls_init();
+}
+
+RSA *tmp_rsa_cb(SSL *ssl, int export, int keylen)
+{
+  if (!export) keylen = 512;
+  if (keylen == 512) {
+    FILE *in = fopen("control/rsa512.pem", "r");
+    if (in) {
+      RSA *rsa = PEM_read_RSAPrivateKey(in, NULL, NULL, NULL);
+      fclose(in);
+      if (rsa) return rsa;
+    }
+  }
+  return RSA_generate_key(keylen, RSA_F4, NULL, NULL);
+}
+
+DH *tmp_dh_cb(SSL *ssl, int export, int keylen)
+{
+  if (!export) keylen = 1024;
+  if (keylen == 512) {
+    FILE *in = fopen("control/dh512.pem", "r");
+    if (in) {
+      DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL);
+      fclose(in);
+      if (dh) return dh;
+    }
+  }
+  if (keylen == 1024) {
+    FILE *in = fopen("control/dh1024.pem", "r");
+    if (in) {
+      DH *dh = PEM_read_DHparams(in, NULL, NULL, NULL);
+      fclose(in);
+      if (dh) return dh;
+    }
+  }
+  return DH_generate_parameters(keylen, DH_GENERATOR_2, NULL, NULL);
+} 
+
+/* don't want to fail handshake if cert isn't verifiable */
+int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { return 1; }
+
+void tls_nogateway()
+{
+  /* there may be cases when relayclient is set */
+  if (!ssl || relayclient) return;
+  out("; no valid cert for gatewaying");
+  if (ssl_verify_err) { out(": "); out(ssl_verify_err); }
+}
+void tls_out(const char *s1, const char *s2)
+{
+  out("454 TLS "); out(s1);
+  if (s2) { out(": "); out(s2); }
+  out(" (#4.3.0)\r\n"); flush();
+}
+void tls_err(const char *s) { tls_out(s, ssl_error()); if (smtps) die_read(); }
+
+# define CLIENTCA "control/clientca.pem"
+# define CLIENTCRL "control/clientcrl.pem"
+# define SERVERCERT "control/servercert.pem"
+
+int tls_verify()
+{
+  stralloc clients = {0};
+  struct constmap mapclients;
+
+  if (!ssl || relayclient || ssl_verified) return 0;
+  ssl_verified = 1; /* don't do this twice */
+
+  /* request client cert to see if it can be verified by one of our CAs
+   * and the associated email address matches an entry in tlsclients */
+  switch (control_readfile(&clients, "control/tlsclients", 0))
+  {
+  case 1:
+    if (constmap_init(&mapclients, clients.s, clients.len, 0)) {
+      /* if CLIENTCA contains all the standard root certificates, a
+       * 0.9.6b client might fail with SSL_R_EXCESSIVE_MESSAGE_SIZE;
+       * it is probably due to 0.9.6b supporting only 8k key exchange
+       * data while the 0.9.6c release increases that limit to 100k */
+      STACK_OF(X509_NAME) *sk = SSL_load_client_CA_file(CLIENTCA);
+      if (sk) {
+        SSL_set_client_CA_list(ssl, sk);
+        SSL_set_verify(ssl, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
+        break;
+      }
+      constmap_free(&mapclients);
+    }
+  case 0: alloc_free(clients.s); return 0;
+  case -1: die_control();
+  }
+
+  if (ssl_timeoutrehandshake(timeout, ssl_rfd, ssl_wfd, ssl) <= 0) {
+    const char *err = ssl_error_str();
+    tls_out("rehandshake failed", err); die_read();
+  }
+
+  do { /* one iteration */
+    X509 *peercert;
+    X509_NAME *subj;
+    stralloc email = {0};
+
+    int n = SSL_get_verify_result(ssl);
+    if (n != X509_V_OK)
+      { ssl_verify_err = X509_verify_cert_error_string(n); break; }
+    peercert = SSL_get_peer_certificate(ssl);
+    if (!peercert) break;
+
+    subj = X509_get_subject_name(peercert);
+    n = X509_NAME_get_index_by_NID(subj, NID_pkcs9_emailAddress, -1);
+    if (n >= 0) {
+      const ASN1_STRING *s = X509_NAME_get_entry(subj, n)->value;
+      if (s) { email.len = s->length; email.s = s->data; }
+    }
+
+    if (email.len <= 0)
+      ssl_verify_err = "contains no email address";
+    else if (!constmap(&mapclients, email.s, email.len))
+      ssl_verify_err = "email address not in my list of tlsclients";
+    else {
+      /* add the cert email to the proto if it helped allow relaying */
+      --proto.len;
+      if (!stralloc_cats(&proto, "\n  (cert ") /* continuation line */
+        || !stralloc_catb(&proto, email.s, email.len)
+        || !stralloc_cats(&proto, ")")
+        || !stralloc_0(&proto)) die_nomem();
+      relayclient = "";
+      protocol = proto.s;
+    }
+
+    X509_free(peercert);
+  } while (0);
+  constmap_free(&mapclients); alloc_free(clients.s);
+
+  /* we are not going to need this anymore: free the memory */
+  SSL_set_client_CA_list(ssl, NULL);
+  SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
+
+  return relayclient ? 1 : 0;
+}
+
+void tls_init()
+{
+  SSL *myssl;
+  SSL_CTX *ctx;
+  const char *ciphers;
+  stralloc saciphers = {0};
+  X509_STORE *store;
+  X509_LOOKUP *lookup;
+
+  SSL_library_init();
+
+  /* a new SSL context with the bare minimum of options */
+  ctx = SSL_CTX_new(SSLv23_server_method());
+  if (!ctx) { tls_err("unable to initialize ctx"); return; }
+
+  if (!SSL_CTX_use_certificate_chain_file(ctx, SERVERCERT))
+    { SSL_CTX_free(ctx); tls_err("missing certificate"); return; }
+  SSL_CTX_load_verify_locations(ctx, CLIENTCA, NULL);
+
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+  /* crl checking */
+  store = SSL_CTX_get_cert_store(ctx);
+  if ((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) &&
+      (X509_load_crl_file(lookup, CLIENTCRL, X509_FILETYPE_PEM) == 1))
+    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK |
+                                X509_V_FLAG_CRL_CHECK_ALL);
+#endif
+
+  /* set the callback here; SSL_set_verify didn't work before 0.9.6c */
+  SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb);
+
+  /* a new SSL object, with the rest added to it directly to avoid copying */
+  myssl = SSL_new(ctx);
+  SSL_CTX_free(ctx);
+  if (!myssl) { tls_err("unable to initialize ssl"); return; }
+
+  /* this will also check whether public and private keys match */
+  if (!SSL_use_RSAPrivateKey_file(myssl, SERVERCERT, SSL_FILETYPE_PEM))
+    { SSL_free(myssl); tls_err("no valid RSA private key"); return; }
+
+  ciphers = env_get("TLSCIPHERS");
+  if (!ciphers) {
+    if (control_readfile(&saciphers, "control/tlsserverciphers") == -1)
+      { SSL_free(myssl); die_control(); }
+    if (saciphers.len) { /* convert all '\0's except the last one to ':' */
+      int i;
+      for (i = 0; i < saciphers.len - 1; ++i)
+        if (!saciphers.s[i]) saciphers.s[i] = ':';
+      ciphers = saciphers.s;
+    }
+  }
+  if (!ciphers || !*ciphers) ciphers = "DEFAULT";
+  SSL_set_cipher_list(myssl, ciphers);
+  alloc_free(saciphers.s);
+
+  SSL_set_tmp_rsa_callback(myssl, tmp_rsa_cb);
+  SSL_set_tmp_dh_callback(myssl, tmp_dh_cb);
+  SSL_set_rfd(myssl, ssl_rfd = substdio_fileno(&ssin));
+  SSL_set_wfd(myssl, ssl_wfd = substdio_fileno(&ssout));
+
+  if (!smtps) { out("220 ready for tls\r\n"); flush(); }
+
+  if (ssl_timeoutaccept(timeout, ssl_rfd, ssl_wfd, myssl) <= 0) {
+    /* neither cleartext nor any other response here is part of a standard */
+    const char *err = ssl_error_str();
+    ssl_free(myssl); tls_out("connection failed", err); die_read();
+  }
+  ssl = myssl;
+
+  /* populate the protocol string, used in Received */
+  if (!stralloc_copys(&proto, "(")
+    || !stralloc_cats(&proto, SSL_get_cipher(ssl))
+    || !stralloc_cats(&proto, " encrypted) SMTP")) die_nomem();
+  if (!stralloc_0(&proto)) die_nomem();
+  protocol = proto.s;
+
+  /* have to discard the pre-STARTTLS HELO/EHLO argument, if any */
+  dohelo(remotehost);
+}
+
+# undef SERVERCERT
+# undef CLIENTCA
+
+#endif
+
 struct commands smtpcommands[] = {
   { "rcpt", smtp_rcpt, 0 }
 , { "mail", smtp_mail, 0 }
 , { "data", smtp_data, flush }
+, { "auth", smtp_auth, flush }
 , { "quit", smtp_quit, flush }
 , { "helo", smtp_helo, flush }
 , { "ehlo", smtp_ehlo, flush }
 , { "rset", smtp_rset, 0 }
 , { "help", smtp_help, flush }
+#ifdef TLS
+, { "starttls", smtp_tls, flush }
+#endif
 , { "noop", err_noop, flush }
 , { "vrfy", err_vrfy, flush }
 , { 0, err_unimpl, flush }
 } ;
 
-void main()
+void main(argc,argv)
+int argc;
+char **argv;
 {
+  childargs = argv + 1;
   sig_pipeignore();
   if (chdir(auto_qmail) == -1) die_control();
   setup();
diff -Naur ./qregex.c ../qmail-1.03-build-10/qregex.c
--- ./qregex.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qregex.c	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,57 @@
+/*
+ * qregex (v2)
+ * $Id: qregex.c,v 2.1 2001/12/28 07:05:21 evan Exp $
+ *
+ * Author  : Evan Borgstrom (evan at unixpimps dot org)
+ * Created : 2001/12/14 23:08:16
+ * Modified: $Date: 2001/12/28 07:05:21 $
+ * Revision: $Revision: 2.1 $
+ *
+ * Do POSIX regex matching on addresses for anti-relay / spam control.
+ * It logs to the maillog
+ * See the qregex-readme file included with this tarball.
+ * If you didn't get this file in a tarball please see the following URL:
+ *  http://www.unixpimps.org/software/qregex
+ *
+ * qregex.c is released under a BSD style copyright.
+ * See http://www.unixpimps.org/software/qregex/copyright.html
+ *
+ * Note: this revision follows the coding guidelines set forth by the rest of
+ *       the qmail code and that described at the following URL.
+ *       http://cr.yp.to/qmail/guarantee.html
+ * 
+ */
+
+#include <sys/types.h>
+#include <regex.h>
+#include "qregex.h"
+
+#define REGCOMP(X,Y)    regcomp(&X, Y, REG_EXTENDED|REG_ICASE)
+#define REGEXEC(X,Y)    regexec(&X, Y, (size_t)0, (regmatch_t *)0, (int)0)
+
+int matchregex(char *text, char *regex) {
+  regex_t qreg;
+  int retval = 0;
+
+
+  /* build the regex */
+  if ((retval = REGCOMP(qreg, regex)) != 0) {
+    regfree(&qreg);
+    return(-retval);
+  }
+
+  /* execute the regex */
+  if ((retval = REGEXEC(qreg, text)) != 0) {
+    /* did we just not match anything? */
+    if (retval == REG_NOMATCH) {
+      regfree(&qreg);
+      return(0);
+    }
+    regfree(&qreg);
+    return(-retval);
+  }
+
+  /* signal the match */
+  regfree(&qreg);
+  return(1);
+}
diff -Naur ./qregex.h ../qmail-1.03-build-10/qregex.h
--- ./qregex.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/qregex.h	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,5 @@
+/* simple header file for the matchregex prototype */
+#ifndef _QREGEX_H_
+#define _QREGEX_H_
+int matchregex(char *text, char *regex);
+#endif
diff -Naur ./README ../qmail-1.03-build-10/README
--- ./README	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/README	2006-04-24 21:24:32.000000000 -0500
@@ -3,6 +3,31 @@
 Copyright 1998
 D. J. Bernstein, qmail@pobox.com
 
+netqmail 1.04
+20031024
+No copyright claimed for changes from qmail 1.03 to netqmail 1.04
+Russell Nelson, nelson@qmail.org
+NOTE: netqmail 1.04 is a community-assembled distribution of qmail from
+the official qmail-1.03.tar.gz and patches approved by the community.
+D. J. Bernstein did not participate in, nor has he been asked to
+approve of this distribution.
+
+netqmail 1.05
+20040121
+James Craig Burley claims copyright on the qmail-isoc patch. For
+more details, see the COPYRIGHTS file shipped with the netqmail-1.05
+distribution.
+
+James' patch has been combined with the original netqmail-1.04 patch
+and the result incorporated into a unified netqmail-1.05 patch.
+Apart from James' copyrights, no other copyright is claimed by the
+distributors of netqmail for changes from qmail 1.03 to netqmail 1.05.
+
+NOTE: netqmail 1.05 is a community-assembled distribution of qmail from
+the official qmail-1.03.tar.gz and patches approved by the community.
+D. J. Bernstein did not participate in, nor has he been asked to
+approve of this distribution.
+
 qmail is a secure, reliable, efficient, simple message transfer agent.
 It is meant as a replacement for the entire sendmail-binmail system on
 typical Internet-connected UNIX hosts. See BLURB, BLURB2, BLURB3, and
diff -Naur ./README.auth ../qmail-1.03-build-10/README.auth
--- ./README.auth	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.auth	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,66 @@
+README qmail-smtpd SMTP Authentication
+======================================
+
+
+History:
+--------
+
+This patch is based on Krzysztof Dabrowski's qmail-smtpd-auth-0.31 patch 
+which itself uses "Mrs. Brisby's" initial code. 
+Version 0.41 of this patch fixes the "CAPS-LOCK" typo announcing
+'CRAM_MD5' instead of 'CRAM-MD5' (german keyboard) - tx to Mike Garrison.
+Version 0.42 fixes the '421 unable to read controls (#4.3.0)' problem
+(can't read control/morercpthosts.cdb) because FD 3 was already closed - tx Richard Lyons.
+Version 0.43 fixes the ba64decode() failure in case CRAM_MD5 is not enabled - tx Vladimir Zidar.
+Version 0.51 includes the evaluation of the 'Auth' and the 'Size' parameter in the 'Mail From:' command.
+Version 0.52 uses DJB functions to copy FDs.
+Version 0.56 corrects some minor mistakes displaying the 'Auth' userid.
+Version 0.57 uses keyword "ESMTPA" in Received header in case of authentication to comply with RFC 3848.
+
+
+Scope:
+------
+
+This patch supports RFC 2554 "SMTP Service Extension for Authentication" for qmail-smtpd.
+Additionally, RFC 1870 is honoured ("SMTP Service Extension for Message Size Declaration").
+For more technical details see: http://www.fehcom.de/qmail/docu/smtpauth.html.
+
+
+Installation:
+-------------
+
+* Untar the source in the qmail-1.03 home direcotry.
+* Run ./install_auth.
+* Modify the compile time option "#define CRAM_MD5" to your needs.
+* Re-make qmail.
+
+
+Setup:
+------
+
+In order to use SMTP Authentication you have to use a 'Pluggable Authentication Module'
+PAM to be called by qmail-smtpd; typically
+
+	/var/qmail/bin/qmail-smtpd /bin/checkpassword true 2>&1
+
+Since qmail-smtpd does not run as root, checkpassword has to be made sticky.
+There is no need to include additionally the hostname in the call.
+In order to compute the CRAM-MD5 challenge, qmail-smtpd uses the 'tcplocalhost' information.
+
+
+Changes wrt. Krysztof Dabrowski's patch:
+----------------------------------------
+
+* Avoid the 'hostname' in the call of the PAM.
+* Confirm to Dan Bernstein's checkpassword interface even for CRAM-MD5.
+* Doesn't close FD 2; thus not inhibiting logging to STDERR.
+* Fixed bugs in base64.c.
+* Modified unconditional close of FD 3 in order to sustain reading of 'control/morecpthosts.cdb'.
+* Evaluation of the (informational) Mail From: < > Auth=username.
+* Additional support for the advertised "Size" via 'Mail From: <return-path> SIZE=123456780' (RFC 1870).
+* RFC 3848 conformance for Received header in case of SMTP Auth.
+
+
+Erwin Hoffmann - Cologne 2005-01-23 (www.fehcom.de)
+
+
diff -Naur ./README.domainkeys ../qmail-1.03-build-10/README.domainkeys
--- ./README.domainkeys	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.domainkeys	2006-05-13 13:06:26.000000000 -0500
@@ -0,0 +1,57 @@
+qmail-dk domainkeys implementation into qmailtoaster
+----------------------------------------------------
+Nick Hemmesch <nick@ndhsoft.com>        May 13, 2006
+
+
+INSTALLATION:
+----------------------------------------------------
+You MUST have either a local dns server or dns caching
+on your mail server.
+
+libdomainkeys must installed before qmail-toaster 
+version >= 1.3.2 can be installed.
+
+The default path to the private key is:
+  
+  /var/qmail/control/domainkeys
+  
+Create a domain (yourdomain.com) directory for 
+your domainkeys:
+  
+  mkdir /var/qmail/control/domainkeys/yourdomain.com
+  
+Create your domainkey with dknewkey:
+
+  dknewkey /var/qmail/control/domainkeys/yourdomain.com/private
+  chown -R root:qmail /var/qmail/control/domainkeys/
+  chmod 444 /var/qmail/control/domainkeys/yourdomain.com/private
+  
+dknewkey will also return your dns entry for a Bind zone file,
+BE SURE TO SAVE IT so you can make your dns entry.
+
+If you use djbdns, a typical entry will look like this:
+
+  '_domainkey.yourdomain.com:o=-; r=you@yourdomain.com
+  'private._domainkey.yourdomain.com:k=rsa; p=MEwwDQYJKoZIhvcNAQEBBQ . . .
+
+Test your dns entry with dnstxt, it may take some time for your dns
+to update the roots to make this test:
+
+  dnstxt private._domainkey.yourdomain.com
+
+Your /etc/tcprules.d/tcp.smtp file should look like this (without the "\"s):
+
+  127.:allow,RELAYCLIENT=""
+  :allow,BADMIMETYPE="",BADLOADERTYPE="M",CHKUSER_RCPTLIMIT="50",\
+  CHKUSER_WRONGRCPTLIMIT="10",DKVERIFY="DEGIJKfh",QMAILQUEUE="/var/qmail/bin/simscan",\
+  DKQUEUE="/var/qmail/bin/qmail-queue.orig"
+ 
+  The DKVERIFY statement is very conservative. To reject mail
+  that has domainkeys but resolves to a different, or erroneous,
+  key add "B".  Example: DKVERIFY="BDEGIJKfh"
+
+Note: You will find numerous qmail-dk configurations on the internet
+      that DO NOT work. This setup DOES work and is a "no brainer"
+      to setup.
+      
+----------------------------------------------------
diff -Naur ./README.qregex ../qmail-1.03-build-10/README.qregex
--- ./README.qregex	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.qregex	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,196 @@
+QREGEX (v2) 20040725 - README July 25, 2004
+A Regular Expression matching patch for qmail 1.03 and netqmail
+
+
+OVERVIEW:
+
+qregex adds the ability to match address evelopes via Regular Expressions (REs)
+in the qmail-smtpd process. It has the abiltiy to match `helo/ehlo` (host name),
+`mail from` (envelope sender), and `rcpt to` (envelope recipient) commands.
+It follows all the base rules that are set out with qmail (ie using control
+files) so it makes for easy integretion into an existing setup (see the
+install instructions for more info). The v2 is specified because qregex was
+re-written to better conform to the security guarantee set forth by the author
+of qmail. The original version used stdio.h and stdlib.h for reading the
+control files whereas v2 now uses all stralloc functions which are much more
+regulated against buffer overruns and the like.
+See: http://cr.yp.to/qmail/guarantee.html
+
+
+FEATURES:
+
+Features of qregex include:
+
+1. Performs pattern matching on envelope senders and envelope
+   recipients against REs in the badmailfrom and badmailto control
+   files. Two additional control files, badmailfromnorelay and
+   badmailtonorelay, are used for pattern matching when the 
+   RELAYCLIENT environment variable is not set.
+
+2. Performs pattern matching on the helo/ehlo host name. Setting the
+   NOBADHELO environment variable prevents the host name from being
+   compared to the patterns in the badhelo control file.
+
+3. Matches to patterns are logged
+
+4. Matching is case insensitive.
+
+5. qregex ignores empty envelope senders. An empty envelope sender is not
+   compared to the patterns in the badmailfrom and badmailfromnorelay
+   control files and is always accepted.
+
+
+PLATFORMS:
+
+qregex has been built and tested on the following platforms. I'm sure it won't
+have any problems on any platform that qmail will run on (providing they have
+a regex interface) but if you run into problems let me know.
+
+	- OpenBSD 3.x
+	- FreeBSD 4.x
+	- Mandrake Linux 9.x
+	- SuSE Linux 8.x
+
+
+
+INSTALLATION INSTRUCTIONS:
+
+Installation is very simple, there is only one requirement. You need to use the
+GNU version of the patch utility (http://www.gnu.org/software/patch/patch.html).
+(For Solaris 8 users it is installed as 'gpatch')
+
+- If this is a new setup.
+Unpack the qmail archive, cd into the qmail-1.03 directory and run
+"patch < /path/to/qregex-<version>.patch". Follow the instructions as per the
+included qmail INSTALL file. Once you are done come back to this file and read
+the section on the control files.
+
+If you are using netqmail, then unpack the netqmail archive. Run the collate.sh
+script and cd into the resulting netqmail-<version> directory. From there, run
+"patch < /path/to/qregex-<version>.patch". Complete the netqmail installation
+normally. Once you are done, come back to this file and read the section on the
+control files.
+
+- If this is an existing setup.
+FIRST: create your control files (see below).
+cd into your existing qmail or netqmail source directory. Run
+"patch < /path/to/qregex-<version>.patch" then "make qmail-smtpd". Now run
+./qmail-smtpd and test your new rules to make sure they work as expected.
+
+Install the new binary by cd'ing to /var/qmail/bin and as root (in one command)
+copy the existing binary to 'qmail-smtpd.old' and copy the new binary from the
+source directory to 'qmail-smtpd'.
+(ex. cp qmail-smtpd qmail-smtpd.old && cp ~/qmail-1.03/qmail-smtpd qmail-smtpd)
+
+You can also optionally just run "make setup check" as it will install the
+updated documentation and man pages provided with this patch. Stopping qmail
+before doing the "make setup check" is always a good idea.
+
+
+LOGGING:
+
+qregex will log matches to the patterns in the various control files. Log
+messages will take these three forms depending on which control file was
+matched:
+
+badhelo
+qmail-smtpd: badhelo: <host> at <remote IP>
+
+badmailfrom and badmailfromnorelay
+qmail-smtpd: badmailfrom: <sender address> at <remote IP>
+
+badmailto and badmailtonorelay
+qmail-smtpd: badmailto: <rcpt address> at <remote IP>
+
+
+CONTROL FILES:
+
+qregex provides you with five control files. None of these control files
+is mandatory and you can use them in any combination you choose in your setup.
+
+The "control/badmailfrom" and "control/badmailto" files contain your REs for
+matching against the 'mail from' (envelope sender) and 'rcpt to' (envelope
+recipient) smtp commands respectively.
+The "control/badmailfromnorelay" and "control/badmailtonorelay" match against
+the same commands but are read only when the RELAYCLIENT environment variable
+is not set.
+The "control/badhelo" file matches against the 'helo/ehlo' smtp command.
+
+If you prefer you can symlink the badmailfrom and badmailto control files
+(ln -s badmailfrom badmailto) and maintain fewer sets of rules. Beware
+this might cause problems in certain setups.
+        
+	Here's an example "badhelo" file.
+	-----------------------------------
+	# block host strings with no dot (not a FQDN)
+	!\.
+	-----------------------------------
+	
+	An example "badmailfrom" file.
+	-----------------------------------
+	# this will drop everything containing the string
+	# bad.domain.com or Bad.Domain.Com or BAD.domain.COM
+	bad\.domain\.com
+	# force users to fully qualify themselves
+	# (i.e. deny "user", accept "user@domain")
+	!@
+	-----------------------------------
+
+	And "badmailto" (a little more interesting)
+	-----------------------------------
+	# must not contain invalid characters, brakets or multiple @'s
+	[!%#:*^(){}]
+	@.*@
+	-----------------------------------
+
+You can use the non-RE character '!' to start an RE as a signal to qregex to
+negate the action. As used above in the badmailfrom file, by negating the '@'
+symbol qregex will signal qmail-smtpd to deny the 'mail from' command whenever
+the address doesn't contain an @ symbol. When used inside a bracket expression,
+the '!' character looses this special meaning. This is shown in the badmailto
+example.
+
+The norelay control files follow the same rules as the other control files but
+are intended to address two specific scenarios.
+The badmailfromnorelay file can be used to block mail trying to spoof a domain
+hosted on your mail server. It prevents a mail client that is not allowed to
+relay email through your server from using one of your hosted domains as its
+envelope sender.
+The badmailtonorelay file can be used to create email addresses that cannot
+receive mail from any source not allowed to relay email through your server.
+This is handy for creating email addresses for use only within your own 
+domain(s) that can't receive spam from the world at large.
+
+
+INTERNALS:
+
+qregex (or regexmatch as the function is called) will be called during the
+`helo/ehlo`, `rcpt to` and `mail from` handling routines in "qmail-smtpd.c".
+When called, it will read the proper control file then one by one compile and
+execute the regex on the string passed into qmail-smtpd. If the regex matches
+it returns TRUE (1) and the qmail-smtpd process will deny the user the ability
+to continue. If you change anything and think it betters this patch please
+send me a new diff file so I can take a peek.
+
+
+CONTACT:
+qregex is maintained by:
+	Andrew St. Jean
+	andrew@arda.homeunix.net
+	www.arda.homeunix.net/store/qmail/
+
+Contributers to qregex:
+	Jeremy Kitchen	
+	kitchen at scriptkitchen dot com
+	http://www.scriptkitchen.com/qmail
+
+	Alex Pleiner
+	alex@zeitform.de
+	zeitform Internet Dienste
+	http://www.zeitform.de/
+
+	Thanos Massias
+
+Original qregex patch written by:
+	Evan Borgstrom
+	evan at unixpimps dot org
diff -Naur ./README.remote-auth ../qmail-1.03-build-10/README.remote-auth
--- ./README.remote-auth	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.remote-auth	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,31 @@
+Docs for http://www.qmail.org/qmail-remote_authenticated_smtp.patch
+a patch to convince qmail-remote to use Authenticated SMTP when
+talking to certain hosts.
+
+This version of the patch has been modified by Robert Sanders so that
+base64 encoding of usernames and passwords is done automatically by
+qmail-remote.
+
+After applying the patch, the username password go into
+/var/qmail/control/smtproutes like so:
+
+domain:relay username password
+
+The domain:relay part is identical to a normal smtproutes entry (see
+the qmail-remote man page). For sites that require authentication, you
+simply add two space separated fields to the line, where the first
+field is the username, the second is the password. For example:
+
+inside.af.mil:firewall.af.mil:26 johndoe secret
+
+would send mail for inside.af.mil to firewall.af.mil, port 26 using
+username 'johndoe' and password 'secret'
+
+Since smtproutes will contain plain text usernames and passwords
+you might want to make the file owned by qmailr and set its permissions
+to 0600. Of course, the entries are going to go over the wire in the clear
+anyway as part of the SMTP transaction.
+
+Good luck.
+
+j.
diff -Naur ./README.starttls ../qmail-1.03-build-10/README.starttls
--- ./README.starttls	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.starttls	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,103 @@
+Frederik Vermeulen <qmail-tls akrul inoa.net> 20060104
+http://inoa.net/qmail-tls/
+
+This patch implements RFC 3207 (was RFC 2487) in qmail. 
+This means you can get SSL or TLS encrypted and 
+authenticated SMTP between the MTAs and from MUA to MTA. 
+The code is considered experimental (but has worked for
+many since its first release on 1999-03-21).
+
+Usage: - install OpenSSL-0.9.8 http://www.openssl.org/
+         (any 0.9.6 to 0.9.8 version is presumed to work)
+       - apply patch to netqmail-1.05 http://qmail.org/netqmail
+         (should work on qmail-1.03 too).  The patches to 
+         qmail-remote.c and qmail-smtpd.c can be applied separately.
+       - provide a server certificate in /var/qmail/control/servercert.pem.
+         "make cert" makes a self-signed certificate.
+         "make cert-req" makes a certificate request.
+         Note: you can add the CA certificate and intermediate
+         certs to the end of servercert.pem.
+       - replace qmail-smtpd and/or qmail-remote binary
+       - verify operation (header information should show
+         something like
+         "Received [..] with (DHE-RSA-AES256-SHA encrypted) SMTP;")
+         If you don't have a server to test with, you can test
+         by sending mail to tag-ping@tbs-internet.com,
+         which will bounce your mail.
+
+Optional: - when DEBUG is defined, some extra TLS info will be logged
+          - qmail-remote will authenticate with the certificate in
+            /var/qmail/control/clientcert.pem. By preference this is
+            the same as servercert.pem, where nsCertType should be 
+            == server,client or be a generic certificate (no usage specified). 
+          - when a 512 bit RSA key is provided in /var/qmail/control/rsa512.pem,
+            this key will be used instead of (slow) on-the-fly generation by
+       	    qmail-smtpd. Idem for 512 and 1024 DH params in control/dh512.pem
+            and control/dh1024.pem. `make tmprsadh` does this.
+            Periodical replacement can be done by crontab:
+       	    01 01 * * * /var/qmail/bin/update_tmprsadh > /dev/null 2>&1
+          - server authentication:
+            qmail-remote requires authentication from servers for which
+            /var/qmail/control/tlshosts/host.dom.ain.pem exists.
+            The .pem file contains the validating CA certificates
+            (or self-signed server certificate).  CommonName has to match.
+            WARNING: this option may cause mail to be delayed, bounced,
+            doublebounced, and lost.
+            If /var/qmail/control/tlshosts/exhaustivelist is present,
+            the lists of hosts in /var/qmail/control/tlshosts is
+            an exhaustive list of hosts TLS is tried on.
+            If /var/qmail/control/notlshosts/host.dom.ain is present,
+            no TLS is tried on this host.
+          - client authentication:
+            when relay rules would reject an incoming mail, 
+            qmail-smtpd can allow the mail based on a presented cert.
+            Certs are verified against a CA list in 
+            /var/qmail/control/clientca.pem (eg. http://www.modssl.org/
+            source/cvs/exp/mod_ssl/pkg.mod_ssl/pkg.sslcfg/ca-bundle.crt)
+            and the cert email-address has to match a line in
+            /var/qmail/control/tlsclients. This email-address is logged
+            in the headers. CRLs can be provided through 
+            /var/qmail/control/clientcrl.pem.
+          - cipher selection:
+            qmail-remote: 
+              openssl cipher string (`man ciphers`) read from 
+              /var/qmail/control/tlsclientciphers
+            qmail-smtpd: 
+              openssl cipher string read from TLSCIPHERS environment variable
+              (can vary based on client IP address e.g.)
+              or if that is not available /var/qmail/control/tlsserverciphers
+          - smtps (deprecated SMTP over TLS via port 465):
+            qmail-remote: when connecting to port 465 
+            qmail-smtpd: when SMTPS environment variable is not empty
+
+Caveats: - do a `make clean` after patching
+         - binaries dynamically linked with current openssl versions need
+           recompilation when the shared openssl libs are upgraded.
+         - this patch could conflict with other patches (notably those
+           replacing \n with \r\n, which is a bad idea on encrypted links).
+         - some broken servers have a problem with TLSv1 compatibility.
+           Uncomment the line where we set the SSL_OP_NO_TLSv1 option.
+         - needs working /dev/urandom (or EGD for openssl versions >0.9.7)
+           for seeding random number generator.
+         - packagers should make sure that installing without a valid 
+           servercert is impossible
+         - when applied in combination with AUTH patch, AUTH patch
+           should be applied first and first part of this patch
+           will fail. This error can be ignored. Packagers should
+           cut the first 12 lines of this patch to make a happy
+           patch
+         - `make tmprsadh` is recommended (or should I say required), 
+           otherwise DH generation can be unpredictably slow
+         - some need "-I/usr/kerberos/include" to be added in conf-cc
+
+Copyright: GPL
+           Links with OpenSSL
+           Inspiration and code from examples in SSLeay (E. Young
+           <eay@cryptsoft.com> and T. Hudson <tjh@cryptsoft.com>),
+           stunnel (M. Trojnara <mtrojnar@ddc.daewoo.com.pl>),
+           Postfix/TLS (L. Jaenicke <Lutz.Jaenicke@aet.tu-cottbus.de>),
+           modssl (R. Engelschall <rse@engelschall.com>),
+           openssl examples of E. Rescorla <ekr@rtfm.com>.
+
+Bug reports: mailto:<qmail-tls akrul inoa.net>
+
diff -Naur ./README.tap ../qmail-1.03-build-10/README.tap
--- ./README.tap	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.tap	2006-05-09 23:21:54.000000000 -0500
@@ -0,0 +1,28 @@
+qmail provides the ability to make a copy of each email that flows through the system.
+This is done using the QUEUE_EXTRA code. See qmail FAQ #8.2
+
+The qmail tap patch adds additional functionality:
+1) Specify which email addresses to tap using a regex style control file. With the
+   regex function, you can specify full domains or individual email addresses.
+
+2) Specify which email address to send the emails to.
+
+3) Qmail does not need to be restated to when the taps control file is changed.
+
+The regex match is applied to both the to and from email addresses. So email
+sent to or from the addresses will be copied. Matching is case insensitive.
+If there are multiple matches, the first match is used.
+
+The queue tap patch adds a new control file:
+
+/var/qmail/control/taps
+Contains a regex style list of addresses to tap and the email
+address of where you want the copy sent to.
+
+Examples:
+a) To tap a whole domain add a line like:
+.*@domain.com:joe@example.com
+
+
+b) To tap an individual email address add a line like:
+user@domain.com:other@example.com
diff -Naur ./README.warlord ../qmail-1.03-build-10/README.warlord
--- ./README.warlord	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/README.warlord	2004-12-09 13:59:58.000000000 -0600
@@ -0,0 +1,27 @@
+README (Warlord)
+================
+
+The Warlord patch is the successor of Russell Nelson's 
+and Charles Cazabon's "qmail-smtpd-viruscan-patch".
+It realizes a robust and efficient base64 scanning.
+
+Features:
+
+- The whole message is scanned for embedded base64 attachments.
+- The first characters of the identified attachments
+  are checked against the strings found in badmimetypes.cdb,
+  if the environment variable BADMIMETYPE is present.
+- The whole content of all base64 attachments
+  are checked against arbitary strings provided in 
+  badloadertypes.cdb. In order to make the search efficient,
+  the required environment variable BADLOADERTYPE has
+  to be supplied with the first character of the content
+  of the badloadertypes.cdb.
+- Customized SMTP 554 reply messages can be defined and used 
+  via the environment variable REPLY554.
+
+By means of the programs qmail-badmimetype and qmail-badloadertype, 
+the databases can be modified by need on the fly.
+
+See man qmail-smtpd, qmail-control, qmail-badmimetypes, and 
+qmail-badloadertypes.
diff -Naur ./sendmail.c ../qmail-1.03-build-10/sendmail.c
--- ./sendmail.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/sendmail.c	2006-04-24 21:24:32.000000000 -0500
@@ -45,6 +45,38 @@
   _exit(111);
 }
 
+void do_sender(s)
+const char *s;
+{
+  char *x;
+  int n;
+  int a;
+  int i;
+  
+  env_unset("QMAILNAME");
+  env_unset("MAILNAME");
+  env_unset("NAME");
+  env_unset("QMAILHOST");
+  env_unset("MAILHOST");
+
+  n = str_len(s);
+  a = str_rchr(s, '@');
+  if (a == n)
+  {
+    env_put2("QMAILUSER", s);
+    return;
+  }
+  env_put2("QMAILHOST", s + a + 1);
+
+  x = (char *) alloc((a + 1) * sizeof(char));
+  if (!x) nomem();
+  for (i = 0; i < a; i++)
+    x[i] = s[i];
+  x[i] = 0;
+  env_put2("QMAILUSER", x);
+  alloc_free(x);
+}
+
 int flagh;
 char *sender;
 
@@ -118,6 +150,7 @@
   if (sender) {
     *arg++ = "-f";
     *arg++ = sender;
+    do_sender(sender);
   }
   *arg++ = "--";
   for (i = 0;i < argc;++i) *arg++ = argv[i];
diff -Naur ./spawn.c ../qmail-1.03-build-10/spawn.c
--- ./spawn.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/spawn.c	2006-05-05 19:47:24.000000000 -0500
@@ -5,6 +5,7 @@
 #include "substdio.h"
 #include "byte.h"
 #include "str.h"
+#include "alloc.h"
 #include "stralloc.h"
 #include "select.h"
 #include "exit.h"
@@ -63,7 +64,7 @@
 int flagreading = 1;
 char outbuf[1024]; substdio ssout;
 
-int stage = 0; /* reading 0:delnum 1:messid 2:sender 3:recip */
+int stage = 0; /* reading 0:delnum 1:delnum2 2:messid 3:sender 4:recip */
 int flagabort = 0; /* if 1, everything except delnum is garbage */
 int delnum;
 stralloc messid = {0};
@@ -73,6 +74,7 @@
 void err(s) char *s;
 {
  char ch; ch = delnum; substdio_put(&ssout,&ch,1);
+ ch = delnum >> 8; substdio_put(&ssout,&ch,1);
  substdio_puts(&ssout,s); substdio_putflush(&ssout,"",1);
 }
 
@@ -155,16 +157,19 @@
     {
      case 0:
        delnum = (unsigned int) (unsigned char) ch;
-       messid.len = 0; stage = 1; break;
+       stage = 1; break;
      case 1:
+       delnum += (unsigned int) ((unsigned int) ch) << 8;
+       messid.len = 0; stage = 2; break;
+     case 2:
        if (!stralloc_append(&messid,&ch)) flagabort = 1;
        if (ch) break;
-       sender.len = 0; stage = 2; break;
-     case 2:
+       sender.len = 0; stage = 3; break;
+     case 3:
        if (!stralloc_append(&sender,&ch)) flagabort = 1;
        if (ch) break;
-       recip.len = 0; stage = 3; break;
-     case 3:
+       recip.len = 0; stage = 4; break;
+     case 4:
        if (!stralloc_append(&recip,&ch)) flagabort = 1;
        if (ch) break;
        docmd();
@@ -201,7 +206,8 @@
 
  initialize(argc,argv);
 
- ch = auto_spawn; substdio_putflush(&ssout,&ch,1);
+ ch = auto_spawn; substdio_put(&ssout,&ch,1);
+ ch = auto_spawn >> 8; substdio_putflush(&ssout,&ch,1);
 
  for (i = 0;i < auto_spawn;++i) { d[i].used = 0; d[i].output.s = 0; }
 
@@ -236,7 +242,8 @@
 	   continue; /* read error on a readable pipe? be serious */
 	 if (r == 0)
 	  {
-           ch = i; substdio_put(&ssout,&ch,1);
+           char ch; ch = i; substdio_put(&ssout,&ch,1);
+           ch = i >> 8; substdio_put(&ssout,&ch,1);
 	   report(&ssout,d[i].wstat,d[i].output.s,d[i].output.len);
 	   substdio_put(&ssout,"",1);
 	   substdio_flush(&ssout);
diff -Naur ./spf.c ../qmail-1.03-build-10/spf.c
--- ./spf.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/spf.c	2006-05-05 21:22:50.000000000 -0500
@@ -0,0 +1,878 @@
+#include "stralloc.h"
+#include "strsalloc.h"
+#include "alloc.h"
+#include "ip.h"
+#include "ipalloc.h"
+#include "ipme.h"
+#include "str.h"
+#include "fmt.h"
+#include "scan.h"
+#include "byte.h"
+#include "now.h"
+#include "dns.h"
+#include "case.h"
+#include "spf.h"
+
+#define SPF_EXT    -1
+#define SPF_SYNTAX -2
+
+#define WSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\r' || (x) == '\n')
+#define NXTOK(b, p, a) do { (b) = (p); \
+          while((p) < (a)->len && !WSPACE((a)->s[(p)])) ++(p); \
+          while((p) < (a)->len && WSPACE((a)->s[(p)])) (a)->s[(p)++] = 0; \
+        } while(0)
+
+/* this table and macro came from wget more or less */
+/* and was in turn stolen by me from libspf as is :) */
+const static unsigned char urlchr_table[256] =
+{
+  1,  1,  1,  1,   1,  1,  1,  1,   /* NUL SOH STX ETX  EOT ENQ ACK BEL */
+  1,  1,  1,  1,   1,  1,  1,  1,   /* BS  HT  LF  VT   FF  CR  SO  SI  */
+  1,  1,  1,  1,   1,  1,  1,  1,   /* DLE DC1 DC2 DC3  DC4 NAK SYN ETB */
+  1,  1,  1,  1,   1,  1,  1,  1,   /* CAN EM  SUB ESC  FS  GS  RS  US  */
+  1,  0,  1,  1,   0,  1,  1,  0,   /* SP  !   "   #    $   %   &   '   */
+  0,  0,  0,  1,   0,  0,  0,  1,   /* (   )   *   +    ,   -   .   /   */
+  0,  0,  0,  0,   0,  0,  0,  0,   /* 0   1   2   3    4   5   6   7   */
+  0,  0,  1,  1,   1,  1,  1,  1,   /* 8   9   :   ;    <   =   >   ?   */
+  1,  0,  0,  0,   0,  0,  0,  0,   /* @   A   B   C    D   E   F   G   */
+  0,  0,  0,  0,   0,  0,  0,  0,   /* H   I   J   K    L   M   N   O   */
+  0,  0,  0,  0,   0,  0,  0,  0,   /* P   Q   R   S    T   U   V   W   */
+  0,  0,  0,  1,   1,  1,  1,  0,   /* X   Y   Z   [    \   ]   ^   _   */
+  1,  0,  0,  0,   0,  0,  0,  0,   /* `   a   b   c    d   e   f   g   */
+  0,  0,  0,  0,   0,  0,  0,  0,   /* h   i   j   k    l   m   n   o   */
+  0,  0,  0,  0,   0,  0,  0,  0,   /* p   q   r   s    t   u   v   w   */
+  0,  0,  0,  1,   1,  1,  1,  1,   /* x   y   z   {    |   }   ~   DEL */
+
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+  1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,   1,  1,  1,  1,
+};
+
+
+extern stralloc addr;
+extern stralloc helohost;
+extern char *remoteip;
+extern char *local;
+
+extern stralloc spflocal;
+extern stralloc spfguess;
+extern stralloc spfexp;
+
+static stralloc sender_fqdn = {0};
+static stralloc explanation = {0};
+static stralloc expdomain = {0};
+static stralloc errormsg = {0};
+static char *received;
+
+static int recursion;
+static struct ip_address ip;
+
+static void hdr_pass() { received = "pass (%{xr}: %{xs} designates %{i} as permitted sender)"; };
+static void hdr_softfail() { received = "softfail (%{xr}: transitioning %{xs} does not designate %{i} as permitted sender)"; };
+static void hdr_fail() { received = "fail (%{xr}: %{xs} does not designate %{i} as permitted sender)"; };
+static void hdr_unknown() { received = "unknown (%{xr}: domain at %{d} does not designate permitted sender hosts)"; };
+static void hdr_neutral() { received = "neutral (%{xr}: %{i} is neither permitted nor denied by %{xs})"; };
+static void hdr_none() { received = "none (%{xr}: domain at %{d} does not designate permitted sender hosts)"; };
+static void hdr_unknown_msg(e) char *e; { stralloc_copys(&errormsg, e); received = "unknown (%{xr}: %{xe})"; };
+static void hdr_ext(e) char *e; { stralloc_copys(&errormsg, e); received = "unknown %{xe} (%{xr}: %{xs} uses mechanism not recognized by this client)"; };
+static void hdr_syntax() { received = "unknown (%{xr}: parse error in %{xs})"; };
+static void hdr_error(e) char *e; { stralloc_copys(&errormsg, e); received = "error (%{xr}: error in processing during lookup of %{d}: %{xe})"; };
+static void hdr_dns() { hdr_error("DNS problem"); }
+
+
+static int matchip(struct ip_address *net, int mask, struct ip_address *ip)
+{
+	int j;
+	int bytemask;
+
+	for (j = 0; j < 4 && mask > 0; ++j) {
+		if (mask > 8) bytemask = 8; else bytemask = mask;
+		mask -= bytemask;
+
+		if ((net->d[j] ^ ip->d[j]) & (0x100 - (1 << (8 - bytemask))))
+			return 0;
+	}
+	return 1;
+}
+
+static int getipmask(char *mask, int ipv6) {
+	unsigned long r;
+	int pos;
+
+	if (!mask) return 32;
+
+	pos = scan_ulong(mask, &r);
+	if (!pos || (mask[pos] && !(mask[pos] == '/' && ipv6))) return -1;
+	if (r > 32) return -1;
+
+	return r;
+}
+
+int spfget(stralloc *spf, stralloc *domain)
+{
+	strsalloc ssa = {0};
+	int j;
+	int begin, pos, i;
+	int r = SPF_NONE;
+
+	spf->len = 0;
+
+	switch(dns_txt(&ssa, domain)) {
+		case DNS_MEM: return SPF_NOMEM;
+		case DNS_SOFT: hdr_dns(); return SPF_ERROR;
+		case DNS_HARD: return SPF_NONE;
+	}
+
+	for (j = 0;j < ssa.len;++j) {
+		pos = 0;
+
+		NXTOK(begin, pos, &ssa.sa[j]);
+		if (str_len(ssa.sa[j].s + begin) < 6) continue;
+		if (!byte_equal(ssa.sa[j].s + begin,6,"v=spf1")) continue;
+		if (ssa.sa[j].s[begin + 6]) {
+			/* check for subversion */
+			if (ssa.sa[j].s[begin + 6] != '.') continue;
+			for(i = begin + 7;;++i)
+				if (!(ssa.sa[j].s[i] >= '0' && ssa.sa[j].s[i] <= '9')) break;
+			if (i == (begin + 7)) continue;
+			if (ssa.sa[j].s[i]) continue;
+		}
+
+		if (spf->len > 0) {
+			spf->len = 0;
+			hdr_unknown_msg("Multiple SPF records returned");
+			r = SPF_UNKNOWN;
+			break;
+		}
+		if (!stralloc_0(&ssa.sa[j])) return SPF_NOMEM;
+		if (!stralloc_copys(spf,ssa.sa[j].s + pos)) return SPF_NOMEM;
+		r = SPF_OK;
+	}
+
+	for (j = 0;j < ssa.len;++j)
+		alloc_free(ssa.sa[j].s);
+	alloc_free(ssa.sa);
+	return r;
+}
+
+static int spf_ptr(char *spec, char *mask);
+
+int spfsubst(stralloc *expand, char *spec, char *domain)
+{
+	static char hexdigits[] = "0123456789abcdef";
+	stralloc sa = {0};
+	char ch;
+	int digits = -1;
+	int urlencode = 0;
+	int reverse = 0;
+	int start = expand->len;
+	int i, pos;
+	char *split = ".";
+
+	if (!stralloc_readyplus(&sa,0)) return 0;
+
+	if (*spec == 'x') { i = 1; ++spec; } else i = 0;
+	ch = *spec++;
+	if (!ch) { alloc_free(sa.s); return 1; }
+	if (ch >= 'A' && ch <= 'Z') { ch += 32; urlencode = 1; }
+	if (i) ch -= 32;
+	while(*spec >= '0' && *spec <= '9') {
+		if (digits < 0) digits = 0;
+		if (digits >= 1000000) { digits = 10000000; continue; }
+		digits = (digits * 10) + (*spec - '0');
+		spec++;
+	}
+
+	while((*spec >= 'a' && *spec <= 'z') || (*spec >= 'A' && *spec <= 'Z')) {
+		if (*spec == 'r') reverse = 1;
+		spec++;
+	}
+
+	if (*spec) split = spec;
+
+	switch(ch) {
+		case 'l':
+			pos = byte_rchr(addr.s, addr.len, '@');
+			if (pos < addr.len) {
+				if (!stralloc_copyb(&sa, addr.s, pos)) return 0;
+			} else
+				if (!stralloc_copys(&sa, "postmaster")) return 0;
+			break;
+		case 's':
+			if (!stralloc_copys(&sa, addr.s)) return 0;
+			break;
+		case 'o':
+			pos = byte_rchr(addr.s, addr.len, '@') + 1;
+			if (pos > addr.len) break;
+			if (!stralloc_copys(&sa, addr.s + pos)) return 0;
+			break;
+		case 'd':
+			if (!stralloc_copys(&sa, domain)) return 0;
+			break;
+		case 'i':
+			if (!stralloc_ready(&sa, IPFMT)) return 0;
+			sa.len = ip_fmt(sa.s, &ip);
+			break;
+		case 't':
+			if (!stralloc_ready(&sa, FMT_ULONG)) return 0;
+			sa.len = fmt_ulong(sa.s, (unsigned long)now());
+			break;
+		case 'p':
+			if (!sender_fqdn.len)
+				spf_ptr(domain, 0);
+			if (sender_fqdn.len) {
+				if (!stralloc_copy(&sa, &sender_fqdn)) return 0;
+			} else
+				if (!stralloc_copys(&sa, "unknown")) return 0;
+			break;
+		case 'v': 
+			if (!stralloc_copys(&sa, "in-addr")) return 0;
+			break;
+		case 'h':
+			if (!stralloc_copys(&sa, helohost.s)) return 0; /* FIXME: FQDN? */
+			break;
+		case 'E':
+			if (errormsg.len && !stralloc_copy(&sa, &errormsg)) return 0;
+			break;
+		case 'R':
+			if (!stralloc_copys(&sa, local)) return 0;
+			break;
+		case 'S':
+			if (expdomain.len > 0) {
+				if (!stralloc_copys(&sa, "SPF record at ")) return 0;
+				if (!stralloc_cats(&sa, expdomain.s)) return 0;
+			} else {
+				if (!stralloc_copys(&sa, "local policy")) return 0;
+			}
+			break;
+	}
+
+	if (reverse) {
+		for(pos = 0; digits; ++pos) {
+			pos += byte_cspn(sa.s + pos, sa.len - pos, split);
+			if (pos >= sa.len) break;
+			if (!--digits) break;
+		}
+
+		for(; pos > 0; pos = i - 1) {
+			i = byte_rcspn(sa.s, pos, split) + 1;
+			if (i > pos) i = 0;
+			if (!stralloc_catb(expand, sa.s + i, pos - i)) return 0;
+			if (i > 0 && !stralloc_append(expand, ".")) return 0;
+		}
+	} else {
+		for(pos = sa.len; digits; --pos) {
+			i = byte_rcspn(sa.s, pos, split) + 1;
+			if (i > pos) { pos = 0; break; }
+			pos = i;
+			if (!--digits) break;
+		}
+
+		if (!stralloc_catb(expand, sa.s + pos, sa.len - pos)) return 0;
+		if (split[0] != '.' || split[1])
+			for(pos = 0; pos < expand->len; pos++) {
+				pos += byte_cspn(expand->s + pos, expand->len - pos, split);
+				if (pos < expand->len)
+					expand->s[pos] = '.';
+			}
+	}
+
+	if (urlencode) {
+		stralloc_copyb(&sa, expand->s + start, expand->len - start);
+		expand->len = start;
+
+		for(pos = 0; pos < sa.len; ++pos) {
+			ch = sa.s[pos];
+			if (urlchr_table[(unsigned char)ch]) {
+				if (!stralloc_readyplus(expand, 3)) return 0;
+				expand->s[expand->len++] = '%';
+				expand->s[expand->len++] = hexdigits[(unsigned char)ch >> 4];
+				expand->s[expand->len++] = hexdigits[(unsigned char)ch & 15];
+			} else
+				if (!stralloc_append(expand, &ch)) return 0;
+		}
+	}
+
+	alloc_free(sa.s);
+	return 1;
+}
+
+int spfexpand(stralloc *sa, char *spec, char *domain)
+{
+	char *p;
+	char append;
+	int pos;
+
+	if (!stralloc_readyplus(sa, 0)) return 0;
+	sa->len = 0;
+
+	for(p = spec; *p; p++) {
+		append = *p;
+		if (*p == '%') {
+			p++;
+			switch(*p) {
+				case '%': break;
+				case '_': append = ' '; break;
+				case '-': if (!stralloc_cats(sa, "%20")) return 0; continue;
+				case '{':
+					pos = str_chr(p, '}');
+					if (p[pos] != '}') { p--; break; }
+					p[pos] = 0;
+					if (!spfsubst(sa, p + 1, domain)) return 0;
+					p += pos;
+					continue;
+				default: p--;
+			}
+		}
+		if (!stralloc_append(sa, &append)) return 0;
+	}
+
+	return 1;
+}
+
+static int spflookup(stralloc *domain);
+
+static int spf_include(char *spec, char *mask)
+{
+	stralloc sa = {0};
+	int r;
+
+	if (!stralloc_copys(&sa, spec)) return SPF_NOMEM;
+	r = spflookup(&sa);
+	alloc_free(sa.s);
+
+	switch(r) {
+		case SPF_NONE:
+			hdr_unknown();
+			r = SPF_UNKNOWN;
+			break;
+		case SPF_SYNTAX:
+			r = SPF_UNKNOWN;
+			break;
+		case SPF_NEUTRAL:
+		case SPF_SOFTFAIL:
+		case SPF_FAIL:
+			r = SPF_NONE;
+			break;
+	}
+
+	return r;
+}
+
+static int spf_a(char *spec, char *mask)
+{
+	stralloc sa = {0};
+	ipalloc ia = {0};
+	int ipmask = getipmask(mask, 1);
+	int r;
+	int j;
+
+	if (ipmask < 0) return SPF_SYNTAX;
+
+	if (!stralloc_copys(&sa, spec)) return SPF_NOMEM;
+	if (!stralloc_readyplus(&ia, 0)) return SPF_NOMEM;
+
+	switch(dns_ip(&ia, &sa)) {
+		case DNS_MEM: return SPF_NOMEM;
+		case DNS_SOFT: hdr_dns(); r = SPF_ERROR; break;
+		case DNS_HARD: r = SPF_NONE; break;
+		default:
+			r = SPF_NONE;
+			for(j = 0; j < ia.len; ++j)
+				if (matchip(&ia.ix[j].ip, ipmask, &ip)) {
+					r = SPF_OK;
+					break;
+				}
+	}
+
+	alloc_free(sa.s);
+	alloc_free(ia.ix);
+	return r;
+}
+
+static int spf_mx(char *spec, char *mask)
+{
+	stralloc sa = {0};
+	ipalloc ia = {0};
+	int ipmask = getipmask(mask, 1);
+	int random = now() + (getpid() << 16);
+	int r;
+	int j;
+
+	if (ipmask < 0) return SPF_SYNTAX;
+
+	if (!stralloc_copys(&sa, spec)) return SPF_NOMEM;
+	if (!stralloc_readyplus(&ia, 0)) return SPF_NOMEM;
+
+	switch(dns_mxip(&ia, &sa, random)) {
+		case DNS_MEM: return SPF_NOMEM;
+		case DNS_SOFT: hdr_dns(); r = SPF_ERROR; break;
+		case DNS_HARD: r = SPF_NONE; break;
+		default:
+			r = SPF_NONE;
+			for(j = 0; j < ia.len; ++j)
+				if (matchip(&ia.ix[j].ip, ipmask, &ip)) {
+					r = SPF_OK;
+					break;
+				}
+	}
+
+	alloc_free(sa.s);
+	alloc_free(ia.ix);
+	return r;
+}
+
+static int spf_ptr(char *spec, char *mask)
+{
+	strsalloc ssa = {0};
+	ipalloc ia = {0};
+	int len = str_len(spec);
+	int r;
+	int j, k;
+	int pos;
+
+	/* we didn't find host with the matching ip before */
+	if (sender_fqdn.len == 7 && str_equal(sender_fqdn.s, "unknown"))
+		return SPF_NONE;
+
+	/* the hostname found will probably be the same as before */
+	while (sender_fqdn.len) {
+		pos = sender_fqdn.len - len;
+		if (pos < 0) break;
+		if (pos > 0 && sender_fqdn.s[pos - 1] != '.') break;
+		if (case_diffb(sender_fqdn.s + pos, len, spec)) break;
+
+		return SPF_OK;
+	}
+
+	/* ok, either it's the first test or it's a very weird setup */
+
+	if (!stralloc_readyplus(&ssa, 0)) return SPF_NOMEM;
+	if (!stralloc_readyplus(&ia, 0)) return SPF_NOMEM;
+
+	switch(dns_ptr(&ssa, &ip)) {
+		case DNS_MEM: return SPF_NOMEM;
+		case DNS_SOFT: hdr_dns(); r = SPF_ERROR; break;
+		case DNS_HARD: r = SPF_NONE; break;
+		default:
+			r = SPF_NONE;
+			for(j = 0; j < ssa.len; ++j) {
+				switch(dns_ip(&ia, &ssa.sa[j])) {
+					case DNS_MEM: return SPF_NOMEM;
+					case DNS_SOFT: hdr_dns(); r = SPF_ERROR; break;
+					case DNS_HARD: break;
+					default:
+						for(k = 0; k < ia.len; ++k)
+							if (matchip(&ia.ix[k].ip, 32, &ip)) {
+								if (!sender_fqdn.len)
+									if (!stralloc_copy(&sender_fqdn, &ssa.sa[j])) return SPF_NOMEM;
+
+								pos = ssa.sa[j].len - len;
+								if (pos < 0) continue;
+								if (pos > 0 && ssa.sa[j].s[pos - 1] != '.') continue;
+								if (case_diffb(ssa.sa[j].s + pos, len, spec)) continue;
+
+								stralloc_copy(&sender_fqdn, &ssa.sa[j]);
+								r = SPF_OK;
+								break;
+							}
+				}
+
+				if (r == SPF_ERROR) break;
+			}
+	}
+
+	for(j = 0;j < ssa.len;++j)
+		alloc_free(ssa.sa[j].s);
+
+	alloc_free(ssa.sa);
+	alloc_free(ia.ix);
+
+	if (!sender_fqdn.len)
+		if (!stralloc_copys(&sender_fqdn, "unknown")) return SPF_NOMEM;
+
+	return r;
+}
+
+static int spf_ip(char *spec, char *mask)
+{
+	struct ip_address net;
+	int ipmask = getipmask(mask, 0);
+
+	if (ipmask < 0) return SPF_SYNTAX;
+	if (!ip_scan(spec, &net)) return SPF_SYNTAX;
+
+	if (matchip(&net, ipmask, &ip)) return SPF_OK;
+
+	return SPF_NONE;
+}
+
+static int spf_exists(char *spec, char *mask)
+{
+	stralloc sa = {0};
+	ipalloc ia = {0};
+	int r;
+
+	if (!stralloc_copys(&sa, spec)) return SPF_NOMEM;
+	if (!stralloc_readyplus(&ia, 0)) return SPF_NOMEM;
+
+	switch(dns_ip(&ia, &sa)) {
+		case DNS_MEM: return SPF_NOMEM;
+		case DNS_SOFT: hdr_dns(); r = SPF_ERROR; break;
+		case DNS_HARD: r = SPF_NONE; break;
+		default: r = SPF_OK;
+	}
+
+	alloc_free(sa.s);
+	alloc_free(ia.ix);
+	return r;
+}
+
+static struct mechanisms {
+  char *mechanism;
+  int (*func)(char *spec, char *mask);
+  unsigned int takes_spec  : 1;
+  unsigned int takes_mask  : 1;
+  unsigned int expands     : 1;
+  unsigned int filldomain  : 1;
+  int defresult            : 4;
+} mechanisms[] = {
+  { "all",      0,          0,0,0,0,SPF_OK   }
+, { "include",  spf_include,1,0,1,0,0        }
+, { "a",        spf_a,      1,1,1,1,0        }
+, { "mx",       spf_mx,     1,1,1,1,0        }
+, { "ptr",      spf_ptr,    1,0,1,1,0        }
+, { "ip4",      spf_ip,     1,1,0,0,0        }
+, { "ip6",      0,          1,1,0,0,SPF_NONE }
+, { "exists",   spf_exists, 1,0,1,0,0        }
+, { "extension",0,          1,1,0,0,SPF_EXT  }
+, { 0,          0,          1,1,0,0,SPF_EXT  }
+};
+
+static int spfmech(char *mechanism, char *spec, char *mask, char *domain)
+{
+	struct mechanisms *mech;
+	stralloc sa = {0};
+	int r;
+	int pos;
+
+	for(mech = mechanisms; mech->mechanism; mech++)
+		if (str_equal(mech->mechanism, mechanism)) break;
+
+	if (mech->takes_spec && !spec && mech->filldomain) spec = domain;
+	if (!mech->takes_spec != !spec) return SPF_SYNTAX;
+	if (!mech->takes_mask && mask) return SPF_SYNTAX;
+	if (!mech->func) return mech->defresult;
+
+	if (!stralloc_readyplus(&sa, 0)) return SPF_NOMEM;
+	if (mech->expands && spec != domain) {
+		if (!spfexpand(&sa, spec, domain)) return SPF_NOMEM;
+		for (pos = 0; (sa.len - pos) > 255;) {
+			pos += byte_chr(sa.s + pos, sa.len - pos, '.');
+			if (pos < sa.len) pos++;
+		}
+		sa.len -= pos;
+		if (pos > 0) byte_copy(sa.s, sa.len, sa.s + pos);
+		stralloc_0(&sa);
+		spec = sa.s;
+	}
+
+	r = mech->func(spec, mask);
+
+	alloc_free(sa.s);
+	return r;
+}
+
+static struct default_aliases {
+  char *alias;
+  int defret;
+} default_aliases[] = {
+  { "allow",   SPF_OK }
+, { "pass",    SPF_OK }
+, { "deny",    SPF_FAIL }
+, { "softdeny",SPF_SOFTFAIL }
+, { "fail",    SPF_FAIL }
+, { "softfail",SPF_SOFTFAIL }
+, { "unknown", SPF_NEUTRAL }
+, { 0,         SPF_UNKNOWN }
+};
+
+static int spflookup(stralloc *domain)
+{
+	stralloc spf = {0};
+	stralloc sa = {0};
+	struct default_aliases *da;
+	int main = !recursion;
+	int local_pos = -1;
+	int r, q;
+	int begin, pos;
+	int i;
+	int prefix;
+	int done;
+	int guessing = 0;
+	char *p;
+
+	if (!stralloc_readyplus(&spf, 0)) return SPF_NOMEM;
+	if (!stralloc_readyplus(&sa, 0)) return SPF_NOMEM;
+
+	/* fallthrough result */
+	if (main) hdr_none();
+
+redirect:
+	if (++recursion > 20) {
+		alloc_free(spf.s);
+		alloc_free(sa.s);
+		hdr_unknown_msg("Maximum nesting level exceeded, possible loop");
+		return SPF_SYNTAX;
+	}
+
+	if (!stralloc_0(domain)) return SPF_NOMEM;
+	if (!stralloc_copy(&expdomain, domain)) return SPF_NOMEM;
+
+	r = spfget(&spf, domain);
+	if (r == SPF_NONE) {
+		if (!main) { alloc_free(spf.s); return r; }
+
+		if (spfguess.len) {
+			/* try to guess */
+			guessing = 1;
+			if (!stralloc_copys(&spf, spfguess.s)) return SPF_NOMEM;
+			if (!stralloc_append(&spf, " ")) return SPF_NOMEM;
+		} else
+			spf.len = 0;
+
+		/* append local rulest */
+		if (spflocal.len) {
+			local_pos = spf.len;
+			if (!stralloc_cats(&spf, spflocal.s)) return SPF_NOMEM;
+		}
+		if (!stralloc_0(&spf)) return SPF_NOMEM;
+
+		expdomain.len = 0;
+	} else if (r == SPF_OK) {
+		if (!stralloc_0(&spf)) return SPF_NOMEM;
+		if (main) hdr_neutral();
+		r = SPF_NEUTRAL;
+
+		/* try to add local rules before fail all mechs */
+		if (main && spflocal.len) {
+			pos = 0;
+			p = (char *) 0;
+			while(pos < spf.len) {
+				NXTOK(begin, pos, &spf);
+				if (!spf.s[begin]) continue;
+
+				if (p && spf.s[begin] != *p) p = (char *) 0;
+				if (!p && (spf.s[begin] == '-' || spf.s[begin] == '~' ||
+				           spf.s[begin] == '?')) p = &spf.s[begin];
+
+				if (p && p > spf.s && str_equal(spf.s + begin + 1, "all")) {
+					/* ok, we can insert the local rules at p */
+					local_pos = p - spf.s;
+
+					stralloc_readyplus(&spf, spflocal.len);
+					p = spf.s + local_pos;
+					byte_copyr(p + spflocal.len, spf.len - local_pos, p);
+					byte_copy(p, spflocal.len, spflocal.s);
+					spf.len += spflocal.len;
+
+					pos += spflocal.len;
+					break;
+				}
+			}
+
+			if (pos >= spf.len) pos = spf.len - 1;
+			for(i = 0; i < pos; i++)
+				if (!spf.s[i]) spf.s[i] = ' ';
+		}
+	} else {
+		alloc_free(spf.s);
+		return r;
+	}
+
+	pos = 0;
+	done = 0;
+	while(pos < spf.len) {
+		NXTOK(begin, pos, &spf);
+		if (!spf.s[begin]) continue;
+
+		/* in local ruleset? */
+		if (!done && local_pos >= 0 && begin >= local_pos) {
+			if (begin < (local_pos + spflocal.len))
+				expdomain.len = 0;
+			else
+				if (!stralloc_copy(&expdomain, domain))
+					return SPF_NOMEM;
+		}
+
+		for (p = spf.s + begin;*p;++p)
+			if (*p == ':' || *p == '/' || *p == '=') break;
+
+		if (*p == '=') {
+			*p++ = 0;
+
+			/* modifiers are simply handled here */
+			if (str_equal(spf.s + begin, "redirect")) {
+				if (done) continue;
+
+				if (!spfexpand(&sa, p, domain->s)) return SPF_NOMEM;
+				stralloc_copy(domain, &sa);
+
+				hdr_unknown();
+				r = SPF_UNKNOWN;
+
+				goto redirect;
+			} else if (str_equal(spf.s + begin, "default")) {
+				if (done) continue;
+
+				for(da = default_aliases; da->alias; ++da)
+					if (str_equal(da->alias, p)) break;
+
+				r = da->defret;
+			} else if (str_equal(spf.s + begin, "exp")) {
+				strsalloc ssa = {0};
+
+				if (!main) continue;
+
+				if (!stralloc_copys(&sa, p)) return SPF_NOMEM;
+				switch(dns_txt(&ssa, &sa)) {
+					case DNS_MEM: return SPF_NOMEM;
+					case DNS_SOFT: continue; /* FIXME... */
+					case DNS_HARD: continue;
+				}
+
+				explanation.len = 0;
+				for(i = 0; i < ssa.len; i++) {
+					if (!stralloc_cat(&explanation, &ssa.sa[i])) return SPF_NOMEM;
+					if (i < (ssa.len - 1))
+						if (!stralloc_append(&explanation, "\n")) return SPF_NOMEM;
+
+					alloc_free(ssa.sa[i].s);
+				}
+				if (!stralloc_0(&explanation)) return SPF_NOMEM;
+			} /* and unknown modifiers are ignored */
+		} else if (!done) {
+			if (!stralloc_copys(&sa, spf.s + begin)) return SPF_NOMEM;
+			if (!stralloc_0(&sa)) return SPF_NOMEM;
+
+			switch(spf.s[begin]) {
+				case '-': begin++; prefix = SPF_FAIL; break;
+				case '~': begin++; prefix = SPF_SOFTFAIL; break;
+				case '+': begin++; prefix = SPF_OK; break;
+				case '?': begin++; prefix = SPF_NEUTRAL; break;
+				default: prefix = SPF_OK;
+			}
+
+			if (*p == '/') {
+				*p++ = 0;
+				q = spfmech(spf.s + begin, 0, p, domain->s);
+			} else {
+				if (*p) *p++ = 0;
+				i = str_chr(p, '/');
+				if (p[i] == '/') {
+					p[i++] = 0;
+					q = spfmech(spf.s + begin, p, p + i, domain->s);
+				} else if (i > 0)
+					q = spfmech(spf.s + begin, p, 0, domain->s);
+				else
+					q = spfmech(spf.s + begin, 0, 0, domain->s);
+			}
+
+			if (q == SPF_OK) q = prefix;
+
+			switch(q) {
+				case SPF_OK: hdr_pass(); break;
+				case SPF_NEUTRAL: hdr_neutral(); break;
+				case SPF_SYNTAX: hdr_syntax(); break;
+				case SPF_SOFTFAIL: hdr_softfail(); break;
+				case SPF_FAIL: hdr_fail(); break;
+				case SPF_EXT: hdr_ext(sa.s); break;
+				case SPF_ERROR:
+					if (!guessing)
+						break;
+					if (local_pos >= 0 && begin >= local_pos)
+						break;
+					hdr_none();
+					q = SPF_NONE;
+					break;
+				case SPF_NONE: continue;
+			}
+
+			r = q;
+			done = 1; /* we're done, no more mechanisms */
+		}
+	}
+
+	/* we fell through, no local rule applied */
+	if (!done && !stralloc_copy(&expdomain, domain)) return SPF_NOMEM;
+
+	alloc_free(spf.s);
+	alloc_free(sa.s);
+	return r;
+}
+
+int spfcheck()
+{
+	stralloc domain = {0};
+	int pos;
+	int r;
+
+	pos = byte_rchr(addr.s, addr.len, '@') + 1;
+	if (pos < addr.len) {
+		if (!stralloc_copys(&domain, addr.s + pos)) return SPF_NOMEM;
+	} else {
+		pos = str_rchr(helohost.s, '@');
+		if (helohost.s[pos]) {
+			if (!stralloc_copys(&domain, helohost.s + pos + 1)) return SPF_NOMEM;
+		} else
+			if (!stralloc_copys(&domain, helohost.s)) return SPF_NOMEM;
+	}
+	if (!stralloc_copys(&explanation, spfexp.s)) return SPF_NOMEM;
+	if (!stralloc_0(&explanation)) return SPF_NOMEM;
+	recursion = 0;
+
+	if (!remoteip || !ip_scan(remoteip, &ip)) {
+		hdr_unknown_msg("No IP address in conversation");
+		return SPF_UNKNOWN;
+	}
+
+	if (!stralloc_readyplus(&expdomain, 0)) return SPF_NOMEM;
+	if (!stralloc_readyplus(&errormsg, 0)) return SPF_NOMEM;
+	expdomain.len = 0;
+	errormsg.len = 0;
+	sender_fqdn.len = 0;
+	received = (char *) 0;
+
+	if ((ip.d[0] == 127 && ip.d[1] == 0 && ip.d[2] == 0 && ip.d[3] == 1) || ipme_is(&ip))
+		{ hdr_pass(); r = SPF_OK; }
+	else
+		r = spflookup(&domain);
+
+	if (r < 0) r = SPF_UNKNOWN;
+
+	alloc_free(domain.s);
+	return r;
+}
+
+int spfexplanation(sa)
+stralloc *sa;
+{
+	return spfexpand(sa, explanation.s, expdomain.s);
+}
+
+int spfinfo(sa)
+stralloc *sa;
+{
+	stralloc tmp = {0};
+	if (!stralloc_copys(&tmp, received)) return 0;
+	if (!stralloc_0(&tmp)) return 0;
+	if (!spfexpand(sa, tmp.s, expdomain.s)) return 0;
+	alloc_free(tmp.s);
+	return 1;
+}
diff -Naur ./spf.h ../qmail-1.03-build-10/spf.h
--- ./spf.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/spf.h	2006-05-05 21:22:50.000000000 -0500
@@ -0,0 +1,20 @@
+#ifndef SPF_H
+#define SPF_H
+
+#define SPF_OK       0
+#define SPF_NONE     1
+#define SPF_UNKNOWN  2
+#define SPF_NEUTRAL  3
+#define SPF_SOFTFAIL 4
+#define SPF_FAIL     5
+#define SPF_ERROR    6
+#define SPF_NOMEM    7
+
+#define SPF_DEFEXP   "See http://spf.pobox.com/" \
+                     "why.html?sender=%{S}&ip=%{I}&receiver=%{xR}"
+
+extern int spfcheck();
+extern int spfexplanation();
+extern int spfinfo();
+
+#endif
diff -Naur ./spfquery.c ../qmail-1.03-build-10/spfquery.c
--- ./spfquery.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/spfquery.c	2006-05-05 21:22:50.000000000 -0500
@@ -0,0 +1,84 @@
+#include "substdio.h"
+#include "subfd.h"
+#include "stralloc.h"
+#include "alloc.h"
+#include "spf.h"
+#include "exit.h"
+
+void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
+void die_usage() { die(100,"fatal: invalid usage\nusage: spfquery <sender-ip> <sender-helo/ehlo> <envelope-from> [<local rules>] [<best guess rules>]\n"); }
+void die_nomem() { die(111,"fatal: out of memory\n"); }
+
+stralloc addr = {0};
+stralloc helohost = {0};
+char *remoteip;
+char *local;
+
+stralloc spflocal = {0};
+stralloc spfguess = {0};
+stralloc spfexp = {0};
+
+void main(argc,argv)
+int argc;
+char **argv;
+{
+	stralloc sa = {0};
+	int r;
+
+	if (argc < 4) die_usage();
+
+	remoteip = (char *)strdup(argv[1]);
+	local = "localhost";
+
+	if (!stralloc_copys(&helohost, argv[2])) die_nomem();
+	if (!stralloc_0(&helohost)) die_nomem();
+
+	if (!stralloc_copys(&addr, argv[3])) die_nomem();
+	if (!stralloc_0(&addr)) die_nomem();
+
+	if (argc > 4) {
+		if (!stralloc_copys(&spflocal, argv[4])) die_nomem();
+		if (spflocal.len && !stralloc_0(&spflocal)) die_nomem();
+	}
+
+	if (argc > 5) {
+		if (!stralloc_copys(&spfguess, argv[5])) die_nomem();
+		if (spfguess.len && !stralloc_0(&spfguess)) die_nomem();
+	}
+
+	if (argc > 6) {
+		if (!stralloc_copys(&spfexp, argv[6])) die_nomem();
+	} else
+		if (!stralloc_copys(&spfexp, SPF_DEFEXP)) die_nomem();
+	if (spfexp.len && !stralloc_0(&spfexp)) die_nomem();
+
+	dns_init(0);
+	r = spfcheck();
+	if (r == SPF_NOMEM) die_nomem();
+
+	substdio_puts(subfdout,"result=");
+	switch(r) {
+		case SPF_OK: substdio_puts(subfdout,"pass"); break;
+		case SPF_NONE: substdio_puts(subfdout,"none"); break;
+		case SPF_UNKNOWN: substdio_puts(subfdout,"unknown"); break;
+		case SPF_NEUTRAL: substdio_puts(subfdout,"neutral"); break;
+		case SPF_SOFTFAIL: substdio_puts(subfdout,"softfail"); break;
+		case SPF_FAIL: substdio_puts(subfdout,"fail"); break;
+		case SPF_ERROR: substdio_puts(subfdout,"error"); break;
+	}
+
+	if (r == SPF_FAIL) {
+		substdio_puts(subfdout,": ");
+		if (!spfexplanation(&sa)) die_nomem();
+		substdio_put(subfdout,sa.s,sa.len);
+	}
+
+	substdio_putsflush(subfdout,"\n");
+
+	substdio_puts(subfdout,"Received-SPF: ");
+	if (!spfinfo(&sa)) die_nomem();
+	substdio_put(subfdout,sa.s,sa.len);
+	substdio_putsflush(subfdout,"\n");
+
+	_exit(0);
+}
diff -Naur ./ssl_timeoutio.c ../qmail-1.03-build-10/ssl_timeoutio.c
--- ./ssl_timeoutio.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/ssl_timeoutio.c	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,94 @@
+#include "select.h"
+#include "error.h"
+#include "ndelay.h"
+#include "ssl_timeoutio.h"
+
+int ssl_timeoutio(int (*fun)(),
+  long t, int rfd, int wfd, SSL *ssl, char *buf, int len)
+{
+  int n;
+  const long end = t + time(NULL);
+
+  do {
+    fd_set fds;
+    struct timeval tv;
+
+    const int r = buf ? fun(ssl, buf, len) : fun(ssl);
+    if (r > 0) return r;
+
+    t = end - time(NULL);
+    if (t < 0) break;
+    tv.tv_sec = t; tv.tv_usec = 0;
+
+    FD_ZERO(&fds);
+    switch (SSL_get_error(ssl, r))
+    {
+    default: return r; /* some other error */
+    case SSL_ERROR_WANT_READ:
+      FD_SET(rfd, &fds); n = select(rfd + 1, &fds, NULL, NULL, &tv);
+      break;
+    case SSL_ERROR_WANT_WRITE:
+      FD_SET(wfd, &fds); n = select(wfd + 1, NULL, &fds, NULL, &tv);
+      break;
+    }
+
+    /* n is the number of descriptors that changed status */
+  } while (n > 0);
+
+  if (n != -1) errno = error_timeout;
+  return -1;
+}
+
+int ssl_timeoutaccept(long t, int rfd, int wfd, SSL *ssl)
+{
+  int r;
+
+  /* if connection is established, keep NDELAY */
+  if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1;
+  r = ssl_timeoutio(SSL_accept, t, rfd, wfd, ssl, NULL, 0);
+
+  if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); }
+  else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+
+  return r;
+}
+
+int ssl_timeoutconn(long t, int rfd, int wfd, SSL *ssl)
+{
+  int r;
+
+  /* if connection is established, keep NDELAY */
+  if (ndelay_on(rfd) == -1 || ndelay_on(wfd) == -1) return -1;
+  r = ssl_timeoutio(SSL_connect, t, rfd, wfd, ssl, NULL, 0);
+
+  if (r <= 0) { ndelay_off(rfd); ndelay_off(wfd); }
+  else SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+
+  return r;
+}
+
+int ssl_timeoutrehandshake(long t, int rfd, int wfd, SSL *ssl)
+{
+  int r;
+
+  SSL_renegotiate(ssl);
+  r = ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
+  if (r <= 0 || ssl->type == SSL_ST_CONNECT) return r;
+
+  /* this is for the server only */
+  ssl->state = SSL_ST_ACCEPT;
+  return ssl_timeoutio(SSL_do_handshake, t, rfd, wfd, ssl, NULL, 0);
+}
+
+int ssl_timeoutread(long t, int rfd, int wfd, SSL *ssl, char *buf, int len)
+{
+  if (!buf) return 0;
+  if (SSL_pending(ssl)) return SSL_read(ssl, buf, len);
+  return ssl_timeoutio(SSL_read, t, rfd, wfd, ssl, buf, len);
+}
+
+int ssl_timeoutwrite(long t, int rfd, int wfd, SSL *ssl, char *buf, int len)
+{
+  if (!buf) return 0;
+  return ssl_timeoutio(SSL_write, t, rfd, wfd, ssl, buf, len);
+}
diff -Naur ./ssl_timeoutio.h ../qmail-1.03-build-10/ssl_timeoutio.h
--- ./ssl_timeoutio.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/ssl_timeoutio.h	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,21 @@
+#ifndef SSL_TIMEOUTIO_H
+#define SSL_TIMEOUTIO_H
+
+#include <openssl/ssl.h>
+
+/* the version is like this: 0xMNNFFPPS: major minor fix patch status */
+#if OPENSSL_VERSION_NUMBER < 0x00906000L
+# error "Need OpenSSL version at least 0.9.6"
+#endif
+
+int ssl_timeoutconn(long t, int rfd, int wfd, SSL *ssl);
+int ssl_timeoutaccept(long t, int rfd, int wfd, SSL *ssl);
+int ssl_timeoutrehandshake(long t, int rfd, int wfd, SSL *ssl);
+
+int ssl_timeoutread(long t, int rfd, int wfd, SSL *ssl, char *buf, int len);
+int ssl_timeoutwrite(long t, int rfd, int wfd, SSL *ssl, char *buf, int len);
+
+int ssl_timeoutio(
+  int (*fun)(), long t, int rfd, int wfd, SSL *ssl, char *buf, int len);
+
+#endif
diff -Naur ./str_cpyb.c ../qmail-1.03-build-10/str_cpyb.c
--- ./str_cpyb.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/str_cpyb.c	2006-05-05 21:22:50.000000000 -0500
@@ -0,0 +1,18 @@
+#include "str.h"
+
+unsigned int str_copyb(s,t,max)
+register char *s;
+register char *t;
+unsigned int max;
+{
+  register int len;
+
+  len = 0;
+  while (max-- > 0) {
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+    if (!(*s = *t)) return len; ++s; ++t; ++len;
+  }
+  return len;
+}
diff -Naur ./str.h ../qmail-1.03-build-10/str.h
--- ./str.h	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/str.h	2006-05-07 12:32:01.000000000 -0500
@@ -2,6 +2,7 @@
 #define STR_H
 
 extern unsigned int str_copy();
+extern unsigned int str_copyb();
 extern int str_diff();
 extern int str_diffn();
 extern unsigned int str_len();
diff -Naur ./strpidt.c ../qmail-1.03-build-10/strpidt.c
--- ./strpidt.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/strpidt.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+** Copyright 1998 - 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if	HAVE_CONFIG_H
+#include	"config.h"
+#endif
+#include	"numlib.h"
+#include	<string.h>
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+char *str_pid_t(pid_t t, char *arg)
+{
+char	buf[NUMBUFSIZE];
+char	*p=buf+sizeof(buf)-1;
+
+	*p=0;
+	do
+	{
+		*--p= '0' + (t % 10);
+		t=t / 10;
+	} while(t);
+	return (strcpy(arg, p));
+}
diff -Naur ./strsalloc.c ../qmail-1.03-build-10/strsalloc.c
--- ./strsalloc.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/strsalloc.c	2006-05-05 21:22:51.000000000 -0500
@@ -0,0 +1,7 @@
+#include "alloc.h"
+#include "gen_allocdefs.h"
+#include "stralloc.h"
+#include "strsalloc.h"
+
+GEN_ALLOC_readyplus(strsalloc,stralloc,sa,len,a,i,n,x,10,strsalloc_readyplus)
+GEN_ALLOC_append(strsalloc,stralloc,sa,len,a,i,n,x,10,strsalloc_readyplus,strsalloc_append)
diff -Naur ./strsalloc.h ../qmail-1.03-build-10/strsalloc.h
--- ./strsalloc.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/strsalloc.h	2006-05-05 21:22:51.000000000 -0500
@@ -0,0 +1,12 @@
+#ifndef STRSALLOC_H
+#define STRSALLOC_H
+
+#include "stralloc.h"
+
+#include "gen_alloc.h"
+
+GEN_ALLOC_typedef(strsalloc,stralloc,sa,len,a)
+extern int strsalloc_readyplus();
+extern int strsalloc_append();
+
+#endif
diff -Naur ./strtimet.c ../qmail-1.03-build-10/strtimet.c
--- ./strtimet.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/strtimet.c	2006-05-03 17:44:55.000000000 -0500
@@ -0,0 +1,26 @@
+/*
+** Copyright 1998 - 2000 Double Precision, Inc.
+** See COPYING for distribution information.
+*/
+
+#if	HAVE_CONFIG_H
+#include	"config.h"
+#endif
+#include	"numlib.h"
+#include	<string.h>
+
+static const char rcsid[]="$Id: qmail-maildir++.patch,v 1.1.1.1.2.1 2005/01/19 23:35:23 tomcollins Exp $";
+
+char *str_time_t(time_t t, char *arg)
+{
+char	buf[NUMBUFSIZE];
+char	*p=buf+sizeof(buf)-1;
+
+	*p=0;
+	do
+	{
+		*--p= '0' + (t % 10);
+		t=t / 10;
+	} while(t);
+	return (strcpy(arg, p));
+}
diff -Naur ./TARGETS ../qmail-1.03-build-10/TARGETS
--- ./TARGETS	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/TARGETS	2006-05-09 23:52:11.000000000 -0500
@@ -10,16 +10,26 @@
 qmail.o
 quote.o
 now.o
+base64.o
 gfrom.o
 myctime.o
 slurpclose.o
 make-makelib
 makelib
+maildirflags.o
+maildirparsequota.o
+maildiropen.o
+maildirgetquota.o
+maildirquota.o
+overmaildirquota.o
+strtimet.o
+strpidt.o
 case_diffb.o
 case_diffs.o
 case_lowerb.o
 case_lowers.o
 case_starts.o
+case_startb.o
 case.a
 getln.o
 getln2.o
@@ -100,11 +110,14 @@
 str_diff.o
 str_diffn.o
 str_cpy.o
+str_cpyb.o
 str_chr.o
 str_rchr.o
 str_start.o
 byte_chr.o
 byte_rchr.o
+byte_cspn.o
+byte_rcspn.o
 byte_diff.o
 byte_copy.o
 byte_cr.o
@@ -168,11 +181,15 @@
 constmap.o
 timeoutread.o
 timeoutwrite.o
+tls.o
+ssl_timeoutio.o
 timeoutconn.o
 tcpto.o
 dns.o
+spf.o
 ip.o
 ipalloc.o
+strsalloc.o
 hassalen.h
 ipme.o
 ndelay.o
@@ -212,6 +229,9 @@
 headerbody.o
 hfield.o
 token822.o
+spf.o
+spfquery.o
+spfquery
 qmail-inject
 predate.o
 predate
@@ -252,11 +272,16 @@
 qmail-qmtpd
 qmail-smtpd.o
 qmail-smtpd
+qregex.o
 sendmail.o
 sendmail
 tcp-env.o
 remoteinfo.o
 tcp-env
+qmail-badmimetypes.o
+qmail-badmimetypes
+qmail-badloadertypes.o
+qmail-badloadertypes
 qmail-newmrh.o
 qmail-newmrh
 config
@@ -270,8 +295,12 @@
 dnsip
 dnsmxip.o
 dnsmxip
+dnstxt.o
+dnstxt
 dnsfq.o
 dnsfq
+qmail-dk
+qmail-dk.o
 hostname.o
 hostname
 ipmeprint.o
@@ -320,6 +349,7 @@
 binm2+df
 binm3
 binm3+df
+Makefile-cert
 it
 qmail-local.0
 qmail-lspawn.0
@@ -352,6 +382,10 @@
 qmail-qmtpd.0
 qmail-smtpd.0
 tcp-env.0
+qmail-badloadertype.8
+qmail-badloadertype.0
+qmail-badmimetype.8
+qmail-badmimetype.0
 qmail-newmrh.8
 qmail-newmrh.0
 qreceipt.0
@@ -385,3 +419,6 @@
 man
 setup
 check
+qregex.o
+chkuser.o
+update_tmprsadh
diff -Naur ./TARGETS.orig ../qmail-1.03-build-10/TARGETS.orig
--- ./TARGETS.orig	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/TARGETS.orig	2006-04-27 11:43:57.000000000 -0500
@@ -0,0 +1,394 @@
+auto-ccld.sh
+make-load
+find-systype
+systype
+load
+make-compile
+compile
+fork.h
+qmail-local.o
+qmail.o
+quote.o
+now.o
+base64.o
+gfrom.o
+myctime.o
+slurpclose.o
+make-makelib
+makelib
+case_diffb.o
+case_diffs.o
+case_lowerb.o
+case_lowers.o
+case_starts.o
+case.a
+getln.o
+getln2.o
+getln.a
+subgetopt.o
+sgetopt.o
+getopt.a
+sig_alarm.o
+hassgprm.h
+sig_block.o
+hassgact.h
+sig_catch.o
+sig_pause.o
+sig_pipe.o
+sig_child.o
+sig_hup.o
+sig_term.o
+sig_bug.o
+sig_misc.o
+sig.a
+open_append.o
+open_excl.o
+open_read.o
+open_trunc.o
+open_write.o
+open.a
+seek_cur.o
+seek_end.o
+seek_set.o
+seek_trunc.o
+seek.a
+hasflock.h
+lock_ex.o
+lock_exnb.o
+lock_un.o
+lock.a
+fd_copy.o
+fd_move.o
+fd.a
+haswaitp.h
+wait_pid.o
+wait_nohang.o
+wait.a
+env.o
+envread.o
+env.a
+stralloc_eady.o
+stralloc_pend.o
+stralloc_copy.o
+stralloc_opys.o
+stralloc_opyb.o
+stralloc_cat.o
+stralloc_cats.o
+stralloc_catb.o
+stralloc_arts.o
+stralloc.a
+alloc.o
+alloc_re.o
+alloc.a
+strerr_sys.o
+strerr_die.o
+strerr.a
+substdio.o
+substdi.o
+substdo.o
+subfderr.o
+subfdout.o
+subfdouts.o
+subfdin.o
+subfdins.o
+substdio_copy.o
+substdio.a
+error.o
+error_str.o
+error_temp.o
+error.a
+str_len.o
+str_diff.o
+str_diffn.o
+str_cpy.o
+str_chr.o
+str_rchr.o
+str_start.o
+byte_chr.o
+byte_rchr.o
+byte_diff.o
+byte_copy.o
+byte_cr.o
+byte_zero.o
+str.a
+fmt_str.o
+fmt_strn.o
+fmt_uint.o
+fmt_uint0.o
+fmt_ulong.o
+scan_ulong.o
+scan_8long.o
+fs.a
+datetime.o
+datetime_un.o
+datetime.a
+auto-str.o
+auto-str
+auto_qmail.c
+auto_qmail.o
+auto-int8.o
+auto-int8
+auto_patrn.c
+auto_patrn.o
+socket.lib
+qmail-local
+uint32.h
+qmail-lspawn.o
+select.h
+chkspawn.o
+auto-int.o
+auto-int
+auto_spawn.c
+auto_spawn.o
+chkspawn
+spawn.o
+chkshsgr.o
+chkshsgr
+hasshsgr.h
+prot.o
+coe.o
+cdb_hash.o
+cdb_unpack.o
+cdb_seek.o
+cdb.a
+auto-uid.o
+auto-uid
+auto-gid.o
+auto-gid
+auto_uids.c
+auto_uids.o
+qmail-lspawn
+qmail-getpw.o
+auto_break.c
+auto_break.o
+auto_usera.c
+auto_usera.o
+qmail-getpw
+qmail-remote.o
+control.o
+constmap.o
+timeoutread.o
+timeoutwrite.o
+tls.o
+ssl_timeoutio.o
+timeoutconn.o
+tcpto.o
+dns.o
+ip.o
+ipalloc.o
+hassalen.h
+ipme.o
+ndelay.o
+ndelay_off.o
+ndelay.a
+dns.lib
+qmail-remote
+qmail-rspawn.o
+tcpto_clean.o
+qmail-rspawn
+direntry.h
+qmail-clean.o
+fmtqfn.o
+auto_split.c
+auto_split.o
+qmail-clean
+qmail-send.o
+qsutil.o
+newfield.o
+prioq.o
+hasmkffo.h
+fifo.o
+hasnpbg1.h
+trigger.o
+readsubdir.o
+date822fmt.o
+qmail-send
+qmail-start.o
+qmail-start
+splogger.o
+syslog.lib
+splogger
+qmail-queue.o
+triggerpull.o
+qmail-queue
+qmail-inject.o
+headerbody.o
+hfield.o
+token822.o
+qmail-inject
+predate.o
+predate
+datemail
+mailsubj
+qmail-upq
+qmail-showctl.o
+qmail-showctl
+qmail-newu.o
+cdbmss.o
+cdbmake_pack.o
+cdbmake_hash.o
+cdbmake_add.o
+cdbmake.a
+qmail-newu
+qmail-pw2u.o
+qmail-pw2u
+qmail-qread.o
+qmail-qread
+qmail-qstat
+qmail-tcpto.o
+qmail-tcpto
+qmail-tcpok.o
+qmail-tcpok
+qmail-pop3d.o
+commands.o
+maildir.o
+qmail-pop3d
+qmail-popup.o
+qmail-popup
+qmail-qmqpc.o
+qmail-qmqpc
+qmail-qmqpd.o
+received.o
+qmail-qmqpd
+qmail-qmtpd.o
+rcpthosts.o
+qmail-qmtpd
+qmail-smtpd.o
+qmail-smtpd
+qregex.o
+sendmail.o
+sendmail
+tcp-env.o
+remoteinfo.o
+tcp-env
+qmail-newmrh.o
+qmail-newmrh
+config
+config-fast
+dnscname.o
+dnsdoe.o
+dnscname
+dnsptr.o
+dnsptr
+dnsip.o
+dnsip
+dnsmxip.o
+dnsmxip
+dnsfq.o
+dnsfq
+hostname.o
+hostname
+ipmeprint.o
+ipmeprint
+qreceipt.o
+qreceipt
+qsmhook.o
+qsmhook
+qbiff.o
+qbiff
+forward.o
+forward
+preline.o
+preline
+condredirect.o
+condredirect
+bouncesaying.o
+bouncesaying
+except.o
+except
+maildirmake.o
+maildirmake
+maildir2mbox.o
+maildir2mbox
+maildirwatch.o
+maildirwatch
+qail
+elq
+pinq
+idedit.o
+idedit
+install-big.o
+install.o
+install-big
+hier.o
+install
+instcheck.o
+instcheck
+home
+home+df
+proc
+proc+df
+binm1
+binm1+df
+binm2
+binm2+df
+binm3
+binm3+df
+Makefile-cert
+it
+qmail-local.0
+qmail-lspawn.0
+qmail-getpw.8
+qmail-getpw.0
+qmail-remote.0
+qmail-rspawn.0
+qmail-clean.0
+qmail-send.8
+qmail-send.0
+qmail-start.8
+qmail-start.0
+splogger.0
+qmail-queue.0
+qmail-inject.0
+mailsubj.0
+qmail-showctl.0
+qmail-newu.8
+qmail-newu.0
+qmail-pw2u.8
+qmail-pw2u.0
+qmail-qread.0
+qmail-qstat.0
+qmail-tcpto.0
+qmail-tcpok.0
+qmail-pop3d.0
+qmail-popup.0
+qmail-qmqpc.0
+qmail-qmqpd.0
+qmail-qmtpd.0
+qmail-smtpd.0
+tcp-env.0
+qmail-newmrh.8
+qmail-newmrh.0
+qreceipt.0
+qbiff.0
+forward.0
+preline.0
+condredirect.0
+bouncesaying.0
+except.0
+maildirmake.0
+maildir2mbox.0
+maildirwatch.0
+qmail.0
+qmail-limits.7
+qmail-limits.0
+qmail-log.0
+qmail-control.5
+qmail-control.0
+qmail-header.0
+qmail-users.5
+qmail-users.0
+dot-qmail.5
+dot-qmail.0
+qmail-command.0
+tcp-environ.0
+maildir.0
+mbox.0
+addresses.0
+envelopes.0
+forgeries.0
+man
+setup
+check
+chkuser.o
+update_tmprsadh
diff -Naur ./tcp-env.c ../qmail-1.03-build-10/tcp-env.c
--- ./tcp-env.c	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/tcp-env.c	2006-05-07 12:39:58.000000000 -0500
@@ -10,6 +10,7 @@
 #include "scan.h"
 #include "subgetopt.h"
 #include "ip.h"
+#include "strsalloc.h"
 #include "dns.h"
 #include "byte.h"
 #include "remoteinfo.h"
@@ -34,6 +35,7 @@
 int argc;
 char *argv[];
 {
+ strsalloc ssa = {0};
  int dummy;
  char *proto;
  int opt;
@@ -74,12 +76,13 @@
    temp[ip_fmt(temp,&iplocal)] = 0;
    if (!env_put2("TCPLOCALIP",temp)) die();
 
-   switch(dns_ptr(&localname,&iplocal))
+   switch(dns_ptr(&ssa,&iplocal))
     {
      case DNS_MEM: die();
      case DNS_SOFT:
        if (!stralloc_copys(&localname,"softdnserror")) die();
      case 0:
+       if (!stralloc_copy(&localname,&ssa.sa[0])) die();
        if (!stralloc_0(&localname)) die();
        case_lowers(localname.s);
        if (!env_put2("TCPLOCALHOST",localname.s)) die();
@@ -99,12 +102,13 @@
    temp[ip_fmt(temp,&ipremote)] = 0;
    if (!env_put2("TCPREMOTEIP",temp)) die();
 
-   switch(dns_ptr(&remotename,&ipremote))
+   switch(dns_ptr(&ssa,&ipremote))
     {
      case DNS_MEM: die();
      case DNS_SOFT:
        if (!stralloc_copys(&remotename,"softdnserror")) die();
      case 0:
+       if (!stralloc_copy(&remotename,&ssa.sa[0])) die();
        if (!stralloc_0(&remotename)) die();
        case_lowers(remotename.s);
        if (!env_put2("TCPREMOTEHOST",remotename.s)) die();
diff -Naur ./tls.c ../qmail-1.03-build-10/tls.c
--- ./tls.c	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/tls.c	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,25 @@
+#include "exit.h"
+#include "error.h"
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+int smtps = 0;
+SSL *ssl = NULL;
+
+void ssl_free(SSL *myssl) { SSL_shutdown(myssl); SSL_free(myssl); }
+void ssl_exit(int status) { if (ssl) ssl_free(ssl); _exit(status); }
+
+const char *ssl_error()
+{
+  int r = ERR_get_error();
+  if (!r) return NULL;
+  SSL_load_error_strings();
+  return ERR_error_string(r, NULL);
+}
+const char *ssl_error_str()
+{
+  const char *err = ssl_error();
+  if (err) return err;
+  if (!errno) return 0;
+  return (errno == error_timeout) ? "timed out" : error_str(errno);
+}
diff -Naur ./tls.h ../qmail-1.03-build-10/tls.h
--- ./tls.h	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/tls.h	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,16 @@
+#ifndef TLS_H
+#define TLS_H
+
+#include <openssl/ssl.h>
+
+extern int smtps;
+extern SSL *ssl;
+
+void ssl_free(SSL *myssl);
+void ssl_exit(int status);
+# define _exit ssl_exit
+
+const char *ssl_error();
+const char *ssl_error_str();
+
+#endif
diff -Naur ./update_tmprsadh.sh ../qmail-1.03-build-10/update_tmprsadh.sh
--- ./update_tmprsadh.sh	1969-12-31 17:00:00.000000000 -0700
+++ ../qmail-1.03-build-10/update_tmprsadh.sh	2006-04-27 11:10:31.000000000 -0500
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Update temporary RSA and DH keys
+# Frederik Vermeulen 2004-05-31 GPL
+
+umask 0077 || exit 0
+
+export PATH="$PATH:/usr/local/bin/ssl:/usr/sbin"
+
+openssl genrsa -out QMAIL/control/rsa512.new 512 &&
+chmod 600 QMAIL/control/rsa512.new &&
+chown UGQMAILD QMAIL/control/rsa512.new &&
+mv -f QMAIL/control/rsa512.new QMAIL/control/rsa512.pem
+echo
+
+openssl dhparam -2 -out QMAIL/control/dh512.new 512 &&
+chmod 600 QMAIL/control/dh512.new &&
+chown UGQMAILD QMAIL/control/dh512.new &&
+mv -f QMAIL/control/dh512.new QMAIL/control/dh512.pem
+echo
+
+openssl dhparam -2 -out QMAIL/control/dh1024.new 1024 &&
+chmod 600 QMAIL/control/dh1024.new &&
+chown UGQMAILD QMAIL/control/dh1024.new &&
+mv -f QMAIL/control/dh1024.new QMAIL/control/dh1024.pem
diff -Naur ./UPGRADE ../qmail-1.03-build-10/UPGRADE
--- ./UPGRADE	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/UPGRADE	2006-04-24 21:24:32.000000000 -0500
@@ -3,7 +3,7 @@
 much more secure and reliable than sendmail, but that's not saying much.
 
 
-Here's how to upgrade to qmail 1.03. This procedure will overwrite the
+Here's how to upgrade to netqmail 1.05. This procedure will overwrite the
 old qmail binaries. Furthermore, it may begin delivering messages from
 the queue before you have had a chance to test it.
 
@@ -17,7 +17,7 @@
 
 
 Before starting, compare conf* to your old conf*, and make any necessary
-changes. You can copy conf* from 1.02.
+changes. You can copy conf* from 1.02 or 1.03.
 
 
 How to install:
diff -Naur ./VERSION ../qmail-1.03-build-10/VERSION
--- ./VERSION	1998-06-15 05:53:16.000000000 -0500
+++ ../qmail-1.03-build-10/VERSION	2006-04-24 21:24:32.000000000 -0500
@@ -1 +1 @@
-qmail 1.03
+netqmail 1.05
openSUSE Build Service is sponsored by