ftp.nice.ch/pub/next/unix/network/infosystems/whois.s.tar.gz#/whois/whois.c

This is whois.c in view mode; [Download] [Up]

/* Replacement for "whois" client */
/* Eric P. Scott, San Francisco State University, April 1993 */

static char sccsid[]="@(#)whois.c	1.0 (SFSU) 4/9/93";

#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/uio.h>

#ifndef WHOIS_DEFAULT
#define WHOIS_DEFAULT "rs.internic.net"
#endif

char defhost[64]=WHOIS_DEFAULT;

int verbose;

main(argc, argv)
int argc;
char *argv[];
{
	extern char *getenv();
	extern int optind;
	extern char *optarg;
	void try();
	unsigned short portfrom();
	register struct hostent *h;
	register int i;
	struct sockaddr_in sin;
	char *host, *port;
	int iovcnt;
	struct iovec iov[16];

	if (!(host=getenv("WHOIS_SERVER"))) host=defhost;
	port=(char *)NULL;
	while ((i=getopt(argc, argv, "h:p:v"))!=EOF) switch (i) {
	case 'h':
		host=optarg;
		break;
	case 'p':
		port=optarg;
		break;
	case 'v':
		verbose++;
		break;
	default:
		goto usage;
	}
	if (argc-optind<1) {
	usage:
		if (verbose) (void)fprintf(stderr,
			"Usage: %s [ -h host ] [ -p port ] [ -v ] name\n\
\tdefault host is %s\n\
\t(can be overridden with WHOIS_SERVER environment variable)\n",
			*argv, defhost);
		else (void)fprintf(stderr, "Usage: %s [ -h host ] name\n",
			*argv);
		exit(1);
	}
	/* allow "name" to consist of multiple "words" */
	iovcnt=0;
	i=optind;
	iov[iovcnt].iov_base=argv[i];
	iov[iovcnt++].iov_len=strlen(argv[i]);
	while (++i<argc) {
		if (iovcnt>=sizeof iov/sizeof iov[0]) goto usage;
		iov[iovcnt].iov_base=" ";
		iov[iovcnt++].iov_len=1;
		if (iovcnt>=sizeof iov/sizeof iov[0]) goto usage;
		iov[iovcnt].iov_base=argv[i];
		iov[iovcnt++].iov_len=strlen(argv[i]);
	}
	if (iovcnt>=sizeof iov/sizeof iov[0]) goto usage;
	iov[iovcnt].iov_base="\r\n";
	iov[iovcnt++].iov_len=2;
	/*
	 * Users rarely need to know numeric IP addresses or port numbers,
	 * but it's still a good idea to support them
	 */
	bzero((char *)&sin, sizeof sin);
	sin.sin_addr.s_addr=inet_addr(host);	/* try x.x.x.x format */
	if (sin.sin_addr.s_addr!=0xffffffff) {
		sin.sin_family=AF_INET;
		sin.sin_port=htons(port ? portfrom(port) : IPPORT_WHOIS);
		try(&sin, iov, iovcnt);
	}
	else {
		if (!(h=gethostbyname(host))) {	/* name lookup */
			herror(host);
			exit(1);
		}
		sin.sin_family=h->h_addrtype;
		sin.sin_port=htons(port ? portfrom(port) : IPPORT_WHOIS);
		i=0; do {	/* some hosts have multiple IP addresses */
			bcopy(h->h_addr_list[i], (char *)&sin.sin_addr,
				h->h_length);
			try(&sin, iov, iovcnt);
		} while (h->h_addr_list[++i]);
	}
	exit(1);
}

/* convert string to TCP port number, return in host order */
unsigned short portfrom(n)
char *n;
{
	register struct servent *se;
	int port, pos;

	pos=0;
	if (sscanf(n, "%d%n", &port, &pos)==1&&pos==0&&(unsigned)port<=65535)
		return(port);
	if (!(se=getservbyname(n, "tcp"))) {
		(void)fprintf(stderr, "%s/tcp: unknown service\n", n);
		exit(1);
	}
	return(ntohl(se->s_port));
}

/* try to establish session with given host; return on failure */
void try(sin, iov, iovcnt)
struct sockaddr_in *sin;
struct iovec *iov;
int iovcnt;
{
	int s, i;
	FILE *f;

	if (verbose) {
		(void)fprintf(stderr, "Trying [%s]... ",
			inet_ntoa(sin->sin_addr));
		(void)fflush(stderr);
	}

	if ((s=socket(PF_INET, SOCK_STREAM, 0))<0) {
		perror("socket");
		exit(1);
	}
	if (connect(s, (struct sockaddr *)sin, sizeof(*sin))<0) {
		perror("");
		(void)close(s);
		return;
	}
	if (verbose) {
		(void)fputs("OK\n", stderr);
		(void)fflush(stderr);
	}

	/* send one-line message to server */
	if (writev(s, iov, iovcnt)<0) {
		perror("writev");
		(void)close(s);
		return;
	}

	/* read from socket, output anything we receive */
	/* convert NVT end-of-line convention to UNIX newline */
	f=fdopen(s, "r");
	while ((s=getc(f))!=EOF) {
		if (s=='\r') {
			if ((s=getc(f))!='\n') putchar('\r');
			if (s==EOF) break;
			if (s=='\0') continue;
		}
		putchar(s);
	}
	(void)fclose(f);

	exit(0);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.