diff -uNr ucspi-tcp-0.88.orig/Makefile ucspi-tcp-0.88.mysql/Makefile
--- ucspi-tcp-0.88.orig/Makefile	2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.mysql/Makefile	2007-05-04 22:16:30.000000000 +0200
@@ -513,6 +513,10 @@
 rules.h stralloc.h
 	./compile rules.c
 
+db.o: \
+compile db.c db.h
+	./compile db.c
+
 scan_ulong.o: \
 compile scan_ulong.c scan.h
 	./compile scan_ulong.c
@@ -742,16 +746,16 @@
 	./compile tcprulescheck.c
 
 tcpserver: \
-load tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a dns.a \
+load tcpserver.o rules.o db.o remoteinfo.o timeoutconn.o cdb.a dns.a \
 time.a unix.a byte.a socket.lib
-	./load tcpserver rules.o remoteinfo.o timeoutconn.o cdb.a \
+	./load tcpserver rules.o db.o remoteinfo.o timeoutconn.o cdb.a \
 	dns.a time.a unix.a byte.a  `cat socket.lib`
 
 tcpserver.o: \
 compile tcpserver.c uint16.h str.h byte.h fmt.h scan.h ip4.h fd.h \
 exit.h env.h prot.h open.h wait.h readwrite.h stralloc.h gen_alloc.h \
 alloc.h buffer.h error.h strerr.h sgetopt.h subgetopt.h pathexec.h \
-socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h \
+socket.h uint16.h ndelay.h remoteinfo.h stralloc.h uint16.h rules.h db.h \
 stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \
 taia.h
 	./compile tcpserver.c
diff -uNr ucspi-tcp-0.88.orig/conf-cc ucspi-tcp-0.88.mysql/conf-cc
--- ucspi-tcp-0.88.orig/conf-cc	2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.mysql/conf-cc	2007-05-04 22:16:30.000000000 +0200
@@ -1,3 +1,3 @@
-gcc -O2
+gcc -O2 -I/usr/include/mysql
 
 This will be used to compile .c files.
diff -uNr ucspi-tcp-0.88.orig/conf-ld ucspi-tcp-0.88.mysql/conf-ld
--- ucspi-tcp-0.88.orig/conf-ld	2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.mysql/conf-ld	2007-05-04 22:16:30.000000000 +0200
@@ -1,3 +1,3 @@
-gcc -s
+gcc -s  -I/usr/include/mysql -L /usr/lib/mysql -l mysqlclient
 
 This will be used to link .o files into an executable.
