Commit f4e6dc59eb1dd2d06176519d7c1772e20ac220b4
1 parent
353fee04
Exists in
master
and in
3 other branches
Implementando novo mecanismo de conexão ao host
Showing
2 changed files
with
164 additions
and
187 deletions
Show diff stats
connect.c
... | ... | @@ -27,16 +27,127 @@ |
27 | 27 | * |
28 | 28 | */ |
29 | 29 | |
30 | +#if defined(_WIN32) | |
31 | + #include <winsock2.h> | |
32 | + #include <windows.h> | |
33 | +#endif | |
34 | + | |
35 | +#include "globals.h" | |
36 | +#include <errno.h> | |
37 | + | |
38 | +#if defined(_WIN32) | |
39 | + #include <ws2tcpip.h> | |
40 | +#else | |
41 | + #include <sys/types.h> | |
42 | + #include <sys/socket.h> | |
43 | + #include <sys/ioctl.h> | |
44 | + #include <netinet/in.h> | |
45 | + #include <netdb.h> | |
46 | + #include <unistd.h> | |
47 | + #include <fcntl.h> | |
48 | +#endif | |
49 | + | |
50 | + | |
51 | +#if defined(_WIN32) /*[*/ | |
52 | + #define SOCK_CLOSE(s) closesocket(s->sock); s->sock = -1; | |
53 | +#else /*][*/ | |
54 | + #define SOCK_CLOSE(s) close(s->sock); s->sock = -1; | |
55 | +#endif /*]*/ | |
56 | + | |
57 | +#include <stdlib.h> | |
58 | +#include "statusc.h" | |
59 | +#include "hostc.h" | |
60 | +#include "trace_dsc.h" | |
61 | +#include "utilc.h" | |
62 | +#include <lib3270/internals.h> | |
63 | + | |
30 | 64 | /*---[ Implement ]-------------------------------------------------------------------------------*/ |
31 | 65 | |
32 | - LIB3270_EXPORT int lib3270_sock_connect(H3270 *hSession, const char *hostname, const char *srvc, int timeout) | |
66 | + | |
67 | +static void net_connected(H3270 *hSession) | |
68 | +{ | |
69 | + trace("***************** %s",__FUNCTION__); | |
70 | + | |
71 | +} | |
72 | + | |
73 | +#if defined(_WIN32) /*[*/ | |
74 | + static void sockstart(H3270 *session) | |
75 | + { | |
76 | + static int initted = 0; | |
77 | + WORD wVersionRequested; | |
78 | + WSADATA wsaData; | |
79 | + | |
80 | + if (initted) | |
81 | + return; | |
82 | + | |
83 | + initted = 1; | |
84 | + | |
85 | + wVersionRequested = MAKEWORD(2, 2); | |
86 | + | |
87 | + if (WSAStartup(wVersionRequested, &wsaData) != 0) | |
88 | + { | |
89 | + lib3270_popup_dialog( session, | |
90 | + LIB3270_NOTIFY_CRITICAL, | |
91 | + N_( "Network startup error" ), | |
92 | + N_( "WSAStartup failed" ), | |
93 | + "%s", win32_strerror(GetLastError()) ); | |
94 | + | |
95 | + _exit(1); | |
96 | + } | |
97 | + | |
98 | + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) | |
99 | + { | |
100 | + lib3270_popup_dialog( session, | |
101 | + LIB3270_NOTIFY_CRITICAL, | |
102 | + N_( "Network startup error" ), | |
103 | + N_( "Bad winsock version" ), | |
104 | + N_( "Can't use winsock version %d.%d" ), LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); | |
105 | + _exit(1); | |
106 | + } | |
107 | + } | |
108 | +#endif /*]*/ | |
109 | + | |
110 | + static void set_ssl_state(H3270 *hSession, LIB3270_SSL_STATE state) | |
111 | + { | |
112 | + if(state == hSession->secure) | |
113 | + return; | |
114 | + | |
115 | + trace_dsn(hSession,"SSL state changes to %d\n",(int) state); | |
116 | + | |
117 | + hSession->update_ssl(hSession,hSession->secure = state); | |
118 | + } | |
119 | + | |
120 | + LIB3270_EXPORT int lib3270_connect_host(H3270 *hSession, const char *hostname, const char *srvc) | |
33 | 121 | { |
34 | 122 | int s; |
35 | 123 | int sock = -1; |
36 | 124 | struct addrinfo hints; |
37 | 125 | struct addrinfo * result = NULL; |
38 | 126 | struct addrinfo * rp = NULL; |
39 | - LIB3270_MESSAGE saved_status = hSession->oia_status; | |
127 | + | |
128 | + if(!hostname) | |
129 | + return EINVAL; | |
130 | + | |
131 | + if(!srvc) | |
132 | + srvc = "telnet"; | |
133 | + | |
134 | + CHECK_SESSION_HANDLE(hSession); | |
135 | + | |
136 | + lib3270_main_iterate(hSession,0); | |
137 | + | |
138 | + if(hSession->auto_reconnect_inprogress) | |
139 | + return EAGAIN; | |
140 | + | |
141 | + if(PCONNECTED) | |
142 | + return EBUSY; | |
143 | + | |
144 | +#if defined(_WIN32) | |
145 | + sockstart(hSession); | |
146 | +#endif | |
147 | + | |
148 | + set_ssl_state(hSession,LIB3270_SSL_UNSECURE); | |
149 | + | |
150 | + hSession->ever_3270 = False; | |
40 | 151 | |
41 | 152 | memset(&hints, 0, sizeof(struct addrinfo)); |
42 | 153 | hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ |
... | ... | @@ -47,9 +158,6 @@ |
47 | 158 | hints.ai_addr = NULL; |
48 | 159 | hints.ai_next = NULL; |
49 | 160 | |
50 | - if(timeout < 0) | |
51 | - timeout = 10; | |
52 | - | |
53 | 161 | if(*hostname == '$') |
54 | 162 | { |
55 | 163 | const char *name = getenv(hostname+1); |
... | ... | @@ -61,6 +169,7 @@ |
61 | 169 | _( "Unable to find selected hostname." ), |
62 | 170 | _( "Can't determine value for environment variable \"%s\" " ), |
63 | 171 | hostname); |
172 | + lib3270_set_disconnected(hSession); | |
64 | 173 | return -1; |
65 | 174 | } |
66 | 175 | hostname = name; |
... | ... | @@ -79,8 +188,7 @@ |
79 | 188 | "%s", |
80 | 189 | gai_strerror(s)); |
81 | 190 | |
82 | - status_changed(hSession,saved_status); | |
83 | - | |
191 | + lib3270_set_disconnected(hSession); | |
84 | 192 | return -1; |
85 | 193 | } |
86 | 194 | |
... | ... | @@ -88,8 +196,8 @@ |
88 | 196 | |
89 | 197 | for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next) |
90 | 198 | { |
91 | - sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | |
92 | - if(sock < 0) | |
199 | + hSession->sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); | |
200 | + if(hSession->sock < 0) | |
93 | 201 | continue; |
94 | 202 | |
95 | 203 | #ifdef WIN32 |
... | ... | @@ -97,9 +205,9 @@ |
97 | 205 | u_int len = sizeof(int); |
98 | 206 | |
99 | 207 | WSASetLastError(0); |
100 | - block = 1; | |
208 | + block = 0; | |
101 | 209 | |
102 | - if(ioctlsocket(sock,FIONBIO,&block)) | |
210 | + if(ioctlsocket(hSession->sock,FIONBIO,&block)) | |
103 | 211 | { |
104 | 212 | lib3270_popup_dialog( hSession, |
105 | 213 | LIB3270_NOTIFY_ERROR, |
... | ... | @@ -107,10 +215,10 @@ |
107 | 215 | _( "ioctlsocket(FIONBIO) failed." ), |
108 | 216 | "Windows error %d", |
109 | 217 | WSAGetLastError() ); |
110 | - close(sock); | |
111 | - sock = -1; | |
218 | + | |
219 | + SOCK_CLOSE(hSession); | |
112 | 220 | } |
113 | - else if(connect(sock, rp->ai_addr, rp->ai_addrlen)) | |
221 | + else if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen)) | |
114 | 222 | { |
115 | 223 | int err = WSAGetLastError(); |
116 | 224 | if(err != WSAEWOULDBLOCK) |
... | ... | @@ -121,98 +229,15 @@ |
121 | 229 | _( "Can't connect to host." ), |
122 | 230 | "Windows error %d", |
123 | 231 | WSAGetLastError() ); |
124 | - close(sock); | |
125 | - sock = -1; | |
126 | - } | |
127 | - } | |
128 | - | |
129 | - #error Implementar | |
130 | - | |
131 | - /* | |
132 | - if(sock > 0) | |
133 | - { | |
134 | - // Connection in progress, wait until socket is available for write | |
135 | - fd_set wr; | |
136 | - struct timeval tm; | |
137 | - int status; | |
138 | - int err; | |
139 | - socklen_t len = sizeof(err); | |
140 | - | |
141 | - FD_ZERO(&wr); | |
142 | - FD_SET(sock, &wr); | |
143 | - memset(&tm,0,sizeof(tm)); | |
144 | - tm.tv_sec = timeout; | |
145 | - | |
146 | - switch(select(sock+1, NULL, &wr, NULL, &tm)) | |
147 | - { | |
148 | - case 0: | |
149 | - lib3270_popup_dialog( hSession, | |
150 | - LIB3270_NOTIFY_ERROR, | |
151 | - _( "Connection error" ), | |
152 | - _( "Can't connect to host." ), | |
153 | - "%s", | |
154 | - strerror(errno = ETIMEDOUT)); | |
155 | - close(sock); | |
156 | - sock = -1; | |
157 | - break; | |
158 | - | |
159 | - case -1: | |
160 | - lib3270_popup_dialog( hSession, | |
161 | - LIB3270_NOTIFY_ERROR, | |
162 | - _( "Connection error" ), | |
163 | - _( "select() error when connecting to host." ), | |
164 | - "%s", | |
165 | - strerror(errno)); | |
166 | - close(sock); | |
167 | - sock = -1; | |
168 | - break; | |
169 | - | |
170 | - default: | |
171 | - // Se o socket nao esta disponivel para gravacao o connect falhou | |
172 | - if(!FD_ISSET(sock,&wr)) | |
173 | - { | |
174 | - lib3270_popup_dialog( hSession, | |
175 | - LIB3270_NOTIFY_ERROR, | |
176 | - _( "Connection error" ), | |
177 | - _( "Error when connecting to host." ), | |
178 | - "%s", | |
179 | - _( "Socket was not available after connect" )); | |
180 | - close(sock); | |
181 | - sock = -1; | |
182 | - } | |
183 | - else if(getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &err, &len) < 0) | |
184 | - { | |
185 | - lib3270_popup_dialog( hSession, | |
186 | - LIB3270_NOTIFY_ERROR, | |
187 | - _( "Connection error" ), | |
188 | - _( "Error getting connection state." ), | |
189 | - "%s", | |
190 | - strerror(errno)); | |
191 | - | |
192 | - close(sock); | |
193 | - sock = -1; | |
194 | - } | |
195 | - else if(err) | |
196 | - { | |
197 | - lib3270_popup_dialog( hSession, | |
198 | - LIB3270_NOTIFY_ERROR, | |
199 | - _( "Connection error" ), | |
200 | - _( "socket error when connecting to host." ), | |
201 | - "Socket error %d", | |
202 | - err); | |
203 | - | |
204 | - close(sock); | |
205 | - sock = -1; | |
206 | - } | |
232 | + SOCK_CLOSE(hSession); | |
207 | 233 | } |
208 | 234 | } |
209 | - */ | |
210 | 235 | |
211 | 236 | #else |
212 | - fcntl(sock, F_SETFL,fcntl(sock,F_GETFL,0)|O_NONBLOCK); | |
237 | + fcntl(hSession->sock, F_SETFL,fcntl(sock,F_GETFL,0)|O_NONBLOCK); | |
213 | 238 | |
214 | 239 | errno = 0; |
215 | - if(connect(sock, rp->ai_addr, rp->ai_addrlen)) | |
240 | + if(connect(hSession->sock, rp->ai_addr, rp->ai_addrlen)) | |
216 | 241 | { |
217 | 242 | if( errno != EINPROGRESS ) |
218 | 243 | { |
... | ... | @@ -222,99 +247,52 @@ |
222 | 247 | _( "Can't connect to host." ), |
223 | 248 | "%s", |
224 | 249 | strerror(errno)); |
225 | - close(sock); | |
226 | - sock = -1; | |
250 | + SOCK_CLOSE(hSession); | |
227 | 251 | } |
228 | 252 | } |
229 | 253 | |
230 | - #error Implementar | |
231 | - | |
232 | -/* | |
233 | - if(sock > 0) | |
234 | - { | |
235 | - // Connection in progress, wait until socket is available for write | |
236 | - fd_set wr; | |
237 | - struct timeval tm; | |
238 | - int status; | |
239 | - int err; | |
240 | - socklen_t len = sizeof(err); | |
241 | - | |
242 | - FD_ZERO(&wr); | |
243 | - FD_SET(sock, &wr); | |
244 | - memset(&tm,0,sizeof(tm)); | |
245 | - tm.tv_sec = timeout; | |
246 | - | |
247 | - switch(select(sock+1, NULL, &wr, NULL, &tm)) | |
248 | - { | |
249 | - case 0: | |
250 | - lib3270_popup_dialog( hSession, | |
251 | - LIB3270_NOTIFY_ERROR, | |
252 | - _( "Connection error" ), | |
253 | - _( "Can't connect to host." ), | |
254 | - "%s", | |
255 | - strerror(errno = ETIMEDOUT)); | |
256 | - close(sock); | |
257 | - sock = -1; | |
258 | - break; | |
259 | - | |
260 | - case -1: | |
261 | - lib3270_popup_dialog( hSession, | |
262 | - LIB3270_NOTIFY_ERROR, | |
263 | - _( "Connection error" ), | |
264 | - _( "select() error when connecting to host." ), | |
265 | - "%s", | |
266 | - strerror(errno)); | |
267 | - close(sock); | |
268 | - sock = -1; | |
269 | - break; | |
270 | - | |
271 | - default: | |
272 | - | |
273 | - // Se o socket nao esta disponivel para gravacao o connect falhou | |
274 | - if(!FD_ISSET(sock,&wr)) | |
275 | - { | |
276 | - lib3270_popup_dialog( hSession, | |
277 | - LIB3270_NOTIFY_ERROR, | |
278 | - _( "Connection error" ), | |
279 | - _( "Error when connecting to host." ), | |
280 | - "%s", | |
281 | - _( "Socket was not available after connect" )); | |
282 | - close(sock); | |
283 | - sock = -1; | |
284 | - } | |
285 | - else if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) < 0) | |
286 | - { | |
287 | - lib3270_popup_dialog( hSession, | |
288 | - LIB3270_NOTIFY_ERROR, | |
289 | - _( "Connection error" ), | |
290 | - _( "Error getting connection state." ), | |
291 | - "%s", | |
292 | - strerror(errno)); | |
293 | - | |
294 | - close(sock); | |
295 | - sock = -1; | |
296 | - } | |
297 | - else if(err) | |
298 | - { | |
299 | - lib3270_popup_dialog( hSession, | |
300 | - LIB3270_NOTIFY_ERROR, | |
301 | - _( "Connection error" ), | |
302 | - _( "socket error when connecting to host." ), | |
303 | - "Socket error %d", | |
304 | - err); | |
305 | - | |
306 | - close(sock); | |
307 | - sock = -1; | |
308 | - } | |
309 | - } | |
310 | - } | |
311 | - */ | |
312 | 254 | #endif // WIN32 |
313 | 255 | } |
314 | 256 | |
315 | 257 | freeaddrinfo(result); |
316 | 258 | |
317 | - status_changed(hSession,saved_status); | |
259 | + // set options for inline out-of-band data and keepalives | |
260 | + | |
261 | + /* | |
262 | + int on = 1; | |
263 | + if (setsockopt(hSession->sock, SOL_SOCKET, SO_OOBINLINE, (char *)&on,sizeof(on)) < 0) | |
264 | + { | |
265 | + popup_a_sockerr(hSession, N_( "setsockopt(%s)" ), "SO_OOBINLINE"); | |
266 | + SOCK_CLOSE(hSession); | |
267 | + } | |
268 | + | |
269 | +#if defined(OMTU) | |
270 | + else if (setsockopt(hSession->sock, SOL_SOCKET, SO_SNDBUF, (char *)&mtu,sizeof(mtu)) < 0) | |
271 | + { | |
272 | + popup_a_sockerr(hSession, N_( "setsockopt(%s)" ), "SO_SNDBUF"); | |
273 | + SOCK_CLOSE(hSession); | |
274 | + } | |
275 | +#endif | |
276 | + | |
277 | + */ | |
278 | + | |
279 | + if(hSession->sock < 0) | |
280 | + { | |
281 | + lib3270_set_disconnected(hSession); | |
282 | + return -1; | |
283 | + } | |
284 | + | |
285 | +#if !defined(_WIN32) | |
286 | + /* don't share the socket with our children */ | |
287 | + (void) fcntl(hSession->sock, F_SETFD, 1); | |
288 | +#endif | |
289 | + | |
290 | + // Connecting, set callbacks, wait for connection | |
291 | + trace_dsn(hSession,"Half-connected.\n"); | |
292 | + | |
293 | + lib3270_st_changed(hSession, LIB3270_STATE_HALF_CONNECT, True); | |
294 | + | |
295 | + hSession->ns_write_id = AddOutput(hSession->sock, hSession, net_connected); | |
318 | 296 | |
319 | 297 | return 0; |
320 | 298 | ... | ... |
sources.mak
... | ... | @@ -33,8 +33,7 @@ TERMINAL_SOURCES = bounds.c ctlr.c util.c toggles.c screen.c selection.c kybd.c |
33 | 33 | # tables.c utf8.c |
34 | 34 | |
35 | 35 | # Network I/O Sources |
36 | -NETWORK_SOURCES = iocalls.c proxy.c | |
37 | -# connect.c | |
36 | +NETWORK_SOURCES = iocalls.c proxy.c connect.c | |
38 | 37 | |
39 | 38 | # Full library sources |
40 | 39 | SOURCES = $(TERMINAL_SOURCES) $(NETWORK_SOURCES) ft.c ft_cut.c ft_dft.c glue.c resources.c \ | ... | ... |