diff --git a/connect.c b/connect.c index 9a7df45..e9c049b 100644 --- a/connect.c +++ b/connect.c @@ -59,6 +59,7 @@ #include "hostc.h" #include "trace_dsc.h" #include "utilc.h" +#include "telnetc.h" #include /*---[ Implement ]-------------------------------------------------------------------------------*/ @@ -66,7 +67,30 @@ static void net_connected(H3270 *hSession) { - trace("***************** %s",__FUNCTION__); + RemoveSource(hSession->ns_write_id); + hSession->ns_write_id = NULL; + +#ifdef _WIN32 + hSession->ns_exception_id = AddExcept(hSession->sockEvent, hSession, net_exception); + hSession->ns_read_id = AddInput(hSession->sockEvent, hSession, net_input); +#else + hSession->ns_exception_id = AddExcept(hSession->sock, hSession, net_exception); + hSession->ns_read_id = AddInput(hSession->sock, hSession, net_input); +#endif // WIN32 + hSession->excepting = 1; + hSession->reading = 1; + +/* +#if defined(HAVE_LIBSSL) + if(hSession->ssl_con && hSession->secure == LIB3270_SSL_UNDEFINED) + { + if(ssl_negotiate(hSession)) + return; + } +#endif +*/ + + lib3270_setup_session(hSession); } @@ -120,7 +144,6 @@ static void net_connected(H3270 *hSession) LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc) { int s; - int sock = -1; struct addrinfo hints; struct addrinfo * result = NULL; struct addrinfo * rp = NULL; @@ -138,7 +161,7 @@ static void net_connected(H3270 *hSession) if(hSession->auto_reconnect_inprogress) return EAGAIN; - if(PCONNECTED) + if(hSession->sock > 0) return EBUSY; #if defined(_WIN32) @@ -194,7 +217,7 @@ static void net_connected(H3270 *hSession) status_changed(hSession,LIB3270_STATUS_CONNECTING); - for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next) + for(rp = result; hSession->sock < 0 && rp != NULL; rp = rp->ai_next) { hSession->sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if(hSession->sock < 0) @@ -204,6 +227,36 @@ static void net_connected(H3270 *hSession) u_long block; u_int len = sizeof(int); + if(session->sockEvent == NULL) + { + char ename[256]; + + snprintf(ename, 255, "%s-%d", PACKAGE_NAME, getpid()); + + session->sockEvent = CreateEvent(NULL, TRUE, FALSE, ename); + if(session->sockEvent == NULL) + { + lib3270_popup_dialog( session, + LIB3270_NOTIFY_CRITICAL, + N_( "Network startup error" ), + N_( "Cannot create socket handle" ), + "%s", win32_strerror(GetLastError()) ); + _exit(1); + } + } + + if (WSAEventSelect(session->sock, session->sockEvent, FD_READ | FD_CONNECT | FD_CLOSE) != 0) + { + lib3270_popup_dialog( session, + LIB3270_NOTIFY_CRITICAL, + N_( "Network startup error" ), + N_( "WSAEventSelect failed" ), + "%s", win32_strerror(GetLastError()) ); + _exit(1); + } + + + WSASetLastError(0); block = 0; @@ -213,8 +266,7 @@ static void net_connected(H3270 *hSession) LIB3270_NOTIFY_ERROR, _( "Connection error" ), _( "ioctlsocket(FIONBIO) failed." ), - "Windows error %d", - WSAGetLastError() ); + "%s", win32_strerror(GetLastError())); SOCK_CLOSE(hSession); } @@ -227,14 +279,13 @@ static void net_connected(H3270 *hSession) LIB3270_NOTIFY_ERROR, _( "Connection error" ), _( "Can't connect to host." ), - "Windows error %d", - WSAGetLastError() ); + "%s", win32_strerror(GetLastError())); SOCK_CLOSE(hSession); } } #else - fcntl(hSession->sock, F_SETFL,fcntl(sock,F_GETFL,0)|O_NONBLOCK); + fcntl(hSession->sock, F_SETFL,fcntl(hSession->sock,F_GETFL,0)|O_NONBLOCK); errno = 0; if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen)) @@ -288,11 +339,13 @@ static void net_connected(H3270 *hSession) #endif // Connecting, set callbacks, wait for connection - trace_dsn(hSession,"Half-connected.\n"); - lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); +#ifdef _WIN32 + hSession->ns_write_id = AddOutput(hSession->sockEvent, hSession, net_connected); +#else hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected); +#endif // WIN32 return 0; diff --git a/globals.h b/globals.h index da0a77c..6a0cedb 100644 --- a/globals.h +++ b/globals.h @@ -357,3 +357,4 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); LIB3270_INTERNAL void check_session_handle(H3270 **hSession); #endif // DEBUG +LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc); diff --git a/iocalls.c b/iocalls.c index 7097a6f..a3dd08d 100644 --- a/iocalls.c +++ b/iocalls.c @@ -269,7 +269,7 @@ static void * internal_add_input(int source, H3270 *session, void (*fn)(H3270 *s { input_t *ip = (input_t *) lib3270_malloc(sizeof(input_t)); - trace("%s session=%p proc=%p",__FUNCTION__,session,fn); + trace("%s session=%p proc=%p handle=%p",__FUNCTION__,session,fn,ip); ip->source = source; ip->condition = InputReadMask; @@ -290,7 +290,7 @@ static void * internal_add_output(int source, H3270 *session, void (*fn)(H3270 * { input_t *ip = (input_t *) lib3270_malloc(sizeof(input_t)); - trace("%s session=%p proc=%p",__FUNCTION__,session,fn); + trace("%s session=%p proc=%p handle=%p",__FUNCTION__,session,fn,ip); ip->source = source; ip->condition = InputWriteMask; @@ -346,7 +346,10 @@ static void internal_remove_source(void *id) } if (ip == (input_t *)NULL) + { + lib3270_write_log(NULL,"lib3270","Double removal on %s: Input %p wasnt found in the list",__FUNCTION__,id); return; + } if (prev != (input_t *)NULL) prev->next = ip->next; @@ -782,6 +785,12 @@ void remove_input_calls(H3270 *session) session->ns_exception_id = NULL; session->excepting = 0; } + if(session->ns_write_id) + { + RemoveSource(session->ns_write_id); + session->ns_write_id = NULL; + session->writing = 0; + } } LIB3270_EXPORT void lib3270_register_time_handlers(void * (*add)(unsigned long interval_ms, H3270 *session, void (*proc)(H3270 *session)), void (*rm)(void *timer)) diff --git a/lib3270.cbp b/lib3270.cbp index c2334a4..75713c5 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -7,7 +7,7 @@