*** tcpserver.c.orig	Wed Mar 14 10:21:33 2001
--- tcpserver.c	Fri Mar 16 13:53:52 2001
***************
*** 1,3 ****
--- 1,4 ----
+ #include <stdio.h>
  #include <sys/types.h>
  #include <sys/param.h>
  #include <netdb.h>
***************
*** 25,36 ****
--- 26,39 ----
  #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;
***************
*** 109,114 ****
--- 112,121 ----
  {
    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,205 ****
    }
    env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0);
  
!   if (fnrules) {
      int fdrules;
      fdrules = open_read(fnrules);
      if (fdrules == -1) {
        if (errno != error_noent) drop_rules();
--- 205,222 ----
    }
    env("TCPREMOTEINFO",flagremoteinfo ? tcpremoteinfo.s : 0);
  
!   if(usemysql) {
!     if(flagdeny==2) {
!        /* drop_db(); */
!     } else if(!flagdeny) {
!        env("RELAYCLIENT","");
!     }
!     flagdeny=0;
!   } 
! 
!   if(fnrules) {
      int fdrules;
+ 
      fdrules = open_read(fnrules);
      if (fdrules == -1) {
        if (errno != error_noent) drop_rules();
***************
*** 240,246 ****
  {
    strerr_warn1("\
  tcpserver: usage: tcpserver \
! [ -1UXpPhHrRoOdDqQv ] \
  [ -c limit ] \
  [ -x rules.cdb ] \
  [ -B banner ] \
--- 257,263 ----
  {
    strerr_warn1("\
  tcpserver: usage: tcpserver \
! [ -1UXpPhHrRoOdDqQvS ] \
  [ -c limit ] \
  [ -x rules.cdb ] \
  [ -B banner ] \
***************
*** 300,306 ****
    int s;
    int t;
   
!   while ((opt = getopt(argc,argv,"dDvqQhHrR1UXx: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;
--- 317,323 ----
    int s;
    int t;
   
!   while ((opt = getopt(argc,argv,"dDvqQhHrR1UXSx: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,332 ****
--- 344,350 ----
        case 'g': scan_ulong(optarg,&gid); break;
        case '1': flag1 = 1; break;
        case 'l': localhost = optarg; break;
+       case 'S': usemysql = 1; break;
        default: usage();
      }
    argc -= optind;
***************
*** 398,403 ****
--- 416,422 ----
    for (;;) {
      while (numchildren >= limit) sig_pause();
  
+     flagdeny=0;
      sig_unblock(sig_child);
      t = socket_accept4(s,remoteip,&remoteport);
      sig_block(sig_child);
***************
*** 405,410 ****
--- 424,499 ----
      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("/var/qmail/control/sql","r")) {
+              char line[256];
+              char tag[256];
+              char value[256];
+      
+              while(fgets(line,256,fp)) {
+                char *comment;
+      
+                if(comment=strchr(line,'#')) {
+                   *comment='\0';
+                }
+                if(sscanf(line,"%s\t%s\n", tag, value) != 2) continue;
+                /* fprintf(stderr,"Warning: got Line: [%s]\n",line); */
+      
+                /*
+                  server  sql.domain.com
+                  port    3306
+                  database        vpopmail
+                  table   relay
+                  user    vpopmail
+                  pass    secret
+                  time    1800
+                */
+                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 {
+                fprintf(stderr,"Warning: Bad sql: TAG: [%s] VALUE: [%s]\n",tag,value);
+                }
+              }
+          }
+          if(db_port==-1) {
+            fprintf(stderr,"Error: Failed to read /var/qmail/control/sql\n");
+            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();
+          if((ret=check_db(remoteipstr))==-1) {
+             flagdeny=2;
+          } else if(ret) {
+             flagdeny=1;
+          } 
+       } 
+     }
+ 
      switch(fork()) {
        case 0:
          close(s);
*** db.c.orig	Fri Mar 16 13:20:22 2001
--- db.c	Wed Mar 14 15:13:05 2001
***************
*** 0 ****
--- 1,122 ----
+ #include <stdio.h>
+ #include <unistd.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
+ */
+ #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;
+ 
+ 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;
+    }
+ 
+    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;
+ }
+ 
+ int check_db(char *remoteip) {
+    char query[MAX_QUERY_STRING];
+    int num_rows = 0;
+    int ret = -1;
+    MYSQL_RES *res;
+     
+    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) {
+       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);
+    }
+ }
+ 
*** db.h.orig	Fri Mar 16 13:20:54 2001
--- db.h	Thu Feb 22 11:35:17 2001
***************
*** 0 ****
--- 1,17 ----
+ #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;
+ 
+ int open_db(char *database, char *host, int port, char *username, char *password);
+ int check_db(char *remoteip);
+ void db_ping();
+ void db_close();
+ 
+ #endif
*** Makefile.orig	Fri Mar 16 13:16:37 2001
--- Makefile	Thu Feb 22 11:28:23 2001
***************
*** 513,518 ****
--- 513,522 ----
  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,757 ****
  	./compile tcprulescheck.c
  
  tcpserver: \
! load tcpserver.o rules.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 \
  	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 \
  stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \
  taia.h
  	./compile tcpserver.c
--- 746,761 ----
  	./compile tcprulescheck.c
  
  tcpserver: \
! 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 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 db.h \
  stralloc.h sig.h dns.h stralloc.h iopause.h taia.h tai.h uint64.h \
  taia.h
  	./compile tcpserver.c
*** conf-ld.orig	Fri Mar 16 13:46:36 2001
--- conf-ld	Fri Mar 16 13:46:43 2001
***************
*** 1,3 ****
! gcc -s
  
  This will be used to link .o files into an executable.
--- 1,3 ----
! gcc -s  -I/usr/include/mysql -L/usr/local/lib/mysql -lmysqlclient
  
  This will be used to link .o files into an executable.
*** conf-cc.orig	Fri Mar 16 13:47:31 2001
--- conf-cc	Fri Mar 16 13:47:37 2001
***************
*** 1,3 ****
! gcc -O2
  
  This will be used to compile .c files.
--- 1,3 ----
! gcc -O2 -I/usr/include/mysql
  
  This will be used to compile .c files.
