This patch written by Andrew Richards 2010. For more details, documentation
etc. please see
	http://free.acrconsulting.co.uk/
diff -Nru ucspi-tcp-0.88/Makefile ucspi-tcp-0.88_logmsg/Makefile
--- ucspi-tcp-0.88/Makefile	2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88_logmsg/Makefile	2010-02-09 14:58:53.000000000 +0000
@@ -151,6 +151,10 @@
 	> choose
 	chmod 755 choose
 
+clean: \
+TARGETS
+	rm -f `cat TARGETS`
+
 commands.o: \
 compile commands.c buffer.h stralloc.h gen_alloc.h str.h case.h \
 commands.h
diff -Nru ucspi-tcp-0.88/rblsmtpd.c ucspi-tcp-0.88_logmsg/rblsmtpd.c
--- ucspi-tcp-0.88/rblsmtpd.c	2000-03-18 15:18:42.000000000 +0000
+++ ucspi-tcp-0.88_logmsg/rblsmtpd.c	2010-07-23 10:41:35.000000000 +0100
@@ -27,6 +27,9 @@
 
 char *ip_env;
 static stralloc ip_reverse;
+static stralloc addr = {0};
+static stralloc foo  = {0};
+static char pid_str[FMT_ULONG]="?PID?";
 
 void ip_init(void)
 {
@@ -48,6 +51,101 @@
   }
 }
 
+void eout(s1) char *s1;			{buffer_puts(buffer_2,s1);}
+void eout2(s1,s2) char *s1,*s2;		{buffer_puts(buffer_2,s1);buffer_puts(buffer_2,s2);}
+void eout3(s1,s2,s3) char *s1,*s2,*s3;	{buffer_puts(buffer_2,s1);buffer_puts(buffer_2,s2);buffer_puts(buffer_2,s3);}
+
+void epid()
+{
+  if (*pid_str == '?') /* not yet set from getpid() */
+    pid_str[fmt_ulong(pid_str,getpid())] = 0;
+  eout(pid_str);
+}
+
+/* Choose your log format here, */
+
+/* rblsmtpd: 192.168.1.1 pid 1234: log msg */
+/* void enew()	{ eout3("rblsmtpd: ",ip_env," pid "); epid(); eout(": "); } */
+
+/* rblsmtpd: pid 1234 from 192.168.1.1: log msg */
+void enew()	{ eout("rblsmtpd: pid "); epid(); eout2(" from ", ip_env); eout(": "); }
+
+void eflush()	{ buffer_flush(buffer_2); }
+
+/* The functions below here come from qmail's qsutil.c with minor changes */
+void eoutsa(sa) stralloc *sa; { buffer_put(buffer_2,sa->s,sa->len); } /* no flush here */
+
+static int issafe(ch) char ch;
+{ /* Differs from qsutil.c version: space and % permitted */
+ if (ch == ':') return 0; /* Replace since used as delimiter in logs */
+ if (ch == '<') return 0; /* Replace since used around addresses in logs */
+ if (ch == '>') return 0; /* Replace since used around addresses in logs */
+ if (ch < 32)   return 0; /* Note that space (32) is permitted */
+ if (ch > 126)  return 0;
+ return 1;
+}
+
+void eoutclean(s) char *s;
+{
+ int i;
+ while (!stralloc_copys(&foo,s)) nomem();
+ for (i = 0;i < foo.len;++i)
+   if (foo.s[i] == '\n')
+     foo.s[i] = '/';
+   else
+     if (!issafe(foo.s[i]))
+       foo.s[i] = '_';
+ eoutsa(&foo);
+}
+
+/* Adapted from qmail-smtpd.c, only needed so we can log the envelope addresses: */
+int addrparse(arg)
+char *arg;
+{
+  int i;
+  char ch;
+  char terminator;
+  int flagesc;
+  int flagquoted;
+
+  terminator = '>';
+  i = str_chr(arg,'<');
+  if (arg[i])
+    arg += i + 1;
+  else { /* partner should go read rfc 821 */
+    terminator = ' ';
+    arg += str_chr(arg,':');
+    if (*arg == ':') ++arg;
+    while (*arg == ' ') ++arg;
+  }
+
+  /* strip source route */
+  if (*arg == '@') while (*arg) if (*arg++ == ':') break;
+
+  if (!stralloc_copys(&addr,"")) nomem();
+  flagesc = 0;
+  flagquoted = 0;
+  for (i = 0;ch = arg[i];++i) { /* copy arg to addr, stripping quotes */
+    if (flagesc) {
+      if (!stralloc_append(&addr,&ch)) nomem();
+      flagesc = 0;
+    }
+    else {
+      if (!flagquoted && (ch == terminator)) break;
+      switch(ch) {
+        case '\\': flagesc = 1; break;
+        case '"': flagquoted = !flagquoted; break;
+        default: if (!stralloc_append(&addr,&ch)) nomem();
+      }
+    }
+  }
+  /* could check for termination failure here, but why bother? */
+  if (!stralloc_append(&addr,"")) nomem();
+
+  if (addr.len > 900) return 0;
+  return 1;
+}
+
 unsigned long timeout = 60;
 int flagrblbounce = 0;
 int flagfailclosed = 0;
