[PATCH] Trafficaccounting in a mysql db

Christian Schulte cs at schulte.it
Wed Apr 9 18:28:33 EDT 2003


Hello again,

this here should work for the current cvs checkout of cyrus-imapd-2_2 
branch. After applying the patch cyrus wont built without specifiying 
the mysql library to link in. How this can be done depends on your mysql 
installation. If you have a libmysqlclient.so file it should be enough to

make distclean
LIBS="-lmysqlclient" ./configure --...
make
make install
man imapd.conf
/mysqllogging

If you have a statically linked mysql library (libmysqlclient.a) things 
will get harder. On Solaris I had to specify LIBS="-lmysqlclient -lm 
-lnsl -lsocket" (mainly every library which got shown in the output of 
ldd mysql) and then had to remove these libraries in the lib/Makefile 
and master/Makefile after configuring to get it linked statically 
against mysql.

Read the imapd.conf manpage after installing! There are new options 
mysqllogging,mysql_host,mysql_user,mysql_pass,mysql_db and mysql_table 
which are important to read.

Hope this works for you.....you should definetly review my changes 
before installing them ;-)


--Christian--


-------------- next part --------------
? MYconfigure
? mysql-logging.patch
? lib/imapoptions.original
? lib/prot.c.original
? lib/prot.h.original
Index: imap/backend.c
===================================================================
RCS file: /cvs/src/cyrus/imap/backend.c,v
retrieving revision 1.7.6.17
diff -c -r1.7.6.17 backend.c
*** imap/backend.c	24 Feb 2003 17:01:15 -0000	1.7.6.17
--- imap/backend.c	9 Apr 2003 23:15:27 -0000
***************
*** 259,264 ****
--- 259,268 ----
      }
  
      /* r == SASL_OK on success */
+ 
+     prot_setlogin(s->in, userid);
+     prot_setlogin(s->out, userid);
+  
      return r;
  }
  
***************
*** 308,315 ****
      memcpy(&ret->addr, res->ai_addr, res->ai_addrlen);
      freeaddrinfo(res0);    
  
!     ret->in = prot_new(sock, 0);
!     ret->out = prot_new(sock, 1);
      ret->sock = sock;
      prot_setflushonread(ret->in, ret->out);
      
--- 312,335 ----
      memcpy(&ret->addr, res->ai_addr, res->ai_addrlen);
      freeaddrinfo(res0);    
  
!     ret->in = prot_new(sock,
!                        0,
!                        "BACKEND",
!                        config_getstring(IMAPOPT_MYSQL_HOST),
!                        config_getstring(IMAPOPT_MYSQL_USER),
!                        config_getstring(IMAPOPT_MYSQL_PASS),
!                        config_getstring(IMAPOPT_MYSQL_DB),
!                        config_getstring(IMAPOPT_MYSQL_TABLE),
!                        config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     ret->out = prot_new(sock,
!                         1,
!                         "BACKEND",
!                         config_getstring(IMAPOPT_MYSQL_HOST),  
!                         config_getstring(IMAPOPT_MYSQL_USER),  
!                         config_getstring(IMAPOPT_MYSQL_PASS),  
!                         config_getstring(IMAPOPT_MYSQL_DB),  
!                         config_getstring(IMAPOPT_MYSQL_TABLE),  
!                         config_getswitch(IMAPOPT_MYSQLLOGGING) );
      ret->sock = sock;
      prot_setflushonread(ret->in, ret->out);
      
Index: imap/deliver.c
===================================================================
RCS file: /cvs/src/cyrus/imap/deliver.c,v
retrieving revision 1.164.4.6
diff -c -r1.164.4.6 deliver.c
*** imap/deliver.c	13 Feb 2003 20:32:55 -0000	1.164.4.6
--- imap/deliver.c	9 Apr 2003 23:15:28 -0000
***************
*** 266,273 ****
  	}
      }
  
!     deliver_in = prot_new(0, 0);
!     deliver_out = prot_new(1, 1);
      prot_setflushonread(deliver_in, deliver_out);
      prot_settimeout(deliver_in, 300);
  
--- 266,289 ----
  	}
      }
  
