File pidentd-ipv6.patch of Package pidentd.19279

--- src/conf.c.orig
+++ src/conf.c
@@ -103,7 +103,7 @@ conf_parse(const char *path,
 	
 	else if (strcasecmp(cp, "server:port") == 0)
 	{
-	    if (str2port(arg, &listen_port) < 0)
+	    if (str2str(arg, &listen_port) < 0)
 		syslog(LOG_ERR, "%s: %d: invalid port: %s",
 		       path, line, arg);
 	}
--- src/k_linux.c.orig
+++ src/k_linux.c
@@ -81,6 +81,7 @@ static int
 netlink_lookup(struct kainfo *kip, struct kernel *kp)
 {
     int status;
+    int i;
     struct {
 	struct nlmsghdr nlh;
 	union {
@@ -95,12 +96,34 @@ netlink_lookup(struct kainfo *kip, struc
     buf.nlh.nlmsg_type = TCPDIAG_GETSOCK;
     buf.nlh.nlmsg_flags = NLM_F_REQUEST;
     buf.nlh.nlmsg_seq = ++kip->seq;
-    buf.u.req.idiag_family = AF_INET;
+    buf.u.req.idiag_family = kp->remote.sg_addr._sg_sa.sa_family;
 
-    buf.u.req.id.idiag_dport = kp->remote.sin_port;
-    buf.u.req.id.idiag_sport = kp->local.sin_port;
-    buf.u.req.id.idiag_dst[0] = kp->remote.sin_addr.s_addr;
-    buf.u.req.id.idiag_src[0] = kp->local.sin_addr.s_addr;
+    switch (buf.u.req.idiag_family) {
+
+    case AF_INET:
+	buf.u.req.id.idiag_dport = kp->remote.sg_addr._sg_sin.sin_port;
+	buf.u.req.id.idiag_sport = kp->local.sg_addr._sg_sin.sin_port;
+	buf.u.req.id.idiag_dst[0] = kp->remote.sg_addr._sg_sin.sin_addr.s_addr;
+	buf.u.req.id.idiag_src[0] = kp->local.sg_addr._sg_sin.sin_addr.s_addr;
+	break;
+
+    case AF_INET6:
+	buf.u.req.id.idiag_dport = kp->remote.sg_addr._sg_sin6.sin6_port;
+	buf.u.req.id.idiag_sport = kp->local.sg_addr._sg_sin6.sin6_port;
+
+	for (i = 0; i < 4; i++) {
+	    buf.u.req.id.idiag_dst[i] =
+		kp->remote.sg_addr._sg_sin6.sin6_addr.__in6_u.__u6_addr32[i];
+	    buf.u.req.id.idiag_src[i] =
+		kp->local.sg_addr._sg_sin6.sin6_addr.__in6_u.__u6_addr32[i];
+	}
+	break;
+
+    default:
+	syslog(LOG_ERR, "netlink_lookup: unknown address family: %d",
+	       buf.u.req.idiag_family);
+	return 3;
+    }
     buf.u.req.id.idiag_cookie[0] = INET_DIAG_NOCOOKIE;
     buf.u.req.id.idiag_cookie[1] = INET_DIAG_NOCOOKIE;
 
@@ -181,10 +204,10 @@ ka_lookup(void *vp, struct kernel *kp)
     if (kip->nlfd >= 0)
 	return netlink_lookup(kip, kp);
 
-    r_rport = ntohs(kp->remote.sin_port);
-    r_lport = ntohs(kp->local.sin_port);
-    r_raddr = kp->remote.sin_addr.s_addr;
-    r_laddr = kp->local.sin_addr.s_addr;
+    r_rport = ntohs(kp->remote.sg_addr._sg_sin.sin_port);
+    r_lport = ntohs(kp->local.sg_addr._sg_sin.sin_port);
+    r_raddr = kp->remote.sg_addr._sg_sin.sin_addr.s_addr;
+    r_laddr = kp->local.sg_addr._sg_sin.sin_addr.s_addr;
 
     fp = kip->proc_net_tcp;
 
--- src/main.c.orig
+++ src/main.c
@@ -162,8 +162,9 @@ main(int argc, char *argv[])
     if (debug)
 	fprintf(stderr, "socktype = %d\n", socket_type);
 
-    if (socket_type == SOCKTYPE_LISTEN || socket_type == SOCKTYPE_CONNECTED)
-	listen_sock = STDIN_FILENO;
+    if (socket_type == SOCKTYPE_LISTEN || socket_type == SOCKTYPE_CONNECTED) {
+	server_set_socket(STDIN_FILENO);
+    }
     
     conf_parse(PATH_CFGFILE, 1);
 
@@ -198,23 +199,23 @@ main(int argc, char *argv[])
 	    break;
 	    
 	  case 'w':
-	    listen_sock = STDIN_FILENO;
+	    server_set_socket(STDIN_FILENO);
 	    socket_type = SOCKTYPE_LISTEN;
 	    break;
 	    
 	  case 'i':
-	    listen_sock = STDIN_FILENO;
+	    server_set_socket(STDIN_FILENO);
 	    socket_type = SOCKTYPE_CONNECTED;
 	    break;
 	    
 	  case 'I':
-	    listen_sock = -1;
+	    server_set_socket(-1);
 	    socket_type = SOCKTYPE_NOTSOCKET;
 	    init_mode = 1;
 	    break;
 	    
 	  case 'b':
-	    listen_sock = -1;
+	    server_set_socket(-1);
 	    socket_type = SOCKTYPE_NOTSOCKET;
 	    break;
 
@@ -223,7 +224,7 @@ main(int argc, char *argv[])
 	    break;
 	    
 	  case 'p':
-	    if (str2port(optarg, &listen_port) < 0)
+	    if (str2str(optarg, &listen_port) < 0)
 	    {
 		syslog(LOG_ERR, "invalid argument to '-p': %s", optarg);
 		if (socket_type == -1 || socket_type == SOCKTYPE_NOTSOCKET)
@@ -352,7 +353,7 @@ main(int argc, char *argv[])
     if (!debug && 
 	getppid() != INIT_PID && !init_mode &&
 	socket_type != SOCKTYPE_CONNECTED &&
-	listen_sock < 0)
+	listen_count == 0)
     {
 	become_daemon();
     }
@@ -380,7 +381,7 @@ main(int argc, char *argv[])
 	if (!debug && pidfile_path != NULL)
 	    pidfile_create(pidfile_path);
 
-	if (listen_sock < 0)
+	if (listen_count == 0)
 	{
 	    request_timeout = 0;
 	}
@@ -442,7 +443,7 @@ main(int argc, char *argv[])
 	server_run();
     }
     else
-	return request_run(listen_sock, 1);
+	return request_run(listen_socks[0], 1);
 
   Exit:
     syslog(LOG_DEBUG, "terminating");
--- src/server.c.orig
+++ src/server.c
@@ -28,9 +28,10 @@
 
 
 
-int listen_sock = -1;
-int listen_port = IPPORT_IDENT;
-int listen_addr = INADDR_ANY;
+int *listen_socks;
+int listen_count = 0;
+char *listen_port = "ident";
+char *listen_addr = NULL;
 int listen_backlog = 256;
 
 
@@ -60,14 +61,30 @@ unlimit_nofile(void)
 #endif
 }
 
+void
+server_set_socket(int fd)
+{
+    if (listen_socks != NULL) {
+	free(listen_socks);
+	listen_socks = NULL;
+    }
+    if (fd < 0) {
+	listen_count = 0;
+    } else {
+	listen_socks = malloc(sizeof(*listen_socks));
+	listen_socks[0] = fd;
+	listen_count = 1;
+    }
+}
 
 int
 server_init(void)
 {
     static int one = 1;
     int nofile;
-    struct sockaddr_in sin;
-    
+    struct addrinfo hints;
+    struct addrinfo *result, *rp;
+    int s;
     
     /*
     ** Increase the number of available file descriptors
@@ -77,91 +94,120 @@ server_init(void)
     if (nofile < 0)
 	return -1;
 
+    if (listen_count > 0) {
+	return 0;
+    }
 
-    if (listen_sock < 0)
-    {
-	listen_sock = socket(AF_INET, SOCK_STREAM, 0);
-	if (listen_sock < 0)
-	{
-	    syslog(LOG_ERR, "socket(AF_INET, SOCK_STREAM) failed: %m");
-	    return -1;
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_PASSIVE;
+
+    s = getaddrinfo(listen_addr, listen_port, &hints, &result);
+    if (s != 0) {
+	fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
+	exit(EXIT_FAILURE);
+    }
+
+    for (rp = result; rp != NULL; rp = rp->ai_next) {
+	int sock;
+
+	sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+
+	if (sock < 0) {
+	    syslog(LOG_ERR, "socket() failed: %m");
+	    continue;
 	}
 
-	(void) setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR,
-		   (void *) &one, sizeof(one));
+	if (rp->ai_family == AF_INET6) {
+	    if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+			   (void *) &one, sizeof(one)) < 0) {
+		syslog(LOG_ERR, "setsockopt(IPV6_V6ONLY,) failed: %m");
+		close(sock);
+		continue;
+	    }
+	}
+
+	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+		       (void *) &one, sizeof(one)) < 0) {
+	    syslog(LOG_ERR, "setsockopt(SO_REUSEADDR) failed: %m");
+	    close(sock);
+	    continue;
+	}
 	
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = htonl(listen_addr);
-	sin.sin_port = htons(listen_port);
-
-	if (bind(listen_sock, (struct sockaddr *) &sin, sizeof(sin)) < 0)
-	{
-	    syslog(LOG_ERR, "bind(port=%d) failed: %m",
+	if (bind(sock, rp->ai_addr, rp->ai_addrlen) < 0) {
+	    syslog(LOG_ERR, "bind(port=%s) failed: %m",
 		   listen_port);
-	    return -1;
+	    close(sock);
+	    continue;
 	}
-    }
 
-    /* We do this outside of the 'if' statement to support
-       some broken 'inetd' daemons... */
-    if (listen(listen_sock, listen_backlog) < 0)
-    {
-	syslog(LOG_ERR, "listen(backlog=%d) failed: %m", listen_backlog);
-	return -1;
+	if (listen(sock, listen_backlog) < 0) {
+	    syslog(LOG_ERR, "listen(backlog=%d) failed: %m", listen_backlog);
+	    close(sock);
+	    continue;
+	}
+
+	if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1) {
+	    syslog(LOG_ERR, "fcntl() failed: %m");
+	    close(sock);
+	    continue;
+	}
+
+	listen_socks = realloc(listen_socks,
+			       sizeof(listen_socks) * listen_count);
+	listen_socks[listen_count] = sock;
+	listen_count++;
     }
 
-    return 0;
+    return listen_count ? 0 : 1;
 }
 
 
 int
 server_run(void)
 {
-    struct pollfd ufds[1];
-    int fd;
+    struct pollfd ufds[listen_count];
+    int i, fd;
     int timeout = request_timeout <= 0 ? -1 : request_timeout * 1000;
     int retval;
 
-    if (fcntl(listen_sock, F_SETFL, O_NONBLOCK) == -1)
-    {
-	syslog(LOG_ERR, "fcntl() failed: %m");
-	return -1;
+    for (i = 0; i < listen_count; i++) {
+	ufds[i].fd = listen_socks[i];
+	ufds[i].events = POLLIN;
     }
-
-    ufds[0].fd = listen_sock;
-    ufds[0].events = POLLIN;
-    while (1)
-    {
-	if ((retval = s_poll(ufds, 1, timeout)) == -1)
-	{
+    while (1) {
+	if ((retval = s_poll(ufds, listen_count, timeout)) == -1) {
 	    syslog(LOG_ERR, "poll() failed: %m");
 	    return -1;
 	}
 	else if (retval == 0)
 	    break;
 
-	fd = s_accept(listen_sock, NULL, NULL);
-	if (fd < 0)
-	{
-	    syslog(LOG_ERR, "accept() failed: %m");
-	    
-	    switch (errno)
-	    {
-	      case EBADF:
-	      case EMFILE:
-	      case ENODEV:
-	      case ENOMEM:
-	      case ENOTSOCK:
-	      case EOPNOTSUPP:
-	      case EWOULDBLOCK:
-		return -1;
+	for (i = 0; i < listen_count; i++) {
+
+	    if (ufds[i].revents & POLLIN) {
+
+		fd = s_accept(listen_socks[i], NULL, NULL);
+		if (fd < 0) {
+		    syslog(LOG_ERR, "accept() failed: %m");
+
+		    switch (errno) {
+		    case EBADF:
+		    case EMFILE:
+		    case ENODEV:
+		    case ENOMEM:
+		    case ENOTSOCK:
+		    case EOPNOTSUPP:
+		    case EWOULDBLOCK:
+			return -1;
+		    }
+		} else {
+		    request_run(fd, 0);
+		}
 	    }
 	}
-
-	request_run(fd, 0);
     }
-
     if (debug)
 	fprintf(stderr, "accept() timed out\n");
     exit(0);
--- src/server.h.orig
+++ src/server.h
@@ -15,13 +15,15 @@
 #ifndef PIDENTD_SERVER_H
 #define PIDENTD_SERVER_H
 
-extern int listen_sock;
-extern int listen_port;
-extern int listen_addr;
+extern int *listen_socks;
+extern int listen_count;
+extern char *listen_port;
+extern char *listen_addr;
 extern int listen_backlog;
 
 
 extern int server_init(void);
 extern int server_run(void);
+extern void server_set_socket(int);
 
 #endif
--- src/sockaddr.h.orig
+++ src/sockaddr.h
@@ -18,6 +18,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <netdb.h>
 
 #ifdef HAVE_IPV6
 
openSUSE Build Service is sponsored by