/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
 * Copyright (c) 2009-2011 by Daniel Stenberg
 * Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 *   Redistributions of source code must retain the above
 *   copyright notice, this list of conditions and the
 *   following disclaimer.
 *
 *   Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials
 *   provided with the distribution.
 *
 *   Neither the name of the copyright holder nor the names
 *   of any other contributors may be used to endorse or
 *   promote products derived from this software without
 *   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 */

#include "libssh2_priv.h"
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <fcntl.h>

#ifdef HAVE_GETTIMEOFDAY
#include <sys/time.h>
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif

#include "transport.h"
#include "session.h"
#include "channel.h"
#include "mac.h"

/* libssh2_default_alloc
 */
static
LIBSSH2_ALLOC_FUNC(libssh2_default_alloc)
{
    (void) abstract;
    return malloc(count);
}

/* libssh2_default_free
 */
static
LIBSSH2_FREE_FUNC(libssh2_default_free)
{
    (void) abstract;
    free(ptr);
}

/* libssh2_default_realloc
 */
static
LIBSSH2_REALLOC_FUNC(libssh2_default_realloc)
{
    (void) abstract;
    return realloc(ptr, count);
}

/*
 * banner_receive
 *
 * Wait for a hello from the remote host
 * Allocate a buffer and store the banner in session->remote.banner
 * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative
 * on failure
 */
static int
banner_receive(LIBSSH2_SESSION * session)
{
    int ret;
    int banner_len;

    if (session->banner_TxRx_state == libssh2_NB_state_idle) {
        banner_len = 0;

        session->banner_TxRx_state = libssh2_NB_state_created;
    } else {
        banner_len = session->banner_TxRx_total_send;
    }

    while ((banner_len < (int) sizeof(session->banner_TxRx_banner)) &&
           ((banner_len == 0)
            || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) {
        char c = '\0';

        /* no incoming block yet! */
        session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;

        ret = _libssh2_recv(session->socket_fd, &c, 1,
                            LIBSSH2_SOCKET_RECV_FLAGS(session));
        if (ret < 0) {
            if(session->api_block_mode || (ret != -EAGAIN))
                /* ignore EAGAIN when non-blocking */
                _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
                               "Error recving %d bytes: %d", 1, -ret);
        }
        else
            _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
                           "Recved %d bytes banner", ret);

        if (ret < 0) {
            if (ret == -EAGAIN) {
                session->socket_block_directions =
                    LIBSSH2_SESSION_BLOCK_INBOUND;
                session->banner_TxRx_total_send = banner_len;
                return LIBSSH2_ERROR_EAGAIN;
            }

            /* Some kinda error */
            session->banner_TxRx_state = libssh2_NB_state_idle;
            session->banner_TxRx_total_send = 0;
            return LIBSSH2_ERROR_SOCKET_RECV;
        }

        if (ret == 0) {
            session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
            return LIBSSH2_ERROR_SOCKET_RECV;
        }

        if (c == '\0') {
            /* NULLs are not allowed in SSH banners */
            session->banner_TxRx_state = libssh2_NB_state_idle;
            session->banner_TxRx_total_send = 0;
            return LIBSSH2_ERROR_BANNER_RECV;
        }

        session->banner_TxRx_banner[banner_len++] = c;
    }

    while (banner_len &&
           ((session->banner_TxRx_banner[banner_len - 1] == '\n') ||
            (session->banner_TxRx_banner[banner_len - 1] == '\r'))) {
        banner_len--;
    }

    /* From this point on, we are done here */
    session->banner_TxRx_state = libssh2_NB_state_idle;
    session->banner_TxRx_total_send = 0;

    if (!banner_len)
        return LIBSSH2_ERROR_BANNER_RECV;

    session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1);
    if (!session->remote.banner) {
        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                              "Error allocating space for remote banner");
    }
    memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len);
    session->remote.banner[banner_len] = '\0';
    _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s",
                   session->remote.banner);
    return LIBSSH2_ERROR_NONE;
}

/*
 * banner_send
 *
 * Send the default banner, or the one set via libssh2_setopt_string
 *
 * Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you
 * should call this function again as soon as it is likely that more data can
 * be sent, and this function should then be called with the same argument set
 * (same data pointer and same data_len) until zero or failure is returned.
 */
static int
banner_send(LIBSSH2_SESSION * session)
{
    char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF;
    int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1;
    ssize_t ret;
#ifdef LIBSSH2DEBUG
    char banner_dup[256];
#endif

    if (session->banner_TxRx_state == libssh2_NB_state_idle) {
        if (session->local.banner) {
            /* setopt_string will have given us our \r\n characters */
            banner_len = strlen((char *) session->local.banner);
            banner = (char *) session->local.banner;
        }
#ifdef LIBSSH2DEBUG
        /* Hack and slash to avoid sending CRLF in debug output */
        if (banner_len < 256) {
            memcpy(banner_dup, banner, banner_len - 2);
            banner_dup[banner_len - 2] = '\0';
        } else {
            memcpy(banner_dup, banner, 255);
            banner[255] = '\0';
        }

        _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s",
                       banner_dup);
#endif

        session->banner_TxRx_state = libssh2_NB_state_created;
    }

    /* no outgoing block yet! */
    session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;

    ret = _libssh2_send(session->socket_fd,
                        banner + session->banner_TxRx_total_send,
                        banner_len - session->banner_TxRx_total_send,
                        LIBSSH2_SOCKET_SEND_FLAGS(session));
    if (ret < 0)
        _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
                       "Error sending %d bytes: %d",
                       banner_len - session->banner_TxRx_total_send, -ret);
    else
        _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
                       "Sent %d/%d bytes at %p+%d", ret,
                       banner_len - session->banner_TxRx_total_send,
                       banner, session->banner_TxRx_total_send);

    if (ret != (banner_len - session->banner_TxRx_total_send)) {
        if (ret >= 0 || ret == -EAGAIN) {
            /* the whole packet could not be sent, save the what was */
            session->socket_block_directions =
                LIBSSH2_SESSION_BLOCK_OUTBOUND;
            if (ret > 0)
                session->banner_TxRx_total_send += ret;
            return LIBSSH2_ERROR_EAGAIN;
        }
        session->banner_TxRx_state = libssh2_NB_state_idle;
        session->banner_TxRx_total_send = 0;
        return LIBSSH2_ERROR_SOCKET_RECV;
    }

    /* Set the state back to idle */
    session->banner_TxRx_state = libssh2_NB_state_idle;
    session->banner_TxRx_total_send = 0;

    return 0;
}