!     deliver_in = prot_new(0,
!                           0,
!                           "DELIVER",
!                           config_getstring(IMAPOPT_MYSQL_HOST),  
!                           config_getstring(IMAPOPT_MYSQL_USER),  
!                           config_getstring(IMAPOPT_MYSQL_PASS),  
!                           config_getstring(IMAPOPT_MYSQL_DB),  
!                           config_getstring(IMAPOPT_MYSQL_TABLE),  
!                           config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     deliver_out = prot_new(1,
!                            1,
!                            "DELIVER",
!                            config_getstring(IMAPOPT_MYSQL_HOST),  
!                            config_getstring(IMAPOPT_MYSQL_USER),  
!                            config_getstring(IMAPOPT_MYSQL_PASS),  
!                            config_getstring(IMAPOPT_MYSQL_DB),  
!                            config_getstring(IMAPOPT_MYSQL_TABLE),  
!                            config_getswitch(IMAPOPT_MYSQLLOGGING) );
      prot_setflushonread(deliver_in, deliver_out);
      prot_settimeout(deliver_in, 300);
  
Index: imap/imapd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/imapd.c,v
retrieving revision 1.398.2.70
diff -c -r1.398.2.70 imapd.c
*** imap/imapd.c	27 Mar 2003 19:36:24 -0000	1.398.2.70
--- imap/imapd.c	9 Apr 2003 23:15:38 -0000
***************
*** 503,510 ****
      id_getcmdline(argc, argv);
  #endif
  
!     imapd_in = prot_new(0, 0);
!     imapd_out = prot_new(1, 1);
  
      /* Find out name of client host */
      salen = sizeof(imapd_remoteaddr);
--- 503,526 ----
      id_getcmdline(argc, argv);
  #endif
  
!     imapd_in = prot_new(0,
!                         0,
!                         "IMAP",
!                         config_getstring(IMAPOPT_MYSQL_HOST),  
!                         config_getstring(IMAPOPT_MYSQL_USER),  
!                         config_getstring(IMAPOPT_MYSQL_PASS),  
!                         config_getstring(IMAPOPT_MYSQL_DB),  
!                         config_getstring(IMAPOPT_MYSQL_TABLE),  
!                         config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     imapd_out = prot_new(1,
!                          1,
!                          "IMAP",
!                          config_getstring(IMAPOPT_MYSQL_HOST),  
!                          config_getstring(IMAPOPT_MYSQL_USER),  
!                          config_getstring(IMAPOPT_MYSQL_PASS),  
!                          config_getstring(IMAPOPT_MYSQL_DB),  
!                          config_getstring(IMAPOPT_MYSQL_TABLE),  
!                          config_getswitch(IMAPOPT_MYSQLLOGGING) );
  
      /* Find out name of client host */
      salen = sizeof(imapd_remoteaddr);
***************
*** 597,603 ****
      char buf[1024];
      char *p;
  
!     motd_in = prot_new(fd, 0);
  
      prot_fgets(buf, sizeof(buf), motd_in);
      if ((p = strchr(buf, '\r'))!=NULL) *p = 0;
--- 613,627 ----
      char buf[1024];
      char *p;
  
!     motd_in = prot_new(fd,
!                        0,
!                        "MOTD_FILE",
!                        config_getstring(IMAPOPT_MYSQL_HOST),  
!                        config_getstring(IMAPOPT_MYSQL_USER),  
!                        config_getstring(IMAPOPT_MYSQL_PASS),  
!                        config_getstring(IMAPOPT_MYSQL_DB),  
!                        config_getstring(IMAPOPT_MYSQL_TABLE),  
!                        config_getswitch(IMAPOPT_MYSQLLOGGING) );
  
      prot_fgets(buf, sizeof(buf), motd_in);
      if ((p = strchr(buf, '\r'))!=NULL) *p = 0;
***************
*** 1607,1612 ****
--- 1631,1640 ----
  		   imapd_clienthost, passwd);
  	    reply = "Anonymous access granted";
  	    imapd_userid = xstrdup("anonymous");
+ 
+             prot_setlogin(imapd_in, imapd_userid);
+             prot_setlogin(imapd_out, imapd_userid);
+ 
  	}
  	else {
  	    syslog(LOG_NOTICE, "badlogin: %s anonymous login refused",
***************
*** 1642,1647 ****
--- 1670,1679 ----
      }
      else {
  	imapd_userid = xstrdup(canon_user);
+ 
+         prot_setlogin(imapd_in, imapd_userid);
+         prot_setlogin(imapd_out, imapd_userid);
+ 
  	snmp_increment_args(AUTHENTICATION_YES, 1,
  			    VARIABLE_AUTH, 0 /*hash_simple("LOGIN") */, 
  			    VARIABLE_LISTEND);
***************
*** 1756,1761 ****
--- 1788,1796 ----
      }
  
      proc_register("imapd", imapd_clienthost, imapd_userid, (char *)0);
+ 
+     prot_setlogin(imapd_in, imapd_userid);
+     prot_setlogin(imapd_out, imapd_userid);
  
      syslog(LOG_NOTICE, "login: %s %s %s%s %s", imapd_clienthost, imapd_userid,
  	   authtype, imapd_starttls_done ? "+TLS" : "", "User logged in");
Index: imap/lmtpd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpd.c,v
retrieving revision 1.99.2.29
diff -c -r1.99.2.29 lmtpd.c
*** imap/lmtpd.c	31 Mar 2003 01:19:31 -0000	1.99.2.29
--- imap/lmtpd.c	9 Apr 2003 23:15:40 -0000
***************
*** 250,257 ****
  {
      int opt;
  
!     deliver_in = prot_new(0, 0);
!     deliver_out = prot_new(1, 1);
      prot_setflushonread(deliver_in, deliver_out);
      prot_settimeout(deliver_in, 360);
  
--- 250,273 ----
  {
      int opt;
  
!     deliver_in = prot_new(0,
!                           0,
!                           "LMTP",
!                           config_getstring(IMAPOPT_MYSQL_HOST),  
!                           config_getstring(IMAPOPT_MYSQL_USER),  
!                           config_getstring(IMAPOPT_MYSQL_PASS),  
!                           config_getstring(IMAPOPT_MYSQL_DB),  
!                           config_getstring(IMAPOPT_MYSQL_TABLE),  
!                           config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     deliver_out = prot_new(1,
!                            1,
!                            "LMTP",
!                            config_getstring(IMAPOPT_MYSQL_HOST),  
!                            config_getstring(IMAPOPT_MYSQL_USER),  
!                            config_getstring(IMAPOPT_MYSQL_PASS),  
!                            config_getstring(IMAPOPT_MYSQL_DB),  
!                            config_getstring(IMAPOPT_MYSQL_TABLE),  
!                            config_getswitch(IMAPOPT_MYSQLLOGGING) );
      prot_setflushonread(deliver_in, deliver_out);
      prot_settimeout(deliver_in, 360);
  
Index: imap/lmtpengine.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpengine.c,v
retrieving revision 1.75.4.19
diff -c -r1.75.4.19 lmtpengine.c
*** imap/lmtpengine.c	5 Mar 2003 18:32:06 -0000	1.75.4.19
--- imap/lmtpengine.c	9 Apr 2003 23:15:41 -0000
***************
*** 726,732 ****
      }
      m->size = sbuf.st_size;
      m->f = f;
!     m->data = prot_new(fileno(f), 0);
  
      return 0;
  }
--- 726,740 ----
      }
      m->size = sbuf.st_size;
      m->f = f;
!     m->data = prot_new(fileno(f),
!                        0,
!                        "LMTP_SPOOL",
!                        config_getstring(IMAPOPT_MYSQL_HOST),  
!                        config_getstring(IMAPOPT_MYSQL_USER),  
!                        config_getstring(IMAPOPT_MYSQL_PASS),  
!                        config_getstring(IMAPOPT_MYSQL_DB),  
!                        config_getstring(IMAPOPT_MYSQL_TABLE),  
!                        config_getswitch(IMAPOPT_MYSQLLOGGING) );
  
      return 0;
  }
