$OpenBSD: patch-main_c,v 1.2 2005/12/14 06:02:09 jolan Exp $
--- main.c.orig	Sun Aug  3 00:54:56 2003
+++ main.c	Mon Nov 28 11:25:21 2005
@@ -23,26 +23,34 @@
 #include "ssl.h"
 #include "strlcpy.h"
 
+#ifndef DEFAULT_GROUP_NAME
+# define DEFAULT_GROUP_NAME "_akpop3d"
+#endif
+
 static char * port = NULL;
 static int become_daemon = 0;
 const char * pidfile = "/var/run/akpop3d.pid";
-const char * ssl_certfile = "/etc/akpop3d/cert.pem";
-const char * ssl_keyfile = "/etc/akpop3d/key.pem";
+const char * ssl_certfile = SYSCONFDIR "/akpop3d/cert.pem";
+const char * ssl_keyfile = SYSCONFDIR "/akpop3d/key.pem";
+const char * group_name = DEFAULT_GROUP_NAME;
 const char * authfile = NULL;
 const char * local_mbox = NULL;
 const char * tmp_dir = "/tmp";
 char * mailspool = "/var/mail/";
 int use_pop3_allow_deny = 0;
 int enable_mysql = 0;
-unsigned int timeout = 30;
+unsigned int timeout = 600;
+extern int *socks, maxs;
+extern fd_set deffds;
 
-
+#ifdef HAVE_LIBMYSQLCLIENT
 /* mysql pointers */
 extern char *HOSTNAME;
 extern char *USERNAME;
 extern char *PASSWORD;
 extern char *DATABASE;
 extern char *TABLE;
+#endif /* HAVE_LIBMYSQLCLIENT */
 
 int daemonize(void);
 void pop3_session(int fd);
@@ -68,14 +76,15 @@ static void usage(char * argv0) {
     "  -s             use SSL for all connections\n"
     "  -c <certfile>  use <certfile> for SSL certificate [%s]\n"
     "  -k <keyfile>   use <keyfile> for SSL RSA key      [%s]\n"
-    "  -p <port>      listen on <port>    [default: 110, or 995 if SSL]\n",
-    ssl_certfile, ssl_keyfile
+    "  -p <port>      listen on <port>    [default: 110, or 995 if SSL]\n"
+    "  -g <group>     use GID <group> to access spool directory [default: %s]\n",
+    ssl_certfile, ssl_keyfile, group_name
   );
   printf(
     "  -l <address>   listen on <address> [default: any]\n"
     "  -a <authfile>  use text file <authfile> for authentication\n"
     "  -m <spooldir>  use directory <spooldir> as mail spool\n"
-    "  -D             use /etc/pop3.{allow,deny} files\n"
+    "  -D             use " SYSCONFDIR "/pop3.{allow,deny} files\n"
     "  -L <mbox>      use ~/<mbox> as mail spool\n"
     "  -t <timeout>   use <timeout> seconds as r/w timeout\n"
 #ifdef HAVE_LIBMYSQLCLIENT
@@ -107,21 +116,25 @@ static void delete_pid(void) {
 }
 
 int main(int argc, char * argv[]) {
-  int listenfd, connfd;
+  int connfd, maxfd;
+  int *socks;
+  fd_set fds;
   pid_t childpid;
   struct stat sbuf;
-  socklen_t addrlen;
 #ifdef HAVE_LIBMYSQLCLIENT
-  const char * optstring = "df:sp:c:k:l:a:m:hvDL:MH:U:P:I:T:t:x:";
+  const char * optstring = "df:sp:c:k:l:a:m:hvDL:MH:U:P:I:T:t:x:g:";
   int len = 0;
 #else
-  const char * optstring = "df:sp:c:k:l:a:m:hvDL:t:x:";
+  const char * optstring = "df:sp:c:k:l:a:m:hvDL:t:x:g:";
 #endif
   char * listenhost = NULL;
   char * progname;
-  int c;
+  int c,i;
+  struct sockaddr_storage client;
   socklen_t clen;
-  struct sockaddr_in client;
+  uint16_t sin_port_number;
+  const char *sin_addr_text;
+  char sin_addr_text_buffer[64];
 #ifdef HAVE_LIBMYSQLCLIENT
   struct rlimit memlim, cpulim;
 
@@ -159,6 +172,7 @@ int main(int argc, char * argv[]) {
       case 'k': ssl_keyfile = optarg; break;
       case 'l': listenhost = optarg; break;
       case 'a': authfile = optarg; break;
+      case 'g': group_name = optarg; break;
       case 't': sscanf(optarg,"%u",&timeout); break;
       case 'x': tmp_dir = optarg; break;
       case 'm': if (stat(optarg,&sbuf)!=0) {
@@ -253,8 +267,13 @@ int main(int argc, char * argv[]) {
   }
   openlog(progname, LOG_PID, LOG_MAIL);
 
-  listenfd = Tcp_listen(listenhost, port, &addrlen);
-
+  socks = Tcp_listen(listenhost, port);
+  for (maxfd = -1, i=0; i<maxs; i++) {
+    if (maxfd < socks[i])
+      maxfd = socks[i];
+  }
+  clen = sizeof(client);
+  
   Signal(SIGCHLD,sig_chld);
 
   Signal(SIGTERM,sig_term);
@@ -263,9 +282,21 @@ int main(int argc, char * argv[]) {
   Signal(SIGQUIT,sig_term);
 
   for (;;) {
-    clen = sizeof(struct sockaddr *);
-
-    if ((connfd = accept(listenfd,(struct sockaddr *) &client,&clen)) < 0) {
+#ifdef FD_COPY
+    FD_COPY(&deffds, &fds);
+#else
+    fds = deffds;
+#endif
+    if (select(maxfd+1, &fds, NULL, NULL, NULL) != 1)
+      continue; 
+    connfd = -1;
+    for (i=0; i<maxs; i++) {
+      if (FD_ISSET(socks[i], &fds)) {
+        connfd = accept(socks[i],(struct sockaddr *) &client,&clen);
+        break;
+      }
+    }
+    if (connfd < 0) {
       if (errno == EINTR) {
         continue;
       } else {
@@ -275,11 +306,20 @@ int main(int argc, char * argv[]) {
     }
 
     getpeername( connfd, (struct sockaddr *) &client, &clen );
+    if (client.ss_family==AF_INET6)
+    {
+      sin_addr_text=inet_ntop(((struct sockaddr_in6 *)&client)->sin6_family,&(((struct sockaddr_in6 *)&client)->sin6_addr),sin_addr_text_buffer,64);
+      sin_port_number=ntohs(((struct sockaddr_in6 *)&client)->sin6_port);
+    }
+    else
+    {
+      sin_addr_text=inet_ntoa(((struct sockaddr_in *)&client)->sin_addr);   // IPv4
+      sin_port_number=ntohs(((struct sockaddr_in *)&client)->sin_port);
+    }
+    syslog( LOG_INFO, "Connection from %s:%u",sin_addr_text,sin_port_number);
 
-    syslog( LOG_INFO, "Connection from %s:%u", inet_ntoa( client.sin_addr ), ntohs( client.sin_port ) );
-
     if ((childpid = fork()) == 0) {
-      close(listenfd);
+/*      close(listenfd); */
       pop3_session(connfd);
       syslog( LOG_INFO, "Connection closed" );
       exit(0);
