MINOR: cli: Add a command to send listening sockets.

Add a new command that will send all the listening sockets, via the
stats socket, and their properties.
This is a first step to workaround the linux problem when reloading
haproxy.
diff --git a/src/proto_uxst.c b/src/proto_uxst.c
index 27ff0fa..d68267e 100644
--- a/src/proto_uxst.c
+++ b/src/proto_uxst.c
@@ -150,6 +150,54 @@
  ********************************/
 
 
+static int uxst_find_compatible_fd(struct listener *l)
+{
+	struct xfer_sock_list *xfer_sock = xfer_sock_list;
+	int ret = -1;
+
+	while (xfer_sock) {
+		struct sockaddr_un *un1 = (void *)&l->addr;
+		struct sockaddr_un *un2 = (void *)&xfer_sock->addr;
+
+		/*
+		 * The bound socket's path as returned by getsockaddr
+		 * will be the temporary name <sockname>.XXXXX.tmp,
+		 * so we can't just compare the two names
+		 */
+		if (xfer_sock->addr.ss_family == AF_UNIX &&
+		    strncmp(un1->sun_path, un2->sun_path,
+		    strlen(un1->sun_path)) == 0) {
+			char *after_sockname = un2->sun_path +
+			    strlen(un1->sun_path);
+			/* Make a reasonnable effort to check that
+			 * it is indeed a haproxy-generated temporary
+			 * name, it's not perfect, but probably good enough.
+			 */
+			if (after_sockname[0] == '.') {
+				after_sockname++;
+				while (after_sockname[0] >= '0' &&
+				    after_sockname[0] <= '9')
+					after_sockname++;
+				if (!strcmp(after_sockname, ".tmp"))
+					break;
+			}
+		}
+		xfer_sock = xfer_sock->next;
+	}
+	if (xfer_sock != NULL) {
+		ret = xfer_sock->fd;
+		if (xfer_sock == xfer_sock_list)
+			xfer_sock_list = xfer_sock->next;
+		if (xfer_sock->prev)
+			xfer_sock->prev->next = xfer_sock->next;
+		if (xfer_sock->next)
+			xfer_sock->next->prev = xfer_sock->next->prev;
+		free(xfer_sock);
+	}
+	return ret;
+
+}
+
 /* This function creates a UNIX socket associated to the listener. It changes
  * the state from ASSIGNED to LISTEN. The socket is NOT enabled for polling.
  * The return value is composed from ERR_NONE, ERR_RETRYABLE and ERR_FATAL. It
@@ -179,6 +227,8 @@
 	if (listener->state != LI_ASSIGNED)
 		return ERR_NONE; /* already bound */
 		
+	if (listener->fd == -1)
+		listener->fd = uxst_find_compatible_fd(listener);
 	path = ((struct sockaddr_un *)&listener->addr)->sun_path;
 
 	/* if the listener already has an fd assigned, then we were offered the