***************
*** 956,961 ****
--- 964,973 ----
  						   the AUTH command */
  	ssf = 2;
  	auth_id = "postman";
+ 
+         prot_setlogin(pin, auth_id);
+         prot_setlogin(pout, auth_id);
+ 
  	sasl_setprop(cd.conn, SASL_SSF_EXTERNAL, &ssf);
  	sasl_setprop(cd.conn, SASL_AUTH_EXTERNAL, auth_id);
      } else {
***************
*** 1098,1103 ****
--- 1110,1118 ----
  	      authenticated += 2;
  	      prot_printf(pout, "235 Authenticated!\r\n");
  
+               prot_setlogin(pin, user);
+               prot_setlogin(pout, user);
+ 
  	      /* set protection layers */
  	      prot_setsasl(pin,  cd.conn);
  	      prot_setsasl(pout, cd.conn);
***************
*** 1887,1894 ****
      conn->mechs = NULL;
      conn->saslconn = NULL;
      /* setup prot layers */
!     conn->pin = prot_new(sock, 0);
!     conn->pout = prot_new(sock, 1);
      prot_setflushonread(conn->pin, conn->pout);
  
      /* read greeting */
--- 1902,1925 ----
      conn->mechs = NULL;
      conn->saslconn = NULL;
      /* setup prot layers */
!     conn->pin = prot_new(sock,
!                          0,
!                          "LMTP",
!                          config_getstring(IMAPOPT_MYSQL_HOST),  
!                          config_getstring(IMAPOPT_MYSQL_USER),  
!                          config_getstring(IMAPOPT_MYSQL_PASS),  
!                          config_getstring(IMAPOPT_MYSQL_DB),  
!                          config_getstring(IMAPOPT_MYSQL_TABLE),  
!                          config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     conn->pout = prot_new(sock,
!                           1,
!                           "LMTP",
!                           config_getstring(IMAPOPT_MYSQL_HOST),  
!                           config_getstring(IMAPOPT_MYSQL_USER),  
!                           config_getstring(IMAPOPT_MYSQL_PASS),  
!                           config_getstring(IMAPOPT_MYSQL_DB),  
!                           config_getstring(IMAPOPT_MYSQL_TABLE),  
!                           config_getswitch(IMAPOPT_MYSQLLOGGING) );
      prot_setflushonread(conn->pin, conn->pout);
  
      /* read greeting */
Index: imap/mupdate-client.c
===================================================================
RCS file: /cvs/src/cyrus/imap/mupdate-client.c,v
retrieving revision 1.32.4.12
diff -c -r1.32.4.12 mupdate-client.c
*** imap/mupdate-client.c	27 Feb 2003 18:39:43 -0000	1.32.4.12
--- imap/mupdate-client.c	9 Apr 2003 23:15:42 -0000
***************
*** 201,208 ****
      free(secprops);
  
      /* create protstream */
!     h->pin = prot_new(h->sock, 0);
!     h->pout = prot_new(h->sock, 1);
  
      prot_setflushonread(h->pin, h->pout);
      prot_settimeout(h->pin, 30*60);
--- 201,224 ----
      free(secprops);
  
      /* create protstream */
!     h->pin = prot_new(h->sock,
!                       0,
!                       "MUPDATE",
!                       config_getstring(IMAPOPT_MYSQL_HOST),  
!                       config_getstring(IMAPOPT_MYSQL_USER),  
!                       config_getstring(IMAPOPT_MYSQL_PASS),  
!                       config_getstring(IMAPOPT_MYSQL_DB),  
!                       config_getstring(IMAPOPT_MYSQL_TABLE),  
!                       config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     h->pout = prot_new(h->sock,
!                        1,
!                        "MUPDATE",
!                        config_getstring(IMAPOPT_MYSQL_HOST),  
!                        config_getstring(IMAPOPT_MYSQL_USER),  
!                        config_getstring(IMAPOPT_MYSQL_PASS),  
!                        config_getstring(IMAPOPT_MYSQL_DB),  
!                        config_getstring(IMAPOPT_MYSQL_TABLE),  
!                        config_getswitch(IMAPOPT_MYSQLLOGGING) );
  
      prot_setflushonread(h->pin, h->pout);
      prot_settimeout(h->pin, 30*60);
Index: imap/pop3d.c
===================================================================
RCS file: /cvs/src/cyrus/imap/pop3d.c,v
retrieving revision 1.122.4.29
diff -c -r1.122.4.29 pop3d.c
*** imap/pop3d.c	12 Mar 2003 16:38:16 -0000	1.122.4.29
--- imap/pop3d.c	9 Apr 2003 23:15:43 -0000
***************
*** 341,348 ****
  
      signals_poll();
  
!     popd_in = prot_new(0, 0);
!     popd_out = prot_new(1, 1);
  
      /* Find out name of client host */
      salen = sizeof(popd_remoteaddr);
--- 341,364 ----
  
      signals_poll();
  
!     popd_in = prot_new(0,
!                        0,
!                        "POP",
!                        config_getstring(IMAPOPT_MYSQL_HOST),  
!                        config_getstring(IMAPOPT_MYSQL_USER),  
!                        config_getstring(IMAPOPT_MYSQL_PASS),  
!                        config_getstring(IMAPOPT_MYSQL_DB),  
!                        config_getstring(IMAPOPT_MYSQL_TABLE),  
!                        config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     popd_out = prot_new(1,
!                         1,
!                         "POP",
!                         config_getstring(IMAPOPT_MYSQL_HOST),  
!                         config_getstring(IMAPOPT_MYSQL_USER),  
!                         config_getstring(IMAPOPT_MYSQL_PASS),  
!                         config_getstring(IMAPOPT_MYSQL_DB),  
!                         config_getstring(IMAPOPT_MYSQL_TABLE),  
!                         config_getswitch(IMAPOPT_MYSQLLOGGING) );
  
      /* Find out name of client host */
      salen = sizeof(popd_remoteaddr);
***************
*** 1042,1047 ****
--- 1058,1065 ----
      syslog(LOG_NOTICE, "login: %s %s APOP %s",
  	   popd_clienthost, popd_userid, "User logged in");
  
+     prot_setlogin(popd_in, popd_userid);
+     prot_setlogin(popd_out, popd_userid);
      popd_auth_done = 1;
      openinbox();
  }
***************
*** 1076,1081 ****
--- 1094,1103 ----
      }
      else {
  	popd_userid = xstrdup(p);
+ 
+         prot_setlogin(popd_in, popd_userid);
+         prot_setlogin(popd_out, popd_userid);
+ 
  	prot_printf(popd_out, "+OK Name is a valid mailbox\r\n");
      }
  }
***************
*** 1304,1309 ****
--- 1326,1334 ----
      
      syslog(LOG_NOTICE, "login: %s %s %s %s", popd_clienthost, popd_userid,
  	   authtype, "User logged in");
+ 
+     prot_setlogin(popd_in, popd_userid);
+     prot_setlogin(popd_out, popd_userid);
  
      popd_auth_done = 1;
      openinbox();
Index: imtest/imtest.c
===================================================================
RCS file: /cvs/src/cyrus/imtest/imtest.c,v
retrieving revision 1.82.2.15
diff -c -r1.82.2.15 imtest.c
*** imtest/imtest.c	19 Mar 2003 01:29:22 -0000	1.82.2.15
--- imtest/imtest.c	9 Apr 2003 23:15:46 -0000
***************
*** 2442,2449 ****
  	}
  	
  	/* set up the prot layer */