diff -uNr ucspi-tcp-0.88.orig/db.c ucspi-tcp-0.88.mysql/db.c
--- ucspi-tcp-0.88.orig/db.c	1970-01-01 01:00:00.000000000 +0100
+++ ucspi-tcp-0.88.mysql/db.c	2007-05-05 23:05:25.000000000 +0200
@@ -0,0 +1,190 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <mysql.h>
+#include "db.h"
+
+/*
+server  sql.mailserver.com
+port    3306
+database        vpopmail
+table   relay
+user    vpopmail
+pass    secret
+time    1800
+denytable deny_from
+denytime  24
+*/
+#define MAX_QUERY_STRING        160
+
+MYSQL *dbh=NULL;
+
+char db_database[256];
+char db_host[256];
+char db_table[256];
+char db_user[256];
+char db_password[256];
+int  db_port=-1;
+int  pop_timeout;
+char db_denytable[256];
+int  deny_timeout;
+
+extern int verbosity;
+
+int open_db(char *database, char *host, int port, char *username, char *password)
+{
+   MYSQL *tmp;
+
+   if (dbh != NULL) {
+      mysql_close(dbh);
+      dbh = NULL;
+   }
+   dbh = (MYSQL *)mysql_init(NULL);
+   if (dbh == NULL)
+   {
+      fprintf(stderr,"MYSQL Init Error:\n");
+      return -1;
+   }
+
+   mysql_options( dbh, MYSQL_READ_DEFAULT_GROUP, "vpopmail" );
+   tmp = mysql_real_connect(dbh, host, username, password, database, port, NULL,0);
+
+   if (!tmp)
+   {
+      fprintf(stderr,"MYSQL Error: %s\n",mysql_error(dbh));
+      return -1;
+   }
+
+   return 0;
+}
+
+/*
+ * check is must deny the remote ip address
+ * -> returns -1 is db error (should be denied for safety)
+ *             0 if not denied
+ *             1 if denied
+ */
+int check_deny(char *remoteip) {
+   char query[MAX_QUERY_STRING];
+   int num_rows = 0;
+   int ret = -1;
+   MYSQL_RES *res;
+
+	/* deny_from timeout is 60x3600x24 = 5184000 sec. */
+   snprintf(query,MAX_QUERY_STRING,"SELECT timestamp FROM %s WHERE '%s' LIKE CONCAT(ip_addr,'%%') AND (timestamp>(UNIX_TIMESTAMP()-%d) OR timestamp IS NULL )", db_denytable, remoteip, deny_timeout*216000);
+
+   ret = mysql_query(dbh,query);
+   res = mysql_store_result(dbh);
+   num_rows = mysql_affected_rows(dbh);
+   mysql_free_result(res);
+
+   if (ret) {
+      char err_str[256];
+
+      snprintf(err_str,255,"-%s-",mysql_error(dbh));
+      fprintf(stderr,"%s",err_str);
+      if(strstr("server has gone away",err_str)) {
+         db_close();
+         db_ping();
+
+         ret = mysql_query(dbh,query);
+         if (ret) {
+            return -1;
+         }
+      } else {
+         db_close();
+         db_ping();
+
+         ret = mysql_query(dbh,query);
+         if (ret) {
+            return -1;
+         }
+      }
+   }
+   if (verbosity >= 3 || getenv( "UCSPI_DEBUG" )) {
+      fprintf(stderr,"QUERY(err:%d/rows:%d): %s\n",ret,num_rows,query); /* */
+   }
+
+   if(num_rows>0) {
+     return 1;
+   } else {
+     return 0;
+   }
+}
+
+/*
+ * check if remote ip address is in vrelay table
+ * ->returns -1 for db error (should not allow relay for safety)
+ *            0 is ip is recorded and ok
+ *            1 if ip is unknow (or timeout is expired)
+ */
+int check_db(char *remoteip) {
+   char query[MAX_QUERY_STRING];
+   int num_rows = 0;
+   int ret = -1;
+   MYSQL_RES *res;
+
+   if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "remoteip=%s\n", remoteip );
+   snprintf(query,MAX_QUERY_STRING,"SELECT timestamp FROM %s WHERE '%s' LIKE CONCAT(ip_addr,'%%') AND (timestamp>(UNIX_TIMESTAMP()-%d) OR timestamp IS NULL )", db_table, remoteip, pop_timeout);
+
+   ret = mysql_query(dbh,query);
+   res = mysql_store_result(dbh);
+   num_rows = mysql_affected_rows(dbh);
+   mysql_free_result(res);
+
+   if (ret) {
+      char err_str[256];
+
+      snprintf(err_str,255,"-%s-",mysql_error(dbh));
+      fprintf(stderr,"%s",err_str);
+      if(strstr("server has gone away",err_str)) {
+         db_close();
+         db_ping();
+
+         ret = mysql_query(dbh,query);
+         if (ret) {
+            return -1;
+         }
+      } else {
+         db_close();
+         db_ping();
+
+         ret = mysql_query(dbh,query);
+         if (ret) {
+            return -1;
+         }
+      }
+   }
+   if (verbosity >= 3 || getenv( "UCSPI_DEBUG" )) {
+      fprintf(stderr,"QUERY(err:%d/rows:%d): %s\n",ret,num_rows,query); /* */
+   }
+
+   if(num_rows>0) {
+     return 0;
+   } else {
+     return 1;
+   }
+}
+
+void db_close()
+{
+   mysql_close(dbh);
+   dbh=NULL;
+
+   if (verbosity >= 2) {
+      fprintf(stderr,"db_close() called!\n");
+   }
+}
+
+void db_ping()
+{
+   if(dbh==NULL || mysql_ping(dbh)) {
+      if (verbosity >= 2) {
+         fprintf(stderr,"db_ping() is re-calling open_db!\n");
+      }
+      open_db(db_database,db_host,db_port,db_user,db_password);
+   }
+}
+
diff -uNr ucspi-tcp-0.88.orig/db.h ucspi-tcp-0.88.mysql/db.h
--- ucspi-tcp-0.88.orig/db.h	1970-01-01 01:00:00.000000000 +0100
+++ ucspi-tcp-0.88.mysql/db.h	2007-05-05 23:05:25.000000000 +0200
@@ -0,0 +1,20 @@
+#ifndef _DB_
+#define _DB_
+
+extern char db_database[256];
+extern char db_host[256];
+extern char db_table[256];
+extern char db_user[256];
+extern char db_password[256];
+extern int  db_port;
+extern int  pop_timeout;
+extern char db_denytable[256];
+extern int  deny_timeout;
+
+int open_db(char *database, char *host, int port, char *username, char *password);
+int check_deny(char *remoteip);
+int check_db(char *remoteip);
+void db_ping();
+void db_close();
+
+#endif
diff -uNr ucspi-tcp-0.88.orig/tcpserver.c ucspi-tcp-0.88.mysql/tcpserver.c
--- ucspi-tcp-0.88.orig/tcpserver.c	2000-03-18 16:18:42.000000000 +0100
+++ ucspi-tcp-0.88.mysql/tcpserver.c	2007-05-05 23:05:25.000000000 +0200
@@ -1,6 +1,11 @@
+#include <errno.h>
+#include <stdio.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+
 #include "uint16.h"
 #include "str.h"
 #include "byte.h"
