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,7 +455,10 @@ static int get_rpq_timezone(H3270 *hSession) | ||
455 | delta = difftime(mktime(&here_tm), mktime(utc_tm)) / 60L; | 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 | if (labs(delta) > 720L) | 462 | if (labs(delta) > 720L) |
460 | rpq_warning(hSession, _("RPQ timezone exceeds 12 hour UTC offset")); | 463 | rpq_warning(hSession, _("RPQ timezone exceeds 12 hour UTC offset")); |
461 | return (labs(delta) > 720L)? 3 : (int) delta; | 464 | return (labs(delta) > 720L)? 3 : (int) delta; |
src/core/windows/connect.c
@@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
18 | * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | 18 | * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin |
19 | * St, Fifth Floor, Boston, MA 02110-1301 USA | 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 | * Contatos: | 23 | * Contatos: |
24 | * | 24 | * |
@@ -29,284 +29,324 @@ | @@ -29,284 +29,324 @@ | ||
29 | 29 | ||
30 | #include <config.h> | 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 | #include <winsock2.h> | 32 | #include <winsock2.h> |
37 | #include <windows.h> | 33 | #include <windows.h> |
38 | #include <ws2tcpip.h> | 34 | #include <ws2tcpip.h> |
39 | 35 | ||
40 | #include <internals.h> | 36 | #include <internals.h> |
41 | -#include <errno.h> | ||
42 | -#include <lib3270/trace.h> | ||
43 | #include <lib3270/log.h> | 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 | #include "hostc.h" | 41 | #include "hostc.h" |
51 | #include "trace_dsc.h" | 42 | #include "trace_dsc.h" |
52 | -#include "telnetc.h" | ||
53 | #include "screen.h" | 43 | #include "screen.h" |
54 | 44 | ||
55 | -#include <lib3270/internals.h> | ||
56 | - | ||
57 | /*---[ Implement ]-------------------------------------------------------------------------------*/ | 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 | struct addrinfo hints; | 136 | struct addrinfo hints; |
151 | struct addrinfo * result = NULL; | 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 | memset(&hints,0,sizeof(hints)); | 138 | memset(&hints,0,sizeof(hints)); |
158 | hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 | 139 | hints.ai_family = AF_UNSPEC; // Allow IPv4 or IPv6 |
159 | hints.ai_socktype = SOCK_STREAM; // Stream socket | 140 | hints.ai_socktype = SOCK_STREAM; // Stream socket |
160 | hints.ai_flags = AI_PASSIVE; // For wildcard IP address | 141 | hints.ai_flags = AI_PASSIVE; // For wildcard IP address |
161 | hints.ai_protocol = 0; // Any protocol | 142 | hints.ai_protocol = 0; // Any protocol |
162 | 143 | ||
163 | - debug("%s(%s,%s)",__FUNCTION__,hSession->host.current, hSession->host.srvc); | ||
164 | - | ||
165 | status_resolving(hSession); | 144 | status_resolving(hSession); |
166 | 145 | ||
167 | int rc = getaddrinfo(hSession->host.current, hSession->host.srvc, &hints, &result); | 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 | return -1; | 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 | status_connecting(hSession); | 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 | continue; | 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 | continue; | 179 | continue; |
200 | } | 180 | } |
201 | 181 | ||
182 | + lib3270_socket_set_non_blocking(hSession,sock,0); | ||
202 | } | 183 | } |
203 | 184 | ||
204 | freeaddrinfo(result); | 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 | return errno = ENOTCONN; | 321 | return errno = ENOTCONN; |
287 | } | 322 | } |
288 | 323 | ||
324 | + // | ||
325 | + // Connected | ||
326 | + // | ||
289 | hSession->ever_3270 = False; | 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 | char buffer[4096]; | 350 | char buffer[4096]; |
311 | snprintf(buffer,4095,_( "Can't %s network keep-alive" ), optval ? _( "enable" ) : _( "disable" )); | 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,32 +354,23 @@ int net_reconnect(H3270 *hSession, int seconds) | ||
314 | LIB3270_NOTIFY_ERROR, | 354 | LIB3270_NOTIFY_ERROR, |
315 | _( "Connection error" ), | 355 | _( "Connection error" ), |
316 | buffer, | 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 | else | 364 | else |
322 | { | 365 | { |
323 | trace_dsn(hSession,"Network keep-alive is %s\n",optval ? "enabled" : "disabled" ); | 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 | // Connecting, set callbacks, wait for connection | 369 | // Connecting, set callbacks, wait for connection |
339 | lib3270_set_cstate(hSession, LIB3270_PENDING); | 370 | lib3270_set_cstate(hSession, LIB3270_PENDING); |
340 | lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); | 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 | trace("%s: Connection in progress",__FUNCTION__); | 375 | trace("%s: Connection in progress",__FUNCTION__); |
345 | 376 | ||
@@ -349,50 +380,11 @@ int net_reconnect(H3270 *hSession, int seconds) | @@ -349,50 +380,11 @@ int net_reconnect(H3270 *hSession, int seconds) | ||
349 | if(rc) | 380 | if(rc) |
350 | { | 381 | { |
351 | lib3270_disconnect(hSession); | 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 | return errno = rc; | 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 | return 0; | 389 | return 0; |
398 | 390 |
src/include/networking.h
@@ -31,8 +31,17 @@ | @@ -31,8 +31,17 @@ | ||
31 | 31 | ||
32 | #define LIB3270_NETWORKING_H_INCLUDED | 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 | #include <sys/socket.h> | 41 | #include <sys/socket.h> |
42 | +#endif // _WIN32 | ||
43 | + | ||
44 | + #include <lib3270/popup.h> | ||
36 | 45 | ||
37 | typedef struct _lib3270_network_popup LIB3270_NETWORK_POPUP; | 46 | typedef struct _lib3270_network_popup LIB3270_NETWORK_POPUP; |
38 | typedef struct _lib3270_net_context LIB3270_NET_CONTEXT; | 47 | typedef struct _lib3270_net_context LIB3270_NET_CONTEXT; |
@@ -207,7 +216,7 @@ | @@ -207,7 +216,7 @@ | ||
207 | * @return Pointer to the hostname or NULL if failed (sets errno). | 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,7 +52,7 @@ | ||
52 | if(hSession->network.context->sock > 0) { | 52 | if(hSession->network.context->sock > 0) { |
53 | shutdown(hSession->network.context->sock, 2); | 53 | shutdown(hSession->network.context->sock, 2); |
54 | #ifdef _WIN32 | 54 | #ifdef _WIN32 |
55 | - sockclose(hSession->network.context->sock); | 55 | + closesocket(hSession->network.context->sock); |
56 | #else | 56 | #else |
57 | close(hSession->network.context->sock); | 57 | close(hSession->network.context->sock); |
58 | #endif // _WIN32 | 58 | #endif // _WIN32 |
src/network_modules/openssl/main.c
@@ -68,7 +68,7 @@ static int openssl_network_disconnect(H3270 *hSession) { | @@ -68,7 +68,7 @@ static int openssl_network_disconnect(H3270 *hSession) { | ||
68 | if(context->sock > 0) { | 68 | if(context->sock > 0) { |
69 | shutdown(context->sock, 2); | 69 | shutdown(context->sock, 2); |
70 | #ifdef _WIN32 | 70 | #ifdef _WIN32 |
71 | - sockclose(context->sock); | 71 | + closesocket(context->sock); |
72 | #else | 72 | #else |
73 | close(context->sock); | 73 | close(context->sock); |
74 | #endif // _WIN32 | 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,7 +41,7 @@ | ||
41 | 41 | ||
42 | /*--[ Implement ]------------------------------------------------------------------------------------*/ | 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 | static const struct { | 46 | static const struct { |
47 | const char *scheme; ///< @brief URL scheme for module. | 47 | const char *scheme; ///< @brief URL scheme for module. |
src/network_modules/tools.c
@@ -60,7 +60,7 @@ | @@ -60,7 +60,7 @@ | ||
60 | .name = "RecvFailed", | 60 | .name = "RecvFailed", |
61 | .type = LIB3270_NOTIFY_ERROR, | 61 | .type = LIB3270_NOTIFY_ERROR, |
62 | .summary = _("Error receiving data from host"), | 62 | .summary = _("Error receiving data from host"), |
63 | - } | 63 | + }; |
64 | 64 | ||
65 | // TODO: Translate WSA Error, update message body. | 65 | // TODO: Translate WSA Error, update message body. |
66 | 66 | ||
@@ -102,7 +102,15 @@ | @@ -102,7 +102,15 @@ | ||
102 | 102 | ||
103 | int rc = WSAGetLastError(); | 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 | #else | 115 | #else |
108 | 116 |