[BACK]Return to whois.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / whois

Diff for /src/usr.bin/whois/whois.c between version 1.17 and 1.18

version 1.17, 2002/12/17 20:17:49 version 1.18, 2002/12/19 20:37:24
Line 54 
Line 54 
 #include <arpa/inet.h>  #include <arpa/inet.h>
 #include <netdb.h>  #include <netdb.h>
   
   #include <ctype.h>
 #include <err.h>  #include <err.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <sysexits.h>  
 #include <unistd.h>  #include <unistd.h>
   
 #define NICHOST         "whois.crsnic.net"  #define NICHOST         "whois.crsnic.net"
Line 71 
Line 71 
 #define RUNICHOST       "whois.ripn.net"  #define RUNICHOST       "whois.ripn.net"
 #define MNICHOST        "whois.ra.net"  #define MNICHOST        "whois.ra.net"
 #define LNICHOST        "whois.lacnic.net"  #define LNICHOST        "whois.lacnic.net"
   #define SNICHOST        "whois.6bone.net"
   #define VNICHOST        "whois.networksolutions.com"
 #define QNICHOST_TAIL   ".whois-servers.net"  #define QNICHOST_TAIL   ".whois-servers.net"
 #define WHOIS_PORT      43  #define WHOIS_PORT      43
   
