+ if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
+ return sock_exec (prog);
+ else
+ return open_socket_out (host, port, bind_address,
+ af_hint);
+}
+
+
+
+/**
+ * Open a socket of the specified type, port and address for incoming data
+ *
+ * Try to be better about handling the results of getaddrinfo(): when
+ * opening an inbound socket, we might get several address results,
+ * e.g. for the machine's ipv4 and ipv6 name.
+ *
+ * If binding a wildcard, then any one of them should do. If an address
+ * was specified but it's insufficiently specific then that's not our
+ * fault.
+ *
+ * However, some of the advertized addresses may not work because e.g. we
+ * don't have IPv6 support in the kernel. In that case go on and try all
+ * addresses until one succeeds.
+ *
+ * @param bind_address Local address to bind, or NULL to allow it to
+ * default.
+ **/
+static int open_socket_in(int type, int port, const char *bind_address,
+ int af_hint)
+{
+ int one=1;
+ int s;
+ struct addrinfo hints, *all_ai, *resp;
+ char portbuf[10];
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af_hint;
+ hints.ai_socktype = type;
+ hints.ai_flags = AI_PASSIVE;
+ snprintf(portbuf, sizeof(portbuf), "%d", port);
+ error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
+ if (error) {
+ rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
+ bind_address, gai_strerror(error));