This patch is a modification of Markus 'Maex' Stumpf's patch from:

  http://www.lamer.de/maex/creative/software/qmail/103-pop3log/qmail-pop3d.c.diff

It can be downloaded from:

  http://devsec.org/patch/qmail/qmail-pop3d.c.tk-1.diff

This patch uses stderr instead of fd5.

-Thor Kooda
 2004-03-18


diff -Naur qmail-1.03.orig/qmail-pop3d.c qmail-1.03/qmail-pop3d.c
--- qmail-1.03.orig/qmail-pop3d.c	Mon Jun 15 05:53:16 1998
+++ qmail-1.03/qmail-pop3d.c	Thu Mar 18 02:16:13 2004
@@ -1,3 +1,5 @@
+#define __mLOGGING
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "commands.h"
@@ -17,7 +19,21 @@
 #include "timeoutread.h"
 #include "timeoutwrite.h"
 
-void die() { _exit(0); }
+#ifdef __mLOGGING
+#include "env.h"
+void log_quit();
+int log_flag = 0;
+#endif /* __mLOGGING */
+
+void flush();
+void puts();
+
+void die() {
+#ifdef __mLOGGING
+    if (!log_flag) log_quit();  
+#endif /* __mLOGGING */
+  _exit(0);
+}
 
 int saferead(fd,buf,len) int fd; char *buf; int len;
 {
@@ -75,6 +91,63 @@
 
 void okay() { puts("+OK \r\n"); flush(); }
 
+#ifdef __mLOGGING
+stralloc logs_pidhostinfo = {0};
+unsigned long log_bytes = 0;
+
+char sslogbuf[512];
+substdio sslog = SUBSTDIO_FDBUF(safewrite,2,sslogbuf,sizeof(sslogbuf));
+
+void log(s) char *s; { log_flag=1; if(substdio_puts(&sslog,s) == -1) _exit(1); log_flag=0;}
+void logf(s) char *s; { log_flag=1; if(substdio_puts(&sslog,s) == -1) _exit(1); if(substdio_flush(&sslog) == -1) _exit(1); log_flag=0;}
+void log_pidhostinfo() { log(logs_pidhostinfo.s); }
+
+void log_quit()
+{
+  char strnum[FMT_ULONG];
+
+  log("acct:"); log_pidhostinfo(); log("logout ");
+  strnum[fmt_ulong(strnum,log_bytes)] = 0;
+  log(strnum); logf(" bytes transferred\n");
+}
+
+void log_init()
+{
+  char strnum[FMT_ULONG];
+  char *remotehost;
+  char *remoteip;
+  char *remoteinfo;
+  char *user;
+
+  remoteip = env_get("TCPREMOTEIP");
+  if (!remoteip) remoteip = "unknown";
+  remotehost = env_get("TCPREMOTEHOST");
+  if (!remotehost) remotehost = "unknown";
+  remoteinfo = env_get("TCPREMOTEINFO");
+  if (!remoteinfo) remoteinfo = "";
+  user = env_get("USER");
+  if (!user) user = "unknown";
+
+  if (!stralloc_copys(&logs_pidhostinfo, " pid ")) die_nomem();
+  strnum[fmt_ulong(strnum,getpid())] = 0;
+  if (!stralloc_cats(&logs_pidhostinfo, strnum)) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, ": ")) die_nomem();
+
+  if (!stralloc_cats(&logs_pidhostinfo, remotehost)) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, ":")) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, remoteip)) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, ":")) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, remoteinfo)) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, " ")) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, user)) die_nomem();
+  if (!stralloc_cats(&logs_pidhostinfo, " ")) die_nomem();
+  if (!stralloc_0(&logs_pidhostinfo)) die_nomem();
+}
+
+
+
+#endif /* __mLOGGING */
+
 void printfn(fn) char *fn;
 {
   fn += 4;
@@ -103,6 +176,10 @@
         put(".",1);
     put(line.s,line.len);
     put("\r\n",2);
+#ifdef __mLOGGING
+    log_bytes += line.len + 2;
+#endif /* __mLOGGING */
+
     if (!match) break;
   }
   put("\r\n.\r\n",5);
@@ -296,6 +373,11 @@
  
   if (!argv[1]) die_nomaildir();
   if (chdir(argv[1]) == -1) die_nomaildir();
+
+#ifdef __mLOGGING
+  log_init();
+  log("acct:"); log_pidhostinfo(); logf("login\n");
+#endif /* __mLOGGING */
  
   getlist();
 