Line 79 
Line 81 
 #define WHOIS_QUICK             0x04  #define WHOIS_QUICK             0x04
   
 static __dead void usage(void);  static __dead void usage(void);
 static int whois(char *, struct addrinfo *, int);  static int whois(const char *, const char *, int);
   static char *choose_server(const char *, const char *);
   
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
         int ch, i, j, error, rval;          int ch, flags, rval;
         int use_qnichost, flags;          char *host, *name, *country, *server;
         size_t len;  
         char *host, *qnichost, *name;  
         struct addrinfo hints, *res;  
   
 #ifdef SOCKS  #ifdef SOCKS
         SOCKSinit(argv[0]);          SOCKSinit(argv[0]);
 #endif  #endif
           country = host = server = NULL;
         host = NULL;          flags = rval = 0;
         qnichost = NULL;          while ((ch = getopt(argc, argv, "ac:dgh:ilmpqQrR6")) != -1)
         flags = 0;  
         use_qnichost = 0;  
         rval = 0;  
         while ((ch = getopt(argc, argv, "adgh:ilmpqQrR")) != -1)  
                 switch((char)ch) {                  switch((char)ch) {
                 case 'a':                  case 'a':
                         host = ANICHOST;                          host = ANICHOST;
                         break;                          break;
                   case 'c':
                           country = optarg;
                           break;
                 case 'd':                  case 'd':
                         host = DNICHOST;                          host = DNICHOST;
                         break;                          break;
Line 137 
Line 136 
                 case 'R':                  case 'R':
                         host = RUNICHOST;                          host = RUNICHOST;
                         break;                          break;
                 case '?':                  case '6':
                           host = SNICHOST;
                           break;
                 default:                  default:
                         usage();                          usage();
                 }                  }
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
   
         if (!argc)          if (!argc || (country != NULL && host != NULL))
                 usage();                  usage();
   
         /*          if (host == NULL && country == NULL && !(flags & WHOIS_QUICK))
          * If no nic host is specified, use whois-servers.net                  flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE;
          * if there is a '.' in the name, else fall back to NICHOST.          for (name = *argv; (name = *argv) != NULL; argv++)
          */                  rval += whois(name, host ? host : choose_server(name, country), flags);
         if (host == NULL) {  
                 use_qnichost = 1;  
                 host = NICHOST;  
                 if (!(flags & WHOIS_QUICK))  
                         flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE;  
         }  
         for (name = *argv; (name = *argv) != NULL; argv++) {  
                 if (use_qnichost) {  
                         if (qnichost) {  
                                 free(qnichost);  
                                 qnichost = NULL;  
                         }  
                         for (i = j = 0; name[i]; i++)  
                                 if (name[i] == '.')  
                                         j = i;  
                         if (j != 0) {  
                                 len = i - j + 1 + strlen(QNICHOST_TAIL);  
                                 qnichost = (char *)calloc(len, sizeof(char));  
                                 if (!qnichost)  
                                         err(1, "calloc");  
                                 strlcpy(qnichost, name + j + 1, len);  
                                 strlcat(qnichost, QNICHOST_TAIL, len);  
                                 memset(&hints, 0, sizeof(hints));  
                                 hints.ai_flags = 0;  
                                 hints.ai_family = AF_UNSPEC;  
                                 hints.ai_socktype = SOCK_STREAM;  
                                 error = getaddrinfo(qnichost, "whois",  
                                     &hints, &res);  
                                 if (error) {  
                                         warnx("%s: %s", qnichost,  
                                             gai_strerror(error));  
                                         rval++;  
                                         continue;  
                                 }  
                         }  
                 }  
                 if (!qnichost) {  
                         memset(&hints, 0, sizeof(hints));  
                         hints.ai_flags = 0;  
                         hints.ai_family = AF_UNSPEC;  
                         hints.ai_socktype = SOCK_STREAM;  
                         error = getaddrinfo(host, "whois", &hints, &res);  
                         if (error) {  
                                 warnx("%s: %s", host, gai_strerror(error));  
                                 rval++;  
                                 continue;  
                         }  
                 }  
   
                 whois(name, res, flags);  
                 freeaddrinfo(res);  
         }  
         exit(rval);          exit(rval);
 }  }
   
 static int  static int
 whois(char *name, struct addrinfo *res, int flags)  whois(const char *name, const char *server, int flags)
 {  {
         FILE *sfi, *sfo;          FILE *sfi, *sfo;
         char *buf, *p, *nhost, *nbuf = NULL;          char *buf, *p, *nhost, *nbuf = NULL;
         size_t len;          size_t len;
         int s, nomatch, rval;          int s, nomatch, error;
         const char *reason = NULL;          const char *reason = NULL;
           struct addrinfo hints, *res;
   
           memset(&hints, 0, sizeof(hints));
           hints.ai_flags = 0;
           hints.ai_family = AF_UNSPEC;
           hints.ai_socktype = SOCK_STREAM;
           error = getaddrinfo(server, "whois", &hints, &res);
           if (error) {
                   warnx("%s: %s", server, gai_strerror(error));
                   return (1);
           }
   
         s = -1;          s = -1;
         rval = 0;  
         for (/*nothing*/; res; res = res->ai_next) {          for (/*nothing*/; res; res = res->ai_next) {
                 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);                  s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
                 if (s < 0) {                  if (s < 0) {
Line 237 
Line 196 
                         warn("%s", reason);                          warn("%s", reason);
                 else                  else
                         warn("unknown error in connection attempt");                          warn("unknown error in connection attempt");
                 return (rval + 1);                  freeaddrinfo(res);
                   return (1);
         }          }
   
         sfi = fdopen(s, "r");          sfi = fdopen(s, "r");
         sfo = fdopen(s, "w");          sfo = fdopen(s, "w");
         if (sfi == NULL || sfo == NULL)          if (sfi == NULL || sfo == NULL)
                 err(EX_OSERR, "fdopen");                  err(1, "fdopen");
         (void)fprintf(sfo, "%s\r\n", name);          (void)fprintf(sfo, "%s\r\n", name);
         (void)fflush(sfo);          (void)fflush(sfo);
         nhost = NULL;          nhost = NULL;
Line 261 
Line 221 
                         buf = nbuf;                          buf = nbuf;
                 }                  }
   
                 if ((flags & WHOIS_RECURSE) && !nhost &&                  if ((flags & WHOIS_RECURSE) && nhost == NULL &&
                     (p = strstr(buf, "Whois Server: "))) {                      (p = strstr(buf, "Whois Server: "))) {
                         p += sizeof("Whois Server: ") - 1;                          p += sizeof("Whois Server: ") - 1;
                         if ((len = strcspn(p, " \t\n\r"))) {                          if ((len = strcspn(p, " \t\n\r"))) {
Line 271 
Line 231 
                                 nhost[len] = '\0';                                  nhost[len] = '\0';
                         }                          }
                 }                  }
                 if ((flags & WHOIS_INIC_FALLBACK) && !nhost && !nomatch &&                  if ((flags & WHOIS_INIC_FALLBACK) && nhost == NULL &&
                     (p = strstr(buf, "No match for \""))) {                      !nomatch && (p = strstr(buf, "No match for \""))) {
                         p += sizeof("No match for \"") - 1;                          p += sizeof("No match for \"") - 1;
                         if ((len = strcspn(p, "\"")) && len == strlen(name) &&                          if ((len = strcspn(p, "\"")) && len == strlen(name) &&
                             strncasecmp(name, p, len) == 0)                              strncasecmp(name, p, len) == 0)
Line 280 
Line 240 
                 }                  }
                 (void)puts(buf);                  (void)puts(buf);
         }          }
         if (nbuf)          if (nbuf != NULL)
                 free(nbuf);                  free(nbuf);
   
         /* Do second lookup as needed */          /* Do second lookup as needed */
         if (nomatch && !nhost) {          if (nomatch && nhost == NULL) {
                 (void)printf("Looking up %s at %s.\n\n", name, INICHOST);                  (void)printf("Looking up %s at %s.\n\n", name, INICHOST);
                 nhost = INICHOST;                  nhost = INICHOST;
         }          }
         if (nhost) {          if (nhost) {
                 struct addrinfo hints, *res2;                  error += whois(name, nhost, 0);
                 int error;  
   
                 memset(&hints, 0, sizeof(hints));  
                 hints.ai_flags = 0;  
                 hints.ai_family = AF_UNSPEC;  
                 hints.ai_socktype = SOCK_STREAM;  
                 error = getaddrinfo(nhost, "whois", &hints, &res2);  
                 if (error) {  
                         warnx("%s: %s", nhost, gai_strerror(error));  
                         return (rval + 1);  
                 }  
                 if (!nomatch)                  if (!nomatch)
                         free(nhost);                          free(nhost);
                 rval += whois(name, res2, 0);  
                 freeaddrinfo(res2);  
         }          }
         return (rval);          freeaddrinfo(res);
           return (error);
 }  }
   
   /*
    * If no country is specified determine the top level domain from the query.
    * If the TLD is a number, query ARIN.  Otherwise, use TLD.whois-server.net.
    * If the domain does not contain '.', fall back to NICHOST (or VNICHOST
    * if name is a handle that starts with a '!').
    */
   static char *
   choose_server(const char *name, const char *country)
   {
           static char *server;
           const char *qhead;
           size_t len;
   
           if (country != NULL)
                   qhead = country;
           else if ((qhead = strrchr(name, '.')) == NULL)
                   return (*name == '!' ? VNICHOST : NICHOST);
           else if (isdigit(*(++qhead)))
                   return (ANICHOST);
           len = strlen(qhead) + sizeof(QNICHOST_TAIL);
           if ((server = realloc(server, len)) == NULL)
                   err(1, "realloc");
           strlcpy(server, qhead, len);
           strlcat(server, QNICHOST_TAIL, len);
           return (server);
   }
   
 static __dead void  static __dead void
 usage(void)  usage(void)
 {  {
           extern char *__progname;
   
         (void)fprintf(stderr,          (void)fprintf(stderr,
             "usage: whois [-adgilmpqQrR] [-h hostname] name ...\n");              "usage: %s [-adgilmpqQrR6] [-c country-code | -h hostname] "
         exit(EX_USAGE);                  "name ...\n", __progname);
           exit(1);
 }  }

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.18