NOEXPORT void local_start(CLI *c) {
    SOCKADDR_UNION addr;
    socklen_t addr_len;

    /* check if local_rfd is a socket and get peer address */
    addr_len=sizeof(SOCKADDR_UNION);
    c->local_rfd.is_socket=!getpeername(c->local_rfd.fd, &addr.sa, &addr_len);
    if(c->local_rfd.is_socket) {
        memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
        c->peer_addr_len=addr_len;
        if(socket_options_set(c->opt, c->local_rfd.fd, 1))
            s_log(LOG_WARNING, "Failed to set local socket options");
    } else {
        if(get_last_socket_error()!=S_ENOTSOCK) {
            sockerror("getpeerbyname (local_rfd)");
            throw_exception(c, 1);
        }
    }

    /* check if local_wfd is a socket and get peer address */
    if(c->local_rfd.fd==c->local_wfd.fd) {
        c->local_wfd.is_socket=c->local_rfd.is_socket;
    } else {
        addr_len=sizeof(SOCKADDR_UNION);
        c->local_wfd.is_socket=!getpeername(c->local_wfd.fd, &addr.sa, &addr_len);
        if(c->local_wfd.is_socket) {
            if(!c->local_rfd.is_socket) { /* already retrieved */
                memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
                c->peer_addr_len=addr_len;
            }
            if(socket_options_set(c->opt, c->local_wfd.fd, 1))
                s_log(LOG_WARNING, "Failed to set local socket options");
        } else {
            if(get_last_socket_error()!=S_ENOTSOCK) {
                sockerror("getpeerbyname (local_wfd)");
                throw_exception(c, 1);
            }
        }
    }

    /* neither of local descriptors is a socket */
    if(!c->local_rfd.is_socket && !c->local_wfd.is_socket) {
#ifndef USE_WIN32
        if(c->opt->option.transparent_src) {
            s_log(LOG_ERR, "Transparent source needs a socket");
            throw_exception(c, 1);
        }
#endif
        s_log(LOG_NOTICE, "Service [%s] accepted connection", c->opt->servname);
        return;
    }

    /* authenticate based on retrieved IP address of the client */
    c->accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
#ifdef USE_LIBWRAP
    libwrap_auth(c);
#endif /* USE_LIBWRAP */
    auth_user(c);
    s_log(LOG_NOTICE, "Service [%s] accepted connection from %s",
        c->opt->servname, c->accepted_address);
}
NOEXPORT void local_start(CLI *c) {
    SOCKADDR_UNION addr;
    socklen_t addr_len;

     
    addr_len=sizeof(SOCKADDR_UNION);
    c->local_rfd.is_socket=!getpeername(c->local_rfd.fd, &addr.sa, &addr_len);
    if(c->local_rfd.is_socket) {
        memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
        c->peer_addr_len=addr_len;
        if(socket_options_set(c->opt, c->local_rfd.fd, 1))
            s_log(LOG_WARNING, "Failed to set local socket options");
    } else {
        if(get_last_socket_error()!=S_ENOTSOCK) {
            sockerror("getpeerbyname (local_rfd)");
            throw_exception(c, 1);
        }
    }

     
    if(c->local_rfd.fd==c->local_wfd.fd) {
        c->local_wfd.is_socket=c->local_rfd.is_socket;
    } else {
        addr_len=sizeof(SOCKADDR_UNION);
        c->local_wfd.is_socket=!getpeername(c->local_wfd.fd, &addr.sa, &addr_len);
        if(c->local_wfd.is_socket) {
            if(!c->local_rfd.is_socket) {  
                memcpy(&c->peer_addr.sa, &addr.sa, (size_t)addr_len);
                c->peer_addr_len=addr_len;
            }
            if(socket_options_set(c->opt, c->local_wfd.fd, 1))
                s_log(LOG_WARNING, "Failed to set local socket options");
        } else {
            if(get_last_socket_error()!=S_ENOTSOCK) {
                sockerror("getpeerbyname (local_wfd)");
                throw_exception(c, 1);
            }
        }
    }

     
    if(!c->local_rfd.is_socket && !c->local_wfd.is_socket) {
#ifndef USE_WIN32
        if(c->opt->option.transparent_src) {
            s_log(LOG_ERR, "Transparent source needs a socket");
            throw_exception(c, 1);
        }
#endif
        s_log(LOG_NOTICE, "Service [%s] accepted connection", c->opt->servname);
        return;
    }

     
    c->accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
#ifdef USE_LIBWRAP
    libwrap_auth(c);
#endif  
    auth_user(c);
    s_log(LOG_NOTICE, "Service [%s] accepted connection from %s",
        c->opt->servname, c->accepted_address);
}