NOEXPORT void auth_user(CLI *c) {
#ifndef _WIN32_WCE
    struct servent *s_ent;    /* structure for getservbyname */
#endif
    SOCKADDR_UNION ident;     /* IDENT socket name */
    char *line, *type, *system, *user;
    unsigned remote_port, local_port;

    if(!c->opt->username)
        return; /* -u option not specified */
#ifdef HAVE_STRUCT_SOCKADDR_UN
    if(c->peer_addr.sa.sa_family==AF_UNIX) {
        s_log(LOG_INFO, "IDENT not supported on Unix sockets");
        return;
    }
#endif
    c->fd=s_socket(c->peer_addr.sa.sa_family, SOCK_STREAM,
        0, 1, "socket (auth_user)");
    if(c->fd==INVALID_SOCKET)
        throw_exception(c, 1);
    memcpy(&ident, &c->peer_addr, (size_t)c->peer_addr_len);
#ifndef _WIN32_WCE
    s_ent=getservbyname("auth", "tcp");
    if(s_ent) {
        ident.in.sin_port=(u_short)s_ent->s_port;
    } else
#endif
    {
        s_log(LOG_WARNING, "Unknown service 'auth': using default 113");
        ident.in.sin_port=htons(113);
    }
    if(s_connect(c, &ident, addr_len(&ident)))
        throw_exception(c, 1);
    s_log(LOG_DEBUG, "IDENT server connected");
    remote_port=ntohs(c->peer_addr.in.sin_port);
    local_port=(unsigned)(c->opt->local_addr.addr ?
        ntohs(c->opt->local_addr.addr[0].in.sin_port) : 0);
    fd_printf(c, c->fd, "%u , %u", remote_port, local_port);
    line=fd_getline(c, c->fd);
    closesocket(c->fd);
    c->fd=INVALID_SOCKET; /* avoid double close on cleanup */
    type=strchr(line, ':');
    if(!type) {
        s_log(LOG_ERR, "Malformed IDENT response");
        str_free(line);
        throw_exception(c, 1);
    }
    *type++='\0';
    system=strchr(type, ':');
    if(!system) {
        s_log(LOG_ERR, "Malformed IDENT response");
        str_free(line);
        throw_exception(c, 1);
    }
    *system++='\0';
    if(strcmp(type, " USERID ")) {
        s_log(LOG_ERR, "Incorrect IDENT response type");
        str_free(line);
        throw_exception(c, 1);
    }
    user=strchr(system, ':');
    if(!user) {
        s_log(LOG_ERR, "Malformed IDENT response");
        str_free(line);
        throw_exception(c, 1);
    }
    *user++='\0';
    while(*user==' ') /* skip leading spaces */
        ++user;
    if(strcmp(user, c->opt->username)) {
        s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user \"%s\")",
            c->accepted_address, user);
        str_free(line);
        throw_exception(c, 1);
    }
    s_log(LOG_INFO, "IDENT authentication passed");
    str_free(line);
}
NOEXPORT void auth_user(CLI *c) {
#ifndef _WIN32_WCE
    struct servent *s_ent;     
#endif
    SOCKADDR_UNION ident;      
    char *line, *type, *system, *user;
    unsigned remote_port, local_port;

    if(!c->opt->username)
        return;  
#ifdef HAVE_STRUCT_SOCKADDR_UN
    if(c->peer_addr.sa.sa_family==AF_UNIX) {
        s_log(LOG_INFO, "IDENT not supported on Unix sockets");
        return;
    }
#endif
    c->fd=s_socket(c->peer_addr.sa.sa_family, SOCK_STREAM,
        0, 1, "socket (auth_user)");
    if(c->fd==INVALID_SOCKET)
        throw_exception(c, 1);
    memcpy(&ident, &c->peer_addr, (size_t)c->peer_addr_len);
#ifndef _WIN32_WCE
    s_ent=getservbyname("auth", "tcp");
    if(s_ent) {
        ident.in.sin_port=(u_short)s_ent->s_port;
    } else
#endif
    {
        s_log(LOG_WARNING, "Unknown service 'auth': using default 113");
        ident.in.sin_port=htons(113);
    }
    if(s_connect(c, &ident, addr_len(&ident)))
        throw_exception(c, 1);
    s_log(LOG_DEBUG, "IDENT server connected");
    remote_port=ntohs(c->peer_addr.in.sin_port);
    local_port=(unsigned)(c->opt->local_addr.addr ?
        ntohs(c->opt->local_addr.addr[0].in.sin_port) : 0);
    fd_printf(c, c->fd, "%u , %u", remote_port, local_port);
    line=fd_getline(c, c->fd);
    closesocket(c->fd);
    c->fd=INVALID_SOCKET;  
    type=strchr(line, ':');
    if(!type) {
        s_log(LOG_ERR, "Malformed IDENT response");
        str_free(line);
        throw_exception(c, 1);
    }
    *type++='\0';
    system=strchr(type, ':');
    if(!system) {
        s_log(LOG_ERR, "Malformed IDENT response");
        str_free(line);
        throw_exception(c, 1);
    }
    *system++='\0';
    if(strcmp(type, " USERID ")) {
        s_log(LOG_ERR, "Incorrect IDENT response type");
        str_free(line);
        throw_exception(c, 1);
    }
    user=strchr(system, ':');
    if(!user) {
        s_log(LOG_ERR, "Malformed IDENT response");
        str_free(line);
        throw_exception(c, 1);
    }
    *user++='\0';
    while(*user==' ')  
        ++user;
    if(strcmp(user, c->opt->username)) {
        s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT (user \"%s\")",
            c->accepted_address, user);
        str_free(line);
        throw_exception(c, 1);
    }
    s_log(LOG_INFO, "IDENT authentication passed");
    str_free(line);
}