/*
 * session_nonblock() sets the given socket to either blocking or
 * non-blocking mode based on the 'nonblock' boolean argument. This function
 * is copied from the libcurl sources with permission.
 */
static int
session_nonblock(libssh2_socket_t sockfd,   /* operate on this */
                 int nonblock /* TRUE or FALSE */ )
{
#undef SETBLOCK
#define SETBLOCK 0
#ifdef HAVE_O_NONBLOCK
    /* most recent unix versions */
    int flags;

    flags = fcntl(sockfd, F_GETFL, 0);
    if (nonblock)
        return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
    else
        return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK));
#undef SETBLOCK
#define SETBLOCK 1
#endif

#if defined(HAVE_FIONBIO) && (SETBLOCK == 0)
    /* older unix versions and VMS*/
    int flags;

    flags = nonblock;
    return ioctl(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 2
#endif

#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0)
    /* Windows? */
    unsigned long flags;
    flags = nonblock;

    return ioctlsocket(sockfd, FIONBIO, &flags);
#undef SETBLOCK
#define SETBLOCK 3
#endif

#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0)
    /* presumably for Amiga */
    return IoctlSocket(sockfd, FIONBIO, (long) nonblock);
#undef SETBLOCK
#define SETBLOCK 4
#endif

#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0)
    /* BeOS */
    long b = nonblock ? 1 : 0;
    return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
#undef SETBLOCK
#define SETBLOCK 5
#endif

#ifdef HAVE_DISABLED_NONBLOCKING
    return 0;                   /* returns success */
#undef SETBLOCK
#define SETBLOCK 6
#endif

#if (SETBLOCK == 0)
#error "no non-blocking method was found/used/set"
#endif
}

/*
 * get_socket_nonblocking()
 *
 * gets the given blocking or non-blocking state of the socket.
 */
static int
get_socket_nonblocking(int sockfd)
{                               /* operate on this */
#undef GETBLOCK
#define GETBLOCK 0
#ifdef HAVE_O_NONBLOCK
    /* most recent unix versions */
    int flags;

    if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
        /* Assume blocking on error */
        return 1;
    }
    return (flags & O_NONBLOCK);
#undef GETBLOCK
#define GETBLOCK 1
#endif

#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0)
    /* Windows? */
    unsigned int option_value;
    socklen_t option_len = sizeof(option_value);

    if (getsockopt
        (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) {
        /* Assume blocking on error */
        return 1;
    }
    return (int) option_value;
#undef GETBLOCK
#define GETBLOCK 2
#endif

#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0)
    /* BeOS */
    long b;
    if (getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) {
        /* Assume blocking on error */
        return 1;
    }
    return (int) b;
#undef GETBLOCK
#define GETBLOCK 5
#endif

#if defined(SO_STATE) && defined( __VMS ) && (GETBLOCK == 0)

    /* VMS TCP/IP Services */

    size_t sockstat = 0;
    int    callstat = 0;
    size_t size = sizeof( int );

    callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE,
                                  (char *)&sockstat, &size);
    if ( callstat == -1 ) return(0);
    if ( (sockstat&SS_NBIO) )return(1);
    return(0);

#undef GETBLOCK
#define GETBLOCK 6
#endif

#ifdef HAVE_DISABLED_NONBLOCKING
    return 1;                   /* returns blocking */
#undef GETBLOCK
#define GETBLOCK 7
#endif

#if (GETBLOCK == 0)
#error "no non-blocking method was found/used/get"
#endif
}

/* libssh2_banner_set
 * Set the local banner
 */
LIBSSH2_API int
libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
{
    size_t banner_len = banner ? strlen(banner) : 0;

    if (session->local.banner) {
        LIBSSH2_FREE(session, session->local.banner);
        session->local.banner = NULL;
    }

    if (!banner_len)
        return 0;

    session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3);
    if (!session->local.banner) {
        return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
                              "Unable to allocate memory for local banner");
    }

    memcpy(session->local.banner, banner, banner_len);

    /* first zero terminate like this so that the debug output is nice */
    session->local.banner[banner_len] = '\0';
    _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s",
                   session->local.banner);
    session->local.banner[banner_len++] = '\r';
    session->local.banner[banner_len++] = '\n';
    session->local.banner[banner_len] = '\0';

    return 0;
}

/*
 * libssh2_session_init_ex
 *
 * Allocate and initialize a libssh2 session structure. Allows for malloc
 * callbacks in case the calling program has its own memory manager It's
 * allowable (but unadvisable) to define some but not all of the malloc
 * callbacks An additional pointer value may be optionally passed to be sent
 * to the callbacks (so they know who's asking)
 */
LIBSSH2_API LIBSSH2_SESSION *
libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
                        LIBSSH2_FREE_FUNC((*my_free)),
                        LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract)
{
    LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc;
    LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free;
    LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc;
    LIBSSH2_SESSION *session;

    if (my_alloc) {
        local_alloc = my_alloc;
    }
    if (my_free) {
        local_free = my_free;
    }
    if (my_realloc) {
        local_realloc = my_realloc;
    }

    session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract);
    if (session) {
        memset(session, 0, sizeof(LIBSSH2_SESSION));
        session->alloc = local_alloc;
        session->free = local_free;
        session->realloc = local_realloc;
        session->abstract = abstract;
        session->api_block_mode = 1; /* blocking API by default */
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                       "New session resource allocated");
        _libssh2_init_if_needed ();
    }
    return session;
}

