diff -Nru mailutils.old/pop3d/pop3d.c mailutils/pop3d/pop3d.c
--- mailutils.old/pop3d/pop3d.c	2004-01-15 18:47:36.000000000 +0100
+++ mailutils/pop3d/pop3d.c	2004-01-25 15:31:13.000000000 +0100
@@ -278,13 +278,41 @@
     }
   else
     {
-      struct sockaddr_in cs;
+      struct sockaddr_storage cs;
       int len = sizeof cs;
-      if (getpeername (fd, (struct sockaddr*)&cs, &len) < 0)
+
+      syslog (LOG_INFO, _("Incoming connection opened"));
+      if (getpeername (fd, (struct sockaddr *) &cs, &len) < 0)
 	syslog (LOG_ERR, _("can't obtain IP address of client: %s"),
 		strerror (errno));
-      else
-	syslog (LOG_INFO, _("connect from %s"), inet_ntoa (cs.sin_addr));
+      else {
+	switch (cs.ss_family) {
+	case AF_INET: {
+	  char str_src[INET_ADDRSTRLEN];
+	  struct in_addr src = ((struct sockaddr_in *) &cs)->sin_addr;
+
+	  if (!inet_ntop (AF_INET, (const void*) &src, str_src, sizeof (str_src))) {
+	    syslog (LOG_ERR, _("inet_ntop error: %s"), strerror (errno));
+	    break;
+	  }
+	  syslog (LOG_INFO, _("connect from %s"), str_src);
+	  break;
+	}
+	case AF_INET6: {
+	  char str_src[INET6_ADDRSTRLEN];
+	  struct in6_addr src = ((struct sockaddr_in6 *) &cs)->sin6_addr;
+
+	  if (!inet_ntop (AF_INET6, (const void*) &src, str_src, sizeof (str_src))) {
+	    syslog (LOG_ERR, _("inet_ntop error: %s"), strerror (errno));
+	    break;
+	  }
+	  syslog (LOG_INFO, _("connect from %s"), str_src);
+	  break;
+	}
+	default:
+	  syslog (LOG_INFO, _("pop3d_log_connection: %s"), strerror(EAFNOSUPPORT));
+	}
+      }
     }
 }
 
@@ -320,13 +348,35 @@
 
     /* Get our canonical hostname. */
     {
-      struct hostent *htbuf;
+      struct addrinfo *htbuf;
+      struct addrinfo hints = {
+	AI_CANONNAME,
+	PF_UNSPEC,
+	SOCK_STREAM,
+	0,
+	0,
+	NULL,
+	NULL,
+	NULL
+      };
+      int ret;
+
+/*       struct hostent *htbuf; */
       gethostname (local_hostname, MAXHOSTNAMELEN);
-      htbuf = gethostbyname (local_hostname);
-      if (htbuf)
+
+      ret = getaddrinfo (local_hostname, NULL, &hints, &htbuf);
+      if (ret)
 	{
+	  syslog (LOG_ERR, "getaddrinfo: %s", gai_strerror (ret));
+	  freeaddrinfo (htbuf);
 	  free (local_hostname);
-	  local_hostname = strdup (htbuf->h_name);
+	  exit (1);
+	}
+      else
+	{
+	  free (local_hostname);
+	  local_hostname = strdup (htbuf->ai_canonname);
+	  freeaddrinfo (htbuf);
 	}
     }
 
