diff --git a/globals.h b/globals.h index abaaf16..99dea63 100644 --- a/globals.h +++ b/globals.h @@ -352,5 +352,6 @@ LIB3270_INTERNAL int cursor_move(H3270 *session, int baddr); // LIB3270_INTERNAL void add_input_calls(H3270 *, void (*)(H3270 *), void (*)(H3270 *)); LIB3270_INTERNAL void toggle_rectselect(H3270 *session, struct lib3270_toggle *t, LIB3270_TOGGLE_TYPE tt); - LIB3270_INTERNAL void remove_input_calls(H3270 *session); + +LIB3270_INTERNAL int lib3270_send(H3270 *hSession, unsigned const char *buf, int len); diff --git a/session.c b/session.c index c71d282..dd2db41 100644 --- a/session.c +++ b/session.c @@ -167,6 +167,7 @@ static void lib3270_session_init(H3270 *hSession, const char *model) hSession->sz = sizeof(H3270); // Default calls + hSession->write = lib3270_send; hSession->update = update_char; hSession->update_model = update_model; hSession->update_cursor = update_cursor; diff --git a/telnet.c b/telnet.c index 6408102..b821f95 100644 --- a/telnet.c +++ b/telnet.c @@ -102,6 +102,8 @@ #include "xioc.h" #include "screen.h" +#include + #if !defined(TELOPT_NAWS) /*[*/ #define TELOPT_NAWS 31 #endif /*]*/ @@ -519,8 +521,8 @@ int net_connect(H3270 *session, const char *host, char *portname, Boolean ls, Bo sockstart(session); #endif - if (session->netrbuf == (unsigned char *)NULL) - session->netrbuf = (unsigned char *)lib3270_malloc(BUFSZ); +// if (session->netrbuf == (unsigned char *)NULL) +// session->netrbuf = (unsigned char *)lib3270_malloc(BUFSZ); #if defined(X3270_ANSI) /*[*/ if (!t_valid) @@ -965,7 +967,6 @@ void net_disconnect(H3270 *session) } - LIB3270_EXPORT void lib3270_data_recv(H3270 *hSession, size_t nr, const unsigned char *netrbuf) { register const unsigned char * cp; @@ -1989,131 +1990,91 @@ void net_exception(H3270 *session) * */ - -/* - * net_rawout - * Send out raw telnet data. We assume that there will always be enough - * space to buffer what we want to transmit, so we don't handle EAGAIN or - * EWOULDBLOCK. - */ -static void -net_rawout(H3270 *session, unsigned const char *buf, int len) +LIB3270_INTERNAL int lib3270_send(H3270 *hSession, unsigned const char *buf, int len) { - int nw; + int rc; - trace_netdata('>', buf, len); +#if defined(HAVE_LIBSSL) + if(hSession->ssl_con != NULL) + rc = SSL_write(hSession->ssl_con, (const char *) buf, len); + else + rc = send(hSession->sock, (const char *) buf, len, 0); +#else + rc = send(hSession->sock, (const char *) buf, len, 0); +#endif // HAVE_LIBSSL - while (len) { -#if defined(OMTU) /*[*/ - int n2w = len; - int pause = 0; + if(rc > 0) + return rc; - if (n2w > OMTU) { - n2w = OMTU; - pause = 1; - } -#else -# define n2w len -#endif -#if defined(HAVE_LIBSSL) /*[*/ - if(session->ssl_con != NULL) - nw = SSL_write(session->ssl_con, (const char *) buf, n2w); - else -#endif /*]*/ + // Recv error, notify -/* -#if defined(LOCAL_PROCESS) - if (local_process) - nw = write(sock, (const char *) buf, n2w); - else -#endif -*/ - nw = send(session->sock, (const char *) buf, n2w, 0); - if (nw < 0) { -#if defined(HAVE_LIBSSL) /*[*/ - if (session->ssl_con != NULL) - { - unsigned long e; - char err_buf[120]; +#if defined(HAVE_LIBSSL) + if(hSession->ssl_con != NULL) + { + unsigned long e; + char err_buf[120]; - e = ERR_get_error(); - (void) ERR_error_string(e, err_buf); - trace_dsn("RCVD SSL_write error %ld (%s)\n", e,err_buf); - popup_an_error(NULL,"SSL_write:\n%s", err_buf); - host_disconnect(session,False); - return; - } -#endif /*]*/ - trace_dsn("RCVD socket error %d\n", errno); - if (socket_errno() == SE_EPIPE || socket_errno() == SE_ECONNRESET) { - host_disconnect(session,False); - return; - } else if (socket_errno() == SE_EINTR) { - goto bot; - } else { - popup_a_sockerr(NULL, N_( "Socket write error" ) ); - host_disconnect(session,True); - return; - } - } - session->ns_bsent += nw; - len -= nw; - buf += nw; - bot: -#if defined(OMTU) - if (pause) - sleep(1); -#endif - ; + e = ERR_get_error(); + (void) ERR_error_string(e, err_buf); + trace_dsn("RCVD SSL_write error %ld (%s)\n", e,err_buf); + popup_an_error(hSession,_( "SSL_write:\n%s" ), err_buf); + return -1; } -} +#endif // HAVE_LIBSSL - -#if defined(X3270_ANSI) /*[*/ -/* - * net_hexansi_out - * Send uncontrolled user data to the host in ANSI mode, performing IAC - * and CR quoting as necessary. - */ /* -void -net_hexansi_out(unsigned char *buf, int len) -{ - unsigned char *tbuf; - unsigned char *xbuf; + trace_dsn("RCVD socket error %d\n", socket_errno()); - if (!len) - return; + switch(socket_errno()) + { + case SE_EPIPE: + popup_an_error(hSession, "%s", N_( "Broken pipe" )); + break; -#if defined(X3270_TRACE) - // Trace the data. - if (lib3270_get_toggle(&h3270,LIB3270_TOGGLE_DS_TRACE)) { - int i; + case SE_ECONNRESET: + popup_an_error(hSession, "%s", N_( "Connection reset by peer" )); + break; - trace_dsn(">"); - for (i = 0; i < len; i++) - trace_dsn(" %s", ctl_see((int) *(buf+i))); - trace_dsn("\n"); - } -#endif + case SE_EINTR: + return 0; - // Expand it - tbuf = xbuf = (unsigned char *)lib3270_malloc(2*len); - while (len) { - unsigned char c = *buf++; + default: + popup_a_sockerr(NULL, "%s", N_( "Socket write error" ) ); - *tbuf++ = c; - len--; - if (c == IAC) - *tbuf++ = IAC; - else if (c == '\r' && (!len || *buf != '\n')) - *tbuf++ = '\0'; } - // Send it to the host - net_rawout(&h3270,xbuf, tbuf - xbuf); - lib3270_free(xbuf); + return -1; } -*/ + +/* + * net_rawout + * Send out raw telnet data. We assume that there will always be enough + * space to buffer what we want to transmit, so we don't handle EAGAIN or + * EWOULDBLOCK. + */ +static void net_rawout(H3270 *hSession, unsigned const char *buf, int len) +{ + trace_netdata('>', buf, len); + + while (len) + { + int nw = hSession->write(hSession,buf,len); + + if (nw > 0) + { + // Data received + hSession->ns_bsent += nw; + len -= nw; + buf += nw; + } + else if(nw < 0) + { + host_disconnect(hSession,True); + return; + } + } +} + +#if defined(X3270_ANSI) /* * net_cookedout -- libgit2 0.21.2