CLEANUP: cli: deduplicate the code in _getsocks

Since the fix 5fd3b28 ("BUG/MEDIUM: cli: _getsocks must send the peers
sockets") for bug #443. The code which sends the socket for the peers
and the proxies is duplicated. This patch move this code in a separated
function.
diff --git a/src/cli.c b/src/cli.c
index 8fcbccd..32f30f8 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -1593,6 +1593,79 @@
 	}
 }
 
+/*
+ * For one proxy, fill the iov and send the msghdr. Also update fd_it and offset.
+ * Return -1 upon error, otherwise 0.
+ *
+ * This function is only meant to deduplicate the code between the peers and
+ * the proxy list in _getsocks(), not to be used anywhere else.
+ */
+inline static int _getsocks_gen_send(struct proxy *px, int sendfd, int *tmpfd, struct iovec *iov,
+                                     int tot_fd_nb, int *fd_it, int *offset, struct msghdr *msghdr)
+{
+	int i = *fd_it;
+	int curoff = *offset;
+	struct listener *l;
+	unsigned char *tmpbuf = iov->iov_base;
+
+	list_for_each_entry(l, &px->conf.listeners, by_fe) {
+		int ret;
+		/* Only transfer IPv4/IPv6 sockets */
+		if (l->state >= LI_ZOMBIE &&
+		    (l->proto->sock_family == AF_INET ||
+		     l->proto->sock_family == AF_INET6 ||
+		     l->proto->sock_family == AF_UNIX)) {
+			memcpy(&tmpfd[i % MAX_SEND_FD], &l->fd, sizeof(l->fd));
+			if (!l->netns)
+				tmpbuf[curoff++] = 0;
+#ifdef USE_NS
+			else {
+				char *name = l->netns->node.key;
+				unsigned char len = l->netns->name_len;
+				tmpbuf[curoff++] = len;
+				memcpy(tmpbuf + curoff, name, len);
+				curoff += len;
+			}
+#endif
+			if (l->interface) {
+				unsigned char len = strlen(l->interface);
+				tmpbuf[curoff++] = len;
+				memcpy(tmpbuf + curoff, l->interface, len);
+				curoff += len;
+			} else
+				tmpbuf[curoff++] = 0;
+			memcpy(tmpbuf + curoff, &l->options,
+			       sizeof(l->options));
+			curoff += sizeof(l->options);
+
+			i++;
+		} else
+			continue;
+		/* if it reaches the max number of fd per msghdr */
+		if ((!(i % MAX_SEND_FD))) {
+			iov->iov_len = curoff;
+			if (sendmsg(sendfd, msghdr, 0) != curoff) {
+				ha_warning("Failed to transfer sockets\n");
+				return -1;
+			}
+			/* Wait for an ack */
+			do {
+				ret = recv(sendfd, &tot_fd_nb,
+				           sizeof(tot_fd_nb), 0);
+			} while (ret == -1 && errno == EINTR);
+			if (ret <= 0) {
+				ha_warning("Unexpected error while transferring sockets\n");
+				return -1;
+			}
+			curoff = 0;
+		}
+	}
+
+	*fd_it = i;
+	*offset = curoff;
+
+	return 0;
+}
 
 
 /* Send all the bound sockets, always returns 1 */