! 	pin = prot_new(sock, 0);
! 	pout = prot_new(sock, 1); 
  	
  #ifdef HAVE_SSL
  	if (dossl==1) {
--- 2442,2465 ----
  	}
  	
  	/* set up the prot layer */
! 	pin = prot_new(sock,
!                        0,
!                        "IMTEST",
!                        NULL,  
!                        NULL,  
!                        NULL,  
!                        NULL,  
!                        NULL,  
!                        0);
! 	pout = prot_new(sock,
!                         1,
!                         "IMTEST",
!                         NULL,  
!                         NULL,  
!                         NULL,  
!                         NULL,  
!                         NULL,  
!                         0);
  	
  #ifdef HAVE_SSL
  	if (dossl==1) {
Index: lib/imapoptions
===================================================================
RCS file: /cvs/src/cyrus/lib/Attic/imapoptions,v
retrieving revision 1.1.2.5
diff -c -r1.1.2.5 imapoptions
*** lib/imapoptions	19 Mar 2003 19:00:39 -0000	1.1.2.5
--- lib/imapoptions	9 Apr 2003 23:15:47 -0000
***************
*** 574,580 ****
  { "virtdomains", 0, SWITCH }
  /* Enable virtual domain support */
  
! /*
  .SH SEE ALSO
  .PP
  \fBimapd(8)\fR, \fBpop3d(8)\fR, \fBlmtpd(8)\fR, \fBtimsieved(8)\fR,
--- 574,626 ----
  { "virtdomains", 0, SWITCH }
  /* Enable virtual domain support */
  
! { "mysqllogging", 0, SWITCH }
! /* Enable accounting into a mysql db */
! 
! { "mysql_host", "localhost", STRING }
! /* The mysql host to connect to:
!    The connection to the db will be made during startup of a service
!    and will be held until it ends. So for e.g. every imap connection
!    the process will hold a connection to the db. The number of
!    simultanous connections to the db depends on the number of
!    simultanous service connections. */
!   
! { "mysql_user", NULL, STRING } 
! /* The mysql user to connect with */
! 
! { "mysql_pass", NULL, STRING }
! /* The mysql password to use. Defaults to no password */
! 
! { "mysql_db", "cyrus", STRING }
! /* The database to use */
! 
! { "mysql_table", "cyrus_accounting", STRING }
! /* The table to use in mysql_db. Fieldnames are hardcoded:
! .br
! .br
!    id int(11) NOT NULL auto_increment
! .br
!    login varchar(128) NOT NULL default ''
! .br
!    service varchar(30) NOT NULL default ''
! .br 
!    bytes double NOT NULL default '0'
! .br
!    type enum('IN','OUT','UNSPECIFIED') NOT NULL default 'UNSPECIFIED'
! .br
!    connect_time datetime default NULL
! .br
!    disconnect_time datetime NOT NULL default '0000-00-00 00:00:00'
! .br
!    PRIMARY KEY  (id)
! .br
!    KEY connect_time (connect_time)
! .br
!    KEY login (login)
! .br
!    KEY disconnect_time (disconnect_time)
! .br */
! 
  .SH SEE ALSO
  .PP
  \fBimapd(8)\fR, \fBpop3d(8)\fR, \fBlmtpd(8)\fR, \fBtimsieved(8)\fR,
Index: lib/prot.c
===================================================================
RCS file: /cvs/src/cyrus/lib/prot.c,v
retrieving revision 1.72.4.17
diff -c -r1.72.4.17 prot.c
*** lib/prot.c	31 Mar 2003 21:48:25 -0000	1.72.4.17
--- lib/prot.c	9 Apr 2003 23:15:47 -0000
***************
*** 73,78 ****
--- 73,80 ----
  #include "util.h"
  #include "xmalloc.h"
  
+ char buf[1024];
+ 
  /* Transparant protgroup structure */
  struct protgroup
  {
***************
*** 85,93 ****
   * Create a new protection stream for file descriptor 'fd'.  Stream
   * will be used for writing iff 'write' is nonzero.
   */
! struct protstream *prot_new(fd, write)
! int fd;
! int write;
  {
      struct protstream *newstream;
  
--- 87,93 ----
   * Create a new protection stream for file descriptor 'fd'.  Stream
   * will be used for writing iff 'write' is nonzero.
   */
! struct protstream *prot_new(int fd,int write,const char *service,const char *mysql_host,const char *mysql_user,const char *mysql_pass,const char *mysql_db,const char *mysql_table,int mysqllogging)
  {
      struct protstream *newstream;
  
***************
*** 101,109 ****
      newstream->write = write;
      newstream->logfd = PROT_NO_FD;
      newstream->big_buffer = PROT_NO_FD;
      if(write)
  	newstream->cnt = PROT_BUFSIZE;
! 
      return newstream;
  }
  
--- 101,148 ----
      newstream->write = write;
      newstream->logfd = PROT_NO_FD;
      newstream->big_buffer = PROT_NO_FD;
+     newstream->bytes=0;
+     newstream->primkey=0;
+     newstream->mysql_host = mysql_host;
+     newstream->mysql_user = mysql_user;
+     newstream->mysql_pass = mysql_pass;
+     newstream->mysql_db = mysql_db;
+     newstream->mysql_table = mysql_table;
+     newstream->mysqllogging = mysqllogging;
      if(write)
  	newstream->cnt = PROT_BUFSIZE;
!     if(mysqllogging) {
!         if(! mysql_init(&newstream->mysql) ) {
!             sprintf(buf, "MYSQL: mysql_init() failed:%s", mysql_error(&newstream->mysql));
!             syslog(LOG_ERR, buf);
!         }
!         else {
!             if(! mysql_connect(&newstream->mysql,
!                                newstream->mysql_host,
!                                newstream->mysql_user,
!                                newstream->mysql_pass)  )
!             {
!                 sprintf(buf, "MYSQL: mysql_connect() failed:%s", mysql_error(&newstream->mysql));
!                 syslog(LOG_ERR, buf);
!             }
!             else {
!                 sprintf(buf, "INSERT INTO %s.%s (service, bytes, type, connect_time) VALUES ('%s',%d,'%s',SYSDATE())",
!                         newstream->mysql_db,
!                         newstream->mysql_table,
!                         service,
!                         0,
!                         write ? "OUT" : "IN");
!                 if( mysql_query(&newstream->mysql, buf) ){
! 		    syslog(LOG_ERR, buf);
!                     sprintf(buf, "MYSQL: mysql_query() failed:%s", mysql_error(&newstream->mysql));
!                     syslog(LOG_ERR, buf);
!                 }
!                 else
!                     newstream->primkey=(unsigned long)mysql_insert_id(&newstream->mysql);
!                     
!             }
!         }
!     } 
      return newstream;
  }
  
***************
*** 112,117 ****
--- 151,157 ----
   */
  int prot_free(struct protstream *s)
  {
+  
      if (s->error) free(s->error);
      free(s->buf);
  
***************
*** 119,127 ****
  	map_free(&(s->bigbuf_base), &(s->bigbuf_siz));
  	close(s->big_buffer);
      }
! 
      free((char*)s);
- 
      return 0;
  }
  
--- 159,182 ----
  	map_free(&(s->bigbuf_base), &(s->bigbuf_siz));
  	close(s->big_buffer);
      }