/*
 * libssh2_session_callback_set
 *
 * Set (or reset) a callback function
 * Returns the prior address
 *
 * FIXME: this function relies on that we can typecast function pointers
 * to void pointers, which isn't allowed in ISO C!
 */
LIBSSH2_API void *
libssh2_session_callback_set(LIBSSH2_SESSION * session,
                             int cbtype, void *callback)
{
    void *oldcb;

    switch (cbtype) {
    case LIBSSH2_CALLBACK_IGNORE:
        oldcb = session->ssh_msg_ignore;
        session->ssh_msg_ignore = callback;
        return oldcb;

    case LIBSSH2_CALLBACK_DEBUG:
        oldcb = session->ssh_msg_debug;
        session->ssh_msg_debug = callback;
        return oldcb;

    case LIBSSH2_CALLBACK_DISCONNECT:
        oldcb = session->ssh_msg_disconnect;
        session->ssh_msg_disconnect = callback;
        return oldcb;

    case LIBSSH2_CALLBACK_MACERROR:
        oldcb = session->macerror;
        session->macerror = callback;
        return oldcb;

    case LIBSSH2_CALLBACK_X11:
        oldcb = session->x11;
        session->x11 = callback;
        return oldcb;

    }
    _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", cbtype);

    return NULL;
}

/*
 * _libssh2_wait_socket()
 *
 * Utility function that waits for action on the socket. Returns 0 when ready
 * to run again or error on timeout.
 */
int _libssh2_wait_socket(LIBSSH2_SESSION *session)
{
    int rc;
    int seconds_to_next;
    int dir;

    /* since libssh2 often sets EAGAIN internally before this function is
       called, we can decrease some amount of confusion in user programs by
       resetting the error code in this function to reduce the risk of EAGAIN
       being stored as error when a blocking function has returned */
    session->err_code = LIBSSH2_ERROR_NONE;

    rc = libssh2_keepalive_send (session, &seconds_to_next);
    if (rc < 0)
        return rc;
    else {
        /* figure out what to wait for */
        dir = libssh2_session_block_directions(session);

        if(!dir) {
            _libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
                           "Nothing to wait for in wait_socket");
            /* To avoid that we hang below just because there's nothing set to
               wait for, we timeout on 1 second to also avoid busy-looping
               during this condition */
            seconds_to_next = 1;
        }
        {
#ifdef HAVE_POLL
            struct pollfd sockets[1];

            sockets[0].fd = session->socket_fd;
            sockets[0].events = 0;
            sockets[0].revents = 0;

            if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
                sockets[0].events |= POLLIN;

            if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
                sockets[0].events |= POLLOUT;

            rc = poll(sockets, 1, seconds_to_next ?
                      seconds_to_next * 1000 : -1);
#else
            fd_set rfd;
            fd_set wfd;
            fd_set *writefd = NULL;
            fd_set *readfd = NULL;
            struct timeval tv;

            tv.tv_sec = seconds_to_next;
            tv.tv_usec = 0;

            if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) {
                FD_ZERO(&rfd);
                FD_SET(session->socket_fd, &rfd);
                readfd = &rfd;
            }

            if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) {
                FD_ZERO(&wfd);
                FD_SET(session->socket_fd, &wfd);
                writefd = &wfd;
            }

            /* Note that this COULD be made to use a timeout that perhaps
               could be customizable by the app or something... */
            rc = select(session->socket_fd + 1, readfd, writefd, NULL,
                        seconds_to_next ? &tv : NULL);
#endif
        }
    }

    if(rc <= 0) {
        /* timeout (or error), bail out with a timeout error */
        session->err_code = LIBSSH2_ERROR_TIMEOUT;
        return LIBSSH2_ERROR_TIMEOUT;
    }

    return 0; /* ready to try again */
}

static int
session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
{
    int rc;

    if (session->startup_state == libssh2_NB_state_idle) {
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                       "session_startup for socket %d", sock);
        if (INVALID_SOCKET == sock) {
            /* Did we forget something? */
            return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET,
                                  "Bad socket provided");
        }
        session->socket_fd = sock;

        session->socket_prev_blockstate =
            !get_socket_nonblocking(session->socket_fd);

        if (session->socket_prev_blockstate) {
            /* If in blocking state chang to non-blocking */
            session_nonblock(session->socket_fd, 1);
        }

        session->startup_state = libssh2_NB_state_created;
    }

    if (session->startup_state == libssh2_NB_state_created) {
        rc = banner_send(session);
        if (rc) {
            return _libssh2_error(session, rc,
                                  "Failed sending banner");
        }
        session->startup_state = libssh2_NB_state_sent;
    }

    if (session->startup_state == libssh2_NB_state_sent) {
        do {
            session->banner_TxRx_state = libssh2_NB_state_idle;

            rc = banner_receive(session);
            if (rc)
                return _libssh2_error(session, rc,
                                      "Failed getting banner");
        } while(strncmp("SSH-", (char *)session->remote.banner, 4));

        session->startup_state = libssh2_NB_state_sent1;
    }

    if (session->startup_state == libssh2_NB_state_sent1) {
        rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state);
        if (rc)
            return _libssh2_error(session, rc,
                                  "Unable to exchange encryption keys");

        session->startup_state = libssh2_NB_state_sent2;
    }

    if (session->startup_state == libssh2_NB_state_sent2) {
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                       "Requesting userauth service");

        /* Request the userauth service */
        session->startup_service[0] = SSH_MSG_SERVICE_REQUEST;
        _libssh2_htonu32(session->startup_service + 1,
                         sizeof("ssh-userauth") - 1);
        memcpy(session->startup_service + 5, "ssh-userauth",
               sizeof("ssh-userauth") - 1);

        session->startup_state = libssh2_NB_state_sent3;
    }

    if (session->startup_state == libssh2_NB_state_sent3) {
        rc = _libssh2_transport_send(session, session->startup_service,
                                     sizeof("ssh-userauth") + 5 - 1,
                                     NULL, 0);
        if (rc) {
            return _libssh2_error(session, rc,
                                  "Unable to ask for ssh-userauth service");
        }

        session->startup_state = libssh2_NB_state_sent4;
    }

    if (session->startup_state == libssh2_NB_state_sent4) {
        rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT,
                                     &session->startup_data,
                                     &session->startup_data_len, 0, NULL, 0,
                                     &session->startup_req_state);
        if (rc)
            return rc;

        session->startup_service_length =
            _libssh2_ntohu32(session->startup_data + 1);

        if ((session->startup_service_length != (sizeof("ssh-userauth") - 1))
            || strncmp("ssh-userauth", (char *) session->startup_data + 5,
                       session->startup_service_length)) {
            LIBSSH2_FREE(session, session->startup_data);
            session->startup_data = NULL;
            return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
                                  "Invalid response received from server");
        }
        LIBSSH2_FREE(session, session->startup_data);
        session->startup_data = NULL;

        session->startup_state = libssh2_NB_state_idle;

        return 0;
    }

    /* just for safety return some error */
    return LIBSSH2_ERROR_INVAL;
}

