Lines 48-53
Link Here
|
48 |
|
48 |
|
49 |
#include <sys/types.h> |
49 |
#include <sys/types.h> |
50 |
#include <sys/socket.h> |
50 |
#include <sys/socket.h> |
|
|
51 |
#include <sys/poll.h> |
51 |
#include <netinet/in.h> |
52 |
#include <netinet/in.h> |
52 |
#include <arpa/inet.h> |
53 |
#include <arpa/inet.h> |
53 |
#include <ctype.h> |
54 |
#include <ctype.h> |
Lines 59-64
Link Here
|
59 |
#include <string.h> |
60 |
#include <string.h> |
60 |
#include <sysexits.h> |
61 |
#include <sysexits.h> |
61 |
#include <unistd.h> |
62 |
#include <unistd.h> |
|
|
63 |
#include <fcntl.h> |
64 |
#include <errno.h> |
62 |
|
65 |
|
63 |
#define ABUSEHOST "whois.abuse.net" |
66 |
#define ABUSEHOST "whois.abuse.net" |
64 |
#define NICHOST "whois.crsnic.net" |
67 |
#define NICHOST "whois.crsnic.net" |
Lines 282-302
Link Here
|
282 |
FILE *sfi, *sfo; |
285 |
FILE *sfi, *sfo; |
283 |
struct addrinfo *hostres, *res; |
286 |
struct addrinfo *hostres, *res; |
284 |
char *buf, *host, *nhost, *p; |
287 |
char *buf, *host, *nhost, *p; |
285 |
int i, s; |
288 |
int i, j, n, s, count; |
286 |
size_t c, len; |
289 |
size_t c, len; |
|
|
290 |
struct pollfd *fds; |
291 |
int timeout = 100; |
287 |
|
292 |
|
288 |
s = -1; |
293 |
s = -1; |
289 |
hostres = gethostinfo(hostname, 1); |
294 |
hostres = gethostinfo(hostname, 1); |
290 |
for (res = hostres; res; res = res->ai_next) { |
295 |
for (res = hostres, count = 0; res; res = res->ai_next) |
|
|
296 |
count++; |
297 |
|
298 |
fds = calloc(count, sizeof(*fds)); |
299 |
if (fds == NULL) |
300 |
err(EX_OSERR, "calloc()"); |
301 |
|
302 |
for (res = hostres, i = 0, count = 0; res; res = res->ai_next) { |
291 |
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); |
303 |
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); |
292 |
if (s < 0) |
304 |
if (s < 0) { |
|
|
305 |
if (res->ai_next != NULL) |
306 |
continue; |
307 |
} else if ((flags = fcntl(s, F_GETFL)) == -1) { |
308 |
close(s); |
309 |
} else if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) { |
310 |
close(s); |
311 |
} else if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { |
312 |
if (errno != EINPROGRESS) { |
313 |
close(s); |
314 |
} else { |
315 |
fds[i].fd = s; |
316 |
fds[i].events = POLLERR | POLLHUP | |
317 |
POLLIN | POLLOUT; |
318 |
count++; |
319 |
i++; |
320 |
} |
321 |
} else |
322 |
goto done; |
323 |
|
324 |
if (count == 0) |
293 |
continue; |
325 |
continue; |
294 |
if (connect(s, res->ai_addr, res->ai_addrlen) == 0) |
326 |
|
295 |
break; |
327 |
do { |
296 |
close(s); |
328 |
if (res->ai_next == NULL) |
|
|
329 |
timeout = -1; |
330 |
n = poll(fds, i, timeout); |
331 |
if (n == 0) { |
332 |
timeout >> 1; |
333 |
break; |
334 |
} |
335 |
if (n < 0 ) { |
336 |
if (errno == EAGAIN || errno == EINTR) |
337 |
continue; |
338 |
s = -1; |
339 |
goto done; |
340 |
} |
341 |
for (j = 0; j < i; j++) { |
342 |
if (fds[j].fd == -1 || fds[j].events == 0 || |
343 |
fds[j].revents == 0) |
344 |
continue; |
345 |
s = fds[j].fd; |
346 |
if (fds[j].revents & POLLHUP) { |
347 |
close(s); |
348 |
fds[j].fd = -1; |
349 |
fds[j].events = 0; |
350 |
count--; |
351 |
continue; |
352 |
} |
353 |
/* Connect succeeded. */ |
354 |
goto done; |
355 |
} |
356 |
} while (timeout == -1 && count != 0); |
297 |
} |
357 |
} |
|
|
358 |
s = -1; |
359 |
|
360 |
done: |
361 |
for (j = 0; j < i; j++) |
362 |
if (fds[j].fd != s && fds[j].fd != -1) |
363 |
close(fds[j].fd); |
364 |
|
365 |
if (s != -1) { |
366 |
/* Restore default blocking behaviour. */ |
367 |
if ((flags = fcntl(s, F_GETFL)) != -1) { |
368 |
flags &= ~O_NONBLOCK; |
369 |
if (fcntl(s, F_SETFL, flags) == -1) |
370 |
err(EX_OSERR, "fcntl()"); |
371 |
} else |
372 |
err(EX_OSERR, "fcntl()"); |
373 |
} |
374 |
|
375 |
free(fds); |
298 |
freeaddrinfo(hostres); |
376 |
freeaddrinfo(hostres); |
299 |
if (res == NULL) |
377 |
if (s == -1) |
300 |
err(EX_OSERR, "connect()"); |
378 |
err(EX_OSERR, "connect()"); |
301 |
|
379 |
|
302 |
sfi = fdopen(s, "r"); |
380 |
sfi = fdopen(s, "r"); |