@@ -456,37 +506,109 @@
 static void
 pop3d_daemon (unsigned int maxchildren, unsigned int port)
 {
-  struct sockaddr_in server, client;
+  struct addrinfo *srv, *ptr;
+  struct addrinfo hints = {
+    AI_PASSIVE,
+    PF_UNSPEC,
+    SOCK_STREAM,
+    0,
+    0,
+    NULL,
+    NULL,
+    NULL
+  };
+  struct sockaddr_storage client;
   pid_t pid;
-  int listenfd, connfd;
-  size_t size;
+  int v4_fd, v6_fd, connfd;
+  fd_set fdset;
+  socklen_t size = sizeof (client);
+  int ret, on;
+
+  /* port in null terminated string format for getaddrinfo 5+1 car (port is a
+     short)*/
+  char str_port[6];
 
-  listenfd = socket (PF_INET, SOCK_STREAM, 0);
-  if (listenfd == -1)
-    {
-      syslog (LOG_ERR, "socket: %s", strerror(errno));
-      exit (EXIT_FAILURE);
-    }
-  size = 1; /* Use size here to avoid making a new variable.  */
-  setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size));
-  size = sizeof (server);
-  memset (&server, 0, size);
-  server.sin_family = AF_INET;
-  server.sin_addr.s_addr = htonl (INADDR_ANY);
-  server.sin_port = htons (port);
+  snprintf (str_port, sizeof (str_port), "%d", port);
+  str_port[5] = 0;
 
-  if (bind (listenfd, (struct sockaddr *)&server, size) == -1)
+  ret = getaddrinfo (NULL, str_port, &hints, &srv);
+  if (ret)
     {
-      syslog (LOG_ERR, "bind: %s", strerror (errno));
-      exit (EXIT_FAILURE);
+      syslog (LOG_ERR, "getaddrinfo: %s", gai_strerror (ret));
+      freeaddrinfo (srv);
+      exit (1);
     }
 