!     if( s->mysqllogging ) {
!         if(s->primkey != 0){
!             sprintf(buf,
!                     "UPDATE %s.%s SET disconnect_time=SYSDATE(),bytes=%lu WHERE id=%lu",
!                     s->mysql_db,
!                     s->mysql_table,
!                     s->bytes, s->primkey);
!             if( mysql_query(&s->mysql, buf) ) {
!                 syslog(LOG_ERR, buf);
!                 sprintf(buf, "MYSQL: mysql_query() failed:%s", mysql_error(&s->mysql));
!                 syslog(LOG_ERR, buf);
!             }
!         }
!         else
! 	    syslog(LOG_ERR, "MYSQL: prot_free did not have a primary db key to update the row");
!         mysql_close(&s->mysql);
!     }
      free((char*)s);
      return 0;
  }
  
***************
*** 134,139 ****
--- 189,220 ----
      return 0;
  }
  
+ /*
+  * Set the the authenticated userid if it is known'.
+  */
+ void prot_setlogin(struct protstream *s, const char *userid)
+ {
+     if( s->mysqllogging ) {
+         if( s->primkey==0 ) {
+             syslog(LOG_ERR, "MYSQL:\tprot_free did not have a primary db key to update the row");
+         }
+         else {
+             sprintf(buf,
+                     "UPDATE %s.%s SET login='%s' WHERE id=%lu",
+                     s->mysql_db,
+                     s->mysql_table,
+                     userid,
+                     s->primkey);
+             if( mysql_query(&s->mysql, buf) ) {
+                 syslog(LOG_ERR, buf);
+                 sprintf(buf, "MYSQL: mysql_query() failed:%s", mysql_error(&s->mysql));
+                 syslog(LOG_ERR, buf);
+             }
+         }
+     }
+ }
+ 
+ 
  #ifdef HAVE_SSL
  
  /*
***************
*** 499,506 ****
  	    s->ptr = s->buf+1;
  	    s->cnt = n;
  	}
! 	
  	if (s->cnt > 0) {
  	    if (s->logfd != -1) {
  		time_t newtime;
  		char timebuf[20];
--- 580,588 ----
  	    s->ptr = s->buf+1;
  	    s->cnt = n;
  	}
! 
  	if (s->cnt > 0) {
+             s->bytes+=s->cnt;
  	    if (s->logfd != -1) {
  		time_t newtime;
  		char timebuf[20];
***************
*** 534,539 ****
--- 616,622 ----
   */
  int prot_flush(struct protstream *s) 
  {
+     s->bytes+=strlen(s->buf);
      return prot_flush_internal(s, 1);
  }
  
