diff -Nru mailutils.old/imap4d/imap4d.c mailutils/imap4d/imap4d.c
--- mailutils.old/imap4d/imap4d.c	2004-01-15 18:47:32.000000000 +0100
+++ mailutils/imap4d/imap4d.c	2004-01-25 15:30:01.000000000 +0100
@@ -230,16 +230,43 @@
   /* log information on the connecting client */
   if (!debug_mode)
     {
-      struct sockaddr_in cs;
+      struct sockaddr_storage cs;
       int len = sizeof cs;
 
       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));
-      text = "IMAP4rev1";
+      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);
+	  text = "IMAP4rev1";
+	  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);
+	  text = "IMAP4rev1";
+	  break;
+	}
+	default:
+	  syslog (LOG_INFO, "imap4d_mainloop: %s", strerror(EAFNOSUPPORT));
+	}
+      }
     }
   else
     {
@@ -300,37 +327,110 @@
 static void
 imap4d_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;
 
-  listenfd = socket (PF_INET, SOCK_STREAM, 0);
-  if (listenfd == -1)
-    {
-      syslog (LOG_ERR, "socket: %s", strerror (errno));
-      exit (1);
-    }
-  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);
 
-  if (bind (listenfd, (struct sockaddr *) &server, size) == -1)
+  /* port in null terminated string format for getaddrinfo 5+1 car (port is a
+     short)*/
+  char str_port[6];
+
+  snprintf (str_port, sizeof (str_port), "%d", port);
+  str_port[5] = 0;
+
+  ret = getaddrinfo (NULL, str_port, &hints, &srv);
+  if (ret)
     {
-      syslog (LOG_ERR, "bind: %s", strerror (errno));
+      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 (1);
+      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);
+	      }
+
+	    ((struct sockaddr_in6 *) ptr->ai_addr)->sin6_flowinfo = 0;
+
+	    on = 1;
+	    if (setsockopt(v6_fd, IPPROTO_IPV6, IPV6_V6ONLY,
+			   (char *)&on, sizeof(on)) == -1)
+		syslog (LOG_ERR, "imap4d_daemon (setsockopt): %s\n", strerror (errno));
+	    
+	    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, "imap4d_daemon: %s", strerror(EAFNOSUPPORT));
+	}
     }
-
+  freeaddrinfo (srv);
   syslog (LOG_INFO, _("GNU imap4d started"));
 
   for (;;)
@@ -342,33 +442,93 @@
 	  pause ();
 	  continue;
 	}
-      connfd = accept (listenfd, (struct sockaddr *) &client,
-		       (socklen_t *) & size);
-      if (connfd == -1)
+
+      FD_ZERO (&fdset);
+      /* Do not listen on fd 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));
+	  syslog (LOG_ERR, "imap4d_daemon: %s", strerror (errno));
 	  exit (1);
 	}
 
-      pid = fork ();
-      if (pid == -1)
-	syslog (LOG_ERR, "fork: %s", strerror (errno));
-      else if (pid == 0)	/* Child.  */
+      /* We have something interesting somewhere*/
+      /* FIXME: duplicated code */
+
+      /* Test the ipv4 socket if any */
+      if (v4_fd && FD_ISSET (v4_fd, &fdset))
 	{
-	  int status;
-	  close (listenfd);
-	  status = imap4d_mainloop (connfd,
-				    fdopen (connfd, "r"),
-				    fdopen (connfd, "w"));
-	  closelog ();
-	  exit (status);
+	  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 (v4_fd);
+	      close (v6_fd);
+
+	      status = imap4d_mainloop (connfd,
+					fdopen (connfd, "r"),
+					fdopen (connfd, "w"));
+	      closelog ();
+	      exit (status);
+	    }
+	  else
+	    {
+	      ++children;
+	    }
+	  close (connfd);
 	}
-      else
+
+      /* Test ipv6 socket if anny */
+      if (v6_fd && FD_ISSET (v6_fd, &fdset))
 	{
-	  ++children;
+	  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 = imap4d_mainloop (connfd,
+					fdopen (connfd, "r"),
+					fdopen (connfd, "w"));
+	      closelog ();
+	      exit (status);
+	    }
+	  else
+	    {
+	      ++children;
+	    }
+	  close (connfd);
 	}
-      close (connfd);
     }
 }
diff -Nru mailutils.old/imap4d/imap4d.h mailutils/imap4d/imap4d.h
--- mailutils.old/imap4d/imap4d.h	2003-10-06 15:08:50.000000000 +0200
+++ mailutils/imap4d/imap4d.h	2003-12-31 00:58:03.000000000 +0100
@@ -57,6 +57,9 @@
 #include <netdb.h>
 #include <ctype.h>
 
+/* POSIX 1003.1g: 6.2 Select from File Descriptor Sets <sys/select.h>  */
+#include <sys/select.h>
+
 #ifdef HAVE_ALLOCA_H
 # include <alloca.h>
 #endif