@@ -25,12 +30,14 @@
 #include "ndelay.h"
 #include "remoteinfo.h"
 #include "rules.h"
+#include "db.h"
 #include "sig.h"
 #include "dns.h"
 
 int verbosity = 1;
 int flagkillopts = 1;
 int flagdelay = 1;
+int usemysql = 0;
 char *banner = "";
 int flagremoteinfo = 1;
 int flagremotehost = 1;
@@ -70,6 +77,7 @@
 #define DROP "tcpserver: warning: dropping connection, "
 
 int flagdeny = 0;
+int flagrelay = 0;
 int flagallownorules = 0;
 char *fnrules = 0;
 
@@ -109,6 +117,10 @@
 {
   strerr_die4sys(111,DROP,"unable to read ",fnrules,": ");
 }
+void drop_db(void)
+{
+  strerr_die4sys(111,DROP,"unable to verify DB ",db_database,": ");
+}
 
 void found(char *data,unsigned int datalen)
 {
@@ -198,8 +210,11 @@
   }
   env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0);
 
-  if (fnrules) {
+  if(usemysql && flagrelay ) env("RELAYCLIENT","");
+
+  if(fnrules) {
     int fdrules;
+
     fdrules = open_read(fnrules);
     if (fdrules == -1) {
       if (errno != error_noent) drop_rules();
@@ -240,9 +255,9 @@
 {
   strerr_warn1("\
 tcpserver: usage: tcpserver \
-[ -1UXpPhHrRoOdDqQv ] \
+[ -1UXpPhHrRoOdDqQvS ] \
 [ -c limit ] \
-[ -x rules.cdb ] \
+[ -x rules.cdb | -S sql.conf ] \
 [ -B banner ] \
 [ -g gid ] \
 [ -u uid ] \
@@ -299,8 +314,9 @@
   unsigned long u;
   int s;
   int t;
- 
-  while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx:t:u:g:l:b:B:c:pPoO")) != opteof)
+  char sqlconf[1024];
+
+  while ((opt = getopt(argc,argv,"dDvqQhHrR1UXS:x:t:u:g:l:b:B:c:pPoO")) != opteof)
     switch(opt) {
       case 'b': scan_ulong(optarg,&backlog); break;
       case 'c': scan_ulong(optarg,&limit); break;
@@ -327,6 +343,10 @@
       case 'g': scan_ulong(optarg,&gid); break;
       case '1': flag1 = 1; break;
       case 'l': localhost = optarg; break;
+      case 'S': usemysql = 1;
+         strcpy( sqlconf, optarg );
+         if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "sqlconf set to %s\n", sqlconf );
+         break;
       default: usage();
     }
   argc -= optind;
@@ -398,6 +418,8 @@
   for (;;) {
     while (numchildren >= limit) sig_pause();
 
+    flagdeny=0;
+    flagrelay=0;
     sig_unblock(sig_child);
     t = socket_accept4(s,remoteip,&remoteport);
     sig_block(sig_child);
@@ -405,6 +427,93 @@
     if (t == -1) continue;
     ++numchildren; printstatus();
  
+    if(usemysql) {
+      int ret;
+
+      remoteipstr[ip4_fmt(remoteipstr,remoteip)] = 0;
+
+      if(db_port==-1) {
+         FILE *fp;
+  
+         if(fp=fopen(sqlconf,"r")) {
+             if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "fopen ok\n" );
+             char line[256];
+             char tag[256];
+             char value[256];
+     
+             while(fgets(line,256,fp)) {
+               /* if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "read line '%s'\n", line ); */
+               char *comment;
+     
+               if(comment=strchr(line,'#')) {
+                  *comment='\0';
+               }
+               /* if(sscanf(line,"%s\t%s\n", tag, value) != 2) continue; */
+               if(sscanf(line,"%s %s\n", tag, value) != 2) continue;
+               /* fprintf(stderr,"Warning: got Line: [%s]\n",line); */
+               if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "tag='%s', value='%s'\n", tag, value );
+     
+               /*
+                 server    sql.domain.com
+                 port      3306
+                 database  vpopmail
+                 table     relay
+                 user      vpopmail
+                 pass      secret
+                 time      1800
+                 denytable deny_from
+                 denytime  24 (h)
+               */
+               if(!strcasecmp(tag,"server")) {
+                        strcpy(db_host,value);
+               } else if(!strcasecmp(tag,"port")) { 
+                        db_port = atoi(value);
+               } else if(!strcasecmp(tag,"database")) {
+                        strcpy(db_database,value);  
+               } else if(!strcasecmp(tag,"table")) {
+                        strcpy(db_table,value);
+               } else if(!strcasecmp(tag,"user")) {
+                        strcpy(db_user,value);
+               } else if(!strcasecmp(tag,"pass")) {
+                        strcpy(db_password,value);
+               } else if(!strcasecmp(tag,"time")) {
+                        pop_timeout=atoi(value);
+               } else if(!strcasecmp(tag,"denytable")) {
+                        strcpy(db_denytable,value);
+               } else if(!strcasecmp(tag,"denytime")) {
+                        deny_timeout=atoi(value);
+               } else {
+               fprintf(stderr,"Warning: Bad sql: TAG: [%s] VALUE: [%s]\n",tag,value);
+               }
+             }
+         } else {
+           fprintf( stderr, "unable to open %s file: %s\n", sqlconf, strerror( errno ));
+         }
+         if(db_port==-1) {
+           fprintf(stderr,"Error: Failed to read %s\n", sqlconf);
+           db_port==-2;
+         } else {
+           fclose(fp);
+         }
+         if (verbosity >= 2) {
+           fprintf(stderr,"db_port set to: [%d]\n", db_port);
+         }
+      }
+      if(db_port>=0) {
+         db_ping();
+         ret=check_deny(remoteipstr);
+         if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "check_deny returns %d (%s)\n", ret, ret<0 ? "db_error" : ( ret>0 ? "denied" : "allowed" ));
+         if( ret != 0 )
+            flagdeny = 1;
+         else {
+           ret=check_db(remoteipstr);
+           if( getenv( "UCSPI_DEBUG" )) fprintf( stderr, "check_db returns %d (%s)\n", ret, ret<0 ? "db_error" : ( ret>0 ? "no_relay_allowed" : "relay_allowed" ));
+           if( ret < 0 ) flagdeny = 1;
+           if( ret == 0 ) flagrelay = 1;
+         } 
+      } 
+    }
+
     switch(fork()) {
       case 0:
         close(s);
