diff --git a/lib3270.cbp b/lib3270.cbp
index 06988b7..0e12ad8 100644
--- a/lib3270.cbp
+++ b/lib3270.cbp
@@ -271,6 +271,7 @@
+
@@ -306,6 +307,9 @@
+
+
+
diff --git a/src/core/connect.c b/src/core/connect.c
index 19c1543..afbc2f8 100644
--- a/src/core/connect.c
+++ b/src/core/connect.c
@@ -121,7 +121,7 @@
return 0;
}
- if(hSession->connection.sock > 0)
+ if(hSession->network.module->is_connected(hSession))
{
errno = EISCONN;
return 0;
@@ -169,3 +169,41 @@
}
+ static int bg_start_tls(H3270 *hSession, void *message)
+ {
+
+ }
+
+ int lib3270_start_tls(H3270 *hSession)
+ {
+ int rc = 0;
+
+ if(hSession->network.module->start_tls)
+ {
+ LIB3270_NETWORK_STATE state;
+ memset(&state,0,sizeof(state));
+
+ non_blocking(hSession,False);
+
+ rc = lib3270_run_task(
+ hSession,
+ (int(*)(H3270 *h, void *)) hSession->network.module->start_tls,
+ &state
+ );
+
+ if(state.popup) {
+ if(lib3270_popup(hSession,state.popup,1)) {
+ lib3270_disconnect(hSession);
+ return rc;
+ }
+
+ // User has selected "continue", ignore error.
+ return 0;
+ }
+
+ }
+
+ return rc;
+ }
+
+
diff --git a/src/core/iocalls.c b/src/core/iocalls.c
index 1138ca9..cb6e64e 100644
--- a/src/core/iocalls.c
+++ b/src/core/iocalls.c
@@ -299,19 +299,18 @@ static void internal_remove_poll(H3270 *session, void *id)
}
+/*
LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id)
{
debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id);
remove_poll(session, id);
}
+*/
LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled)
{
if(id)
- {
- debug("%s: Polling on %d (%p) is %s",__FUNCTION__,session->connection.sock,id,(enabled ? "enabled" : "disabled"));
set_poll_state(session, id, enabled);
- }
}
LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd)
@@ -349,7 +348,7 @@ LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_FL
}
LIB3270_EXPORT void * lib3270_add_poll_fd(H3270 *session, int fd, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata ) {
- debug("%s(%d)",__FUNCTION__,session->connection.sock);
+ debug("%s(%d)",__FUNCTION__,fd);
return add_poll(session,fd,flag,call,userdata);
}
@@ -400,11 +399,10 @@ void x_except_on(H3270 *h)
if(reading)
lib3270_remove_poll(h,h->xio.read);
- h->xio.except = lib3270_add_poll_fd(h,h->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
+ h->xio.except = h->network.module->add_poll(h,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
if(reading)
- h->xio.read = lib3270_add_poll_fd(h,h->connection.sock,LIB3270_IO_FLAG_READ,net_input,0);
- debug("%s",__FUNCTION__);
+ h->xio.read = h->network.module->add_poll(h,LIB3270_IO_FLAG_READ,net_input,0);
}
@@ -522,61 +520,9 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo
int non_blocking(H3270 *hSession, Boolean on)
{
-
- if(hSession->connection.sock < 0)
+ if(hSession->network.module->non_blocking,on)
return 0;
-#ifdef WIN32
-
- WSASetLastError(0);
- u_long iMode= on ? 1 : 0;
-
- if(ioctlsocket(hSession->connection.sock,FIONBIO,&iMode))
- {
- lib3270_popup_dialog( hSession,
- LIB3270_NOTIFY_ERROR,
- _( "Connection error" ),
- _( "ioctlsocket(FIONBIO) failed." ),
- "%s", lib3270_win32_strerror(GetLastError()));
- return -1;
- }
-
-#else
-
- int f;
-
- if ((f = fcntl(hSession->connection.sock, F_GETFL, 0)) == -1)
- {
- lib3270_popup_dialog( hSession,
- LIB3270_NOTIFY_ERROR,
- _( "Socket error" ),
- _( "fcntl() error when getting socket state." ),
- _( "%s" ), strerror(errno)
- );
-
- return -1;
- }
-
- if (on)
- f |= O_NDELAY;
- else
- f &= ~O_NDELAY;
-
- if (fcntl(hSession->connection.sock, F_SETFL, f) < 0)
- {
- lib3270_popup_dialog( hSession,
- LIB3270_NOTIFY_ERROR,
- _( "Socket error" ),
- on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ),
- _( "%s" ), strerror(errno)
- );
- return -1;
- }
-
-#endif
-
- debug("Socket %d is now %s",hSession->connection.sock,(on ? "Non Blocking" : "Blocking"));
-
lib3270_set_poll_state(hSession,hSession->xio.read, on);
lib3270_set_poll_state(hSession,hSession->xio.write, on);
lib3270_set_poll_state(hSession,hSession->xio.except, on);
diff --git a/src/core/linux/connect.c b/src/core/linux/connect.c
index 88b38ff..b8847b8 100644
--- a/src/core/linux/connect.c
+++ b/src/core/linux/connect.c
@@ -42,7 +42,7 @@
#include
#include
-#define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1;
+// #define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1;
#include
@@ -69,7 +69,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
hSession->xio.write = NULL;
}
- if(getsockopt(hSession->connection.sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0)
+ if(hSession->network.module->getsockopt(hSession, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0)
{
lib3270_disconnect(hSession);
lib3270_popup_dialog(
@@ -88,16 +88,11 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
return;
}
- hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
- hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_READ,net_input,0);
+ hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0);
+ hSession->xio.read = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_READ,net_input,0);
-#if defined(HAVE_LIBSSL)
- if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED)
- {
- if(ssl_negotiate(hSession))
- return;
- }
-#endif
+ if(lib3270_start_tls(hSession))
+ return;
lib3270_setup_session(hSession);
lib3270_set_connected_initial(hSession);
@@ -238,8 +233,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG
lib3270_set_cstate(hSession, LIB3270_PENDING);
lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True);
- hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_WRITE,net_connected,0);
- // hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected);
+ hSession->xio.write = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_WRITE,net_connected,0);
trace("%s: Connection in progress",__FUNCTION__);
diff --git a/src/core/model.c b/src/core/model.c
index 1abf682..870a9f7 100644
--- a/src/core/model.c
+++ b/src/core/model.c
@@ -28,6 +28,7 @@
*/
#include
+ #include
#include "screen.h"
#include "ctlrc.h"
#include "popupsc.h"
diff --git a/src/core/rpq.c b/src/core/rpq.c
index db0680f..4ce873f 100644
--- a/src/core/rpq.c
+++ b/src/core/rpq.c
@@ -690,7 +690,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen
void *src = NULL;
int len = 0;
- if(net_getsockname(hSession, &u, &addrlen) < 0)
+ if(hSession->network.module->getsockname(hSession, (struct sockaddr *) &u, &addrlen) < 0)
return 0;
SET16(buf, u.sa.sa_family);
x += 2;
diff --git a/src/core/session.c b/src/core/session.c
index 16f5bbc..e8e53b9 100644
--- a/src/core/session.c
+++ b/src/core/session.c
@@ -74,7 +74,7 @@ void lib3270_session_free(H3270 *h)
shutdown_toggles(h);
-#ifdef SSL_ENABLE_CRL_CHECK
+#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
if(h->ssl.crl.prefer)
{
free(h->ssl.crl.prefer);
@@ -281,7 +281,7 @@ void lib3270_reset_callbacks(H3270 *hSession)
memset(&hSession->cbk,0,sizeof(hSession->cbk));
hSession->cbk.write = lib3270_sock_send;
- hSession->cbk.disconnect = lib3270_sock_disconnect;
+// hSession->cbk.disconnect = lib3270_sock_disconnect;
hSession->cbk.update = update_char;
hSession->cbk.update_model = update_model;
hSession->cbk.update_cursor = update_cursor;
@@ -331,7 +331,6 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char
hSession->unlock_delay = 1;
hSession->icrnl = 1;
hSession->onlcr = 1;
- hSession->connection.sock = -1;
hSession->model_num = -1;
hSession->connection.state = LIB3270_NOT_CONNECTED;
hSession->oia.status = -1;
@@ -446,7 +445,7 @@ H3270 * lib3270_session_new(const char *model)
hSession->ssl.protocol.max_version = 0;
#endif // HAVE_LIBSSL
-#ifdef SSL_ENABLE_CRL_CHECK
+#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL)
hSession->ssl.crl.download = 1;
#endif // SSL_ENABLE_CRL_CHECK
diff --git a/src/core/telnet.c b/src/core/telnet.c
index 110ff32..2c35576 100644
--- a/src/core/telnet.c
+++ b/src/core/telnet.c
@@ -507,9 +507,11 @@ static void connection_complete(H3270 *session)
}
+/*
LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
{
- trace("%s",__FUNCTION__);
+ LIB3270_NETWORK_STATE state;
+ memset(&state,0,sizeof(state));
#if defined(HAVE_LIBSSL)
if(hSession->ssl.con != NULL)
@@ -527,37 +529,47 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession)
hSession->xio.write = 0;
}
- if(hSession->connection.sock >= 0)
- {
- shutdown(hSession->connection.sock, 2);
- SOCK_CLOSE(hSession->connection.sock);
- hSession->connection.sock = -1;
- }
+ hSession->network.module->disconnect(hSession->network.context,hSession,&state);
}
+*/
/**
- * @brief Shut down the socket.
+ * @brief Disconnect from host.
*/
-void net_disconnect(H3270 *session)
+void net_disconnect(H3270 *hSession)
{
+ LIB3270_NETWORK_STATE state;
+ memset(&state,0,sizeof(state));
+
+ // Disconnect from host
#if defined(HAVE_LIBSSL)
- set_ssl_state(session,LIB3270_SSL_UNSECURE);
-#endif // HAVE_LIBSSL
+ if(hSession->ssl.con != NULL)
+ {
+ set_ssl_state(hSession,LIB3270_SSL_UNDEFINED);
+ SSL_shutdown(hSession->ssl.con);
+ SSL_free(hSession->ssl.con);
+ hSession->ssl.con = NULL;
+ }
+ else
+ {
+ set_ssl_state(hSession,LIB3270_SSL_UNSECURE);
+ }
+#endif
- session->cbk.disconnect(session);
+ if(hSession->xio.write)
+ {
+ lib3270_remove_poll(hSession, hSession->xio.write);
+ hSession->xio.write = 0;
+ }
- trace_dsn(session,"SENT disconnect\n");
+ hSession->network.module->disconnect(hSession,&state);
- /* Restore terminal type to its default. */
- /*
- if (session->termname == CN)
- session->termtype = session->full_model_name;
- */
+ trace_dsn(hSession,"SENT disconnect\n");
// We're not connected to an LU any more.
- session->lu.associated = CN;
- status_lu(session,CN);
+ hSession->lu.associated = CN;
+ status_lu(hSession,CN);
}
@@ -618,8 +630,8 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
for (;;)
#endif
{
- if (hSession->connection.sock < 0)
- return;
+// if (hSession->connection.sock < 0)
+// return;
#if defined(X3270_ANSI)
hSession->ansi_data = 0;
@@ -629,9 +641,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED
if (hSession->ssl.con != NULL)
nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ);
else
- nr = recv(hSession->connection.sock, (char *) buffer, BUFSZ, 0);
+ nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ);
#else
- nr = recv(hSession->connection.sock, (char *) buffer, BUFSZ, 0);
+ nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ);
#endif // HAVE_LIBSSL
if (nr < 0)
@@ -1637,7 +1649,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf
else
rc = send(hSession->connection.sock, (const char *) buf, len, 0);
#else
- rc = send(hSession->connection.sock, (const char *) buf, len, 0);
+ rc = hSession->network.module->send(hSession, buf, len);
#endif // HAVE_LIBSSL
if(rc > 0)
@@ -2650,9 +2662,12 @@ void net_abort(H3270 *hSession)
#endif /*]*/
/* Return the local address for the socket. */
+
+/*
int net_getsockname(const H3270 *session, void *buf, int *len)
{
if (session->connection.sock < 0)
return -1;
return getsockname(session->connection.sock, buf, (socklen_t *)(void *)len);
}
+*/
diff --git a/src/core/toggles/init.c b/src/core/toggles/init.c
index 2564ef5..be02226 100644
--- a/src/core/toggles/init.c
+++ b/src/core/toggles/init.c
@@ -79,21 +79,19 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle
static void toggle_keepalive(H3270 *session, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt))
{
- if(session->connection.sock > 0)
- {
- // Update keep-alive option
- int optval = t->value ? 1 : 0;
+ // Update keep-alive option
+ int optval = t->value ? 1 : 0;
- if (setsockopt(session->connection.sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0)
- {
+ if(session->network.module->setsockopt(session, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0)
+ {
+ if(errno != ENOTCONN)
popup_a_sockerr(session, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" ));
- }
- else
- {
- trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" );
- }
-
}
+ else
+ {
+ trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" );
+ }
+
}
static void toggle_connect(H3270 *hSession, const struct lib3270_toggle *toggle, LIB3270_TOGGLE_TYPE tt)
diff --git a/src/core/util.c b/src/core/util.c
index 32cc6d7..a00d02a 100644
--- a/src/core/util.c
+++ b/src/core/util.c
@@ -516,6 +516,7 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr)
}
+/*
LIB3270_EXPORT int lib3270_getpeername(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen)
{
CHECK_SESSION_HANDLE(hSession);
@@ -544,7 +545,7 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s
return getsockname(hSession->connection.sock, addr, addrlen);
}
-
+*/
static int xdigit_value(const char scanner)
{
diff --git a/src/include/internals.h b/src/include/internals.h
index cffed11..40f2885 100644
--- a/src/include/internals.h
+++ b/src/include/internals.h
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#if defined(HAVE_LIBSSL)
#include
@@ -319,12 +320,22 @@ struct _h3270
{
struct lib3270_session_callbacks cbk; ///< @brief Callback table - Always the first one.
- // Session info
- char id; ///< @brief Session Identifier.
+ /// @brief Session Identifier.
+ char id;
+
+ // Network
+ struct {
+
+ /// @brief Network module.
+ const LIB3270_NET_MODULE * module;
+
+ /// @brief Network context.
+ LIB3270_NET_CONTEXT * context;
+
+ } network;
// Connection info
struct {
- int sock; ///< @brief Network socket.
LIB3270_CSTATE state; ///< @brief Connection state.
} connection;
@@ -745,7 +756,7 @@ LIB3270_INTERNAL void toggle_rectselect(H3270 *session, const struct lib3270_tog
LIB3270_INTERNAL void remove_input_calls(H3270 *session);
LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf, int len);
-LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession);
+// LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession);
LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block);
@@ -871,3 +882,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on);
/// @brief Fire CState change.
LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate);
+
+ inline LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession) {
+ return hSession->network.context;
+ }
+
+ LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession);
+
+
diff --git a/src/include/lib3270/session.h b/src/include/lib3270/session.h
index 3ff28af..e63a331 100644
--- a/src/include/lib3270/session.h
+++ b/src/include/lib3270/session.h
@@ -49,7 +49,7 @@
struct lib3270_session_callbacks
{
int (*write)(H3270 *hSession, unsigned const char *buf, int len);
- void (*disconnect)(H3270 *hSession);
+// void (*disconnect)(H3270 *hSession);
void (*configure)(H3270 *session, unsigned short rows, unsigned short cols);
void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor);
diff --git a/src/include/networking.h b/src/include/networking.h
new file mode 100644
index 0000000..ab73371
--- /dev/null
+++ b/src/include/networking.h
@@ -0,0 +1,141 @@
+/*
+ * "Software G3270, 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 ', 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 networking.h e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
+ *
+ */
+
+#ifndef LIB3270_NETWORKING_H_INCLUDED
+
+ #define LIB3270_NETWORKING_H_INCLUDED
+
+ #include
+ #include
+
+ typedef struct lib3270_network_state {
+
+ int syserror; ///< @brief System error (errno)
+#ifdef _WIN32
+ DWORD winerror; ///< @brief Win32 error got from GetLastError()
+#endif // _WIN32
+
+ const LIB3270_POPUP *popup; /// @brief Detailed info for popup.
+
+ } LIB3270_NETWORK_STATE;
+
+ typedef struct _lib3270_new_context LIB3270_NET_CONTEXT;
+
+ typedef struct lib3270_net_module {
+
+ const char * name; ///< @brief The network module name.
+
+ /// @brief Initialize network module
+ ///
+ /// @param hSession TN3270 session.
+ /// @param state Pointer to state message.
+ ///
+ /// @return Allocated network context.
+ ///
+ /// @retval NULL Initialization failed.
+ ///
+ LIB3270_NET_CONTEXT * (*init)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
+
+ /// @brief Deinitialize network module.
+ ///
+ /// @param context Network context.
+ /// @param hSession TN3270 session.
+ /// @param state Pointer to state message.
+ ///
+ void (*deinit)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
+
+ /// @brief Connect to host.
+ ///
+ /// @param context Network context.
+ /// @param hSession TN3270 session.
+ /// @param seconds Seconds for timeout.
+ /// @param state Pointer to state message.
+ ///
+ int (*connect)(H3270 *hSession, int seconds, LIB3270_NETWORK_STATE *state);
+
+ /// @brief Disconnect from host.
+ ///
+ /// @param context Network context.
+ /// @param hSession TN3270 session.
+ /// @param state Pointer to state message.
+ ///
+ int (*disconnect)(H3270 *hSession, LIB3270_NETWORK_STATE *state);
+
+ int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg);
+
+ /// @brief Send on network context.
+ ///
+ /// @return Positive on data received, negative on error.
+ ///
+ ssize_t (*send)(H3270 *hSession, const void *buffer, size_t length);
+
+ /// @brief Receive on network context.
+ ///
+ /// @return Positive on data received, negative on error.
+ ///
+ /// @retval -ENOTCONN Not connected to host.
+ ///
+ ssize_t (*recv)(H3270 *hSession, void *buf, size_t len);
+
+ /// @brief Add socket in poll list.
+ void * (*add_poll)(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata);
+
+ /// @brief Set non blocking mode.
+ ///
+ /// @retval 0 Not connected or Success.
+ /// @retval -1 Failed (popup was sent).
+ int (*non_blocking)(H3270 *hSession, const unsigned char on);
+
+ /// @brief Check if the session is online.
+ ///
+ /// @retval 0 The session is offline.
+ int (*is_connected)(H3270 *hSession);
+
+ /// @brief get socket name.
+ ///
+ /// @return On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
+ ///
+ /// @retval 0 Success.
+ /// @retval -1 Error (errno is set).
+ int (*getsockname)(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen);
+
+ /// @brief Set socket options.
+ int (*setsockopt)(H3270 *hSession, int level, int optname, void *optval, size_t optlen);
+
+ /// @brief Get socket options.
+ int (*getsockopt)(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen);
+
+ } LIB3270_NET_MODULE;
+
+ LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession);
+ LIB3270_NET_CONTEXT * lib3270_get_default_net_context(void);
+
+
+#endif // LIB3270_NETWORKING_H_INCLUDED
+
diff --git a/src/include/telnetc.h b/src/include/telnetc.h
index b649dbd..689570a 100644
--- a/src/include/telnetc.h
+++ b/src/include/telnetc.h
@@ -62,4 +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);
+// LIB3270_INTERNAL int net_getsockname(const H3270 *h3270, void *buf, int *len);
diff --git a/src/network_modules/unsecure.c b/src/network_modules/unsecure.c
new file mode 100644
index 0000000..998e1eb
--- /dev/null
+++ b/src/network_modules/unsecure.c
@@ -0,0 +1,193 @@
+/*
+ * "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 ', 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 networking.h e possui - linhas de código.
+ *
+ * Contatos:
+ *
+ * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck)
+ * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça)
+ *
+ */
+
+ /**
+ * @brief Default networking methods.
+ *
+ */
+
+ #include
+ #ifdef _WIN32
+ #include
+ #include
+ #endif // _WIN32
+
+ #include
+ #include
+
+ struct _lib3270_new_context {
+ int sock;
+ };
+
+ LIB3270_NET_CONTEXT * unsecure_network_init(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
+
+ LIB3270_NET_CONTEXT * context = lib3270_malloc(sizeof(LIB3270_NET_CONTEXT));
+
+ context->sock = -1;
+
+ return context;
+ }
+
+ void unsecure_network_deinit(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
+ unsecure_network_disconnect(hSession->network.context,hSession,state);
+ lib3270_free(context);
+ }
+
+int unsecure_network_disconnect(H3270 *hSession, LIB3270_NETWORK_STATE *state) {
+
+ debug("%s",__FUNCTION__);
+ if(context->sock >= 0) {
+ shutdown(hSession.network.context->sock, 2);
+ close(hSession->network.context->sock);
+ hSession.network.context->sock = -1;
+ }
+
+}
+
+ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) {
+
+ if(hSession->network.context->sock < 0) {
+ return -(errno = ENOTCONN);
+ }
+
+ ssize_t bytes = send(hSession->network.context->sock,buffer,length,0);
+
+ if(bytes < 0)
+ return -errno;
+
+ return 0;
+}
+
+ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) {
+
+ if(hSession->network.context->sock < 0) {
+ return -(errno = ENOTCONN);
+ }
+
+ ssize_t bytes = recv(hSession->network.context->sock, (char *) buffer, len, 0);
+
+ if(bytes < 0) {
+ return -errno;
+ }
+
+ return bytes;
+}
+
+int unsecure_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) {
+ if(hSession->network.context->sock < 0)
+ return -(errno = ENOTCONN);
+ return getsockname(hSession->network.context->sock, buf, addrlen);
+}
+
+void * unsecure_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) {
+ return lib3270_add_poll_fd(hSession,hSession->network.context->sock,flag,call,userdata);
+}
+
+int unsecure_non_blocking(H3270 *hSession, const unsigned char on) {
+
+ if(hSession->network.context->sock < 0)
+ return 0;
+
+#ifdef WIN32
+
+ WSASetLastError(0);
+ u_long iMode= on ? 1 : 0;
+
+ if(ioctlsocket(hSession->network.context->sock,FIONBIO,&iMode))
+ {
+ lib3270_popup_dialog( hSession,
+ LIB3270_NOTIFY_ERROR,
+ _( "Connection error" ),
+ _( "ioctlsocket(FIONBIO) failed." ),
+ "%s", lib3270_win32_strerror(GetLastError()));
+ return -1;
+ }
+
+#else
+
+ int f;
+
+ if ((f = fcntl(hSession->network.context->sock, F_GETFL, 0)) == -1)
+ {
+ lib3270_popup_dialog( hSession,
+ LIB3270_NOTIFY_ERROR,
+ _( "Socket error" ),
+ _( "fcntl() error when getting socket state." ),
+ _( "%s" ), strerror(errno)
+ );
+
+ return -1;
+ }
+
+ if (on)
+ f |= O_NDELAY;
+ else
+ f &= ~O_NDELAY;
+
+ if (fcntl(hSession->network.context->sock, F_SETFL, f) < 0)
+ {
+ lib3270_popup_dialog( hSession,
+ LIB3270_NOTIFY_ERROR,
+ _( "Socket error" ),
+ on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ),
+ _( "%s" ), strerror(errno)
+ );
+ return -1;
+ }
+
+#endif
+
+ debug("Socket %d is now %s",hSession->network.context->sock,(on ? "Non Blocking" : "Blocking"));
+
+}
+
+int unsecure_is_connected(H3270 *hSession) {
+ return hSession->network.context.sock > 0;
+}
+
+int unsecure_setsockopt(H3270 *hSession, int level, int optname, const void *optval, size_t optlen) {
+
+ if(hSession->network.context.sock < 0) {
+ errno = ENOTCONN;
+ return -1;
+ }
+
+ return setsockopt(hSession->network.context.sock, level, optname, optval, optlen);
+
+}
+
+int unsecure_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) {
+
+ if(hSession->network.context.sock < 0) {
+ errno = ENOTCONN;
+ return -1;
+ }
+
+ return getsockopt(hSession->network.context.sock, level, optname, optval, optlen)
+}
--
libgit2 0.21.2