/*
 * libssh2_session_handshake()
 *
 * session: LIBSSH2_SESSION struct allocated and owned by the calling program
 * sock:    *must* be populated with an opened and connected socket.
 *
 * Returns: 0 on success, or non-zero on failure
 */
LIBSSH2_API int
libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock)
{
    int rc;

    BLOCK_ADJUST(rc, session, session_startup(session, sock) );

    return rc;
}

/*
 * libssh2_session_startup()
 *
 * DEPRECATED. Use libssh2_session_handshake() instead! This function is not
 * portable enough.
 *
 * session: LIBSSH2_SESSION struct allocated and owned by the calling program
 * sock:    *must* be populated with an opened and connected socket.
 *
 * Returns: 0 on success, or non-zero on failure
 */
LIBSSH2_API int
libssh2_session_startup(LIBSSH2_SESSION *session, int sock)
{
    return libssh2_session_handshake(session, (libssh2_socket_t) sock);
}

/*
 * libssh2_session_free
 *
 * Frees the memory allocated to the session
 * Also closes and frees any channels attached to this session
 */
static int
session_free(LIBSSH2_SESSION *session)
{
    int rc;
    LIBSSH2_PACKET *pkg;
    LIBSSH2_CHANNEL *ch;
    LIBSSH2_LISTENER *l;

    if (session->free_state == libssh2_NB_state_idle) {
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Freeing session resource",
                       session->remote.banner);

        session->state = libssh2_NB_state_created;
    }

    if (session->free_state == libssh2_NB_state_created) {
        while ((ch = _libssh2_list_first(&session->channels))) {

            rc = _libssh2_channel_free(ch);
            if (rc == LIBSSH2_ERROR_EAGAIN)
                return rc;
        }

        session->state = libssh2_NB_state_sent;
    }

    if (session->state == libssh2_NB_state_sent) {
        while ((l = _libssh2_list_first(&session->listeners))) {
            rc = _libssh2_channel_forward_cancel(l);
            if (rc == LIBSSH2_ERROR_EAGAIN)
                return rc;
        }

        session->state = libssh2_NB_state_sent1;
    }

    if (session->state & LIBSSH2_STATE_NEWKEYS) {
        /* hostkey */
        if (session->hostkey && session->hostkey->dtor) {
            session->hostkey->dtor(session, &session->server_hostkey_abstract);
        }

        /* Client to Server */
        /* crypt */
        if (session->local.crypt && session->local.crypt->dtor) {
            session->local.crypt->dtor(session,
                                       &session->local.crypt_abstract);
        }
        /* comp */
        if (session->local.comp && session->local.comp->dtor) {
            session->local.comp->dtor(session, 1,
                                      &session->local.comp_abstract);
        }
        /* mac */
        if (session->local.mac && session->local.mac->dtor) {
            session->local.mac->dtor(session, &session->local.mac_abstract);
        }

        /* Server to Client */
        /* crypt */
        if (session->remote.crypt && session->remote.crypt->dtor) {
            session->remote.crypt->dtor(session,
                                        &session->remote.crypt_abstract);
        }
        /* comp */
        if (session->remote.comp && session->remote.comp->dtor) {
            session->remote.comp->dtor(session, 0,
                                       &session->remote.comp_abstract);
        }
        /* mac */
        if (session->remote.mac && session->remote.mac->dtor) {
            session->remote.mac->dtor(session, &session->remote.mac_abstract);
        }

        /* session_id */
        if (session->session_id) {
            LIBSSH2_FREE(session, session->session_id);
        }
    }

    /* Free banner(s) */
    if (session->remote.banner) {
        LIBSSH2_FREE(session, session->remote.banner);
    }
    if (session->local.banner) {
        LIBSSH2_FREE(session, session->local.banner);
    }

    /* Free preference(s) */
    if (session->kex_prefs) {
        LIBSSH2_FREE(session, session->kex_prefs);
    }
    if (session->hostkey_prefs) {
        LIBSSH2_FREE(session, session->hostkey_prefs);
    }

    if (session->local.kexinit) {
        LIBSSH2_FREE(session, session->local.kexinit);
    }
    if (session->local.crypt_prefs) {
        LIBSSH2_FREE(session, session->local.crypt_prefs);
    }
    if (session->local.mac_prefs) {
        LIBSSH2_FREE(session, session->local.mac_prefs);
    }
    if (session->local.comp_prefs) {
        LIBSSH2_FREE(session, session->local.comp_prefs);
    }
    if (session->local.lang_prefs) {
        LIBSSH2_FREE(session, session->local.lang_prefs);
    }

    if (session->remote.kexinit) {
        LIBSSH2_FREE(session, session->remote.kexinit);
    }
    if (session->remote.crypt_prefs) {
        LIBSSH2_FREE(session, session->remote.crypt_prefs);
    }
    if (session->remote.mac_prefs) {
        LIBSSH2_FREE(session, session->remote.mac_prefs);
    }
    if (session->remote.comp_prefs) {
        LIBSSH2_FREE(session, session->remote.comp_prefs);
    }
    if (session->remote.lang_prefs) {
        LIBSSH2_FREE(session, session->remote.lang_prefs);
    }

    /*
     * Make sure all memory used in the state variables are free
     */
    if (session->kexinit_data) {
        LIBSSH2_FREE(session, session->kexinit_data);
    }
    if (session->startup_data) {
        LIBSSH2_FREE(session, session->startup_data);
    }
    if (session->userauth_list_data) {
        LIBSSH2_FREE(session, session->userauth_list_data);
    }
    if (session->userauth_pswd_data) {
        LIBSSH2_FREE(session, session->userauth_pswd_data);
    }
    if (session->userauth_pswd_newpw) {
        LIBSSH2_FREE(session, session->userauth_pswd_newpw);
    }
    if (session->userauth_host_packet) {
        LIBSSH2_FREE(session, session->userauth_host_packet);
    }
    if (session->userauth_host_method) {
        LIBSSH2_FREE(session, session->userauth_host_method);
    }
    if (session->userauth_host_data) {
        LIBSSH2_FREE(session, session->userauth_host_data);
    }
    if (session->userauth_pblc_data) {
        LIBSSH2_FREE(session, session->userauth_pblc_data);
    }
    if (session->userauth_pblc_packet) {
        LIBSSH2_FREE(session, session->userauth_pblc_packet);
    }
    if (session->userauth_pblc_method) {
        LIBSSH2_FREE(session, session->userauth_pblc_method);
    }
    if (session->userauth_kybd_data) {
        LIBSSH2_FREE(session, session->userauth_kybd_data);
    }
    if (session->userauth_kybd_packet) {
        LIBSSH2_FREE(session, session->userauth_kybd_packet);
    }
    if (session->userauth_kybd_auth_instruction) {
        LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction);
    }
    if (session->open_packet) {
        LIBSSH2_FREE(session, session->open_packet);
    }
    if (session->open_data) {
        LIBSSH2_FREE(session, session->open_data);
    }
    if (session->direct_message) {
        LIBSSH2_FREE(session, session->direct_message);
    }
    if (session->fwdLstn_packet) {
        LIBSSH2_FREE(session, session->fwdLstn_packet);
    }
    if (session->pkeyInit_data) {
        LIBSSH2_FREE(session, session->pkeyInit_data);
    }
    if (session->scpRecv_command) {
        LIBSSH2_FREE(session, session->scpRecv_command);
    }
    if (session->scpSend_command) {
        LIBSSH2_FREE(session, session->scpSend_command);
    }

    /* Cleanup all remaining packets */
    while ((pkg = _libssh2_list_first(&session->packets))) {
        /* unlink the node */
        _libssh2_list_remove(&pkg->node);

        /* free */
        LIBSSH2_FREE(session, pkg->data);
        LIBSSH2_FREE(session, pkg);
    }

    if(session->socket_prev_blockstate)
        /* if the socket was previously blocking, put it back so */
        session_nonblock(session->socket_fd, 0);

    if (session->server_hostkey) {
        LIBSSH2_FREE(session, session->server_hostkey);
    }

    LIBSSH2_FREE(session, session);

    return 0;
}

