int do_server(int *accept_sock, const char *host, const char *port,
              int family, int type,
              int (*cb) (const char *hostname, int s, int stype,
                         unsigned char *context), unsigned char *context,
              int naccept)
{
    int asock = 0;
    int sock;
    int i;
    BIO_ADDRINFO *res = NULL;
    int ret = 0;
    int protocol = (type == SOCK_STREAM ? IPPROTO_TCP : IPPROTO_UDP);

    if (!BIO_sock_init())
        return 0;

    if (!BIO_lookup(host, port, BIO_LOOKUP_SERVER, family, type, &res)) {
        ERR_print_errors(bio_err);
        return 0;
    }

# ifdef AF_UNIX
    if (BIO_ADDRINFO_family(res) == AF_UNIX)
        protocol = 0;
# endif
    /* Admitedly, these checks are quite paranoid, we should
       not get anything in the BIO_ADDRINFO chain that we haven't
       asked for */
    OPENSSL_assert((family == AF_UNSPEC || family == BIO_ADDRINFO_family(res))
                   && (type == 0 || type == BIO_ADDRINFO_socktype(res))
                   && (protocol == BIO_ADDRINFO_protocol(res)));

    asock = BIO_socket(BIO_ADDRINFO_family(res), BIO_ADDRINFO_socktype(res),
                       BIO_ADDRINFO_protocol(res), 0);
    if (asock == INVALID_SOCKET
        || !BIO_listen(asock, BIO_ADDRINFO_address(res), BIO_SOCK_REUSEADDR)) {
        BIO_ADDRINFO_free(res);
        ERR_print_errors(bio_err);
        if (asock != INVALID_SOCKET)
            BIO_closesocket(asock);
        goto end;
    }

    BIO_ADDRINFO_free(res);

    if (accept_sock != NULL) {
        *accept_sock = asock;
    }
    for (;;) {
        BIO_ADDR *accepted_addr = NULL;
        char *name = NULL;
        if (type == SOCK_STREAM) {
            if ((accepted_addr = BIO_ADDR_new()) == NULL) {
                BIO_closesocket(asock);
                return 0;
            }
         redoit:
            sock = BIO_accept_ex(asock, accepted_addr, 0);
            if (sock < 0) {
                if (BIO_sock_should_retry(ret)) {
                    goto redoit;
                } else {
                    ERR_print_errors(bio_err);
                    BIO_ADDR_free(accepted_addr);
                    SHUTDOWN(asock);
                    break;
                }
            }
        } else {
            sock = asock;
        }

        /* accepted_addr is NULL if we're dealing with SOCK_DGRAM
         * this means that for SOCK_DGRAM, name will be NULL
         */
        if (accepted_addr != NULL) {
#ifdef AF_UNIX
            if (family == AF_UNIX)
                name = BIO_ADDR_path_string(accepted_addr);
            else
#endif
                name = BIO_ADDR_hostname_string(accepted_addr, 0);
        }
        i = (*cb) (name, sock, type, context);
        OPENSSL_free(name);
        BIO_ADDR_free(accepted_addr);
        if (type == SOCK_STREAM)
            SHUTDOWN2(sock);
        if (naccept != -1)
            naccept--;
        if (i < 0 || naccept == 0) {
            SHUTDOWN2(asock);
            ret = i;
            break;
        }
    }
 end:
# ifdef AF_UNIX
    if (family == AF_UNIX)
        unlink(host);
# endif
    return ret;
}