Commit 0669cde0aa80aed19ced0b75f2f8e6f8e41c37d4
1 parent
09dddac0
Exists in
master
and in
3 other branches
Refactoring network subsystem for modularity.
Showing
15 changed files
with
472 additions
and
123 deletions
Show diff stats
lib3270.cbp
| @@ -271,6 +271,7 @@ | @@ -271,6 +271,7 @@ | ||
| 271 | <Unit filename="src/include/lib3270/trace.h" /> | 271 | <Unit filename="src/include/lib3270/trace.h" /> |
| 272 | <Unit filename="src/include/linkedlist.h" /> | 272 | <Unit filename="src/include/linkedlist.h" /> |
| 273 | <Unit filename="src/include/localdefs.h" /> | 273 | <Unit filename="src/include/localdefs.h" /> |
| 274 | + <Unit filename="src/include/networking.h" /> | ||
| 274 | <Unit filename="src/include/popupsc.h" /> | 275 | <Unit filename="src/include/popupsc.h" /> |
| 275 | <Unit filename="src/include/proxyc.h" /> | 276 | <Unit filename="src/include/proxyc.h" /> |
| 276 | <Unit filename="src/include/resolverc.h" /> | 277 | <Unit filename="src/include/resolverc.h" /> |
| @@ -306,6 +307,9 @@ | @@ -306,6 +307,9 @@ | ||
| 306 | <Unit filename="src/mkfb/mkfb.c"> | 307 | <Unit filename="src/mkfb/mkfb.c"> |
| 307 | <Option compilerVar="CC" /> | 308 | <Option compilerVar="CC" /> |
| 308 | </Unit> | 309 | </Unit> |
| 310 | + <Unit filename="src/network_modules/unsecure.c"> | ||
| 311 | + <Option compilerVar="CC" /> | ||
| 312 | + </Unit> | ||
| 309 | <Unit filename="src/selection/actions.c"> | 313 | <Unit filename="src/selection/actions.c"> |
| 310 | <Option compilerVar="CC" /> | 314 | <Option compilerVar="CC" /> |
| 311 | </Unit> | 315 | </Unit> |
src/core/connect.c
| @@ -121,7 +121,7 @@ | @@ -121,7 +121,7 @@ | ||
| 121 | return 0; | 121 | return 0; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | - if(hSession->connection.sock > 0) | 124 | + if(hSession->network.module->is_connected(hSession)) |
| 125 | { | 125 | { |
| 126 | errno = EISCONN; | 126 | errno = EISCONN; |
| 127 | return 0; | 127 | return 0; |
| @@ -169,3 +169,41 @@ | @@ -169,3 +169,41 @@ | ||
| 169 | 169 | ||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | + static int bg_start_tls(H3270 *hSession, void *message) | ||
| 173 | + { | ||
| 174 | + | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + int lib3270_start_tls(H3270 *hSession) | ||
| 178 | + { | ||
| 179 | + int rc = 0; | ||
| 180 | + | ||
| 181 | + if(hSession->network.module->start_tls) | ||
| 182 | + { | ||
| 183 | + LIB3270_NETWORK_STATE state; | ||
| 184 | + memset(&state,0,sizeof(state)); | ||
| 185 | + | ||
| 186 | + non_blocking(hSession,False); | ||
| 187 | + | ||
| 188 | + rc = lib3270_run_task( | ||
| 189 | + hSession, | ||
| 190 | + (int(*)(H3270 *h, void *)) hSession->network.module->start_tls, | ||
| 191 | + &state | ||
| 192 | + ); | ||
| 193 | + | ||
| 194 | + if(state.popup) { | ||
| 195 | + if(lib3270_popup(hSession,state.popup,1)) { | ||
| 196 | + lib3270_disconnect(hSession); | ||
| 197 | + return rc; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + // User has selected "continue", ignore error. | ||
| 201 | + return 0; | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + return rc; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + |
src/core/iocalls.c
| @@ -299,19 +299,18 @@ static void internal_remove_poll(H3270 *session, void *id) | @@ -299,19 +299,18 @@ static void internal_remove_poll(H3270 *session, void *id) | ||
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | 301 | ||
| 302 | +/* | ||
| 302 | LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) | 303 | LIB3270_EXPORT void lib3270_remove_poll(H3270 *session, void *id) |
| 303 | { | 304 | { |
| 304 | debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id); | 305 | debug("%s(%d,%p)",__FUNCTION__,session->connection.sock,id); |
| 305 | remove_poll(session, id); | 306 | remove_poll(session, id); |
| 306 | } | 307 | } |
| 308 | +*/ | ||
| 307 | 309 | ||
| 308 | LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled) | 310 | LIB3270_EXPORT void lib3270_set_poll_state(H3270 *session, void *id, int enabled) |
| 309 | { | 311 | { |
| 310 | if(id) | 312 | if(id) |
| 311 | - { | ||
| 312 | - debug("%s: Polling on %d (%p) is %s",__FUNCTION__,session->connection.sock,id,(enabled ? "enabled" : "disabled")); | ||
| 313 | set_poll_state(session, id, enabled); | 313 | set_poll_state(session, id, enabled); |
| 314 | - } | ||
| 315 | } | 314 | } |
| 316 | 315 | ||
| 317 | LIB3270_EXPORT void lib3270_remove_poll_fd(H3270 *session, int fd) | 316 | 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 | @@ -349,7 +348,7 @@ LIB3270_EXPORT void lib3270_update_poll_fd(H3270 *session, int fd, LIB3270_IO_FL | ||
| 349 | } | 348 | } |
| 350 | 349 | ||
| 351 | 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 ) { | 350 | 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 ) { |
| 352 | - debug("%s(%d)",__FUNCTION__,session->connection.sock); | 351 | + debug("%s(%d)",__FUNCTION__,fd); |
| 353 | return add_poll(session,fd,flag,call,userdata); | 352 | return add_poll(session,fd,flag,call,userdata); |
| 354 | } | 353 | } |
| 355 | 354 | ||
| @@ -400,11 +399,10 @@ void x_except_on(H3270 *h) | @@ -400,11 +399,10 @@ void x_except_on(H3270 *h) | ||
| 400 | if(reading) | 399 | if(reading) |
| 401 | lib3270_remove_poll(h,h->xio.read); | 400 | lib3270_remove_poll(h,h->xio.read); |
| 402 | 401 | ||
| 403 | - h->xio.except = lib3270_add_poll_fd(h,h->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); | 402 | + h->xio.except = h->network.module->add_poll(h,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); |
| 404 | 403 | ||
| 405 | if(reading) | 404 | if(reading) |
| 406 | - h->xio.read = lib3270_add_poll_fd(h,h->connection.sock,LIB3270_IO_FLAG_READ,net_input,0); | ||
| 407 | - debug("%s",__FUNCTION__); | 405 | + h->xio.read = h->network.module->add_poll(h,LIB3270_IO_FLAG_READ,net_input,0); |
| 408 | 406 | ||
| 409 | } | 407 | } |
| 410 | 408 | ||
| @@ -522,61 +520,9 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo | @@ -522,61 +520,9 @@ LIB3270_EXPORT int lib3270_run_task(H3270 *hSession, int(*callback)(H3270 *h, vo | ||
| 522 | 520 | ||
| 523 | int non_blocking(H3270 *hSession, Boolean on) | 521 | int non_blocking(H3270 *hSession, Boolean on) |
| 524 | { | 522 | { |
| 525 | - | ||
| 526 | - if(hSession->connection.sock < 0) | 523 | + if(hSession->network.module->non_blocking,on) |
| 527 | return 0; | 524 | return 0; |
| 528 | 525 | ||
| 529 | -#ifdef WIN32 | ||
| 530 | - | ||
| 531 | - WSASetLastError(0); | ||
| 532 | - u_long iMode= on ? 1 : 0; | ||
| 533 | - | ||
| 534 | - if(ioctlsocket(hSession->connection.sock,FIONBIO,&iMode)) | ||
| 535 | - { | ||
| 536 | - lib3270_popup_dialog( hSession, | ||
| 537 | - LIB3270_NOTIFY_ERROR, | ||
| 538 | - _( "Connection error" ), | ||
| 539 | - _( "ioctlsocket(FIONBIO) failed." ), | ||
| 540 | - "%s", lib3270_win32_strerror(GetLastError())); | ||
| 541 | - return -1; | ||
| 542 | - } | ||
| 543 | - | ||
| 544 | -#else | ||
| 545 | - | ||
| 546 | - int f; | ||
| 547 | - | ||
| 548 | - if ((f = fcntl(hSession->connection.sock, F_GETFL, 0)) == -1) | ||
| 549 | - { | ||
| 550 | - lib3270_popup_dialog( hSession, | ||
| 551 | - LIB3270_NOTIFY_ERROR, | ||
| 552 | - _( "Socket error" ), | ||
| 553 | - _( "fcntl() error when getting socket state." ), | ||
| 554 | - _( "%s" ), strerror(errno) | ||
| 555 | - ); | ||
| 556 | - | ||
| 557 | - return -1; | ||
| 558 | - } | ||
| 559 | - | ||
| 560 | - if (on) | ||
| 561 | - f |= O_NDELAY; | ||
| 562 | - else | ||
| 563 | - f &= ~O_NDELAY; | ||
| 564 | - | ||
| 565 | - if (fcntl(hSession->connection.sock, F_SETFL, f) < 0) | ||
| 566 | - { | ||
| 567 | - lib3270_popup_dialog( hSession, | ||
| 568 | - LIB3270_NOTIFY_ERROR, | ||
| 569 | - _( "Socket error" ), | ||
| 570 | - on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ), | ||
| 571 | - _( "%s" ), strerror(errno) | ||
| 572 | - ); | ||
| 573 | - return -1; | ||
| 574 | - } | ||
| 575 | - | ||
| 576 | -#endif | ||
| 577 | - | ||
| 578 | - debug("Socket %d is now %s",hSession->connection.sock,(on ? "Non Blocking" : "Blocking")); | ||
| 579 | - | ||
| 580 | lib3270_set_poll_state(hSession,hSession->xio.read, on); | 526 | lib3270_set_poll_state(hSession,hSession->xio.read, on); |
| 581 | lib3270_set_poll_state(hSession,hSession->xio.write, on); | 527 | lib3270_set_poll_state(hSession,hSession->xio.write, on); |
| 582 | lib3270_set_poll_state(hSession,hSession->xio.except, on); | 528 | lib3270_set_poll_state(hSession,hSession->xio.except, on); |
src/core/linux/connect.c
| @@ -42,7 +42,7 @@ | @@ -42,7 +42,7 @@ | ||
| 42 | #include <unistd.h> | 42 | #include <unistd.h> |
| 43 | #include <fcntl.h> | 43 | #include <fcntl.h> |
| 44 | 44 | ||
| 45 | -#define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1; | 45 | +// #define SOCK_CLOSE(s) close(s->connection.sock); s->connection.sock = -1; |
| 46 | 46 | ||
| 47 | #include <stdlib.h> | 47 | #include <stdlib.h> |
| 48 | 48 | ||
| @@ -69,7 +69,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG | @@ -69,7 +69,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG | ||
| 69 | hSession->xio.write = NULL; | 69 | hSession->xio.write = NULL; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | - if(getsockopt(hSession->connection.sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0) | 72 | + if(hSession->network.module->getsockopt(hSession, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0) |
| 73 | { | 73 | { |
| 74 | lib3270_disconnect(hSession); | 74 | lib3270_disconnect(hSession); |
| 75 | lib3270_popup_dialog( | 75 | lib3270_popup_dialog( |
| @@ -88,16 +88,11 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG | @@ -88,16 +88,11 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG | ||
| 88 | return; | 88 | return; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | - hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); | ||
| 92 | - hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_READ,net_input,0); | 91 | + hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); |
| 92 | + hSession->xio.read = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_READ,net_input,0); | ||
| 93 | 93 | ||
| 94 | -#if defined(HAVE_LIBSSL) | ||
| 95 | - if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED) | ||
| 96 | - { | ||
| 97 | - if(ssl_negotiate(hSession)) | ||
| 98 | - return; | ||
| 99 | - } | ||
| 100 | -#endif | 94 | + if(lib3270_start_tls(hSession)) |
| 95 | + return; | ||
| 101 | 96 | ||
| 102 | lib3270_setup_session(hSession); | 97 | lib3270_setup_session(hSession); |
| 103 | lib3270_set_connected_initial(hSession); | 98 | lib3270_set_connected_initial(hSession); |
| @@ -238,8 +233,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG | @@ -238,8 +233,7 @@ static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG | ||
| 238 | lib3270_set_cstate(hSession, LIB3270_PENDING); | 233 | lib3270_set_cstate(hSession, LIB3270_PENDING); |
| 239 | lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); | 234 | lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); |
| 240 | 235 | ||
| 241 | - hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_WRITE,net_connected,0); | ||
| 242 | - // hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected); | 236 | + hSession->xio.write = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_WRITE,net_connected,0); |
| 243 | 237 | ||
| 244 | trace("%s: Connection in progress",__FUNCTION__); | 238 | trace("%s: Connection in progress",__FUNCTION__); |
| 245 | 239 |
src/core/model.c
src/core/rpq.c
| @@ -690,7 +690,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen | @@ -690,7 +690,7 @@ static int get_rpq_address(H3270 *hSession, unsigned char *buf, const int maxlen | ||
| 690 | void *src = NULL; | 690 | void *src = NULL; |
| 691 | int len = 0; | 691 | int len = 0; |
| 692 | 692 | ||
| 693 | - if(net_getsockname(hSession, &u, &addrlen) < 0) | 693 | + if(hSession->network.module->getsockname(hSession, (struct sockaddr *) &u, &addrlen) < 0) |
| 694 | return 0; | 694 | return 0; |
| 695 | SET16(buf, u.sa.sa_family); | 695 | SET16(buf, u.sa.sa_family); |
| 696 | x += 2; | 696 | x += 2; |
src/core/session.c
| @@ -74,7 +74,7 @@ void lib3270_session_free(H3270 *h) | @@ -74,7 +74,7 @@ void lib3270_session_free(H3270 *h) | ||
| 74 | 74 | ||
| 75 | shutdown_toggles(h); | 75 | shutdown_toggles(h); |
| 76 | 76 | ||
| 77 | -#ifdef SSL_ENABLE_CRL_CHECK | 77 | +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL) |
| 78 | if(h->ssl.crl.prefer) | 78 | if(h->ssl.crl.prefer) |
| 79 | { | 79 | { |
| 80 | free(h->ssl.crl.prefer); | 80 | free(h->ssl.crl.prefer); |
| @@ -281,7 +281,7 @@ void lib3270_reset_callbacks(H3270 *hSession) | @@ -281,7 +281,7 @@ void lib3270_reset_callbacks(H3270 *hSession) | ||
| 281 | memset(&hSession->cbk,0,sizeof(hSession->cbk)); | 281 | memset(&hSession->cbk,0,sizeof(hSession->cbk)); |
| 282 | 282 | ||
| 283 | hSession->cbk.write = lib3270_sock_send; | 283 | hSession->cbk.write = lib3270_sock_send; |
| 284 | - hSession->cbk.disconnect = lib3270_sock_disconnect; | 284 | +// hSession->cbk.disconnect = lib3270_sock_disconnect; |
| 285 | hSession->cbk.update = update_char; | 285 | hSession->cbk.update = update_char; |
| 286 | hSession->cbk.update_model = update_model; | 286 | hSession->cbk.update_model = update_model; |
| 287 | hSession->cbk.update_cursor = update_cursor; | 287 | hSession->cbk.update_cursor = update_cursor; |
| @@ -331,7 +331,6 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char | @@ -331,7 +331,6 @@ static void lib3270_session_init(H3270 *hSession, const char *model, const char | ||
| 331 | hSession->unlock_delay = 1; | 331 | hSession->unlock_delay = 1; |
| 332 | hSession->icrnl = 1; | 332 | hSession->icrnl = 1; |
| 333 | hSession->onlcr = 1; | 333 | hSession->onlcr = 1; |
| 334 | - hSession->connection.sock = -1; | ||
| 335 | hSession->model_num = -1; | 334 | hSession->model_num = -1; |
| 336 | hSession->connection.state = LIB3270_NOT_CONNECTED; | 335 | hSession->connection.state = LIB3270_NOT_CONNECTED; |
| 337 | hSession->oia.status = -1; | 336 | hSession->oia.status = -1; |
| @@ -446,7 +445,7 @@ H3270 * lib3270_session_new(const char *model) | @@ -446,7 +445,7 @@ H3270 * lib3270_session_new(const char *model) | ||
| 446 | hSession->ssl.protocol.max_version = 0; | 445 | hSession->ssl.protocol.max_version = 0; |
| 447 | #endif // HAVE_LIBSSL | 446 | #endif // HAVE_LIBSSL |
| 448 | 447 | ||
| 449 | -#ifdef SSL_ENABLE_CRL_CHECK | 448 | +#if defined(SSL_ENABLE_CRL_CHECK) && defined(HAVE_LIBSSL) |
| 450 | hSession->ssl.crl.download = 1; | 449 | hSession->ssl.crl.download = 1; |
| 451 | #endif // SSL_ENABLE_CRL_CHECK | 450 | #endif // SSL_ENABLE_CRL_CHECK |
| 452 | 451 |
src/core/telnet.c
| @@ -507,9 +507,11 @@ static void connection_complete(H3270 *session) | @@ -507,9 +507,11 @@ static void connection_complete(H3270 *session) | ||
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | 509 | ||
| 510 | +/* | ||
| 510 | LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) | 511 | LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) |
| 511 | { | 512 | { |
| 512 | - trace("%s",__FUNCTION__); | 513 | + LIB3270_NETWORK_STATE state; |
| 514 | + memset(&state,0,sizeof(state)); | ||
| 513 | 515 | ||
| 514 | #if defined(HAVE_LIBSSL) | 516 | #if defined(HAVE_LIBSSL) |
| 515 | if(hSession->ssl.con != NULL) | 517 | if(hSession->ssl.con != NULL) |
| @@ -527,37 +529,47 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) | @@ -527,37 +529,47 @@ LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession) | ||
| 527 | hSession->xio.write = 0; | 529 | hSession->xio.write = 0; |
| 528 | } | 530 | } |
| 529 | 531 | ||
| 530 | - if(hSession->connection.sock >= 0) | ||
| 531 | - { | ||
| 532 | - shutdown(hSession->connection.sock, 2); | ||
| 533 | - SOCK_CLOSE(hSession->connection.sock); | ||
| 534 | - hSession->connection.sock = -1; | ||
| 535 | - } | 532 | + hSession->network.module->disconnect(hSession->network.context,hSession,&state); |
| 536 | 533 | ||
| 537 | } | 534 | } |
| 535 | +*/ | ||
| 538 | 536 | ||
| 539 | /** | 537 | /** |
| 540 | - * @brief Shut down the socket. | 538 | + * @brief Disconnect from host. |
| 541 | */ | 539 | */ |
| 542 | -void net_disconnect(H3270 *session) | 540 | +void net_disconnect(H3270 *hSession) |
| 543 | { | 541 | { |
| 542 | + LIB3270_NETWORK_STATE state; | ||
| 543 | + memset(&state,0,sizeof(state)); | ||
| 544 | + | ||
| 545 | + // Disconnect from host | ||
| 544 | #if defined(HAVE_LIBSSL) | 546 | #if defined(HAVE_LIBSSL) |
| 545 | - set_ssl_state(session,LIB3270_SSL_UNSECURE); | ||
| 546 | -#endif // HAVE_LIBSSL | 547 | + if(hSession->ssl.con != NULL) |
| 548 | + { | ||
| 549 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | ||
| 550 | + SSL_shutdown(hSession->ssl.con); | ||
| 551 | + SSL_free(hSession->ssl.con); | ||
| 552 | + hSession->ssl.con = NULL; | ||
| 553 | + } | ||
| 554 | + else | ||
| 555 | + { | ||
| 556 | + set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | ||
| 557 | + } | ||
| 558 | +#endif | ||
| 547 | 559 | ||
| 548 | - session->cbk.disconnect(session); | 560 | + if(hSession->xio.write) |
| 561 | + { | ||
| 562 | + lib3270_remove_poll(hSession, hSession->xio.write); | ||
| 563 | + hSession->xio.write = 0; | ||
| 564 | + } | ||
| 549 | 565 | ||
| 550 | - trace_dsn(session,"SENT disconnect\n"); | 566 | + hSession->network.module->disconnect(hSession,&state); |
| 551 | 567 | ||
| 552 | - /* Restore terminal type to its default. */ | ||
| 553 | - /* | ||
| 554 | - if (session->termname == CN) | ||
| 555 | - session->termtype = session->full_model_name; | ||
| 556 | - */ | 568 | + trace_dsn(hSession,"SENT disconnect\n"); |
| 557 | 569 | ||
| 558 | // We're not connected to an LU any more. | 570 | // We're not connected to an LU any more. |
| 559 | - session->lu.associated = CN; | ||
| 560 | - status_lu(session,CN); | 571 | + hSession->lu.associated = CN; |
| 572 | + status_lu(hSession,CN); | ||
| 561 | 573 | ||
| 562 | } | 574 | } |
| 563 | 575 | ||
| @@ -618,8 +630,8 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED | @@ -618,8 +630,8 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED | ||
| 618 | for (;;) | 630 | for (;;) |
| 619 | #endif | 631 | #endif |
| 620 | { | 632 | { |
| 621 | - if (hSession->connection.sock < 0) | ||
| 622 | - return; | 633 | +// if (hSession->connection.sock < 0) |
| 634 | +// return; | ||
| 623 | 635 | ||
| 624 | #if defined(X3270_ANSI) | 636 | #if defined(X3270_ANSI) |
| 625 | hSession->ansi_data = 0; | 637 | hSession->ansi_data = 0; |
| @@ -629,9 +641,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED | @@ -629,9 +641,9 @@ void net_input(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED | ||
| 629 | if (hSession->ssl.con != NULL) | 641 | if (hSession->ssl.con != NULL) |
| 630 | nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ); | 642 | nr = SSL_read(hSession->ssl.con, (char *) buffer, BUFSZ); |
| 631 | else | 643 | else |
| 632 | - nr = recv(hSession->connection.sock, (char *) buffer, BUFSZ, 0); | 644 | + nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ); |
| 633 | #else | 645 | #else |
| 634 | - nr = recv(hSession->connection.sock, (char *) buffer, BUFSZ, 0); | 646 | + nr = hSession->network.module->recv(hSession->network.context, buffer, BUFSZ); |
| 635 | #endif // HAVE_LIBSSL | 647 | #endif // HAVE_LIBSSL |
| 636 | 648 | ||
| 637 | if (nr < 0) | 649 | if (nr < 0) |
| @@ -1637,7 +1649,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf | @@ -1637,7 +1649,7 @@ LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf | ||
| 1637 | else | 1649 | else |
| 1638 | rc = send(hSession->connection.sock, (const char *) buf, len, 0); | 1650 | rc = send(hSession->connection.sock, (const char *) buf, len, 0); |
| 1639 | #else | 1651 | #else |
| 1640 | - rc = send(hSession->connection.sock, (const char *) buf, len, 0); | 1652 | + rc = hSession->network.module->send(hSession, buf, len); |
| 1641 | #endif // HAVE_LIBSSL | 1653 | #endif // HAVE_LIBSSL |
| 1642 | 1654 | ||
| 1643 | if(rc > 0) | 1655 | if(rc > 0) |
| @@ -2650,9 +2662,12 @@ void net_abort(H3270 *hSession) | @@ -2650,9 +2662,12 @@ void net_abort(H3270 *hSession) | ||
| 2650 | #endif /*]*/ | 2662 | #endif /*]*/ |
| 2651 | 2663 | ||
| 2652 | /* Return the local address for the socket. */ | 2664 | /* Return the local address for the socket. */ |
| 2665 | + | ||
| 2666 | +/* | ||
| 2653 | int net_getsockname(const H3270 *session, void *buf, int *len) | 2667 | int net_getsockname(const H3270 *session, void *buf, int *len) |
| 2654 | { | 2668 | { |
| 2655 | if (session->connection.sock < 0) | 2669 | if (session->connection.sock < 0) |
| 2656 | return -1; | 2670 | return -1; |
| 2657 | return getsockname(session->connection.sock, buf, (socklen_t *)(void *)len); | 2671 | return getsockname(session->connection.sock, buf, (socklen_t *)(void *)len); |
| 2658 | } | 2672 | } |
| 2673 | +*/ |
src/core/toggles/init.c
| @@ -79,21 +79,19 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle | @@ -79,21 +79,19 @@ static void toggle_nop(H3270 GNUC_UNUSED(*session), const struct lib3270_toggle | ||
| 79 | 79 | ||
| 80 | static void toggle_keepalive(H3270 *session, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt)) | 80 | static void toggle_keepalive(H3270 *session, const struct lib3270_toggle GNUC_UNUSED(*t), LIB3270_TOGGLE_TYPE GNUC_UNUSED(tt)) |
| 81 | { | 81 | { |
| 82 | - if(session->connection.sock > 0) | ||
| 83 | - { | ||
| 84 | - // Update keep-alive option | ||
| 85 | - int optval = t->value ? 1 : 0; | 82 | + // Update keep-alive option |
| 83 | + int optval = t->value ? 1 : 0; | ||
| 86 | 84 | ||
| 87 | - if (setsockopt(session->connection.sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0) | ||
| 88 | - { | 85 | + if(session->network.module->setsockopt(session, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) |
| 86 | + { | ||
| 87 | + if(errno != ENOTCONN) | ||
| 89 | popup_a_sockerr(session, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); | 88 | popup_a_sockerr(session, _( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); |
| 90 | - } | ||
| 91 | - else | ||
| 92 | - { | ||
| 93 | - trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | } | 89 | } |
| 90 | + else | ||
| 91 | + { | ||
| 92 | + trace_dsn(session,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); | ||
| 93 | + } | ||
| 94 | + | ||
| 97 | } | 95 | } |
| 98 | 96 | ||
| 99 | static void toggle_connect(H3270 *hSession, const struct lib3270_toggle *toggle, LIB3270_TOGGLE_TYPE tt) | 97 | static void toggle_connect(H3270 *hSession, const struct lib3270_toggle *toggle, LIB3270_TOGGLE_TYPE tt) |
src/core/util.c
| @@ -516,6 +516,7 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr) | @@ -516,6 +516,7 @@ LIB3270_EXPORT LIB3270_POINTER lib3270_get_pointer(H3270 *hSession, int baddr) | ||
| 516 | 516 | ||
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | +/* | ||
| 519 | LIB3270_EXPORT int lib3270_getpeername(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) | 520 | LIB3270_EXPORT int lib3270_getpeername(H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) |
| 520 | { | 521 | { |
| 521 | CHECK_SESSION_HANDLE(hSession); | 522 | CHECK_SESSION_HANDLE(hSession); |
| @@ -544,7 +545,7 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s | @@ -544,7 +545,7 @@ LIB3270_EXPORT int lib3270_getsockname(H3270 *hSession, struct sockaddr *addr, s | ||
| 544 | 545 | ||
| 545 | return getsockname(hSession->connection.sock, addr, addrlen); | 546 | return getsockname(hSession->connection.sock, addr, addrlen); |
| 546 | } | 547 | } |
| 547 | - | 548 | +*/ |
| 548 | static int xdigit_value(const char scanner) | 549 | static int xdigit_value(const char scanner) |
| 549 | { | 550 | { |
| 550 | 551 |
src/include/internals.h
| @@ -39,6 +39,7 @@ | @@ -39,6 +39,7 @@ | ||
| 39 | #include <lib3270/session.h> | 39 | #include <lib3270/session.h> |
| 40 | #include <lib3270/actions.h> | 40 | #include <lib3270/actions.h> |
| 41 | #include <lib3270/popup.h> | 41 | #include <lib3270/popup.h> |
| 42 | +#include <networking.h> | ||
| 42 | 43 | ||
| 43 | #if defined(HAVE_LIBSSL) | 44 | #if defined(HAVE_LIBSSL) |
| 44 | #include <openssl/ssl.h> | 45 | #include <openssl/ssl.h> |
| @@ -319,12 +320,22 @@ struct _h3270 | @@ -319,12 +320,22 @@ struct _h3270 | ||
| 319 | { | 320 | { |
| 320 | struct lib3270_session_callbacks cbk; ///< @brief Callback table - Always the first one. | 321 | struct lib3270_session_callbacks cbk; ///< @brief Callback table - Always the first one. |
| 321 | 322 | ||
| 322 | - // Session info | ||
| 323 | - char id; ///< @brief Session Identifier. | 323 | + /// @brief Session Identifier. |
| 324 | + char id; | ||
| 325 | + | ||
| 326 | + // Network | ||
| 327 | + struct { | ||
| 328 | + | ||
| 329 | + /// @brief Network module. | ||
| 330 | + const LIB3270_NET_MODULE * module; | ||
| 331 | + | ||
| 332 | + /// @brief Network context. | ||
| 333 | + LIB3270_NET_CONTEXT * context; | ||
| 334 | + | ||
| 335 | + } network; | ||
| 324 | 336 | ||
| 325 | // Connection info | 337 | // Connection info |
| 326 | struct { | 338 | struct { |
| 327 | - int sock; ///< @brief Network socket. | ||
| 328 | LIB3270_CSTATE state; ///< @brief Connection state. | 339 | LIB3270_CSTATE state; ///< @brief Connection state. |
| 329 | } connection; | 340 | } connection; |
| 330 | 341 | ||
| @@ -745,7 +756,7 @@ LIB3270_INTERNAL void toggle_rectselect(H3270 *session, const struct lib3270_tog | @@ -745,7 +756,7 @@ LIB3270_INTERNAL void toggle_rectselect(H3270 *session, const struct lib3270_tog | ||
| 745 | LIB3270_INTERNAL void remove_input_calls(H3270 *session); | 756 | LIB3270_INTERNAL void remove_input_calls(H3270 *session); |
| 746 | 757 | ||
| 747 | LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf, int len); | 758 | LIB3270_INTERNAL int lib3270_sock_send(H3270 *hSession, unsigned const char *buf, int len); |
| 748 | -LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); | 759 | +// LIB3270_INTERNAL void lib3270_sock_disconnect(H3270 *hSession); |
| 749 | 760 | ||
| 750 | LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); | 761 | LIB3270_INTERNAL int lib3270_default_event_dispatcher(H3270 *hSession, int block); |
| 751 | 762 | ||
| @@ -871,3 +882,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | @@ -871,3 +882,11 @@ LIB3270_INTERNAL int non_blocking(H3270 *session, Boolean on); | ||
| 871 | 882 | ||
| 872 | /// @brief Fire CState change. | 883 | /// @brief Fire CState change. |
| 873 | LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate); | 884 | LIB3270_INTERNAL int lib3270_set_cstate(H3270 *hSession, LIB3270_CSTATE cstate); |
| 885 | + | ||
| 886 | + inline LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession) { | ||
| 887 | + return hSession->network.context; | ||
| 888 | + } | ||
| 889 | + | ||
| 890 | + LIB3270_INTERNAL int lib3270_start_tls(H3270 *hSession); | ||
| 891 | + | ||
| 892 | + |
src/include/lib3270/session.h
| @@ -49,7 +49,7 @@ | @@ -49,7 +49,7 @@ | ||
| 49 | struct lib3270_session_callbacks | 49 | struct lib3270_session_callbacks |
| 50 | { | 50 | { |
| 51 | int (*write)(H3270 *hSession, unsigned const char *buf, int len); | 51 | int (*write)(H3270 *hSession, unsigned const char *buf, int len); |
| 52 | - void (*disconnect)(H3270 *hSession); | 52 | +// void (*disconnect)(H3270 *hSession); |
| 53 | 53 | ||
| 54 | void (*configure)(H3270 *session, unsigned short rows, unsigned short cols); | 54 | void (*configure)(H3270 *session, unsigned short rows, unsigned short cols); |
| 55 | void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor); | 55 | void (*update)(H3270 *session, int baddr, unsigned char c, unsigned short attr, unsigned char cursor); |
| @@ -0,0 +1,141 @@ | @@ -0,0 +1,141 @@ | ||
| 1 | +/* | ||
| 2 | + * "Software G3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | ||
| 3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | ||
| 4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | ||
| 5 | + * | ||
| 6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | ||
| 7 | + * | ||
| 8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | ||
| 9 | + * os termos da GPL v.2 - Licença Pública Geral ', conforme publicado pela | ||
| 10 | + * Free Software Foundation. | ||
| 11 | + * | ||
| 12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | ||
| 13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | ||
| 14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | ||
| 15 | + * obter mais detalhes. | ||
| 16 | + * | ||
| 17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | ||
| 18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | ||
| 19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | + * | ||
| 21 | + * Este programa está nomeado como networking.h e possui - linhas de código. | ||
| 22 | + * | ||
| 23 | + * Contatos: | ||
| 24 | + * | ||
| 25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | ||
| 26 | + * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça) | ||
| 27 | + * | ||
| 28 | + */ | ||
| 29 | + | ||
| 30 | +#ifndef LIB3270_NETWORKING_H_INCLUDED | ||
| 31 | + | ||
| 32 | + #define LIB3270_NETWORKING_H_INCLUDED | ||
| 33 | + | ||
| 34 | + #include <lib3270/popup.h> | ||
| 35 | + #include <sys/socket.h> | ||
| 36 | + | ||
| 37 | + typedef struct lib3270_network_state { | ||
| 38 | + | ||
| 39 | + int syserror; ///< @brief System error (errno) | ||
| 40 | +#ifdef _WIN32 | ||
| 41 | + DWORD winerror; ///< @brief Win32 error got from GetLastError() | ||
| 42 | +#endif // _WIN32 | ||
| 43 | + | ||
| 44 | + const LIB3270_POPUP *popup; /// @brief Detailed info for popup. | ||
| 45 | + | ||
| 46 | + } LIB3270_NETWORK_STATE; | ||
| 47 | + | ||
| 48 | + typedef struct _lib3270_new_context LIB3270_NET_CONTEXT; | ||
| 49 | + | ||
| 50 | + typedef struct lib3270_net_module { | ||
| 51 | + | ||
| 52 | + const char * name; ///< @brief The network module name. | ||
| 53 | + | ||
| 54 | + /// @brief Initialize network module | ||
| 55 | + /// | ||
| 56 | + /// @param hSession TN3270 session. | ||
| 57 | + /// @param state Pointer to state message. | ||
| 58 | + /// | ||
| 59 | + /// @return Allocated network context. | ||
| 60 | + /// | ||
| 61 | + /// @retval NULL Initialization failed. | ||
| 62 | + /// | ||
| 63 | + LIB3270_NET_CONTEXT * (*init)(H3270 *hSession, LIB3270_NETWORK_STATE *state); | ||
| 64 | + | ||
| 65 | + /// @brief Deinitialize network module. | ||
| 66 | + /// | ||
| 67 | + /// @param context Network context. | ||
| 68 | + /// @param hSession TN3270 session. | ||
| 69 | + /// @param state Pointer to state message. | ||
| 70 | + /// | ||
| 71 | + void (*deinit)(H3270 *hSession, LIB3270_NETWORK_STATE *state); | ||
| 72 | + | ||
| 73 | + /// @brief Connect to host. | ||
| 74 | + /// | ||
| 75 | + /// @param context Network context. | ||
| 76 | + /// @param hSession TN3270 session. | ||
| 77 | + /// @param seconds Seconds for timeout. | ||
| 78 | + /// @param state Pointer to state message. | ||
| 79 | + /// | ||
| 80 | + int (*connect)(H3270 *hSession, int seconds, LIB3270_NETWORK_STATE *state); | ||
| 81 | + | ||
| 82 | + /// @brief Disconnect from host. | ||
| 83 | + /// | ||
| 84 | + /// @param context Network context. | ||
| 85 | + /// @param hSession TN3270 session. | ||
| 86 | + /// @param state Pointer to state message. | ||
| 87 | + /// | ||
| 88 | + int (*disconnect)(H3270 *hSession, LIB3270_NETWORK_STATE *state); | ||
| 89 | + | ||
| 90 | + int (*start_tls)(H3270 *hSession, LIB3270_NETWORK_STATE *msg); | ||
| 91 | + | ||
| 92 | + /// @brief Send on network context. | ||
| 93 | + /// | ||
| 94 | + /// @return Positive on data received, negative on error. | ||
| 95 | + /// | ||
| 96 | + ssize_t (*send)(H3270 *hSession, const void *buffer, size_t length); | ||
| 97 | + | ||
| 98 | + /// @brief Receive on network context. | ||
| 99 | + /// | ||
| 100 | + /// @return Positive on data received, negative on error. | ||
| 101 | + /// | ||
| 102 | + /// @retval -ENOTCONN Not connected to host. | ||
| 103 | + /// | ||
| 104 | + ssize_t (*recv)(H3270 *hSession, void *buf, size_t len); | ||
| 105 | + | ||
| 106 | + /// @brief Add socket in poll list. | ||
| 107 | + void * (*add_poll)(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata); | ||
| 108 | + | ||
| 109 | + /// @brief Set non blocking mode. | ||
| 110 | + /// | ||
| 111 | + /// @retval 0 Not connected or Success. | ||
| 112 | + /// @retval -1 Failed (popup was sent). | ||
| 113 | + int (*non_blocking)(H3270 *hSession, const unsigned char on); | ||
| 114 | + | ||
| 115 | + /// @brief Check if the session is online. | ||
| 116 | + /// | ||
| 117 | + /// @retval 0 The session is offline. | ||
| 118 | + int (*is_connected)(H3270 *hSession); | ||
| 119 | + | ||
| 120 | + /// @brief get socket name. | ||
| 121 | + /// | ||
| 122 | + /// @return On success, zero is returned. On error, -1 is returned, and errno is set appropriately. | ||
| 123 | + /// | ||
| 124 | + /// @retval 0 Success. | ||
| 125 | + /// @retval -1 Error (errno is set). | ||
| 126 | + int (*getsockname)(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen); | ||
| 127 | + | ||
| 128 | + /// @brief Set socket options. | ||
| 129 | + int (*setsockopt)(H3270 *hSession, int level, int optname, void *optval, size_t optlen); | ||
| 130 | + | ||
| 131 | + /// @brief Get socket options. | ||
| 132 | + int (*getsockopt)(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen); | ||
| 133 | + | ||
| 134 | + } LIB3270_NET_MODULE; | ||
| 135 | + | ||
| 136 | + LIB3270_NET_CONTEXT * lib3270_get_net_context(H3270 *hSession); | ||
| 137 | + LIB3270_NET_CONTEXT * lib3270_get_default_net_context(void); | ||
| 138 | + | ||
| 139 | + | ||
| 140 | +#endif // LIB3270_NETWORKING_H_INCLUDED | ||
| 141 | + |
src/include/telnetc.h
| @@ -62,4 +62,4 @@ LIB3270_INTERNAL void space3270out(H3270 *hSession, int n); | @@ -62,4 +62,4 @@ LIB3270_INTERNAL void space3270out(H3270 *hSession, int n); | ||
| 62 | #define trace_netdata(direction, buf, len) /* */ | 62 | #define trace_netdata(direction, buf, len) /* */ |
| 63 | #endif // X3270_TRACE | 63 | #endif // X3270_TRACE |
| 64 | 64 | ||
| 65 | -LIB3270_INTERNAL int net_getsockname(const H3270 *h3270, void *buf, int *len); | 65 | +// LIB3270_INTERNAL int net_getsockname(const H3270 *h3270, void *buf, int *len); |
| @@ -0,0 +1,193 @@ | @@ -0,0 +1,193 @@ | ||
| 1 | +/* | ||
| 2 | + * "Software PW3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | ||
| 3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | ||
| 4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | ||
| 5 | + * | ||
| 6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | ||
| 7 | + * | ||
| 8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | ||
| 9 | + * os termos da GPL v.2 - Licença Pública Geral ', conforme publicado pela | ||
| 10 | + * Free Software Foundation. | ||
| 11 | + * | ||
| 12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | ||
| 13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | ||
| 14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | ||
| 15 | + * obter mais detalhes. | ||
| 16 | + * | ||
| 17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | ||
| 18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | ||
| 19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 20 | + * | ||
| 21 | + * Este programa está nomeado como networking.h e possui - linhas de código. | ||
| 22 | + * | ||
| 23 | + * Contatos: | ||
| 24 | + * | ||
| 25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | ||
| 26 | + * erico.mendonca@gmail.com (Erico Mascarenhas de Mendonça) | ||
| 27 | + * | ||
| 28 | + */ | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * @brief Default networking methods. | ||
| 32 | + * | ||
| 33 | + */ | ||
| 34 | + | ||
| 35 | + #include <config.h> | ||
| 36 | + #ifdef _WIN32 | ||
| 37 | + #include <winsock.h> | ||
| 38 | + #include <windows.h> | ||
| 39 | + #endif // _WIN32 | ||
| 40 | + | ||
| 41 | + #include <internals.h> | ||
| 42 | + #include <networking.h> | ||
| 43 | + | ||
| 44 | + struct _lib3270_new_context { | ||
| 45 | + int sock; | ||
| 46 | + }; | ||
| 47 | + | ||
| 48 | + LIB3270_NET_CONTEXT * unsecure_network_init(H3270 *hSession, LIB3270_NETWORK_STATE *state) { | ||
| 49 | + | ||
| 50 | + LIB3270_NET_CONTEXT * context = lib3270_malloc(sizeof(LIB3270_NET_CONTEXT)); | ||
| 51 | + | ||
| 52 | + context->sock = -1; | ||
| 53 | + | ||
| 54 | + return context; | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + void unsecure_network_deinit(H3270 *hSession, LIB3270_NETWORK_STATE *state) { | ||
| 58 | + unsecure_network_disconnect(hSession->network.context,hSession,state); | ||
| 59 | + lib3270_free(context); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | +int unsecure_network_disconnect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { | ||
| 63 | + | ||
| 64 | + debug("%s",__FUNCTION__); | ||
| 65 | + if(context->sock >= 0) { | ||
| 66 | + shutdown(hSession.network.context->sock, 2); | ||
| 67 | + close(hSession->network.context->sock); | ||
| 68 | + hSession.network.context->sock = -1; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +ssize_t unsecure_network_send(H3270 *hSession, const void *buffer, size_t length) { | ||
| 74 | + | ||
| 75 | + if(hSession->network.context->sock < 0) { | ||
| 76 | + return -(errno = ENOTCONN); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + ssize_t bytes = send(hSession->network.context->sock,buffer,length,0); | ||
| 80 | + | ||
| 81 | + if(bytes < 0) | ||
| 82 | + return -errno; | ||
| 83 | + | ||
| 84 | + return 0; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +ssize_t unsecure_network_recv(H3270 *hSession, void *buf, size_t len) { | ||
| 88 | + | ||
| 89 | + if(hSession->network.context->sock < 0) { | ||
| 90 | + return -(errno = ENOTCONN); | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + ssize_t bytes = recv(hSession->network.context->sock, (char *) buffer, len, 0); | ||
| 94 | + | ||
| 95 | + if(bytes < 0) { | ||
| 96 | + return -errno; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + return bytes; | ||
| 100 | +} | ||
| 101 | + | ||
| 102 | +int unsecure_getsockname(const H3270 *hSession, struct sockaddr *addr, socklen_t *addrlen) { | ||
| 103 | + if(hSession->network.context->sock < 0) | ||
| 104 | + return -(errno = ENOTCONN); | ||
| 105 | + return getsockname(hSession->network.context->sock, buf, addrlen); | ||
| 106 | +} | ||
| 107 | + | ||
| 108 | +void * unsecure_add_poll(H3270 *hSession, LIB3270_IO_FLAG flag, void(*call)(H3270 *, int, LIB3270_IO_FLAG, void *), void *userdata) { | ||
| 109 | + return lib3270_add_poll_fd(hSession,hSession->network.context->sock,flag,call,userdata); | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +int unsecure_non_blocking(H3270 *hSession, const unsigned char on) { | ||
| 113 | + | ||
| 114 | + if(hSession->network.context->sock < 0) | ||
| 115 | + return 0; | ||
| 116 | + | ||
| 117 | +#ifdef WIN32 | ||
| 118 | + | ||
| 119 | + WSASetLastError(0); | ||
| 120 | + u_long iMode= on ? 1 : 0; | ||
| 121 | + | ||
| 122 | + if(ioctlsocket(hSession->network.context->sock,FIONBIO,&iMode)) | ||
| 123 | + { | ||
| 124 | + lib3270_popup_dialog( hSession, | ||
| 125 | + LIB3270_NOTIFY_ERROR, | ||
| 126 | + _( "Connection error" ), | ||
| 127 | + _( "ioctlsocket(FIONBIO) failed." ), | ||
| 128 | + "%s", lib3270_win32_strerror(GetLastError())); | ||
| 129 | + return -1; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | +#else | ||
| 133 | + | ||
| 134 | + int f; | ||
| 135 | + | ||
| 136 | + if ((f = fcntl(hSession->network.context->sock, F_GETFL, 0)) == -1) | ||
| 137 | + { | ||
| 138 | + lib3270_popup_dialog( hSession, | ||
| 139 | + LIB3270_NOTIFY_ERROR, | ||
| 140 | + _( "Socket error" ), | ||
| 141 | + _( "fcntl() error when getting socket state." ), | ||
| 142 | + _( "%s" ), strerror(errno) | ||
| 143 | + ); | ||
| 144 | + | ||
| 145 | + return -1; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + if (on) | ||
| 149 | + f |= O_NDELAY; | ||
| 150 | + else | ||
| 151 | + f &= ~O_NDELAY; | ||
| 152 | + | ||
| 153 | + if (fcntl(hSession->network.context->sock, F_SETFL, f) < 0) | ||
| 154 | + { | ||
| 155 | + lib3270_popup_dialog( hSession, | ||
| 156 | + LIB3270_NOTIFY_ERROR, | ||
| 157 | + _( "Socket error" ), | ||
| 158 | + on ? _( "Can't set socket to blocking mode." ) : _( "Can't set socket to non blocking mode" ), | ||
| 159 | + _( "%s" ), strerror(errno) | ||
| 160 | + ); | ||
| 161 | + return -1; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | +#endif | ||
| 165 | + | ||
| 166 | + debug("Socket %d is now %s",hSession->network.context->sock,(on ? "Non Blocking" : "Blocking")); | ||
| 167 | + | ||
| 168 | +} | ||
| 169 | + | ||
| 170 | +int unsecure_is_connected(H3270 *hSession) { | ||
| 171 | + return hSession->network.context.sock > 0; | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +int unsecure_setsockopt(H3270 *hSession, int level, int optname, const void *optval, size_t optlen) { | ||
| 175 | + | ||
| 176 | + if(hSession->network.context.sock < 0) { | ||
| 177 | + errno = ENOTCONN; | ||
| 178 | + return -1; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + return setsockopt(hSession->network.context.sock, level, optname, optval, optlen); | ||
| 182 | + | ||
| 183 | +} | ||
| 184 | + | ||
| 185 | +int unsecure_getsockopt(H3270 *hSession, int level, int optname, void *optval, socklen_t *optlen) { | ||
| 186 | + | ||
| 187 | + if(hSession->network.context.sock < 0) { | ||
| 188 | + errno = ENOTCONN; | ||
| 189 | + return -1; | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + return getsockopt(hSession->network.context.sock, level, optname, optval, optlen) | ||
| 193 | +} |