-  if (listen (listenfd, 128) == -1)
+  for (ptr = srv; ptr; ptr = ptr->ai_next)
     {
-      syslog (LOG_ERR, "listen: %s", strerror (errno));
-      exit (EXIT_FAILURE);
+      switch (ptr->ai_family)
+	{
+	case AF_INET:
+	  {
+	    /* FIXME add an --ipv4 | -4 option to break here if ipv4 is unwanted */
+
+	    v4_fd = socket (PF_INET, SOCK_STREAM, 0);
+	    if (v4_fd == -1)
+	      {
+		syslog (LOG_ERR, "socket: %s", strerror (errno));
+		break;
+	      }
+
+	    on = 1;
+	    setsockopt (v4_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
+
+	    if (bind (v4_fd, ptr->ai_addr, ptr->ai_addrlen) == -1)
+	      {
+		syslog (LOG_ERR, "bind: %s", strerror (errno));
+		exit (1);
+	      }
+
+	    if (listen (v4_fd, 128) == -1)
+	      {
+		syslog (LOG_ERR, "listen: %s", strerror (errno));
+		exit (1);
+	      }
+	    break;
+	  }
+	case AF_INET6:
+	  {
+	    /* FIXME add an --ipv6 | -6 option to break here if ipv6 is unwanted */
+	    
+	    v6_fd = socket (PF_INET6, SOCK_STREAM, 0);
+	    if (v6_fd == -1)
+	      {
+		syslog (LOG_ERR, "socket: %s", strerror (errno));
+		exit (1);
+	      }
+
+	    on = 1;
+	    if (setsockopt(v6_fd, IPPROTO_IPV6, IPV6_V6ONLY,
+			   (char *)&on, sizeof(on)) == -1)
+		syslog (LOG_ERR, "pop3d_daemon (setsockopt): %s\n", strerror (errno));
+	    
+	    ((struct sockaddr_in6 *) ptr->ai_addr)->sin6_flowinfo = 0;
+
+	    on = 1;
+	    setsockopt (v6_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
+
+	    if (bind (v6_fd, ptr->ai_addr, ptr->ai_addrlen) == -1)
+	      {
+		syslog (LOG_ERR, "bind: %s", strerror (errno));
+		exit (1);
+	      }
+
+	    if (listen (v6_fd, 128) == -1)
+	      {
+		syslog (LOG_ERR, "listen: %s", strerror (errno));
+		exit (1);
+	      }
+	    break;
+	  }
+	default:
+	  syslog (LOG_INFO, "pop3d_daemon: %s", strerror(EAFNOSUPPORT));
+	}
     }
-
+  freeaddrinfo (srv);
   syslog (LOG_INFO, _("GNU pop3d started"));
 
   for (;;)
@@ -499,34 +621,93 @@
           pause ();
           continue;
         }
-      connfd = accept (listenfd, (struct sockaddr *)&client,
-		       (socklen_t *) &size);
-      if (connfd == -1)
-        {
-          if (errno == EINTR)
+
+      FD_ZERO (&fdset);
+      /* Do not listen on ipv4 if unwanted or file descriptor to big for slect
+	 (paranoiac attitude) */
+      if (v4_fd && (v4_fd < FD_SETSIZE))
+	  FD_SET (v4_fd, &fdset);
+	  
+      if (v6_fd && (v6_fd < FD_SETSIZE))
+	  FD_SET (v6_fd, &fdset);
+
+      if (select (FD_SETSIZE, &fdset, NULL, NULL, NULL) < 0)
+	{
+	  if (errno == EINTR)
 	    continue;
-          syslog (LOG_ERR, "accept: %s", strerror (errno));
-          continue;
-          /*exit (EXIT_FAILURE);*/
-        }
+	  syslog (LOG_ERR, "pop3d_daemon: %s", strerror (errno));
+	  exit (1);
+	}
 
-      pid = fork ();
-      if (pid == -1)
-	syslog(LOG_ERR, "fork: %s", strerror (errno));
-      else if (pid == 0) /* Child.  */
-        {
-	  int status;
+      /* We have something interesting somewhere*/
+      /* FIXME: duplicated code need sub function */
+
+      /* Test the ipv4 socket if any */
+      if (v4_fd && FD_ISSET (v4_fd, &fdset))
+	{
+	  connfd = accept (v4_fd, (struct sockaddr *) &client, &size);
+	  if (connfd == -1)
+	    {
+	      if (errno == EINTR)
+		continue;
+	      syslog (LOG_ERR, "accept: %s", strerror (errno));
+	      exit (1);
+
+	    }
+
+	  pid = fork ();
+	  if (pid == -1)
+	    syslog(LOG_ERR, "fork: %s", strerror (errno));
+	  else if (pid == 0) /* Child.  */
+	    {
+	      int status;
 	  
-	  close (listenfd);
-          status = pop3d_mainloop (connfd,
-				   fdopen (connfd, "r"), fdopen (connfd, "w"));
-	  closelog ();
-	  exit (status);
-        }
-      else
-        {
-          ++children;
-        }
-      close (connfd);
+	      close (v4_fd);
+	      close (v6_fd);
+	      status = pop3d_mainloop (connfd, fdopen (connfd, "r"),
+				       fdopen (connfd, "w"));
+	      closelog ();
+	      exit (status);
+	    }
+	  else
+	    {
+	      ++children;
+	    }
+	  close (connfd);
+	}
+
+      /* Test the ipv6 socket if any */
+      if (v6_fd && FD_ISSET (v6_fd, &fdset))
+	{
+	  connfd = accept (v6_fd, (struct sockaddr *) &client, &size);
+	  if (connfd == -1)
+	    {
+	      if (errno == EINTR)
+		continue;
+	      syslog (LOG_ERR, "accept: %s", strerror (errno));
+	      exit (1);
+
+	    }
+
+	  pid = fork ();
+	  if (pid == -1)
+	    syslog(LOG_ERR, "fork: %s", strerror (errno));
+	  else if (pid == 0) /* Child.  */
+	    {
+	      int status;
+	  
+	      close (v4_fd);
+	      close (v6_fd);
+	      status = pop3d_mainloop (connfd, fdopen (connfd, "r"),
+				       fdopen (connfd, "w"));
+	      closelog ();
+	      exit (status);
+	    }
+	  else
+	    {
+	      ++children;
+	    }
+	  close (connfd);
+	}
     }
 }