/*
 * libssh2_session_free
 *
 * Frees the memory allocated to the session
 * Also closes and frees any channels attached to this session
 */
LIBSSH2_API int
libssh2_session_free(LIBSSH2_SESSION * session)
{
    int rc;

    BLOCK_ADJUST(rc, session, session_free(session) );

    return rc;
}

/*
 * libssh2_session_disconnect_ex
 */
static int
session_disconnect(LIBSSH2_SESSION *session, int reason,
                   const char *description,
                   const char *lang)
{
    unsigned char *s;
    unsigned long descr_len = 0, lang_len = 0;
    int rc;

    if (session->disconnect_state == libssh2_NB_state_idle) {
        _libssh2_debug(session, LIBSSH2_TRACE_TRANS,
                       "Disconnecting: reason=%d, desc=%s, lang=%s", reason,
                       description, lang);
        if (description)
            descr_len = strlen(description);

        if (lang)
            lang_len = strlen(lang);

        if(descr_len > 256)
            return _libssh2_error(session, LIBSSH2_ERROR_INVAL,
                                  "too long description");

        /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */
        session->disconnect_data_len = descr_len + lang_len + 13;

        s = session->disconnect_data;

        *(s++) = SSH_MSG_DISCONNECT;
        _libssh2_store_u32(&s, reason);
        _libssh2_store_str(&s, description, descr_len);
        /* store length only, lang is sent separately */
        _libssh2_store_u32(&s, lang_len);

        session->disconnect_state = libssh2_NB_state_created;
    }

    rc = _libssh2_transport_send(session, session->disconnect_data,
                                 session->disconnect_data_len,
                                 (unsigned char *)lang, lang_len);
    if (rc == LIBSSH2_ERROR_EAGAIN)
        return rc;

    session->disconnect_state = libssh2_NB_state_idle;

    return 0;
}

/*
 * libssh2_session_disconnect_ex
 */
