Commit f4e6dc59eb1dd2d06176519d7c1772e20ac220b4

Authored by perry.werneck@gmail.com
1 parent 353fee04

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 \
... ...