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.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * 8/1/97 - Ted Felix <tfelix@fred.net>
34  *          Ported to Win32 from 4.4-BSDLITE2 from wcarchive.
35  *          Added WSAStartup()/WSACleanup() and switched from the
36  *          more convenient fdopen()/fprintf() to send()/recv().
37  */
38 
39 //#include <sys/types.h>
40 #define WIN32_NO_STATUS
41 #include <windef.h>
42 #define _INC_WINDOWS
43 #include <winsock2.h>
44 /* #include <sys/socket.h> */
45 /* #include <netinet/in.h> */
46 /* #include <netdb.h> */
47 #include <stdio.h>
48 #include <stdlib.h>
49 
50 /* #include <various.h> */
51 /* #include <getopt.h> */
52 /* #include <io.h> */
53 
54 static char NICHOST[] = "whois.internic.net";
55 char *host = NULL;
56 int optset = 0;
57 static void usage();
58 static void cleanup(int iExitCode);
59 
60 void getwhoisserver(int argc, char **argv)
61 {
62 	int i = 1;
63 
64     while(i < argc)
65 	{
66 		if (!strcmp(argv[i], "-h"))
67 		{
68 			if (i + 2 < argc)
69 			{
70 				host = argv[i +1];
71 				optset = i + 1;
72 			}
73 			else
74 			{
75 				optset = argc;
76 			}
77 			return;
78 		}
79 		i++;
80 	}
81 	host = NICHOST;
82 	optset = 1;
83 }
84 
85 int main(int argc, char **argv)
86 {
87 	char ch;
88 	struct sockaddr_in sin;
89 	struct hostent *hp;
90 	struct servent *sp;
91 	SOCKET s;
92 
93 	WORD wVersionRequested;
94 	WSADATA wsaData;
95 	int err;
96 
97 	getwhoisserver(argc, argv);
98 	argc -= optset;
99 	argv += optset;
100 
101     if (!host || !argc)
102 		usage();
103 
104 	/* Start winsock */
105 	wVersionRequested = MAKEWORD( 1, 1 );
106 	err = WSAStartup( wVersionRequested, &wsaData );
107 	if ( err != 0 )
108 	{
109 		/* Tell the user that we couldn't find a usable */
110 		/* WinSock DLL.                                 */
111 		perror("whois: WSAStartup failed");
112 		cleanup(1);
113 	}
114 
115 	hp = gethostbyname(host);
116 	if (hp == NULL) {
117 		(void)fprintf(stderr, "whois: %s: ", host);
118 		cleanup(1);
119 	}
120 	host = hp->h_name;
121 
122 	s = socket(hp->h_addrtype, SOCK_STREAM, 0);
123 	if (s == INVALID_SOCKET) {
124 		perror("whois: socket");
125 		cleanup(1);
126 	}
127 
128 	memset(/*(caddr_t)*/&sin, 0, sizeof(sin));
129 	sin.sin_family = hp->h_addrtype;
130 	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
131 		perror("whois: bind");
132 		cleanup(1);
133 	}
134 
135 	memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
136 	sp = getservbyname("nicname", "tcp");
137 	if (sp == NULL) {
138 		(void)fprintf(stderr, "whois: nicname/tcp: unknown service\n");
139 		cleanup(1);
140 	}
141 
142 	sin.sin_port = sp->s_port;
143 
144 	/* have network connection; identify the host connected with */
145 	(void)printf("[%s]\n", hp->h_name);
146 
147 	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
148 		fprintf(stderr, "whois: connect error = %d\n", WSAGetLastError());
149 		cleanup(1);
150 	}
151 
152 	/* WinSock doesn't allow using a socket as a file descriptor. */
153 	/* Have to use send() and recv().  whois will drop connection. */
154 
155 	/* For each request */
156 	while (argc-- > 1)
157 	{
158 		/* Send the request */
159 		send(s, *argv, strlen(*argv), 0);
160 		send(s, " ", 1, 0);
161 		argv++;
162 	}
163 	/* Send the last request */
164 	send(s, *argv, strlen(*argv), 0);
165 	send(s, "\r\n", 2, 0);
166 
167 	/* Receive anything and print it */
168 	while (recv(s, &ch, 1, 0) == 1)
169 		putchar(ch);
170 
171 	cleanup(0);
172 	return 0;
173 }
174 
175 static void usage()
176 {
177 	(void)fprintf(stderr, "usage: whois [-h hostname] name ...\n");
178 	cleanup(1);
179 }
180 
181 static void cleanup(int iExitCode)
182 {
183 	WSACleanup();
184 	exit(iExitCode);
185 }
186