LIBSSH2_API int
libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
                              const char *desc, const char *lang)
{
    int rc;

    BLOCK_ADJUST(rc, session,
                 session_disconnect(session, reason, desc, lang));

    return rc;
}

/* libssh2_session_methods
 *
 * Return the currently active methods for method_type
 *
 * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string
 * regardless of actual negotiation Strings should NOT be freed
 */
LIBSSH2_API const char *
libssh2_session_methods(LIBSSH2_SESSION * session, int method_type)
{
    /* All methods have char *name as their first element */
    const LIBSSH2_KEX_METHOD *method = NULL;

    switch (method_type) {
    case LIBSSH2_METHOD_KEX:
        method = session->kex;
        break;

    case LIBSSH2_METHOD_HOSTKEY:
        method = (LIBSSH2_KEX_METHOD *) session->hostkey;
        break;

    case LIBSSH2_METHOD_CRYPT_CS:
        method = (LIBSSH2_KEX_METHOD *) session->local.crypt;
        break;

    case LIBSSH2_METHOD_CRYPT_SC:
        method = (LIBSSH2_KEX_METHOD *) session->remote.crypt;
        break;

    case LIBSSH2_METHOD_MAC_CS:
        method = (LIBSSH2_KEX_METHOD *) session->local.mac;
        break;

    case LIBSSH2_METHOD_MAC_SC:
        method = (LIBSSH2_KEX_METHOD *) session->remote.mac;
        break;

    case LIBSSH2_METHOD_COMP_CS:
        method = (LIBSSH2_KEX_METHOD *) session->local.comp;
        break;

    case LIBSSH2_METHOD_COMP_SC:
        method = (LIBSSH2_KEX_METHOD *) session->remote.comp;
        break;

    case LIBSSH2_METHOD_LANG_CS:
        return "";

    case LIBSSH2_METHOD_LANG_SC:
        return "";

    default:
        _libssh2_error(session, LIBSSH2_ERROR_INVAL,
                       "Invalid parameter specified for method_type");
        return NULL;
    }

    if (!method) {
        _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE,
                       "No method negotiated");
        return NULL;
    }

    return method->name;
}

/* libssh2_session_abstract
 * Retrieve a pointer to the abstract property
 */
LIBSSH2_API void **
libssh2_session_abstract(LIBSSH2_SESSION * session)
{
    return &session->abstract;
}

/* libssh2_session_last_error
 *
 * Returns error code and populates an error string into errmsg If want_buf is
 * non-zero then the string placed into errmsg must be freed by the calling
 * program. Otherwise it is assumed to be owned by libssh2
 */
LIBSSH2_API int
libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg,
                           int *errmsg_len, int want_buf)
{
    size_t msglen = 0;

    /* No error to report */
    if (!session->err_code) {
        if (errmsg) {
            if (want_buf) {
                *errmsg = LIBSSH2_ALLOC(session, 1);
                if (*errmsg) {
                    **errmsg = 0;
                }
            } else {
                *errmsg = (char *) "";
            }
        }
        if (errmsg_len) {
            *errmsg_len = 0;
        }
        return 0;
    }

    if (errmsg) {
        const char *error = session->err_msg ? session->err_msg : "";

        msglen = strlen(error);

        if (want_buf) {
            /* Make a copy so the calling program can own it */
            *errmsg = LIBSSH2_ALLOC(session, msglen + 1);
            if (*errmsg) {
                memcpy(*errmsg, error, msglen);
                (*errmsg)[msglen] = 0;
            }
        }
        else
            *errmsg = (char *)error;
    }

    if (errmsg_len) {
        *errmsg_len = msglen;
    }

    return session->err_code;
}

/* libssh2_session_last_errno
 *
 * Returns error code
 */
LIBSSH2_API int
libssh2_session_last_errno(LIBSSH2_SESSION * session)
{
    return session->err_code;
}

/* libssh2_session_flag
 *
 * Set/Get session flags
 *
 * Return error code.
 */
LIBSSH2_API int
libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value)
{
    switch(flag) {
    case LIBSSH2_FLAG_SIGPIPE:
        session->flag.sigpipe = value;
        break;
    case LIBSSH2_FLAG_COMPRESS:
        session->flag.compress = value;
        break;
    default:
        /* unknown flag */
        return LIBSSH2_ERROR_INVAL;
    }

    return LIBSSH2_ERROR_NONE;
}

/* _libssh2_session_set_blocking
 *
 * Set a session's blocking mode on or off, return the previous status when
 * this function is called. Note this function does not alter the state of the
 * actual socket involved.
 */
int
_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking)
{
    int bl = session->api_block_mode;
    _libssh2_debug(session, LIBSSH2_TRACE_CONN,
                   "Setting blocking mode %s", blocking?"ON":"OFF");
    session->api_block_mode = blocking;

    return bl;
}

/* libssh2_session_set_blocking
 *
 * Set a channel's blocking mode on or off, similar to a socket's
 * fcntl(fd, F_SETFL, O_NONBLOCK); type command
 */
LIBSSH2_API void
libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking)
{
    (void) _libssh2_session_set_blocking(session, blocking);
}

/* libssh2_session_get_blocking
 *
 * Returns a session's blocking mode on or off
 */
LIBSSH2_API int
libssh2_session_get_blocking(LIBSSH2_SESSION * session)
{
    return session->api_block_mode;
}

/*
 * libssh2_poll_channel_read
 *
 * Returns 0 if no data is waiting on channel,
 * non-0 if data is available
 */
LIBSSH2_API int
libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended)
{
    LIBSSH2_SESSION *session;
    LIBSSH2_PACKET *packet;

    if(!channel)
        return LIBSSH2_ERROR_BAD_USE;

    session = channel->session;
    packet = _libssh2_list_first(&session->packets);

    while (packet) {
        if ( channel->local.id == _libssh2_ntohu32(packet->data + 1)) {
            if ( extended == 1 &&
                 (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA
                  || packet->data[0] == SSH_MSG_CHANNEL_DATA )) {
                return 1;
            } else if ( extended == 0 &&
                        packet->data[0] == SSH_MSG_CHANNEL_DATA) {
                return 1;
            }
            /* else - no data of any type is ready to be read */
        }
        packet = _libssh2_list_next(&packet->node);
    }

    return 0;
}

