From 5b6f048197a56d0b45ad642431f2b5ee718c53e9 Mon Sep 17 00:00:00 2001 From: Aris Adamantiadis Date: Wed, 12 Jan 2011 23:04:43 +0100 Subject: Use termination functions for event polling --- src/client.c | 37 +++++++++++++++++++++++-------------- src/session.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/client.c b/src/client.c index c77e5828..a737ba80 100644 --- a/src/client.c +++ b/src/client.c @@ -588,6 +588,21 @@ static void ssh_client_connection_callback(ssh_session session){ leave_function(); } +/** @internal + * @brief describe under which conditions the ssh_connect function may stop + */ +static int ssh_connect_termination(void *user){ + ssh_session session = (ssh_session)user; + switch(session->session_state){ + case SSH_SESSION_STATE_ERROR: + case SSH_SESSION_STATE_AUTHENTICATING: + case SSH_SESSION_STATE_DISCONNECTED: + return 1; + default: + return 0; + } +} + /** * @brief Connect to the ssh server. * @@ -670,20 +685,14 @@ int ssh_connect(ssh_session session) { ssh_log(session,SSH_LOG_PROTOCOL,"Socket connecting, now waiting for the callbacks to work"); pending: session->pending_call_state=SSH_PENDING_CALL_CONNECT; - while(session->session_state != SSH_SESSION_STATE_ERROR && - session->session_state != SSH_SESSION_STATE_AUTHENTICATING && - session->session_state != SSH_SESSION_STATE_DISCONNECTED){ - /* loop until SSH_SESSION_STATE_BANNER_RECEIVED or - * SSH_SESSION_STATE_ERROR */ - if(ssh_is_blocking(session)) - ssh_handle_packets(session,-1); - else - ssh_handle_packets(session,0); - ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state); - if(!ssh_is_blocking(session)){ - leave_function(); - return SSH_AGAIN; - } + if(ssh_is_blocking(session)) + ssh_handle_packets_termination(session,-1,ssh_connect_termination,session); + else + ssh_handle_packets_termination(session,0,ssh_connect_termination, session); + ssh_log(session,SSH_LOG_PACKET,"ssh_connect: Actual state : %d",session->session_state); + if(!ssh_is_blocking(session) && !ssh_connect_termination(session)){ + leave_function(); + return SSH_AGAIN; } leave_function(); session->pending_call_state=SSH_PENDING_CALL_NONE; diff --git a/src/session.c b/src/session.c index c862e714..83436dc2 100644 --- a/src/session.c +++ b/src/session.c @@ -395,6 +395,43 @@ int ssh_handle_packets(ssh_session session, int timeout) { return SSH_ERROR; } +/** + * @internal + * + * @brief Poll the current session for an event and call the appropriate + * callbacks. + * + * This will block until termination fuction returns true, or timeout expired. + * + * @param[in] session The session handle to use. + * + * @param[in] timeout Set an upper limit on the time for which this function + * will block, in milliseconds. Specifying a negative value + * means an infinite timeout. This parameter is passed to + * the poll() function. + * @param[in] fct Termination function to be used to determine if it is + * possible to stop polling. + * @param[in] user User parameter to be passed to fct termination function. + * @return SSH_OK on success, SSH_ERROR otherwise. + */ +int ssh_handle_packets_termination(ssh_session session, int timeout, + ssh_termination_function fct, void *user){ + int ret; + while(!fct(user)){ + ret = ssh_handle_packets(session, timeout); + if(ret == SSH_ERROR) + return SSH_ERROR; + if(timeout == 0){ + if(fct(user)) + return SSH_OK; + else + return SSH_AGAIN; + } + /* TODO: verify that total timeout has not expired and then return SSH_AGAIN */ + } + return ret; +} + /** * @brief Get session status * -- cgit v1.2.3