***************
*** 832,838 ****
      assert(s->write);
      if(s->error || s->eof) return EOF;
      if(len == 0) return 0;
!     
      while (len >= s->cnt) {
  	/* XXX can we manage to write data from 'buf' without copying it
  	   to s->ptr ? */
--- 915,922 ----
      assert(s->write);
      if(s->error || s->eof) return EOF;
      if(len == 0) return 0;
!    
!     s->bytes+=len; 
      while (len >= s->cnt) {
  	/* XXX can we manage to write data from 'buf' without copying it
  	   to s->ptr ? */
***************
*** 1246,1251 ****
--- 1330,1336 ----
      assert(s->write);
      assert(s->cnt > 0);
  
+     s->bytes+=1;
      *s->ptr++ = c;
      if (--s->cnt == 0) {
  	return prot_flush_internal(s,0);
Index: lib/prot.h
===================================================================
RCS file: /cvs/src/cyrus/lib/prot.h,v
retrieving revision 1.35.4.7
diff -c -r1.35.4.7 prot.h
*** lib/prot.h	13 Feb 2003 20:33:14 -0000	1.35.4.7
--- lib/prot.h	9 Apr 2003 23:15:48 -0000
***************
*** 51,56 ****
--- 51,57 ----
  #include <stdlib.h>
  
  #include <sasl/sasl.h>
+ #include <mysql/mysql.h>
  
  #ifdef HAVE_SSL
  #include <openssl/ssl.h>
***************
*** 111,116 ****
--- 112,127 ----
  
      /* For use by applications */
      void *userdata;
+ 
+     unsigned long primkey;
+     unsigned long bytes;
+     MYSQL mysql;
+     const char *mysql_host;
+     const char *mysql_user;
+     const char *mysql_pass;
+     const char *mysql_db;
+     const char *mysql_table;
+     int mysqllogging;
  };
  
  typedef struct prot_waitevent *prot_waiteventcallback_t(struct protstream *s,
***************
*** 160,170 ****
  #define prot_IS_BLOCKING(s) ((s)->dontblock == 0)
  
  /* Allocate/free the protstream structure */
! extern struct protstream *prot_new(int fd, int write);
  extern int prot_free(struct protstream *s);
  
  /* Set the telemetry logfile for a given protstream */
  extern int prot_setlog(struct protstream *s, int fd);
  
  /* Set the SASL options for a protstream (requires authentication to
   * be complete for the given sasl_conn_t */
--- 171,185 ----
  #define prot_IS_BLOCKING(s) ((s)->dontblock == 0)
  
  /* Allocate/free the protstream structure */
! extern struct protstream *prot_new(int fd,int write,const char *service,const char *mysql_host,const char *mysql_user,const char *mysql_pass,const char *mysql_db,const char *mysql_table,int mysqllogging);
! 
  extern int prot_free(struct protstream *s);
  
  /* Set the telemetry logfile for a given protstream */
  extern int prot_setlog(struct protstream *s, int fd);
+ 
+ /* Set the userid of this stream for storage in MySQL db */
+ extern void prot_setlogin(struct protstream *s, const char *userid);
  
  /* Set the SASL options for a protstream (requires authentication to
   * be complete for the given sasl_conn_t */
Index: perl/sieve/lib/isieve.c
===================================================================
RCS file: /cvs/src/cyrus/perl/sieve/lib/isieve.c,v
retrieving revision 1.24.4.4
diff -c -r1.24.4.4 isieve.c
*** perl/sieve/lib/isieve.c	13 Feb 2003 20:33:28 -0000	1.24.4.4
--- perl/sieve/lib/isieve.c	9 Apr 2003 23:15:48 -0000
***************
*** 151,158 ****
    (*obj)->port = port;
  
    /* set up the prot layer */
!   (*obj)->pin = prot_new(sock, 0);
!   (*obj)->pout = prot_new(sock, 1); 
  
    return 0;
  }
--- 151,174 ----
    (*obj)->port = port;
  
    /* set up the prot layer */
!   (*obj)->pin = prot_new(sock,
!                          0,
!                          "SIEVE",
!                          NULL,  
!                          NULL,  
!                          NULL,  
!                          NULL,  
!                          NULL,  
!                          0);
!   (*obj)->pout = prot_new(sock,
!                           1,
!                           "SIEVE",
!                           NULL,
!                           NULL,
!                           NULL,
!                           NULL,
!                           NULL,
!                           0); 
  
    return 0;
  }
Index: timsieved/timsieved.c
===================================================================
RCS file: /cvs/src/cyrus/timsieved/timsieved.c,v
retrieving revision 1.40.4.12
diff -c -r1.40.4.12 timsieved.c
*** timsieved/timsieved.c	13 Feb 2003 20:33:36 -0000	1.40.4.12
--- timsieved/timsieved.c	9 Apr 2003 23:15:50 -0000
***************
*** 217,224 ****
      char hbuf[NI_MAXHOST];
  
      /* set up the prot streams */
!     sieved_in = prot_new(0, 0);
!     sieved_out = prot_new(1, 1);
  
      timeout = config_getint(IMAPOPT_TIMEOUT);
      if (timeout < 10) timeout = 10;
--- 217,240 ----
      char hbuf[NI_MAXHOST];
  
      /* set up the prot streams */
!     sieved_in = prot_new(0,
!                          0,
!                          "SIEVE",
!                          config_getstring(IMAPOPT_MYSQL_HOST),
!                          config_getstring(IMAPOPT_MYSQL_USER),
!                          config_getstring(IMAPOPT_MYSQL_PASS),
!                          config_getstring(IMAPOPT_MYSQL_DB),
!                          config_getstring(IMAPOPT_MYSQL_TABLE),
!                          config_getswitch(IMAPOPT_MYSQLLOGGING) );
!     sieved_out = prot_new(1,
!                           1,
!                           "SIEVE",
!                           config_getstring(IMAPOPT_MYSQL_HOST),
!                           config_getstring(IMAPOPT_MYSQL_USER),
!                           config_getstring(IMAPOPT_MYSQL_PASS),
!                           config_getstring(IMAPOPT_MYSQL_DB),
!                           config_getstring(IMAPOPT_MYSQL_TABLE),
!                           config_getswitch(IMAPOPT_MYSQLLOGGING) );
  
      timeout = config_getint(IMAPOPT_TIMEOUT);
      if (timeout < 10) timeout = 10;


More information about the Info-cyrus mailing list