Commit a67b1c99d367cb55c374a699626a2ebcc3dd8319

Authored by perry.werneck@gmail.com
1 parent 8d885e30

Iniciando substituição das chamadas a gethostbyname

Showing 1 changed file with 314 additions and 0 deletions   Show diff stats
connect.c 0 → 100644
... ... @@ -0,0 +1,314 @@
  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 GNU, 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 connect.c 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 Mendonça)
  27 + *
  28 + */
  29 +
  30 +/*---[ Implement ]-------------------------------------------------------------------------------*/
  31 +
  32 + LIB3270_EXPORT int lib3270_sock_connect(H3270 *hSession, const char *hostname, const char *srvc, int timeout)
  33 + {
  34 + int s;
  35 + int sock = -1;
  36 + struct addrinfo hints;
  37 + struct addrinfo * result = NULL;
  38 + struct addrinfo * rp = NULL;
  39 + LIB3270_MESSAGE saved_status = hSession->oia_status;
  40 +
  41 + memset(&hints, 0, sizeof(struct addrinfo));
  42 + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
  43 + hints.ai_socktype = SOCK_STREAM; /* Stream socket */
  44 + hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
  45 + hints.ai_protocol = 0; /* Any protocol */
  46 + hints.ai_canonname = NULL;
  47 + hints.ai_addr = NULL;
  48 + hints.ai_next = NULL;
  49 +
  50 + if(timeout < 0)
  51 + timeout = 10;
  52 +
  53 + if(*hostname == '$')
  54 + {
  55 + const char *name = getenv(hostname+1);
  56 + if(!name)
  57 + {
  58 + lib3270_popup_dialog( hSession,
  59 + LIB3270_NOTIFY_ERROR,
  60 + _( "Connection error" ),
  61 + _( "Unable to find selected hostname." ),
  62 + _( "Can't determine value for environment variable \"%s\" " ),
  63 + hostname);
  64 + return -1;
  65 + }
  66 + hostname = name;
  67 + }
  68 +
  69 + status_changed(hSession,LIB3270_STATUS_RESOLVING);
  70 +
  71 + s = getaddrinfo(hostname, srvc, &hints, &result);
  72 +
  73 + if(s != 0)
  74 + {
  75 + lib3270_popup_dialog( hSession,
  76 + LIB3270_NOTIFY_ERROR,
  77 + _( "Connection error" ),
  78 + _( "Can't resolve hostname." ),
  79 + "%s",
  80 + gai_strerror(s));
  81 +
  82 + status_changed(hSession,saved_status);
  83 +
  84 + return -1;
  85 + }
  86 +
  87 + status_changed(hSession,LIB3270_STATUS_CONNECTING);
  88 +
  89 + for(rp = result; sock < 0 && rp != NULL; rp = rp->ai_next)
  90 + {
  91 + sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
  92 + if(sock < 0)
  93 + continue;
  94 +
  95 +#ifdef WIN32
  96 + u_long block;
  97 + u_int len = sizeof(int);
  98 +
  99 + WSASetLastError(0);
  100 + block = 1;
  101 +
  102 + if(ioctlsocket(sock,FIONBIO,&block))
  103 + {
  104 + lib3270_popup_dialog( hSession,
  105 + LIB3270_NOTIFY_ERROR,
  106 + _( "Connection error" ),
  107 + _( "ioctlsocket(FIONBIO) failed." ),
  108 + "Windows error %d",
  109 + WSAGetLastError() );
  110 + close(sock);
  111 + sock = -1;
  112 + }
  113 + else if(connect(sock, rp->ai_addr, rp->ai_addrlen))
  114 + {
  115 + int err = WSAGetLastError();
  116 + if(err != WSAEWOULDBLOCK)
  117 + {
  118 + lib3270_popup_dialog( hSession,
  119 + LIB3270_NOTIFY_ERROR,
  120 + _( "Connection error" ),
  121 + _( "Can't connect to host." ),
  122 + "Windows error %d",
  123 + WSAGetLastError() );
  124 + close(sock);
  125 + sock = -1;
  126 + }
  127 + }
  128 +
  129 + if(sock > 0)
  130 + {
  131 + // Connection in progress, wait until socket is available for write
  132 + fd_set wr;
  133 + struct timeval tm;
  134 + int status;
  135 + int err;
  136 + socklen_t len = sizeof(err);
  137 +
  138 + FD_ZERO(&wr);
  139 + FD_SET(sock, &wr);
  140 + memset(&tm,0,sizeof(tm));
  141 + tm.tv_sec = timeout;
  142 +
  143 + switch(select(sock+1, NULL, &wr, NULL, &tm))
  144 + {
  145 + case 0:
  146 + lib3270_popup_dialog( hSession,
  147 + LIB3270_NOTIFY_ERROR,
  148 + _( "Connection error" ),
  149 + _( "Can't connect to host." ),
  150 + "%s",
  151 + strerror(errno = ETIMEDOUT));
  152 + close(sock);
  153 + sock = -1;
  154 + break;
  155 +
  156 + case -1:
  157 + lib3270_popup_dialog( hSession,
  158 + LIB3270_NOTIFY_ERROR,
  159 + _( "Connection error" ),
  160 + _( "select() error when connecting to host." ),
  161 + "%s",
  162 + strerror(errno));
  163 + close(sock);
  164 + sock = -1;
  165 + break;
  166 +
  167 + default:
  168 + // Se o socket nao esta disponivel para gravacao o connect falhou
  169 + if(!FD_ISSET(sock,&wr))
  170 + {
  171 + lib3270_popup_dialog( hSession,
  172 + LIB3270_NOTIFY_ERROR,
  173 + _( "Connection error" ),
  174 + _( "Error when connecting to host." ),
  175 + "%s",
  176 + _( "Socket was not available after connect" ));
  177 + close(sock);
  178 + sock = -1;
  179 + }
  180 + else if(getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &err, &len) < 0)
  181 + {
  182 + lib3270_popup_dialog( hSession,
  183 + LIB3270_NOTIFY_ERROR,
  184 + _( "Connection error" ),
  185 + _( "Error getting connection state." ),
  186 + "%s",
  187 + strerror(errno));
  188 +
  189 + close(sock);
  190 + sock = -1;
  191 + }
  192 + else if(err)
  193 + {
  194 + lib3270_popup_dialog( hSession,
  195 + LIB3270_NOTIFY_ERROR,
  196 + _( "Connection error" ),
  197 + _( "socket error when connecting to host." ),
  198 + "Socket error %d",
  199 + err);
  200 +
  201 + close(sock);
  202 + sock = -1;
  203 + }
  204 + }
  205 + }
  206 +
  207 +#else
  208 + fcntl(sock, F_SETFL,fcntl(sock,F_GETFL,0)|O_NONBLOCK);
  209 +
  210 + errno = 0;
  211 + if(connect(sock, rp->ai_addr, rp->ai_addrlen))
  212 + {
  213 + if( errno != EINPROGRESS )
  214 + {
  215 + lib3270_popup_dialog( hSession,
  216 + LIB3270_NOTIFY_ERROR,
  217 + _( "Connection error" ),
  218 + _( "Can't connect to host." ),
  219 + "%s",
  220 + strerror(errno));
  221 + close(sock);
  222 + sock = -1;
  223 + }
  224 + }
  225 +
  226 + if(sock > 0)
  227 + {
  228 + // Connection in progress, wait until socket is available for write
  229 + fd_set wr;
  230 + struct timeval tm;
  231 + int status;
  232 + int err;
  233 + socklen_t len = sizeof(err);
  234 +
  235 + FD_ZERO(&wr);
  236 + FD_SET(sock, &wr);
  237 + memset(&tm,0,sizeof(tm));
  238 + tm.tv_sec = timeout;
  239 +
  240 + switch(select(sock+1, NULL, &wr, NULL, &tm))
  241 + {
  242 + case 0:
  243 + lib3270_popup_dialog( hSession,
  244 + LIB3270_NOTIFY_ERROR,
  245 + _( "Connection error" ),
  246 + _( "Can't connect to host." ),
  247 + "%s",
  248 + strerror(errno = ETIMEDOUT));
  249 + close(sock);
  250 + sock = -1;
  251 + break;
  252 +
  253 + case -1:
  254 + lib3270_popup_dialog( hSession,
  255 + LIB3270_NOTIFY_ERROR,
  256 + _( "Connection error" ),
  257 + _( "select() error when connecting to host." ),
  258 + "%s",
  259 + strerror(errno));
  260 + close(sock);
  261 + sock = -1;
  262 + break;
  263 +
  264 + default:
  265 +
  266 + // Se o socket nao esta disponivel para gravacao o connect falhou
  267 + if(!FD_ISSET(sock,&wr))
  268 + {
  269 + lib3270_popup_dialog( hSession,
  270 + LIB3270_NOTIFY_ERROR,
  271 + _( "Connection error" ),
  272 + _( "Error when connecting to host." ),
  273 + "%s",
  274 + _( "Socket was not available after connect" ));
  275 + close(sock);
  276 + sock = -1;
  277 + }
  278 + else if(getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
  279 + {
  280 + lib3270_popup_dialog( hSession,
  281 + LIB3270_NOTIFY_ERROR,
  282 + _( "Connection error" ),
  283 + _( "Error getting connection state." ),
  284 + "%s",
  285 + strerror(errno));
  286 +
  287 + close(sock);
  288 + sock = -1;
  289 + }
  290 + else if(err)
  291 + {
  292 + lib3270_popup_dialog( hSession,
  293 + LIB3270_NOTIFY_ERROR,
  294 + _( "Connection error" ),
  295 + _( "socket error when connecting to host." ),
  296 + "Socket error %d",
  297 + err);
  298 +
  299 + close(sock);
  300 + sock = -1;
  301 + }
  302 + }
  303 + }
  304 +#endif // WIN32
  305 + }
  306 +
  307 + freeaddrinfo(result);
  308 +
  309 + status_changed(hSession,saved_status);
  310 +
  311 + return sock;
  312 +
  313 + }
  314 +
... ...