@@ -93,7 +191,6 @@
     decision = 1;
 }
 
-char strnum[FMT_ULONG];
 static stralloc message;
 
 char inspace[64]; buffer in = BUFFER_INIT(read,0,inspace,sizeof inspace);
@@ -102,17 +199,43 @@
 void reject() { buffer_putflush(&out,message.s,message.len); }
 void accept() { buffer_putsflush(&out,"250 rblsmtpd.local\r\n"); }
 void greet()  { buffer_putsflush(&out,"220 rblsmtpd.local\r\n"); }
-void quit()   { buffer_putsflush(&out,"221 rblsmtpd.local\r\n"); _exit(0); }
-void drop()   { _exit(0); }
+void quit()   { buffer_putsflush(&out,"221 rblsmtpd.local\r\n"); enew(); eout("Remote end QUIT: quitting\n"); eflush(); _exit(0); }
+void drop()   { enew(); eout("Session timed out: quitting\n"); eflush(); _exit(0); }
+void err_vrfy() { buffer_putsflush(&out,"252 rblsmtpd.local\r\n"); }
+
+void smtp_mail(arg) char *arg;
+{
+  enew();
+  if (!addrparse(arg))	{ eout("MAIL with too long address\n"); }
+  else			{ eout("Sender <"); eoutclean(addr.s); eout(">\n"); }
+  eflush();
+  accept();
+}
+
+void smtp_rcpt(arg) char *arg;
+{
+  enew();
+  if (!addrparse(arg))	{ eout("RCPT with too long address\n"); }
+  else			{ eout("Recipient <"); eoutclean(addr.s); eout(">\n"); }
+  eflush();
+  reject();
+/*
+ * We now have the envelope info for logging, assuming sender address
+ * already supplied - to be thorough we could check that the sender
+ * was supplied using the same logic as in qmail-smtpd.c
+ */
+}
 
 struct commands smtpcommands[] = {
   { "quit", quit, 0 }
 , { "helo", accept, 0 }
 , { "ehlo", accept, 0 }
-, { "mail", accept, 0 }
+, { "mail", smtp_mail, 0 }
 , { "rset", accept, 0 }
+, { "vrfy", err_vrfy, 0 }	/* Needed in a minimal SMTP implementation */
 , { "noop", accept, 0 }
-, { 0, reject, 0 }
+, { "rcpt", smtp_rcpt, 0 }
+, { 0, reject, 0 }		/* Including DATA */
 } ;
 
 void rblsmtpd(void)
@@ -131,14 +254,11 @@
     if ((message.s[i] < 32) || (message.s[i] > 126))
       message.s[i] = '?';
   
-  buffer_puts(buffer_2,"rblsmtpd: ");
-  buffer_puts(buffer_2,ip_env);
-  buffer_puts(buffer_2," pid ");
-  buffer_put(buffer_2,strnum,fmt_ulong(strnum,getpid()));
-  buffer_puts(buffer_2,": ");
-  buffer_put(buffer_2,message.s,message.len);
-  buffer_puts(buffer_2,"\n");
-  buffer_flush(buffer_2);
+  enew();
+  eout("RBL message is ");
+  eoutsa(&message);
+  eout("\n");
+  eflush();
 
   if (!stralloc_cats(&message,"\r\n")) nomem();
 
@@ -150,6 +270,9 @@
     greet();
     commands(&in,smtpcommands);
   }
+  enew();
+  eout("Session terminated: quitting\n"); /* Normally client disconnecting */
+  eflush();
   _exit(0);
 }
 
