Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only)
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only, int address_family)
Socket sk_newlistener(char *srcaddr, int port, Plug plug, int local_host_only){    int s;#ifdef IPV6#if 0    struct sockaddr_in6 a6;#endif    struct addrinfo hints, *ai;    char portstr[6];#endif    struct sockaddr_in a;    int err;    Actual_Socket ret;    int retcode;    int on = 1;    /*     * Create Socket structure.     */    ret = snew(struct Socket_tag);    ret->fn = &tcp_fn_table;    ret->error = NULL;    ret->plug = plug;    bufchain_init(&ret->output_data);    ret->writable = 0;		       /* to start with */    ret->sending_oob = 0;    ret->frozen = 0;    ret->frozen_readable = 0;    ret->localhost_only = local_host_only;    ret->pending_error = 0;    ret->oobpending = FALSE;    ret->listener = 1;    /*     * Open socket.     */    s = socket(AF_INET, SOCK_STREAM, 0);    ret->s = s;    if (s < 0) {	ret->error = error_string(errno);	return (Socket) ret;    }    ret->oobinline = 0;    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));    /* BSD IP stacks need sockaddr_in zeroed before filling in */    memset(&a,'\0',sizeof(struct sockaddr_in));#ifdef IPV6#if 0    memset(&a6,'\0',sizeof(struct sockaddr_in6));#endif    hints.ai_flags = AI_NUMERICHOST;    hints.ai_family = AF_UNSPEC;    hints.ai_socktype = 0;    hints.ai_protocol = 0;    hints.ai_addrlen = 0;    hints.ai_addr = NULL;    hints.ai_canonname = NULL;    hints.ai_next = NULL;    sprintf(portstr, "%d", port);    if (srcaddr != NULL && getaddrinfo(srcaddr, portstr, &hints, &ai) == 0)	retcode = bind(s, ai->ai_addr, ai->ai_addrlen);    else#if 0    {	/*	 * FIXME: Need two listening sockets, in principle, one for v4	 * and one for v6	 */	if (local_host_only)	    a6.sin6_addr = in6addr_loopback;	else	    a6.sin6_addr = in6addr_any;	a6.sin6_port = htons(port);    } else#endif#endif    {	int got_addr = 0;	a.sin_family = AF_INET;	/*	 * Bind to source address. First try an explicitly	 * specified one...	 */	if (srcaddr) {	    a.sin_addr.s_addr = inet_addr(srcaddr);	    if (a.sin_addr.s_addr != INADDR_NONE) {		/* Override localhost_only with specified listen addr. */		ret->localhost_only = ipv4_is_loopback(a.sin_addr);		got_addr = 1;	    }	}	/*	 * ... and failing that, go with one of the standard ones.	 */	if (!got_addr) {	    if (local_host_only)		a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);	    else		a.sin_addr.s_addr = htonl(INADDR_ANY);	}	a.sin_port = htons((short)port);	retcode = bind(s, (struct sockaddr *) &a, sizeof(a));    }    if (retcode >= 0) {	err = 0;    } else {	err = errno;    }    if (err) {	ret->error = error_string(err);	return (Socket) ret;    }    if (listen(s, SOMAXCONN) < 0) {        close(s);	ret->error = error_string(errno);	return (Socket) ret;    }    uxsel_tell(ret);    add234(sktree, ret);    return (Socket) ret;}