whois.c (53048) | whois.c (53291) |
---|---|
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 --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93"; 43#endif 44static const char rcsid[] = | 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 --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)whois.c 8.1 (Berkeley) 6/6/93"; 43#endif 44static const char rcsid[] = |
45 "$FreeBSD: head/usr.bin/whois/whois.c 53048 1999-11-09 09:01:38Z ache $"; | 45 "$FreeBSD: head/usr.bin/whois/whois.c 53291 1999-11-17 19:11:51Z ache $"; |
46#endif /* not lint */ 47 48#include <sys/types.h> 49#include <sys/socket.h> 50#include <netinet/in.h> 51#include <arpa/inet.h> 52#include <err.h> 53#include <netdb.h> 54#include <stdio.h> | 46#endif /* not lint */ 47 48#include <sys/types.h> 49#include <sys/socket.h> 50#include <netinet/in.h> 51#include <arpa/inet.h> 52#include <err.h> 53#include <netdb.h> 54#include <stdio.h> |
55#include <stdlib.h> |
|
55#include <string.h> 56#include <sysexits.h> 57#include <unistd.h> 58 | 56#include <string.h> 57#include <sysexits.h> 58#include <unistd.h> 59 |
59#define NICHOST "whois.crsnic.net" 60#define INICHOST "whois.internic.net" | 60#define NICHOST "whois.crsnic.net" 61#define INICHOST "whois.internic.net" |
61#define DNICHOST "whois.nic.mil" 62#define GNICHOST "whois.nic.gov" 63#define ANICHOST "whois.arin.net" 64#define RNICHOST "whois.ripe.net" 65#define PNICHOST "whois.apnic.net" | 62#define DNICHOST "whois.nic.mil" 63#define GNICHOST "whois.nic.gov" 64#define ANICHOST "whois.arin.net" 65#define RNICHOST "whois.ripe.net" 66#define PNICHOST "whois.apnic.net" |
66#define RUNICHOST "whois.ripn.net" | 67#define RUNICHOST "whois.ripn.net" 68#define MNICHOST "whois.ra.net" 69#define QNICHOST_TAIL ".whois-servers.net" |
67#define WHOIS_PORT 43 68 | 70#define WHOIS_PORT 43 71 |
72#define WHOIS_RECURSE 0x01 73#define WHOIS_INIC_FALLBACK 0x02 74#define WHOIS_QUICK 0x04 75 |
|
69static void usage __P((void)); | 76static void usage __P((void)); |
77static void whois __P((char *, struct sockaddr_in *, int)); |
|
70 71int 72main(argc, argv) 73 int argc; 74 char **argv; 75{ | 78 79int 80main(argc, argv) 81 int argc; 82 char **argv; 83{ |
76 register FILE *sfi, *sfo; 77 register int ch; 78 struct sockaddr_in sin; 79 struct hostent *hp; 80 struct servent *sp; 81 int s; | 84 int ch, i, j; 85 int use_qnichost, flags; |
82 char *host; | 86 char *host; |
87 char *qnichost; 88 struct servent *sp; 89 struct hostent *hp; 90 struct sockaddr_in sin; |
|
83 84#ifdef SOCKS 85 SOCKSinit(argv[0]); 86#endif 87 | 91 92#ifdef SOCKS 93 SOCKSinit(argv[0]); 94#endif 95 |
88 host = NICHOST; 89 while ((ch = getopt(argc, argv, "adgh:iprR")) != -1) | 96 host = NULL; 97 qnichost = NULL; 98 flags = 0; 99 use_qnichost = 0; 100 while ((ch = getopt(argc, argv, "adgh:impQrR")) != -1) |
90 switch((char)ch) { 91 case 'a': 92 host = ANICHOST; 93 break; 94 case 'd': 95 host = DNICHOST; 96 break; 97 case 'g': 98 host = GNICHOST; 99 break; 100 case 'h': 101 host = optarg; 102 break; 103 case 'i': 104 host = INICHOST; 105 break; | 101 switch((char)ch) { 102 case 'a': 103 host = ANICHOST; 104 break; 105 case 'd': 106 host = DNICHOST; 107 break; 108 case 'g': 109 host = GNICHOST; 110 break; 111 case 'h': 112 host = optarg; 113 break; 114 case 'i': 115 host = INICHOST; 116 break; |
117 case 'm': 118 host = MNICHOST; 119 break; |
|
106 case 'p': 107 host = PNICHOST; 108 break; | 120 case 'p': 121 host = PNICHOST; 122 break; |
123 case 'Q': 124 flags |= WHOIS_QUICK; 125 break; |
|
109 case 'r': 110 host = RNICHOST; 111 break; 112 case 'R': 113 host = RUNICHOST; 114 break; 115 case '?': 116 default: 117 usage(); 118 } 119 argc -= optind; 120 argv += optind; 121 122 if (!argc) 123 usage(); 124 | 126 case 'r': 127 host = RNICHOST; 128 break; 129 case 'R': 130 host = RUNICHOST; 131 break; 132 case '?': 133 default: 134 usage(); 135 } 136 argc -= optind; 137 argv += optind; 138 139 if (!argc) 140 usage(); 141 |
125 s = socket(PF_INET, SOCK_STREAM, 0); 126 if (s < 0) 127 err(EX_OSERR, "socket"); 128 129 memset(&sin, 0, sizeof sin); 130 sin.sin_len = sizeof sin; | 142 memset(&sin, 0, sizeof(sin)); 143 sin.sin_len = sizeof(sin); |
131 sin.sin_family = AF_INET; | 144 sin.sin_family = AF_INET; |
132 133 if (inet_aton(host, &sin.sin_addr) == 0) { 134 hp = gethostbyname2(host, AF_INET); 135 if (hp == NULL) 136 errx(EX_NOHOST, "%s: %s", host, hstrerror(h_errno)); 137 host = hp->h_name; 138 sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; 139 } 140 | |
141 sp = getservbyname("whois", "tcp"); 142 if (sp == NULL) 143 sin.sin_port = htons(WHOIS_PORT); 144 else 145 sin.sin_port = sp->s_port; 146 | 145 sp = getservbyname("whois", "tcp"); 146 if (sp == NULL) 147 sin.sin_port = htons(WHOIS_PORT); 148 else 149 sin.sin_port = sp->s_port; 150 |
147 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) | 151 /* 152 * If no nic host is specified, use whois-servers.net 153 * if there is a '.' in the name, else fall back to NICHOST. 154 */ 155 if (host == NULL) { 156 use_qnichost = 1; 157 host = NICHOST; 158 if (!(flags & WHOIS_QUICK)) 159 flags |= WHOIS_INIC_FALLBACK | WHOIS_RECURSE; 160 } 161 while (argc--) { 162 if (use_qnichost) { 163 if (qnichost) { 164 free(qnichost); 165 qnichost = NULL; 166 } 167 for (i = j = 0; (*argv)[i]; i++) 168 if ((*argv)[i] == '.') 169 j = i; 170 if (j != 0) { 171 qnichost = (char *) calloc(i - j + 1 + 172 strlen(QNICHOST_TAIL), sizeof(char)); 173 if (!qnichost) 174 err(1, "calloc"); 175 strcpy(qnichost, *argv + j + 1); 176 strcat(qnichost, QNICHOST_TAIL); 177 178 if (inet_aton(qnichost, &sin.sin_addr) == 0) { 179 hp = gethostbyname2(qnichost, AF_INET); 180 if (hp == NULL) { 181 free(qnichost); 182 qnichost = NULL; 183 } else { 184 sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; 185 } 186 } 187 } 188 } 189 if (!qnichost && inet_aton(host, &sin.sin_addr) == 0) { 190 hp = gethostbyname2(host, AF_INET); 191 if (hp == NULL) 192 errx(EX_NOHOST, "%s: %s", host, 193 hstrerror(h_errno)); 194 host = hp->h_name; 195 sin.sin_addr = *(struct in_addr *)hp->h_addr_list[0]; 196 } 197 198 whois(*argv++, &sin, flags); 199 } 200 exit(0); 201} 202 203static void 204whois(name, sinp, flags) 205 char *name; 206 struct sockaddr_in *sinp; 207 int flags; 208{ 209 FILE *sfi, *sfo; 210 char *buf, *p, *nhost; 211 size_t len; 212 int s, nomatch; 213 214 s = socket(PF_INET, SOCK_STREAM, 0); 215 if (s < 0) 216 err(EX_OSERR, "socket"); 217 218 if (connect(s, (struct sockaddr *)sinp, sizeof(*sinp)) < 0) |
148 err(EX_OSERR, "connect"); 149 150 sfi = fdopen(s, "r"); 151 sfo = fdopen(s, "w"); 152 if (sfi == NULL || sfo == NULL) 153 err(EX_OSERR, "fdopen"); | 219 err(EX_OSERR, "connect"); 220 221 sfi = fdopen(s, "r"); 222 sfo = fdopen(s, "w"); 223 if (sfi == NULL || sfo == NULL) 224 err(EX_OSERR, "fdopen"); |
154 while (argc-- > 1) 155 (void)fprintf(sfo, "%s ", *argv++); 156 (void)fprintf(sfo, "%s\r\n", *argv); | 225 (void)fprintf(sfo, "%s\r\n", name); |
157 (void)fflush(sfo); | 226 (void)fflush(sfo); |
158 while ((ch = getc(sfi)) != EOF) 159 putchar(ch); 160 exit(0); | 227 nhost = NULL; 228 nomatch = 0; 229 while ((buf = fgetln(sfi, &len))) { 230 if (buf[len - 2] == '\r') 231 buf[len - 2] = '\0'; 232 else 233 buf[len - 1] = '\0'; 234 235 if ((flags & WHOIS_RECURSE) && !nhost && 236 (p = strstr(buf, "Whois Server: "))) { 237 p += sizeof("Whois Server: ") - 1; 238 if ((len = strcspn(p, " \t\n\r"))) { 239 if ((nhost = malloc(len + 1)) == NULL) 240 err(1, "malloc"); 241 memcpy(nhost, p, len); 242 nhost[len] = '\0'; 243 } 244 } 245 if ((flags & WHOIS_INIC_FALLBACK) && !nhost && !nomatch && 246 (p = strstr(buf, "No match for \""))) { 247 p += sizeof("No match for \"") - 1; 248 if ((len = strcspn(p, "\"")) && 249 name[len] == '\0' && 250 strncasecmp(name, p, len) == 0 && 251 strchr(name, '.') == NULL) 252 nomatch = 1; 253 } 254 (void)puts(buf); 255 } 256 257 /* Do second lookup as needed */ 258 if (nomatch && !nhost) { 259 (void)printf("Looking up %s at %s.\n\n", name, INICHOST); 260 nhost = INICHOST; 261 } 262 if (nhost) { 263 if (inet_aton(nhost, &sinp->sin_addr) == 0) { 264 struct hostent *hp = gethostbyname2(nhost, AF_INET); 265 if (hp == NULL) 266 return; 267 sinp->sin_addr = *(struct in_addr *)hp->h_addr_list[0]; 268 } 269 if (!nomatch) 270 free(nhost); 271 whois(name, sinp, 0); 272 } |
161} 162 163static void 164usage() 165{ | 273} 274 275static void 276usage() 277{ |
166 fprintf(stderr, "usage: whois [-adgiprR] [-h hostname] name ...\n"); | 278 (void)fprintf(stderr, 279 "usage: whois [-adgimpQrR] [-h hostname] name ...\n"); |
167 exit(EX_USAGE); 168} | 280 exit(EX_USAGE); 281} |