/*
 * poll_channel_write
 *
 * Returns 0 if writing to channel would block,
 * non-0 if data can be written without blocking
 */
static inline int
poll_channel_write(LIBSSH2_CHANNEL * channel)
{
    return channel->local.window_size ? 1 : 0;
}

/* poll_listener_queued
 *
 * Returns 0 if no connections are waiting to be accepted
 * non-0 if one or more connections are available
 */
static inline int
poll_listener_queued(LIBSSH2_LISTENER * listener)
{
    return _libssh2_list_first(&listener->queue) ? 1 : 0;
}

/*
 * libssh2_poll
 *
 * Poll sockets, channels, and listeners for activity
 */
LIBSSH2_API int
libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
{
    long timeout_remaining;
    unsigned int i, active_fds;
#ifdef HAVE_POLL
    LIBSSH2_SESSION *session = NULL;
#ifdef HAVE_ALLOCA
    struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds);
#else
    struct pollfd sockets[256];

    if (nfds > 256)
        /* systems without alloca use a fixed-size array, this can be fixed if
           we really want to, at least if the compiler is a C99 capable one */
        return -1;
#endif
    /* Setup sockets for polling */
    for(i = 0; i < nfds; i++) {
        fds[i].revents = 0;
        switch (fds[i].type) {
        case LIBSSH2_POLLFD_SOCKET:
            sockets[i].fd = fds[i].fd.socket;
            sockets[i].events = fds[i].events;
            sockets[i].revents = 0;
            break;

        case LIBSSH2_POLLFD_CHANNEL:
            sockets[i].fd = fds[i].fd.channel->session->socket_fd;
            sockets[i].events = POLLIN;
            sockets[i].revents = 0;
            if (!session)
                session = fds[i].fd.channel->session;
            break;

        case LIBSSH2_POLLFD_LISTENER:
            sockets[i].fd = fds[i].fd.listener->session->socket_fd;
            sockets[i].events = POLLIN;
            sockets[i].revents = 0;
            if (!session)
                session = fds[i].fd.listener->session;
            break;

        default:
            if (session)
                _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
                               "Invalid descriptor passed to libssh2_poll()");
            return -1;
        }
    }
#elif defined(HAVE_SELECT)
    LIBSSH2_SESSION *session = NULL;
    libssh2_socket_t maxfd = 0;
    fd_set rfds, wfds;
    struct timeval tv;

    FD_ZERO(&rfds);
    FD_ZERO(&wfds);
    for(i = 0; i < nfds; i++) {
        fds[i].revents = 0;
        switch (fds[i].type) {
        case LIBSSH2_POLLFD_SOCKET:
            if (fds[i].events & LIBSSH2_POLLFD_POLLIN) {
                FD_SET(fds[i].fd.socket, &rfds);
                if (fds[i].fd.socket > maxfd)
                    maxfd = fds[i].fd.socket;
            }
            if (fds[i].events & LIBSSH2_POLLFD_POLLOUT) {
                FD_SET(fds[i].fd.socket, &wfds);
                if (fds[i].fd.socket > maxfd)
                    maxfd = fds[i].fd.socket;
            }
            break;

        case LIBSSH2_POLLFD_CHANNEL:
            FD_SET(fds[i].fd.channel->session->socket_fd, &rfds);
            if (fds[i].fd.channel->session->socket_fd > maxfd)
                maxfd = fds[i].fd.channel->session->socket_fd;
            if (!session)
                session = fds[i].fd.channel->session;
            break;

        case LIBSSH2_POLLFD_LISTENER:
            FD_SET(fds[i].fd.listener->session->socket_fd, &rfds);
            if (fds[i].fd.listener->session->socket_fd > maxfd)
                maxfd = fds[i].fd.listener->session->socket_fd;
            if (!session)
                session = fds[i].fd.listener->session;
            break;

        default:
            if (session)
                _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE,
                               "Invalid descriptor passed to libssh2_poll()");
            return -1;
        }
    }
#else
    /* No select() or poll()
     * no sockets sturcture to setup
     */

    timeout = 0;
#endif /* HAVE_POLL or HAVE_SELECT */

    timeout_remaining = timeout;
    do {
#if defined(HAVE_POLL) || defined(HAVE_SELECT)
        int sysret;
#endif

        active_fds = 0;

        for(i = 0; i < nfds; i++) {
            if (fds[i].events != fds[i].revents) {
                switch (fds[i].type) {
                case LIBSSH2_POLLFD_CHANNEL:
                    if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
                        /* Want to be ready for read */
                        ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
                        /* Not yet known to be ready for read */
                        fds[i].revents |=
                            libssh2_poll_channel_read(fds[i].fd.channel,
                                                      0) ?
                            LIBSSH2_POLLFD_POLLIN : 0;
                    }
                    if ((fds[i].events & LIBSSH2_POLLFD_POLLEXT) &&
                        /* Want to be ready for extended read */
                        ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) {
                        /* Not yet known to be ready for extended read */
                        fds[i].revents |=
                            libssh2_poll_channel_read(fds[i].fd.channel,
                                                      1) ?
                            LIBSSH2_POLLFD_POLLEXT : 0;
                    }
                    if ((fds[i].events & LIBSSH2_POLLFD_POLLOUT) &&
                        /* Want to be ready for write */
                        ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) {
                        /* Not yet known to be ready for write */
                        fds[i].revents |=
                            poll_channel_write(fds[i].fd. channel) ?
                            LIBSSH2_POLLFD_POLLOUT : 0;
                    }
                    if (fds[i].fd.channel->remote.close
                        || fds[i].fd.channel->local.close) {
                        fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED;
                    }
                    if (fds[i].fd.channel->session->socket_state ==
                        LIBSSH2_SOCKET_DISCONNECTED) {
                        fds[i].revents |=
                            LIBSSH2_POLLFD_CHANNEL_CLOSED |
                            LIBSSH2_POLLFD_SESSION_CLOSED;
                    }
                    break;

                case LIBSSH2_POLLFD_LISTENER:
                    if ((fds[i].events & LIBSSH2_POLLFD_POLLIN) &&
                        /* Want a connection */
                        ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) {
                        /* No connections known of yet */
                        fds[i].revents |=
                            poll_listener_queued(fds[i].fd. listener) ?
                            LIBSSH2_POLLFD_POLLIN : 0;
                    }
                    if (fds[i].fd.listener->session->socket_state ==
                        LIBSSH2_SOCKET_DISCONNECTED) {
                        fds[i].revents |=
                            LIBSSH2_POLLFD_LISTENER_CLOSED |
                            LIBSSH2_POLLFD_SESSION_CLOSED;
                    }
                    break;
                }
            }
            if (fds[i].revents) {
                active_fds++;
            }
        }

        if (active_fds) {
            /* Don't block on the sockets if we have channels/listeners which
               are ready */
            timeout_remaining = 0;
        }
