whois.c (267871) | whois.c (281959) |
---|---|
1/* | 1/*- |
2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. --- 25 unchanged lines hidden (view full) --- 35 36#if 0 37#ifndef lint 38static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93"; 39#endif /* not lint */ 40#endif 41 42#include <sys/cdefs.h> | 2 * Copyright (c) 1980, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. --- 25 unchanged lines hidden (view full) --- 35 36#if 0 37#ifndef lint 38static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93"; 39#endif /* not lint */ 40#endif 41 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/usr.bin/whois/whois.c 267871 2014-06-25 15:39:08Z ume $"); | 43__FBSDID("$FreeBSD: head/usr.bin/whois/whois.c 281959 2015-04-25 00:51:44Z delphij $"); |
44 45#include <sys/types.h> 46#include <sys/socket.h> | 44 45#include <sys/types.h> 46#include <sys/socket.h> |
47#include <sys/poll.h> |
|
47#include <netinet/in.h> 48#include <arpa/inet.h> 49#include <ctype.h> 50#include <err.h> 51#include <netdb.h> 52#include <stdarg.h> 53#include <stdio.h> 54#include <stdlib.h> 55#include <string.h> 56#include <sysexits.h> 57#include <unistd.h> | 48#include <netinet/in.h> 49#include <arpa/inet.h> 50#include <ctype.h> 51#include <err.h> 52#include <netdb.h> 53#include <stdarg.h> 54#include <stdio.h> 55#include <stdlib.h> 56#include <string.h> 57#include <sysexits.h> 58#include <unistd.h> |
59#include <fcntl.h> 60#include <errno.h> |
|
58 59#define ABUSEHOST "whois.abuse.net" 60#define NICHOST "whois.crsnic.net" 61#define INICHOST "whois.networksolutions.com" 62#define GNICHOST "whois.nic.gov" 63#define ANICHOST "whois.arin.net" 64#define LNICHOST "whois.lacnic.net" 65#define KNICHOST "whois.krnic.net" --- 209 unchanged lines hidden (view full) --- 275} 276 277static void 278whois(const char *query, const char *hostname, int flags) 279{ 280 FILE *fp; 281 struct addrinfo *hostres, *res; 282 char *buf, *host, *nhost, *p; | 61 62#define ABUSEHOST "whois.abuse.net" 63#define NICHOST "whois.crsnic.net" 64#define INICHOST "whois.networksolutions.com" 65#define GNICHOST "whois.nic.gov" 66#define ANICHOST "whois.arin.net" 67#define LNICHOST "whois.lacnic.net" 68#define KNICHOST "whois.krnic.net" --- 209 unchanged lines hidden (view full) --- 278} 279 280static void 281whois(const char *query, const char *hostname, int flags) 282{ 283 FILE *fp; 284 struct addrinfo *hostres, *res; 285 char *buf, *host, *nhost, *p; |
283 int i, s; | 286 int i, j, s = -1, count; |
284 size_t c, len; | 287 size_t c, len; |
288 struct pollfd *fds; 289 int timeout = 180; |
|
285 | 290 |
286 s = -1; | |
287 hostres = gethostinfo(hostname, 1); | 291 hostres = gethostinfo(hostname, 1); |
288 for (res = hostres; res; res = res->ai_next) { 289 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); | 292 for (res = hostres, count = 0; res; res = res->ai_next) 293 count++; 294 295 fds = calloc(count, sizeof(*fds)); 296 if (fds == NULL) 297 err(EX_OSERR, "calloc()"); 298 299 /* 300 * Traverse the result list elements and make non-block 301 * connection attempts. 302 */ 303 count = i = 0; 304 for (res = hostres; res != NULL; res = res->ai_next) { 305 s = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK, 306 res->ai_protocol); |
290 if (s < 0) 291 continue; | 307 if (s < 0) 308 continue; |
292 if (connect(s, res->ai_addr, res->ai_addrlen) == 0) 293 break; 294 close(s); | 309 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { 310 if (errno == EINPROGRESS) { 311 /* Add the socket to poll list */ 312 fds[i].fd = s; 313 fds[i].events = POLLERR | POLLHUP | 314 POLLIN | POLLOUT; 315 count++; 316 i++; 317 } else { 318 close(s); 319 s = -1; 320 321 /* 322 * Poll only if we have something to poll, 323 * otherwise just go ahead and try next 324 * address 325 */ 326 if (count == 0) 327 continue; 328 } 329 } else 330 goto done; 331 332 /* 333 * If we are at the last address, poll until a connection is 334 * established or we failed all connection attempts. 335 */ 336 if (res->ai_next == NULL) 337 timeout = INFTIM; 338 339 /* 340 * Poll the watched descriptors for successful connections: 341 * if we still have more untried resolved addresses, poll only 342 * once; otherwise, poll until all descriptors have errors, 343 * which will be considered as ETIMEDOUT later. 344 */ 345 do { 346 int n; 347 348 n = poll(fds, i, timeout); 349 if (n == 0) { 350 /* 351 * No event reported in time. Try with a 352 * smaller timeout (but cap at 2-3ms) 353 * after a new host have been added. 354 */ 355 if (timeout >= 3) 356 timeout <<= 1; 357 358 break; 359 } else if (n < 0) { 360 /* 361 * errno here can only be EINTR which we would want 362 * to clean up and bail out. 363 */ 364 s = -1; 365 goto done; 366 } 367 368 /* 369 * Check for the event(s) we have seen. 370 */ 371 for (j = 0; j < i; j++) { 372 if (fds[j].fd == -1 || fds[j].events == 0 || 373 fds[j].revents == 0) 374 continue; 375 if (fds[j].revents & ~(POLLIN | POLLOUT)) { 376 close(s); 377 fds[j].fd = -1; 378 fds[j].events = 0; 379 count--; 380 continue; 381 } else if (fds[j].revents & (POLLIN | POLLOUT)) { 382 /* Connect succeeded. */ 383 s = fds[j].fd; 384 385 goto done; 386 } 387 388 } 389 } while (timeout == INFTIM && count != 0); |
295 } | 390 } |
391 392 /* All attempts were failed */ 393 s = -1; 394 if (count == 0) 395 errno = ETIMEDOUT; 396 397done: 398 /* Close all watched fds except the succeeded one */ 399 for (j = 0; j < i; j++) 400 if (fds[j].fd != s && fds[j].fd != -1) 401 close(fds[j].fd); 402 403 if (s != -1) { 404 /* Restore default blocking behavior. */ 405 if ((flags = fcntl(s, F_GETFL)) != -1) { 406 flags &= ~O_NONBLOCK; 407 if (fcntl(s, F_SETFL, flags) == -1) 408 err(EX_OSERR, "fcntl()"); 409 } else 410 err(EX_OSERR, "fcntl()"); 411 } 412 413 free(fds); |
|
296 freeaddrinfo(hostres); | 414 freeaddrinfo(hostres); |
297 if (res == NULL) | 415 if (s == -1) |
298 err(EX_OSERR, "connect()"); 299 300 fp = fdopen(s, "r+"); 301 if (fp == NULL) 302 err(EX_OSERR, "fdopen()"); 303 if (strcmp(hostname, GERMNICHOST) == 0) { 304 fprintf(fp, "-T dn,ace -C US-ASCII %s\r\n", query); 305 } else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) { --- 63 unchanged lines hidden --- | 416 err(EX_OSERR, "connect()"); 417 418 fp = fdopen(s, "r+"); 419 if (fp == NULL) 420 err(EX_OSERR, "fdopen()"); 421 if (strcmp(hostname, GERMNICHOST) == 0) { 422 fprintf(fp, "-T dn,ace -C US-ASCII %s\r\n", query); 423 } else if (strcmp(hostname, "dk" QNICHOST_TAIL) == 0) { --- 63 unchanged lines hidden --- |