Commit ca836b4339a24c72eb6fc85568d24e1d8a509a3b
1 parent
ddc05b6e
Exists in
master
and in
3 other branches
Implementing windows methods.
Showing
9 changed files
with
273 additions
and
261 deletions
Show diff stats
src/core/rpq.c
| ... | ... | @@ -455,7 +455,10 @@ static int get_rpq_timezone(H3270 *hSession) |
| 455 | 455 | delta = difftime(mktime(&here_tm), mktime(utc_tm)) / 60L; |
| 456 | 456 | } |
| 457 | 457 | |
| 458 | - /* sanity check: difference cannot exceed +/- 12 hours */ | |
| 458 | + // sanity check: difference cannot exceed +/- 12 hours | |
| 459 | +#ifdef _WIN32 | |
| 460 | + #pragma GCC diagnostic ignored "-Wabsolute-value" | |
| 461 | +#endif // _WIN32 | |
| 459 | 462 | if (labs(delta) > 720L) |
| 460 | 463 | rpq_warning(hSession, _("RPQ timezone exceeds 12 hour UTC offset")); |
| 461 | 464 | return (labs(delta) > 720L)? 3 : (int) delta; | ... | ... |
src/core/windows/connect.c
| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin |
| 19 | 19 | * St, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | 20 | * |
| 21 | - * Este programa está nomeado como connect.c e possui - linhas de código. | |
| 21 | + * Este programa está nomeado como - e possui - linhas de código. | |
| 22 | 22 | * |
| 23 | 23 | * Contatos: |
| 24 | 24 | * |
| ... | ... | @@ -29,284 +29,324 @@ |
| 29 | 29 | |
| 30 | 30 | #include <config.h> |
| 31 | 31 | |
| 32 | -// Compiling for WinXP or later: Expose getaddrinfo()/freeaddrinfo(). | |
| 33 | -#undef _WIN32_WINNT | |
| 34 | -#define _WIN32_WINNT 0x0501 | |
| 35 | - | |
| 36 | 32 | #include <winsock2.h> |
| 37 | 33 | #include <windows.h> |
| 38 | 34 | #include <ws2tcpip.h> |
| 39 | 35 | |
| 40 | 36 | #include <internals.h> |
| 41 | -#include <errno.h> | |
| 42 | -#include <lib3270/trace.h> | |
| 43 | 37 | #include <lib3270/log.h> |
| 44 | -#include <lib3270/toggle.h> | |
| 45 | - | |
| 46 | -#ifdef HAVE_ICONV | |
| 47 | - #include <iconv.h> | |
| 48 | -#endif // HAVE_ICONV | |
| 38 | +#include <lib3270/internals.h> | |
| 49 | 39 | |
| 40 | +#include "telnetc.h" | |
| 50 | 41 | #include "hostc.h" |
| 51 | 42 | #include "trace_dsc.h" |
| 52 | -#include "telnetc.h" | |
| 53 | 43 | #include "screen.h" |
| 54 | 44 | |
| 55 | -#include <lib3270/internals.h> | |
| 56 | - | |
| 57 | 45 | /*---[ Implement ]-------------------------------------------------------------------------------*/ |
| 58 | 46 | |
| 47 | + static int sock_connect(H3270 *hSession, int sock, const struct sockaddr *address, socklen_t address_len) { | |
| 59 | 48 | |
| 60 | -static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno)) | |
| 61 | -{ | |
| 62 | - int err; | |
| 63 | - socklen_t len = sizeof(err); | |
| 49 | + lib3270_socket_set_non_blocking(hSession, sock, 1); | |
| 64 | 50 | |
| 65 | - if(hSession->xio.write) { | |
| 66 | - trace("%s write=%p",__FUNCTION__,hSession->xio.write); | |
| 67 | - lib3270_remove_poll(hSession, hSession->xio.write); | |
| 68 | - hSession->xio.write = NULL; | |
| 69 | - } | |
| 51 | + WSASetLastError(0); | |
| 70 | 52 | |
| 71 | - if(getsockopt(hSession->connection.sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0) | |
| 72 | - { | |
| 73 | - lib3270_disconnect(hSession); | |
| 74 | - lib3270_popup_dialog( hSession, | |
| 75 | - LIB3270_NOTIFY_ERROR, | |
| 76 | - _( "Network error" ), | |
| 77 | - _( "Unable to get connection state." ), | |
| 78 | - "%s", lib3270_win32_strerror(WSAGetLastError()) | |
| 79 | - ); | |
| 80 | - return; | |
| 81 | - } | |
| 82 | - else if(err) | |
| 83 | - { | |
| 84 | - lib3270_autoptr(char) body = lib3270_strdup_printf(_("%s (rc=%d)"),strerror(err),err); | |
| 53 | + if(!connect(sock,address,address_len)) | |
| 54 | + return 0; | |
| 85 | 55 | |
| 86 | - connection_failed(hSession,body); | |
| 87 | - return; | |
| 88 | - } | |
| 56 | + debug("WSAGetLastError=%d",(int) WSAGetLastError()); | |
| 89 | 57 | |
| 90 | - hSession->xio.except = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); | |
| 91 | - hSession->xio.read = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_READ,net_input,0); | |
| 58 | + unsigned int timer; | |
| 59 | + for(timer = 0; timer < hSession->connection.timeout; timer += 10) { | |
| 60 | + | |
| 61 | + if(lib3270_get_connection_state(hSession) != LIB3270_CONNECTING) | |
| 62 | + return errno = ECANCELED; | |
| 63 | + | |
| 64 | + struct timeval tm; | |
| 65 | + | |
| 66 | + tm.tv_sec = 0; | |
| 67 | + tm.tv_usec = 10; | |
| 68 | + | |
| 69 | + fd_set wfds; | |
| 70 | + FD_ZERO(&wfds); | |
| 71 | + FD_SET(sock, &wfds); | |
| 72 | + | |
| 73 | + int ns = select(sock+1, NULL, &wfds, NULL, &tm); | |
| 74 | + | |
| 75 | + if (ns < 0 && errno != EINTR) { | |
| 76 | + return errno; | |
| 77 | + } | |
| 78 | + | |
| 79 | + if(FD_ISSET(sock, &wfds)) | |
| 80 | + return 0; | |
| 92 | 81 | |
| 93 | -#if defined(HAVE_LIBSSL) | |
| 94 | - if(hSession->ssl.con && hSession->ssl.state == LIB3270_SSL_UNDEFINED) | |
| 95 | - { | |
| 96 | - if(ssl_negotiate(hSession)) | |
| 97 | - return; | |
| 98 | 82 | } |
| 99 | -#endif | |
| 100 | 83 | |
| 101 | - lib3270_setup_session(hSession); | |
| 102 | - lib3270_set_connected_initial(hSession); | |
| 84 | + return errno = ETIMEDOUT; | |
| 103 | 85 | |
| 104 | -} | |
| 86 | + } | |
| 105 | 87 | |
| 106 | -static void sockstart(H3270 *session) | |
| 107 | -{ | |
| 108 | - static int initted = 0; | |
| 109 | - WORD wVersionRequested; | |
| 110 | - WSADATA wsaData; | |
| 111 | 88 | |
| 112 | - if (initted) | |
| 113 | - return; | |
| 89 | + int lib3270_network_connect(H3270 *hSession, LIB3270_NETWORK_STATE *state) { | |
| 114 | 90 | |
| 115 | - initted = 1; | |
| 91 | + // Do we need to start wsa? | |
| 92 | + static unsigned char wsa_is_started = 0; | |
| 93 | + if(!wsa_is_started) { | |
| 116 | 94 | |
| 117 | - wVersionRequested = MAKEWORD(2, 2); | |
| 95 | + WORD wVersionRequested; | |
| 96 | + WSADATA wsaData; | |
| 118 | 97 | |
| 119 | - if (WSAStartup(wVersionRequested, &wsaData) != 0) | |
| 120 | - { | |
| 121 | - lib3270_popup_dialog( session, | |
| 122 | - LIB3270_NOTIFY_CRITICAL, | |
| 123 | - _( "Network startup error" ), | |
| 124 | - _( "WSAStartup failed" ), | |
| 125 | - "%s", lib3270_win32_strerror(GetLastError()) ); | |
| 98 | + wVersionRequested = MAKEWORD(2, 2); | |
| 126 | 99 | |
| 127 | - _exit(1); | |
| 128 | - } | |
| 100 | + if (WSAStartup(wVersionRequested, &wsaData) != 0) | |
| 101 | + { | |
| 102 | + static const LIB3270_POPUP popup = { | |
| 103 | + .type = LIB3270_NOTIFY_CRITICAL, | |
| 104 | + .summary = N_("WSAStartup failed") | |
| 105 | + }; | |
| 129 | 106 | |
| 130 | - if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) | |
| 131 | - { | |
| 132 | - lib3270_popup_dialog( session, | |
| 133 | - LIB3270_NOTIFY_CRITICAL, | |
| 134 | - _( "Network startup error" ), | |
| 135 | - _( "Bad winsock version" ), | |
| 136 | - _( "Can't use winsock version %d.%d" ), LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); | |
| 137 | - _exit(1); | |
| 107 | + state->popup = &popup; | |
| 108 | + state->winerror = GetLastError(); | |
| 109 | + | |
| 110 | + return -1; | |
| 111 | + } | |
| 112 | + | |
| 113 | + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) | |
| 114 | + { | |
| 115 | + static const LIB3270_POPUP popup = { | |
| 116 | + .type = LIB3270_NOTIFY_CRITICAL, | |
| 117 | + .summary = N_("Bad winsock version"), | |
| 118 | + .body = N_("Can't use this system winsock") | |
| 119 | + }; | |
| 120 | + | |
| 121 | + state->popup = &popup; | |
| 122 | + state->winerror = GetLastError(); | |
| 123 | + | |
| 124 | + return -1; | |
| 125 | + } | |
| 126 | + | |
| 127 | + wsa_is_started = 1; | |
| 138 | 128 | } |
| 139 | -} | |
| 140 | 129 | |
| 141 | - struct resolver | |
| 142 | - { | |
| 143 | - int rc; | |
| 144 | - int convert; | |
| 145 | - const char * message; | |
| 146 | - }; | |
| 130 | + // Reset state | |
| 131 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | |
| 147 | 132 | |
| 148 | - static int background_connect(H3270 *hSession, void *host) | |
| 149 | - { | |
| 133 | + // | |
| 134 | + // Resolve hostname | |
| 135 | + // | |
| 150 | 136 | struct addrinfo hints; |
| 151 | 137 | struct addrinfo * result = NULL; |
| 152 | - struct addrinfo * rp = NULL; | |
| 153 | - | |
| 154 | - if(!(hSession->host.current && hSession->host.srvc)) | |
| 155 | - return errno = ENOENT; | |
| 156 | - | |
| 157 | 138 | memset(&hints,0,sizeof(hints)); |
| 158 | 139 | hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 |
| 159 | 140 | hints.ai_socktype = SOCK_STREAM; // Stream socket |
| 160 | 141 | hints.ai_flags = AI_PASSIVE; // For wildcard IP address |
| 161 | 142 | hints.ai_protocol = 0; // Any protocol |
| 162 | 143 | |
| 163 | - debug("%s(%s,%s)",__FUNCTION__,hSession->host.current, hSession->host.srvc); | |
| 164 | - | |
| 165 | 144 | status_resolving(hSession); |
| 166 | 145 | |
| 167 | 146 | int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result); |
| 168 | - debug("getaddrinfo(%s,%s) returns %d",hSession->host.current,hSession->host.srvc,rc); | |
| 169 | - | |
| 170 | - if(rc != 0) | |
| 147 | + if(rc) | |
| 171 | 148 | { |
| 172 | - ((struct resolver *) host)->rc = rc; | |
| 173 | - ((struct resolver *) host)->message = gai_strerror(rc); | |
| 174 | - ((struct resolver *) host)->convert = 1; | |
| 149 | + state->error_message = gai_strerror(rc); | |
| 175 | 150 | return -1; |
| 176 | 151 | } |
| 177 | 152 | |
| 153 | + // | |
| 154 | + // Try connecting to hosts. | |
| 155 | + // | |
| 156 | + int sock = -1; | |
| 157 | + struct addrinfo * rp = NULL; | |
| 158 | + | |
| 178 | 159 | status_connecting(hSession); |
| 179 | 160 | |
| 180 | - for(rp = result; hSession->connection.sock < 0 && rp != NULL; rp = rp->ai_next) | |
| 161 | + for(rp = result; sock < 0 && rp != NULL && state->syserror != ECANCELED; rp = rp->ai_next) | |
| 181 | 162 | { |
| 182 | - hSession->connection.sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | |
| 183 | - | |
| 184 | - if(hSession->connection.sock < 0) | |
| 163 | + // Got socket from host definition. | |
| 164 | + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | |
| 165 | + if(sock < 0) | |
| 185 | 166 | { |
| 186 | - ((struct resolver *) host)->rc = errno; | |
| 187 | - ((struct resolver *) host)->message = strerror(errno); | |
| 188 | - debug("Socket error %d: %s",((struct resolver *) host)->rc,((struct resolver *) host)->message); | |
| 167 | + // Can't get socket. | |
| 168 | + state->syserror = errno; | |
| 189 | 169 | continue; |
| 190 | 170 | } |
| 191 | 171 | |
| 192 | - // Connected! | |
| 193 | - if(connect(hSession->connection.sock, rp->ai_addr, rp->ai_addrlen)) | |
| 172 | + // Try connect. | |
| 173 | + if(sock_connect(hSession, sock, rp->ai_addr, rp->ai_addrlen)) | |
| 194 | 174 | { |
| 195 | - ((struct resolver *) host)->rc = errno; | |
| 196 | - ((struct resolver *) host)->message = strerror(errno); | |
| 197 | - debug("Connection error %d: %s",((struct resolver *) host)->rc,((struct resolver *) host)->message); | |
| 198 | - SOCK_CLOSE(hSession); | |
| 175 | + // Can't connect to host | |
| 176 | + state->syserror = errno; | |
| 177 | + closesocket(sock); | |
| 178 | + sock = -1; | |
| 199 | 179 | continue; |
| 200 | 180 | } |
| 201 | 181 | |
| 182 | + lib3270_socket_set_non_blocking(hSession,sock,0); | |
| 202 | 183 | } |
| 203 | 184 | |
| 204 | 185 | freeaddrinfo(result); |
| 205 | 186 | |
| 206 | - debug("%s: Connected using socket %d",__FUNCTION__,hSession->connection.sock); | |
| 187 | + if(sock < 0) | |
| 188 | + { | |
| 189 | + static const LIB3270_POPUP popup = { | |
| 190 | + .name = "CantConnect", | |
| 191 | + .type = LIB3270_NOTIFY_ERROR, | |
| 192 | + .summary = N_("Can't connect to host"), | |
| 193 | + .label = N_("Try again") | |
| 194 | + }; | |
| 195 | + | |
| 196 | + state->popup = &popup; | |
| 197 | + return sock; | |
| 198 | + } | |
| 207 | 199 | |
| 208 | - return 0; | |
| 200 | + return sock; | |
| 201 | + } | |
| 209 | 202 | |
| 210 | -} | |
| 203 | + static void net_connected(H3270 *hSession, int GNUC_UNUSED(fd), LIB3270_IO_FLAG GNUC_UNUSED(flag), void GNUC_UNUSED(*dunno)) | |
| 204 | + { | |
| 205 | + int err; | |
| 206 | + socklen_t len = sizeof(err); | |
| 211 | 207 | |
| 212 | -int net_reconnect(H3270 *hSession, int seconds) | |
| 213 | -{ | |
| 214 | - struct resolver host; | |
| 208 | + if(hSession->xio.write) { | |
| 209 | + trace("%s write=%p",__FUNCTION__,hSession->xio.write); | |
| 210 | + lib3270_remove_poll(hSession, hSession->xio.write); | |
| 211 | + hSession->xio.write = NULL; | |
| 212 | + } | |
| 215 | 213 | |
| 216 | - memset(&host,0,sizeof(host)); | |
| 214 | + if(hSession->network.module->getsockopt(hSession, SOL_SOCKET, SO_ERROR, (char *) &err, &len) < 0) | |
| 215 | + { | |
| 216 | + lib3270_disconnect(hSession); | |
| 217 | + lib3270_popup_dialog( | |
| 218 | + hSession, | |
| 219 | + LIB3270_NOTIFY_ERROR, | |
| 220 | + _( "Network error" ), | |
| 221 | + _( "Unable to get connection state." ), | |
| 222 | + _( "The system error was %s" ), lib3270_win32_strerror(WSAGetLastError()) | |
| 223 | + ); | |
| 224 | + return; | |
| 225 | + } | |
| 226 | + else if(err) | |
| 227 | + { | |
| 228 | + lib3270_autoptr(LIB3270_POPUP) popup = | |
| 229 | + lib3270_popup_clone_printf( | |
| 230 | + NULL, | |
| 231 | + _( "Can't connect to %s:%s"), | |
| 232 | + hSession->host.current, | |
| 233 | + hSession->host.srvc | |
| 234 | + ); | |
| 235 | + | |
| 236 | + lib3270_autoptr(char) syserror = | |
| 237 | + lib3270_strdup_printf( | |
| 238 | + _("The system error was \"%s\""), | |
| 239 | + lib3270_win32_strerror(WSAGetLastError()) | |
| 240 | + ); | |
| 241 | + | |
| 242 | + if(lib3270_popup(hSession,popup,!hSession->auto_reconnect_inprogress) == 0) | |
| 243 | + lib3270_activate_auto_reconnect(hSession,1000); | |
| 244 | + | |
| 245 | + return; | |
| 246 | + } | |
| 217 | 247 | |
| 218 | - sockstart(hSession); | |
| 248 | + if(lib3270_start_tls(hSession)) { | |
| 249 | + lib3270_disconnect(hSession); | |
| 250 | + return; | |
| 251 | + } | |
| 219 | 252 | |
| 220 | - if(lib3270_run_task(hSession, background_connect, &host) || hSession->connection.sock < 0) | |
| 253 | + hSession->xio.except = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_EXCEPTION,net_exception,0); | |
| 254 | + hSession->xio.read = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_READ,net_input,0); | |
| 255 | + | |
| 256 | + lib3270_setup_session(hSession); | |
| 257 | + lib3270_set_connected_initial(hSession); | |
| 258 | + | |
| 259 | + lib3270_notify_tls(hSession); | |
| 260 | + | |
| 261 | + } | |
| 262 | + | |
| 263 | + int net_reconnect(H3270 *hSession, int seconds) | |
| 264 | + { | |
| 265 | + LIB3270_NETWORK_STATE state; | |
| 266 | + memset(&state,0,sizeof(state)); | |
| 267 | + | |
| 268 | + // Initialize and connect to host | |
| 269 | + set_ssl_state(hSession,LIB3270_SSL_UNDEFINED); | |
| 270 | + lib3270_set_cstate(hSession,LIB3270_CONNECTING); | |
| 271 | + | |
| 272 | + if(lib3270_run_task(hSession, (int(*)(H3270 *, void *)) hSession->network.module->connect, &state)) | |
| 221 | 273 | { |
| 222 | - if(host.message) | |
| 274 | + lib3270_autoptr(LIB3270_POPUP) popup = | |
| 275 | + lib3270_popup_clone_printf( | |
| 276 | + NULL, | |
| 277 | + _( "Can't connect to %s:%s"), | |
| 278 | + hSession->host.current, | |
| 279 | + hSession->host.srvc | |
| 280 | + ); | |
| 281 | + | |
| 282 | + if(!popup->summary) | |
| 223 | 283 | { |
| 224 | - // Have windows message, convert charset. | |
| 225 | - | |
| 226 | - char msg[4096]; | |
| 227 | - snprintf(msg,sizeof(msg),"%s (RC=%d)",host.message,host.rc); | |
| 228 | - | |
| 229 | - if(hEventLog) | |
| 230 | - { | |
| 231 | - // Register on event log | |
| 232 | - lib3270_autoptr(char) username = lib3270_get_user_name(); | |
| 233 | - | |
| 234 | - const char *outMsg[] = { | |
| 235 | - username, | |
| 236 | - "networking", | |
| 237 | - msg | |
| 238 | - }; | |
| 239 | - | |
| 240 | - ReportEvent( | |
| 241 | - hEventLog, | |
| 242 | - EVENTLOG_ERROR_TYPE, | |
| 243 | - 1, | |
| 244 | - 0, | |
| 245 | - NULL, | |
| 246 | - (sizeof(outMsg)/sizeof(outMsg[0])), | |
| 247 | - 0, | |
| 248 | - outMsg, | |
| 249 | - NULL | |
| 250 | - ); | |
| 251 | - | |
| 252 | - } | |
| 253 | - | |
| 254 | - | |
| 255 | -#ifdef HAVE_ICONV | |
| 256 | - if(host.convert) | |
| 257 | - { | |
| 258 | - char * ptr = msg; | |
| 259 | - size_t out = 4096; | |
| 260 | - size_t in = strlen(host.message); | |
| 261 | - | |
| 262 | - iconv_t hConv = iconv_open("UTF-8",lib3270_win32_local_charset()); | |
| 263 | - if(iconv( | |
| 264 | - hConv, | |
| 265 | - (ICONV_CONST char **) &host.message, | |
| 266 | - &in, | |
| 267 | - &ptr,&out | |
| 268 | - ) == ((size_t) -1)) | |
| 269 | - { | |
| 270 | - strncpy(msg,host.message,4095); | |
| 271 | - } | |
| 272 | - iconv_close(hConv); | |
| 273 | - | |
| 274 | - } | |
| 275 | -#endif // HAVE_ICONV | |
| 276 | - | |
| 277 | - connection_failed(hSession,msg); | |
| 284 | + popup->summary = popup->body; | |
| 285 | + popup->body = NULL; | |
| 286 | + } | |
| 278 | 287 | |
| 288 | + lib3270_autoptr(char) syserror = NULL; | |
| 289 | + if(state.syserror) | |
| 290 | + { | |
| 291 | + syserror = lib3270_strdup_printf( | |
| 292 | + _("The system error was \"%s\" (rc=%d)"), | |
| 293 | + strerror(state.syserror), | |
| 294 | + state.syserror | |
| 295 | + ); | |
| 279 | 296 | } |
| 280 | - else | |
| 297 | +#ifdef _WIN32 | |
| 298 | + else if(state.winerror) | |
| 281 | 299 | { |
| 282 | - connection_failed(hSession,NULL); | |
| 300 | + syserror = lib3270_strdup_printf( | |
| 301 | + _("The system error was \"%s\""), | |
| 302 | + lib3270_win32_strerror(WSAGetLastError()) | |
| 303 | + ); | |
| 283 | 304 | } |
| 305 | +#endif // _WIN32 | |
| 306 | + | |
| 307 | + if(!popup->body) | |
| 308 | + { | |
| 309 | + if(state.error_message) | |
| 310 | + popup->body = state.error_message; | |
| 311 | + else | |
| 312 | + popup->body = syserror; | |
| 313 | + } | |
| 314 | + | |
| 315 | + lib3270_disconnect(hSession); // To cleanup states. | |
| 316 | + | |
| 317 | + popup->label = _("_Retry"); | |
| 318 | + if(lib3270_popup(hSession,popup,!hSession->auto_reconnect_inprogress) == 0) | |
| 319 | + lib3270_activate_auto_reconnect(hSession,1000); | |
| 284 | 320 | |
| 285 | - lib3270_set_disconnected(hSession); | |
| 286 | 321 | return errno = ENOTCONN; |
| 287 | 322 | } |
| 288 | 323 | |
| 324 | + // | |
| 325 | + // Connected | |
| 326 | + // | |
| 289 | 327 | hSession->ever_3270 = False; |
| 290 | 328 | |
| 291 | -#if defined(HAVE_LIBSSL) | |
| 292 | - hSession->ssl.host = 0; | |
| 293 | - | |
| 294 | - if(hSession->ssl.enabled) | |
| 329 | + // set options for inline out-of-band data and keepalives | |
| 330 | + int optval = 1; | |
| 331 | + if(hSession->network.module->setsockopt(hSession, SOL_SOCKET, SO_OOBINLINE, &optval, sizeof(optval)) < 0) | |
| 295 | 332 | { |
| 296 | - hSession->ssl.host = 1; | |
| 297 | - if(ssl_init(hSession)) | |
| 298 | - return errno = ENOTCONN; | |
| 299 | - | |
| 333 | + int rc = errno; | |
| 334 | + lib3270_popup_dialog( hSession, | |
| 335 | + LIB3270_NOTIFY_ERROR, | |
| 336 | + _( "Connection error" ), | |
| 337 | + _( "setsockopt(SO_OOBINLINE) has failed" ), | |
| 338 | + _( "The system error was %s" ), | |
| 339 | + lib3270_win32_strerror(WSAGetLastError()) | |
| 340 | + ); | |
| 341 | + hSession->network.module->disconnect(hSession); | |
| 342 | + return rc; | |
| 300 | 343 | } |
| 301 | -#endif // HAVE_LIBSSL | |
| 302 | 344 | |
| 303 | - /* connect */ | |
| 304 | - | |
| 305 | - WSASetLastError(0); | |
| 306 | - | |
| 307 | - int optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; | |
| 308 | - if (setsockopt(hSession->connection.sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)) < 0) | |
| 345 | + optval = lib3270_get_toggle(hSession,LIB3270_TOGGLE_KEEP_ALIVE) ? 1 : 0; | |
| 346 | + if (hSession->network.module->setsockopt(hSession, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) | |
| 309 | 347 | { |
| 348 | + int rc = errno; | |
| 349 | + | |
| 310 | 350 | char buffer[4096]; |
| 311 | 351 | snprintf(buffer,4095,_( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); |
| 312 | 352 | |
| ... | ... | @@ -314,32 +354,23 @@ int net_reconnect(H3270 *hSession, int seconds) |
| 314 | 354 | LIB3270_NOTIFY_ERROR, |
| 315 | 355 | _( "Connection error" ), |
| 316 | 356 | buffer, |
| 317 | - "%s", lib3270_win32_strerror(WSAGetLastError())); | |
| 318 | - SOCK_CLOSE(hSession); | |
| 319 | - return errno = ENOTCONN; | |
| 357 | + _( "The system error was %s" ), | |
| 358 | + lib3270_win32_strerror(WSAGetLastError()) | |
| 359 | + ); | |
| 360 | + | |
| 361 | + hSession->network.module->disconnect(hSession); | |
| 362 | + return rc; | |
| 320 | 363 | } |
| 321 | 364 | else |
| 322 | 365 | { |
| 323 | 366 | trace_dsn(hSession,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); |
| 324 | 367 | } |
| 325 | 368 | |
| 326 | - optval = 1; | |
| 327 | - if (setsockopt(hSession->connection.sock, SOL_SOCKET, SO_OOBINLINE, (char *)&optval,sizeof(optval)) < 0) | |
| 328 | - { | |
| 329 | - lib3270_popup_dialog( hSession, | |
| 330 | - LIB3270_NOTIFY_ERROR, | |
| 331 | - _( "Connection error" ), | |
| 332 | - _( "setsockopt(SO_OOBINLINE) has failed" ), | |
| 333 | - "%s", lib3270_win32_strerror(WSAGetLastError())); | |
| 334 | - SOCK_CLOSE(hSession); | |
| 335 | - return errno = ENOTCONN; | |
| 336 | - } | |
| 337 | - | |
| 338 | 369 | // Connecting, set callbacks, wait for connection |
| 339 | 370 | lib3270_set_cstate(hSession, LIB3270_PENDING); |
| 340 | 371 | lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); |
| 341 | 372 | |
| 342 | - hSession->xio.write = lib3270_add_poll_fd(hSession,hSession->connection.sock,LIB3270_IO_FLAG_WRITE,net_connected,0); | |
| 373 | + hSession->xio.write = hSession->network.module->add_poll(hSession,LIB3270_IO_FLAG_WRITE,net_connected,0); | |
| 343 | 374 | |
| 344 | 375 | trace("%s: Connection in progress",__FUNCTION__); |
| 345 | 376 | |
| ... | ... | @@ -349,50 +380,11 @@ int net_reconnect(H3270 *hSession, int seconds) |
| 349 | 380 | if(rc) |
| 350 | 381 | { |
| 351 | 382 | lib3270_disconnect(hSession); |
| 352 | - lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(rc)); | |
| 383 | + lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT)); | |
| 353 | 384 | return errno = rc; |
| 354 | 385 | } |
| 355 | - } | |
| 356 | - | |
| 357 | - /* | |
| 358 | - if(seconds) | |
| 359 | - { | |
| 360 | - time_t end = time(0)+seconds; | |
| 361 | - | |
| 362 | - while(time(0) < end) | |
| 363 | - { | |
| 364 | - lib3270_main_iterate(hSession,1); | |
| 365 | - | |
| 366 | - switch(hSession->connection.state) | |
| 367 | - { | |
| 368 | - case LIB3270_PENDING: | |
| 369 | - case LIB3270_CONNECTED_INITIAL: | |
| 370 | - case LIB3270_CONNECTED_ANSI: | |
| 371 | - case LIB3270_CONNECTED_3270: | |
| 372 | - case LIB3270_CONNECTED_INITIAL_E: | |
| 373 | - case LIB3270_CONNECTED_NVT: | |
| 374 | - case LIB3270_CONNECTED_SSCP: | |
| 375 | - case LIB3270_RESOLVING: | |
| 376 | - break; | |
| 377 | - | |
| 378 | - case LIB3270_NOT_CONNECTED: | |
| 379 | - return errno = ENOTCONN; | |
| 380 | - | |
| 381 | - case LIB3270_CONNECTED_TN3270E: | |
| 382 | - return 0; | |
| 383 | - | |
| 384 | - default: | |
| 385 | - lib3270_write_log(hSession,"connect", "%s: State changed to unexpected state %d",__FUNCTION__,hSession->connection.state); | |
| 386 | - return -1; | |
| 387 | - } | |
| 388 | - | |
| 389 | - } | |
| 390 | 386 | |
| 391 | - lib3270_disconnect(hSession); | |
| 392 | - lib3270_write_log(hSession,"connect", "%s: %s",__FUNCTION__,strerror(ETIMEDOUT)); | |
| 393 | - return errno = ETIMEDOUT; | |
| 394 | 387 | } |
| 395 | - */ | |
| 396 | 388 | |
| 397 | 389 | return 0; |
| 398 | 390 | ... | ... |
src/include/networking.h
| ... | ... | @@ -31,8 +31,17 @@ |
| 31 | 31 | |
| 32 | 32 | #define LIB3270_NETWORKING_H_INCLUDED |
| 33 | 33 | |
| 34 | - #include <lib3270/popup.h> | |
| 34 | +#ifdef _WIN32 | |
| 35 | + #include <winsock2.h> | |
| 36 | + #include <windows.h> | |
| 37 | + | |
| 38 | + typedef int socklen_t; | |
| 39 | + | |
| 40 | +#else | |
| 35 | 41 | #include <sys/socket.h> |
| 42 | +#endif // _WIN32 | |
| 43 | + | |
| 44 | + #include <lib3270/popup.h> | |
| 36 | 45 | |
| 37 | 46 | typedef struct _lib3270_network_popup LIB3270_NETWORK_POPUP; |
| 38 | 47 | typedef struct _lib3270_net_context LIB3270_NET_CONTEXT; |
| ... | ... | @@ -207,7 +216,7 @@ |
| 207 | 216 | * @return Pointer to the hostname or NULL if failed (sets errno). |
| 208 | 217 | * |
| 209 | 218 | */ |
| 210 | - LIB3270_INTERNAL char * lib3270_set_network_module_from_url(H3270 *hSession, const char *url); | |
| 219 | + LIB3270_INTERNAL char * lib3270_set_network_module_from_url(H3270 *hSession, char *url); | |
| 211 | 220 | |
| 212 | 221 | |
| 213 | 222 | /** | ... | ... |
src/network_modules/default/main.c
| ... | ... | @@ -52,7 +52,7 @@ |
| 52 | 52 | if(hSession->network.context->sock > 0) { |
| 53 | 53 | shutdown(hSession->network.context->sock, 2); |
| 54 | 54 | #ifdef _WIN32 |
| 55 | - sockclose(hSession->network.context->sock); | |
| 55 | + closesocket(hSession->network.context->sock); | |
| 56 | 56 | #else |
| 57 | 57 | close(hSession->network.context->sock); |
| 58 | 58 | #endif // _WIN32 | ... | ... |
src/network_modules/openssl/main.c
| ... | ... | @@ -68,7 +68,7 @@ static int openssl_network_disconnect(H3270 *hSession) { |
| 68 | 68 | if(context->sock > 0) { |
| 69 | 69 | shutdown(context->sock, 2); |
| 70 | 70 | #ifdef _WIN32 |
| 71 | - sockclose(context->sock); | |
| 71 | + closesocket(context->sock); | |
| 72 | 72 | #else |
| 73 | 73 | close(context->sock); |
| 74 | 74 | #endif // _WIN32 | ... | ... |
src/network_modules/openssl/private.h
src/network_modules/openssl/start.c
src/network_modules/select.c
| ... | ... | @@ -41,7 +41,7 @@ |
| 41 | 41 | |
| 42 | 42 | /*--[ Implement ]------------------------------------------------------------------------------------*/ |
| 43 | 43 | |
| 44 | - char * lib3270_set_network_module_from_url(H3270 *hSession, const char *url) { | |
| 44 | +char * lib3270_set_network_module_from_url(H3270 *hSession, char *url) { | |
| 45 | 45 | |
| 46 | 46 | static const struct { |
| 47 | 47 | const char *scheme; ///< @brief URL scheme for module. | ... | ... |
src/network_modules/tools.c
| ... | ... | @@ -60,7 +60,7 @@ |
| 60 | 60 | .name = "RecvFailed", |
| 61 | 61 | .type = LIB3270_NOTIFY_ERROR, |
| 62 | 62 | .summary = _("Error receiving data from host"), |
| 63 | - } | |
| 63 | + }; | |
| 64 | 64 | |
| 65 | 65 | // TODO: Translate WSA Error, update message body. |
| 66 | 66 | |
| ... | ... | @@ -102,7 +102,15 @@ |
| 102 | 102 | |
| 103 | 103 | int rc = WSAGetLastError(); |
| 104 | 104 | |
| 105 | - #error Have work to do. | |
| 105 | + lib3270_popup_dialog( | |
| 106 | + hSession, | |
| 107 | + LIB3270_NOTIFY_ERROR, | |
| 108 | + NULL, | |
| 109 | + _("Erro sending data to host"), | |
| 110 | + _( "The system error was %s (%d)" ), | |
| 111 | + lib3270_win32_strerror(rc), | |
| 112 | + rc | |
| 113 | + ); | |
| 106 | 114 | |
| 107 | 115 | #else |
| 108 | 116 | ... | ... |