#ifdef HAVE_POLL

#ifdef HAVE_GETTIMEOFDAY
        {
            struct timeval tv_begin, tv_end;

            gettimeofday((struct timeval *) &tv_begin, NULL);
            sysret = poll(sockets, nfds, timeout_remaining);
            gettimeofday((struct timeval *) &tv_end, NULL);
            timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
            timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
        }
#else
        /* If the platform doesn't support gettimeofday,
         * then just make the call non-blocking and walk away
         */
        sysret = poll(sockets, nfds, timeout_remaining);
        timeout_remaining = 0;
#endif /* HAVE_GETTIMEOFDAY */

        if (sysret > 0) {
            for(i = 0; i < nfds; i++) {
                switch (fds[i].type) {
                case LIBSSH2_POLLFD_SOCKET:
                    fds[i].revents = sockets[i].revents;
                    sockets[i].revents = 0; /* In case we loop again, be nice */
                    if (fds[i].revents) {
                        active_fds++;
                    }
                    break;
                case LIBSSH2_POLLFD_CHANNEL:
                    if (sockets[i].events & POLLIN) {
                        /* Spin session until no data available */
                        while (_libssh2_transport_read(fds[i].fd.channel->session)
                               > 0);
                    }
                    if (sockets[i].revents & POLLHUP) {
                        fds[i].revents |=
                            LIBSSH2_POLLFD_CHANNEL_CLOSED |
                            LIBSSH2_POLLFD_SESSION_CLOSED;
                    }
                    sockets[i].revents = 0;
                    break;
                case LIBSSH2_POLLFD_LISTENER:
                    if (sockets[i].events & POLLIN) {
                        /* Spin session until no data available */
                        while (_libssh2_transport_read(fds[i].fd.listener->session)
                               > 0);
                    }
                    if (sockets[i].revents & POLLHUP) {
                        fds[i].revents |=
                            LIBSSH2_POLLFD_LISTENER_CLOSED |
                            LIBSSH2_POLLFD_SESSION_CLOSED;
                    }
                    sockets[i].revents = 0;
                    break;
                }
            }
        }
#elif defined(HAVE_SELECT)
        tv.tv_sec = timeout_remaining / 1000;
        tv.tv_usec = (timeout_remaining % 1000) * 1000;
#ifdef HAVE_GETTIMEOFDAY
        {
            struct timeval tv_begin, tv_end;

            gettimeofday((struct timeval *) &tv_begin, NULL);
            sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
            gettimeofday((struct timeval *) &tv_end, NULL);

            timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000;
            timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000;
        }
#else
        /* If the platform doesn't support gettimeofday,
         * then just make the call non-blocking and walk away
         */
        sysret = select(maxfd+1, &rfds, &wfds, NULL, &tv);
        timeout_remaining = 0;
#endif

        if (sysret > 0) {
            for(i = 0; i < nfds; i++) {
                switch (fds[i].type) {
                case LIBSSH2_POLLFD_SOCKET:
                    if (FD_ISSET(fds[i].fd.socket, &rfds)) {
                        fds[i].revents |= LIBSSH2_POLLFD_POLLIN;
                    }
                    if (FD_ISSET(fds[i].fd.socket, &wfds)) {
                        fds[i].revents |= LIBSSH2_POLLFD_POLLOUT;
                    }
                    if (fds[i].revents) {
                        active_fds++;
                    }
                    break;

                case LIBSSH2_POLLFD_CHANNEL:
                    if (FD_ISSET(fds[i].fd.channel->session->socket_fd, &rfds)) {
                        /* Spin session until no data available */
                        while (_libssh2_transport_read(fds[i].fd.channel->session)
                               > 0);
                    }
                    break;

                case LIBSSH2_POLLFD_LISTENER:
                    if (FD_ISSET
                        (fds[i].fd.listener->session->socket_fd, &rfds)) {
                        /* Spin session until no data available */
                        while (_libssh2_transport_read(fds[i].fd.listener->session)
                               > 0);
                    }
                    break;
                }
            }
        }
#endif /* else no select() or poll() -- timeout (and by extension
        * timeout_remaining) will be equal to 0 */
    } while ((timeout_remaining > 0) && !active_fds);

    return active_fds;
}

/*
 * libssh2_session_block_directions
 *
 * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN
 * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked
 * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked
 */
LIBSSH2_API int
libssh2_session_block_directions(LIBSSH2_SESSION *session)
{
    return session->socket_block_directions;
}

