/* ** File name: WHOIS.C ** Product: TCPware for VMS ** Version: V5.6 ** Edit level: 20 ** ** Copyright (c) 1989-2000, 2001, 2002 by ** Process Software ** Framingham, Massachusetts ** ** This software is furnished under a license for use on a ** single computer system and may be copied only with the ** inclusion of the above copyright notice. This software, or ** any other copies thereof, may not be provided or otherwise ** made available to any other person except for use on such ** system and to one who agrees to these license terms. Title ** to and ownership of the software shall at all times remain ** in Process Software's name. ** ** The information in this document is subject to change ** without notice and should not be construed as a commitment ** by Process Software. Process Software assumes no ** responsibility for any errors that may appear in this document. ** ** Abstract: ** whois or nicname - DARPA Internet user name directory ** service as defined in RFC 742. ** ** Written by: DDN Network Information Center. ** This code may be freely copied for any use. ** ** Usage: whois [ -h host ] name ** ** 'host' may be either by name or address. ** ** Note: ** Modified for use with TCPware for OpenVMS. ** ** ** To use on a VAX with VAX C: ** $ CC WHOIS.C ** $ LINK WHOIS,SYS$INPUT/OPTIONS ** SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE ** SYS$SHARE:VAXCRTL/SHARE ** $ WHOIS :== $WHOIS ** ** To use on a VAX or Alpha with DEC C: ** $ CC/PREFIX=ALL WHOIS.C ** $ LINK WHOIS ** $ WHOIS :== $WHOIS ** ** Modification History: ** ** V5.5-1-18 18-May-2000 R. Young D/E 6225 ** When TCPware isn't running, an alpha system would report errors ** opening UCX$IPC_SHR. Changed code to catch that event and exit ** a little nicer. ** ** V5.5-1-19 19-May-2000 R. Young D/E 6238 ** Merged new version (from H. Goatley) which uses normal DEC C ** socket routines, automatically contacts the second ** server, and compiles cleanly with DEC C (no longer need ** /STANDARD=VAXC) ** ** V5.5-1-20 9-JUN-2000 Hunter Goatley ** When compiling on VAX with VAX C, use socket_recv() and socket_send(). ** */ #include #include #include #include #include #include /*#include */ #include #include #include #include #include #ifndef __DECC #define recv socket_recv #define send socket_send #endif #if defined(__DECC) && __DECC_VER < 60500000 #define bzero(str,len) memset((str),0,(len)) #define bcopy(from,to,size) memcpy((to),(from),(size)) #endif /* ** Define Constants */ #define SERVICE "whois" #define PROTOCOL "tcp" #define MAXTMPLEN 512 /* max length of tmp array declared below */ /* ** the possible host names for the whois server. */ char *whois_servers[] = { "rs.internic.net", "ds.internic.net", NULL /* null pointer terminates the list */ }; char whois_server_text[] = "Whois Server: "; main(argc, argv) char *argv[]; { int skt; int i, j, x; int whois_port; char tmp[MAXTMPLEN], *lnm, tmp2[MAXTMPLEN]; char new_whois_server[128], *y; struct sockaddr_in sin; struct hostent *hp; struct servent *sp; /* ** Decrement argc if argv[argc-1] is blank. Workaround for ** a problem with VMS 6.0 and before. If the image is invoked ** by way of a cld file set on the command table (via set command) ** argc comes in being one higher than it should. */ if (*argv[argc-1] == 0) argc--; argc--, argv++; /* test for presence of TCPWARE_WHOIS_SERVER logical */ if ((lnm = getenv("TCPWARE_WHOIS_SERVER")) != 0) { /* copy specified-host pointer to the array */ whois_servers[0] = lnm; /* make the specified-host the only entry */ whois_servers[1] = NULL; } /* test for presence of the -h flag. */ if (argc > 2 && strcmp(*argv, "-h") == 0) { argv++, argc--; /* copy specified-host pointer to the array */ whois_servers[0] = *argv++; /* make the specified-host the only entry */ whois_servers[1] = NULL; argc--; } /* punt if syntax is wrong */ if (argc != 1) { fprintf(stderr, "usage: whois [ -h host ] name\n"); exit(1); } /* run thru the list of whois servers till one is found * with an IP addr. Look first by hostname, then by * hostaddr that fails. */ for (i = 0; ;i++) if (whois_servers[i] == NULL) exit(1); else if ((hp = gethostbyname (whois_servers[i]))) break; else { struct in_addr hostaddr; /* * on ALPHA platform, ENOENT error occurs when * TCPware is not running * whois relies on UCX$IPC_SHR logical, DEC C * returns ENOENT if UCX$IPC_SHR unavailable */ if (errno == ENOENT) { exit(SS$_NOSUCHFILE); } hostaddr.s_addr = inet_addr (whois_servers[i]); if ((hp = gethostbyaddr ((char *)&hostaddr, 4, AF_INET))) break; else { fprintf(stderr, "whois: can't find host '%s'.\n", whois_servers[i]); continue; } } bzero(&sin,sizeof(sin)); sin.sin_family = hp->h_addrtype; /* create a socket */ if ((skt = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { perror("whois: socket"); exit(1); } bcopy (hp->h_addr, &sin.sin_addr, hp->h_length); /* get the port number for the whois server */ if ((sp = getservbyname(SERVICE, PROTOCOL)) == NULL) { fprintf(stderr, "whois: Don't know what service %s/%s is.\n", SERVICE, PROTOCOL); exit(1); } whois_port = sp->s_port; /* Now, connect to that port */ sin.sin_port = sp->s_port; if (connect (skt, (struct sockaddr *) &sin, sizeof (sin)) < 0) { perror("whois: connect"); exit(1); } /* write out the request to the server (remember to terminate * with ). */ sprintf(tmp, "%s\r\n", *argv); if (send(skt,tmp,strlen(tmp),0) < 0) { perror("whois: send"); exit(1); } new_whois_server[0] = '\0'; x = 0; /* read back results */ while (1) { i = recv(skt,tmp,sizeof(tmp),0); if (i <= 0) break; /* * The remote server sends back linefeed-terminated * strings, so buffer them up and print them as lines * instead of using putchar(); it looks a lot better * under VMS that way. No length checking is done, since * each line should be fewer than 80 characters. */ for(j=0; j 0) { printf("Please wait, connecting to new WHOIS server %s....\n", new_whois_server); if ((hp = gethostbyname (new_whois_server)) == 0) { fprintf(stderr, "whois: can't find host '%s'.\n", new_whois_server); exit(1); } bzero(&sin,sizeof(sin)); sin.sin_family = hp->h_addrtype; /* create a socket */ if ((skt = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { perror("whois: socket"); exit(1); } bcopy (hp->h_addr, &sin.sin_addr, hp->h_length); /* Now, connect to that port */ sin.sin_port = whois_port; if (connect (skt, (struct sockaddr *) &sin, sizeof (sin)) < 0) { perror("whois: connect"); exit(1); } /* write out the request to the server (remember to terminate * with ). */ sprintf(tmp, "%s\r\n", *argv); if (send(skt,tmp,strlen(tmp),0) < 0) { perror("whois: send"); exit(1); } x = 0; /* read back results */ while (1) { i = recv(skt,tmp,sizeof(tmp),0); if (i <= 0) break; /* * The remote server sends back linefeed-terminated * strings, so buffer them up and print them as lines * instead of using putchar(); it looks a lot better * under VMS that way. No length checking is done, since * each line should be fewer than 80 characters. */ for(j=0; j