@@ -1720,119 +1793,18 @@
 	iov.iov_base = tmpbuf;
 	px = proxies_list;
 	while (px) {
-		struct listener *l;
-
-		list_for_each_entry(l, &px->conf.listeners, by_fe) {
-			int ret;
-			/* Only transfer IPv4/IPv6 sockets */
-			if (l->state >= LI_ZOMBIE &&
-			    (l->proto->sock_family == AF_INET ||
-			    l->proto->sock_family == AF_INET6 ||
-			    l->proto->sock_family == AF_UNIX)) {
-				memcpy(&tmpfd[i % MAX_SEND_FD], &l->fd, sizeof(l->fd));
-				if (!l->netns)
-					tmpbuf[curoff++] = 0;
-#ifdef USE_NS
-				else {
-					char *name = l->netns->node.key;
-					unsigned char len = l->netns->name_len;
-					tmpbuf[curoff++] = len;
-					memcpy(tmpbuf + curoff, name, len);
-					curoff += len;
-				}
-#endif
-				if (l->interface) {
-					unsigned char len = strlen(l->interface);
-					tmpbuf[curoff++] = len;
-					memcpy(tmpbuf + curoff, l->interface, len);
-				curoff += len;
-				} else
-					tmpbuf[curoff++] = 0;
-				memcpy(tmpbuf + curoff, &l->options,
-				    sizeof(l->options));
-				curoff += sizeof(l->options);
-
-				i++;
-			} else
-				continue;
-			if ((!(i % MAX_SEND_FD))) {
-				iov.iov_len = curoff;
-				if (sendmsg(fd, &msghdr, 0) != curoff) {
-					ha_warning("Failed to transfer sockets\n");
-					goto out;
-				}
-				/* Wait for an ack */
-				do {
-					ret = recv(fd, &tot_fd_nb,
-					    sizeof(tot_fd_nb), 0);
-				} while (ret == -1 && errno == EINTR);
-				if (ret <= 0) {
-					ha_warning("Unexpected error while transferring sockets\n");
-					goto out;
-				}
-				curoff = 0;
-			}
-		}
+		if (_getsocks_gen_send(px, fd, tmpfd, &iov,
+		                   tot_fd_nb, &i, &curoff, &msghdr) < 0)
+			goto out;
 		px = px->next;
 	}
 	/* should be done for peers too */
 	prs = cfg_peers;
 	while (prs) {
-		if (prs->peers_fe) {
-			struct listener *l;
-
-			list_for_each_entry(l, &prs->peers_fe->conf.listeners, by_fe) {
-				int ret;
-				/* Only transfer IPv4/IPv6 sockets */
-				if (l->state >= LI_ZOMBIE &&
-				    (l->proto->sock_family == AF_INET ||
-				     l->proto->sock_family == AF_INET6 ||
-				     l->proto->sock_family == AF_UNIX)) {
-					memcpy(&tmpfd[i % MAX_SEND_FD], &l->fd, sizeof(l->fd));
-					if (!l->netns)
-						tmpbuf[curoff++] = 0;
-#ifdef USE_NS
-					else {
-						char *name = l->netns->node.key;
-						unsigned char len = l->netns->name_len;
-						tmpbuf[curoff++] = len;
-						memcpy(tmpbuf + curoff, name, len);
-						curoff += len;
-					}
-#endif
-					if (l->interface) {
-						unsigned char len = strlen(l->interface);
-						tmpbuf[curoff++] = len;
-						memcpy(tmpbuf + curoff, l->interface, len);
-						curoff += len;
-					} else
-						tmpbuf[curoff++] = 0;
-					memcpy(tmpbuf + curoff, &l->options,
-					       sizeof(l->options));
-					curoff += sizeof(l->options);
-
-					i++;
-				} else
-					continue;
-				if ((!(i % MAX_SEND_FD))) {
-					iov.iov_len = curoff;
-					if (sendmsg(fd, &msghdr, 0) != curoff) {
-						ha_warning("Failed to transfer sockets\n");
-						goto out;
-					}
-					/* Wait for an ack */
-					do {
-						ret = recv(fd, &tot_fd_nb,
-							   sizeof(tot_fd_nb), 0);
-					} while (ret == -1 && errno == EINTR);
-					if (ret <= 0) {
-						ha_warning("Unexpected error while transferring sockets\n");
-						goto out;
-					}
-					curoff = 0;
-				}
-			}
-		}
+		if (prs->peers_fe)
+			if (_getsocks_gen_send(prs->peers_fe, fd, tmpfd, &iov,
+			                       tot_fd_nb, &i, &curoff, &msghdr) < 0)
+				goto out;
 		prs = prs->next;
 	}