From 64d1f0f80c78651a966ab301e29435b118b58bff Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Fri, 1 Feb 2019 11:21:27 -0200 Subject: [PATCH] Adding status "resolving", reorganizing auto-reconnect methods to avoid "popup hangs". --- lib3270.cbp | 3 +++ src/include/lib3270.h | 3 ++- src/include/screen.h | 3 ++- src/include/telnetc.h | 52 +++++++++++++++++++++++++++++++--------------------- src/lib3270/connect.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib3270/host.c | 7 ++----- src/lib3270/linux/connect.c | 65 +++++------------------------------------------------------------ src/lib3270/screen.c | 22 +++++++++++++++++++--- src/lib3270/session.c | 2 +- src/lib3270/ssl/ctx_init.c | 2 +- src/lib3270/windows/connect.c | 63 +++++++-------------------------------------------------------- 11 files changed, 168 insertions(+), 149 deletions(-) create mode 100644 src/lib3270/connect.c diff --git a/lib3270.cbp b/lib3270.cbp index 974dba4..886582a 100644 --- a/lib3270.cbp +++ b/lib3270.cbp @@ -127,6 +127,9 @@ + + diff --git a/src/include/lib3270.h b/src/include/lib3270.h index 6113623..9df75e9 100644 --- a/src/include/lib3270.h +++ b/src/include/lib3270.h @@ -381,7 +381,8 @@ */ typedef enum _lib3270_state { - LIB3270_STATE_RESOLVING, + LIB3270_STATE_RESOLVING, ///< @brief Resolving DNS. + LIB3270_STATE_CONNECTING, ///< @brief Connecting to host. LIB3270_STATE_HALF_CONNECT, LIB3270_STATE_CONNECT, LIB3270_STATE_3270_MODE, diff --git a/src/include/screen.h b/src/include/screen.h index d0e1edc..f2a0c86 100644 --- a/src/include/screen.h +++ b/src/include/screen.h @@ -18,5 +18,6 @@ LIB3270_INTERNAL int *char_width, *char_height; LIB3270_INTERNAL void screen_update(H3270 *session, int bstart, int bend); -LIB3270_INTERNAL void status_connecting(H3270 *session, Boolean on); +LIB3270_INTERNAL void status_connecting(H3270 *session); +LIB3270_INTERNAL void status_resolving(H3270 *session); diff --git a/src/include/telnetc.h b/src/include/telnetc.h index 6c800eb..fb14360 100644 --- a/src/include/telnetc.h +++ b/src/include/telnetc.h @@ -1,28 +1,36 @@ /* - * Copyright 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2007 by Paul Mattes. - * RPQNAMES modifications Copyright 2004 by Don Russell. - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appear in all copies and that - * both that copyright notice and this permission notice appear in - * supporting documentation. - * - * x3270, c3270, s3270 and tcl3270 are distributed in the hope that they will - * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE - * for more details. + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * */ -/* - * telnetc.h - * Global declarations for telnet.c. +/** + * @brief Global declarations for telnet.c. */ -/* Output buffer. */ -// extern unsigned char *obuf; -// extern unsigned char *obptr; - /* Spelled-out tty control character. */ struct ctl_char { const char *name; @@ -32,7 +40,10 @@ struct ctl_char { LIB3270_INTERNAL void net_abort(H3270 *hSession); LIB3270_INTERNAL void net_add_eor(unsigned char *buf, int len); LIB3270_INTERNAL void net_break(H3270 *hSession); + LIB3270_INTERNAL int net_connect(H3270 *session, const char *, char *, Boolean, Boolean *, Boolean *); +LIB3270_INTERNAL int net_reconnect(H3270 *hSession, int seconds); + LIB3270_INTERNAL void net_disconnect(H3270 *session); LIB3270_INTERNAL void net_exception(H3270 *session, int fd, LIB3270_IO_FLAG flag, void *dunno); LIB3270_INTERNAL void net_input(H3270 *session, int fd, LIB3270_IO_FLAG flag, void *dunno); @@ -51,5 +62,4 @@ LIB3270_INTERNAL void space3270out(H3270 *hSession, int n); #define trace_netdata(direction, buf, len) /* */ #endif // X3270_TRACE - LIB3270_INTERNAL int net_getsockname(const H3270 *h3270, void *buf, int *len); diff --git a/src/lib3270/connect.c b/src/lib3270/connect.c new file mode 100644 index 0000000..f827352 --- /dev/null +++ b/src/lib3270/connect.c @@ -0,0 +1,95 @@ +/* + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a + * aplicativos mainframe. Registro no INPI sob o nome G3270. + * + * Copyright (C) <2008> + * + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela + * Free Software Foundation. + * + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para + * obter mais detalhes. + * + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin + * St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Este programa está nomeado como - e possui - linhas de código. + * + * Contatos: + * + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) + * + */ + +#include +#include "private.h" +#include "telnetc.h" +#include +#include + +/*---[ Implement ]-------------------------------------------------------------------------------*/ + + LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait) + { + CHECK_SESSION_HANDLE(hSession); + + if(url && *url) + { + lib3270_set_url(hSession,url); + } + + return lib3270_reconnect(hSession, wait); + + } + + int lib3270_reconnect(H3270 *hSession, int seconds) + { + FAIL_IF_ONLINE(hSession); + + // + // Can't reconnect if already reconnecting *OR* there's an open popup + // (to avoid open more than one connect error popup. + // + if(hSession->auto_reconnect_inprogress || hSession->popups) + return errno = EAGAIN; + + if(hSession->sock > 0) + return errno = EBUSY; + + if(!(hSession->host.current && hSession->host.srvc)) + { + // No host info, try the default one. + if(lib3270_set_url(hSession,NULL)) + { + int err = errno; + lib3270_trace_event(hSession,"Can't set default URL (%s)\n",strerror(err)); + return errno = err; + } + + if(!(hSession->host.current && hSession->host.srvc)) + { + return errno = EINVAL; + } + } + +#if defined(HAVE_LIBSSL) + set_ssl_state(hSession,LIB3270_SSL_UNSECURE); +#endif // HAVE_LIBSSL + + snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num); + + lib3270_trace_event(hSession,"Reconnecting to %s\n",lib3270_get_url(hSession)); + + hSession->ever_3270 = False; + hSession->ssl.host = 0; + + return net_reconnect(hSession,seconds); + + } + diff --git a/src/lib3270/host.c b/src/lib3270/host.c index f24e455..8fe319a 100644 --- a/src/lib3270/host.c +++ b/src/lib3270/host.c @@ -193,10 +193,10 @@ LIB3270_EXPORT void lib3270_register_schange(H3270 *h, LIB3270_STATE tx, void (* void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) { #if defined(DEBUG) - static const char * state_name[LIB3270_STATE_USER] = { "LIB3270_STATE_RESOLVING", + "LIB3270_STATE_CONNECTING", "LIB3270_STATE_HALF_CONNECT", "LIB3270_STATE_CONNECT", "LIB3270_STATE_3270_MODE", @@ -204,10 +204,8 @@ void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) "LIB3270_STATE_REMODEL", "LIB3270_STATE_PRINTER", "LIB3270_STATE_EXITING", - "LIB3270_STATE_CHARSET", - + "LIB3270_STATE_CHARSET" }; - #endif // DEBUG struct lib3270_state_callback *st; @@ -218,7 +216,6 @@ void lib3270_st_changed(H3270 *h, LIB3270_STATE tx, int mode) for (st = h->st_callbacks[tx];st;st = st->next) { -// trace("st=%p func=%p",st,st->func); st->func(h,mode,st->data); } diff --git a/src/lib3270/linux/connect.c b/src/lib3270/linux/connect.c index 02bbe08..4312ea4 100644 --- a/src/lib3270/linux/connect.c +++ b/src/lib3270/linux/connect.c @@ -48,10 +48,8 @@ #include -//#include "statusc.h" #include "hostc.h" #include "trace_dsc.h" -//#include "utilc.h" #include "telnetc.h" #include "screen.h" @@ -117,19 +115,6 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u } - LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait) - { - CHECK_SESSION_HANDLE(hSession); - - if(url && *url) - { - lib3270_set_url(hSession,url); - } - - return lib3270_reconnect(hSession, wait); - - } - struct resolver { const char * message; @@ -147,6 +132,8 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u hints.ai_flags = AI_PASSIVE; // For wildcard IP address hints.ai_protocol = 0; // Any protocol + status_resolving(hSession); + int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result); if(rc != 0) { @@ -154,7 +141,7 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u return -1; } - status_connecting(hSession,1); + status_connecting(hSession); for(rp = result; hSession->sock < 0 && rp != NULL; rp = rp->ai_next) { @@ -181,50 +168,11 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u } - int lib3270_reconnect(H3270 *hSession, int seconds) + int net_reconnect(H3270 *hSession, int seconds) { - int optval; struct resolver host; - - CHECK_SESSION_HANDLE(hSession); memset(&host,0,sizeof(host)); - if(hSession->auto_reconnect_inprogress) - return errno = EAGAIN; - - if(hSession->sock > 0) - return errno = EBUSY; - - if(!(hSession->host.current && hSession->host.srvc)) - { - // No host info, try the default one. - if(lib3270_set_url(hSession,NULL)) - { - int err = errno; - lib3270_trace_event(hSession,"Can't set default URL (%s)\n",strerror(err)); - return errno = err; - } - - if(!(hSession->host.current && hSession->host.srvc)) - { - return errno = ENOENT; - } - } - -#if defined(HAVE_LIBSSL) - set_ssl_state(hSession,LIB3270_SSL_UNSECURE); -#endif // HAVE_LIBSSL - - snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num); - - lib3270_trace_event(hSession,"Reconnecting to %s\n",lib3270_get_url(hSession)); - - hSession->ever_3270 = False; - hSession->cstate = LIB3270_RESOLVING; - - lib3270_st_changed(hSession, LIB3270_STATE_RESOLVING, True); - - // s = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result); if(lib3270_run_task(hSession, background_connect, &host) || hSession->sock < 0) { char buffer[4096]; @@ -245,10 +193,8 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u (void) fcntl(hSession->sock, F_SETFD, 1); hSession->ever_3270 = False; - hSession->ssl.host = 0; #if defined(HAVE_LIBSSL) - debug("** SSL init %s","begins"); if(hSession->ssl.enabled) { hSession->ssl.host = 1; @@ -257,11 +203,10 @@ static void net_connected(H3270 *hSession, int fd unused, LIB3270_IO_FLAG flag u return errno = ENOTCONN; } - debug("** SSL init %s","ends"); #endif // HAVE_LIBSSL // set options for inline out-of-band data and keepalives - optval = 1; + int optval = 1; if (setsockopt(hSession->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&optval,sizeof(optval)) < 0) { int rc = errno; diff --git a/src/lib3270/screen.c b/src/lib3270/screen.c index 1b41089..3206c5a 100644 --- a/src/lib3270/screen.c +++ b/src/lib3270/screen.c @@ -556,10 +556,26 @@ void status_oerr(H3270 *session, int error_type) } -void status_connecting(H3270 *session, Boolean on) +/** + * @brief Resolving DNS name. + * + */ +void status_resolving(H3270 *hSession) +{ + hSession->cstate = LIB3270_RESOLVING; + lib3270_st_changed(hSession, LIB3270_STATE_RESOLVING, True); + + mcursor_set(hSession,LIB3270_POINTER_LOCKED); + status_changed(hSession, LIB3270_MESSAGE_RESOLVING); +} + +void status_connecting(H3270 *hSession) { - mcursor_set(session,on ? LIB3270_POINTER_LOCKED : LIB3270_POINTER_UNLOCKED); - status_changed(session, on ? LIB3270_MESSAGE_CONNECTING : LIB3270_MESSAGE_NONE); + hSession->cstate = LIB3270_RESOLVING; + lib3270_st_changed(hSession, LIB3270_STATE_CONNECTING, True); + + mcursor_set(hSession,LIB3270_POINTER_LOCKED); + status_changed(hSession, LIB3270_MESSAGE_CONNECTING); } void status_reset(H3270 *session) diff --git a/src/lib3270/session.c b/src/lib3270/session.c index 872c4b8..0e22cb5 100644 --- a/src/lib3270/session.c +++ b/src/lib3270/session.c @@ -86,6 +86,7 @@ void lib3270_session_free(H3270 *h) X509_CRL_free(h->ssl.crl.cert); h->ssl.crl.cert = NULL; } +#endif // SSL_ENABLE_CRL_CHECK // Release state change callbacks for(f=0;fst_callbacks[f] = next; } } -#endif // SSL_ENABLE_CRL_CHECK // Release memory #define release_pointer(x) lib3270_free(x); x = NULL; diff --git a/src/lib3270/ssl/ctx_init.c b/src/lib3270/ssl/ctx_init.c index b9f53bf..02e540e 100644 --- a/src/lib3270/ssl/ctx_init.c +++ b/src/lib3270/ssl/ctx_init.c @@ -147,7 +147,7 @@ int ssl_ctx_init(H3270 *hSession, SSL_ERROR_MESSAGE * message) if(hSession->ssl.crl.cert) { X509_STORE_add_crl(store, hSession->ssl.crl.cert); - trace_ssl(hSession,"CRL was added to cert store"); + trace_ssl(hSession,"CRL was added to cert store\n"); } X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new(); diff --git a/src/lib3270/windows/connect.c b/src/lib3270/windows/connect.c index c814814..2af06ad 100644 --- a/src/lib3270/windows/connect.c +++ b/src/lib3270/windows/connect.c @@ -39,8 +39,7 @@ #include "../private.h" #include - -#include +#include #ifdef HAVE_ICONV #include @@ -150,19 +149,6 @@ static void sockstart(H3270 *session) } } -LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wait) -{ - CHECK_SESSION_HANDLE(hSession); - - if(url && *url) - { - lib3270_set_url(hSession,url); - } - - return lib3270_reconnect(hSession, wait); - -} - struct resolver { int convert; @@ -186,6 +172,8 @@ LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wai debug("%s(%s,%s)",__FUNCTION__,hSession->host.current, hSession->host.srvc); + status_resolving(hSession); + int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result); if(rc != 0) { @@ -194,7 +182,7 @@ LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wai return -1; } - status_connecting(hSession,1); + status_connecting(hSession); for(rp = result; hSession->sock < 0 && rp != NULL; rp = rp->ai_next) { @@ -221,50 +209,14 @@ LIB3270_EXPORT int lib3270_connect_url(H3270 *hSession, const char *url, int wai } -int lib3270_reconnect(H3270 *hSession, int seconds) +int net_reconnect(H3270 *hSession, int seconds) { - int optval; - struct resolver host; - - CHECK_SESSION_HANDLE(hSession); + struct resolver host; memset(&host,0,sizeof(host)); - if(hSession->auto_reconnect_inprogress) - return errno = EAGAIN; - - if(hSession->sock > 0) - return errno = EBUSY; - - if(!(hSession->host.current && hSession->host.srvc)) - { - // No host info, try the default one. - if(lib3270_set_url(hSession,NULL)) - { - int err = errno; - lib3270_trace_event(hSession,"Can't set default URL (%s)\n",strerror(err)); - return errno = err; - } - - if(!(hSession->host.current && hSession->host.srvc)) - { - return errno = ENOENT; - } - } - sockstart(hSession); -#if defined(HAVE_LIBSSL) - set_ssl_state(hSession,LIB3270_SSL_UNSECURE); -#endif // HAVE_LIBSSL - - snprintf(hSession->full_model_name,LIB3270_FULL_MODEL_NAME_LENGTH,"IBM-327%c-%d",hSession->m3279 ? '9' : '8', hSession->model_num); - - hSession->ever_3270 = False; - hSession->cstate = LIB3270_RESOLVING; - - lib3270_st_changed(hSession, LIB3270_STATE_RESOLVING, True); - if(lib3270_run_task(hSession, background_connect, &host) || hSession->sock < 0) { lib3270_autoptr(char) message = lib3270_strdup_printf(_( "Can't connect to %s"), lib3270_get_url(hSession)); @@ -333,9 +285,8 @@ int lib3270_reconnect(H3270 *hSession, int seconds) /* connect */ WSASetLastError(0); - // u_long iMode=1; - optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; + int optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; if (setsockopt(hSession->sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0) { char buffer[4096]; -- libgit2 0.21.2