xref: /reactos/base/applications/network/finger/net.c (revision 69931a4a)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *	This product includes software developed by the University of
19  *	California, Berkeley and its contributors.
20  * 4. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include "precomp.h"
38 
39 void
40 netfinger(char *name)
41 {
42 	extern int lflag;
43 	char c, lastc;
44 	struct in_addr defaddr;
45 	struct hostent *hp, def;
46 	struct servent *sp;
47 	struct sockaddr_in sin;
48 	SOCKET s;
49 	char *alist[1], *host;
50 
51 	/* If this is a local request */
52 	if (!(host = rindex(name, '@')))
53 		return;
54 
55 	*host++ = '\0';
56 	if (isdigit(*host) && (defaddr.s_addr = inet_addr(host)) != (unsigned long)-1) {
57 		def.h_name = host;
58 		def.h_addr_list = alist;
59 		def.h_addr = (char *)&defaddr;
60 		def.h_length = sizeof(struct in_addr);
61 		def.h_addrtype = AF_INET;
62 		def.h_aliases = 0;
63 		hp = &def;
64 	} else if (!(hp = gethostbyname(host))) {
65 		(void)fprintf(stderr,
66 		    "finger: unknown host: %s\n", host);
67 		return;
68 	}
69 	if (!(sp = getservbyname("finger", "tcp"))) {
70 		(void)fprintf(stderr, "finger: tcp/finger: unknown service\n");
71 		return;
72 	}
73 	sin.sin_family = hp->h_addrtype;
74 	bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
75 	sin.sin_port = sp->s_port;
76 	if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) == INVALID_SOCKET) {
77 		perror("finger: socket");
78 		return;
79 	}
80 
81 	/* have network connection; identify the host connected with */
82 	(void)printf("[%s]\n", hp->h_name);
83 	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
84 		fprintf(stderr, "finger: connect rc = %d", WSAGetLastError());
85 		(void)closesocket(s);
86 		return;
87 	}
88 
89 	/* -l flag for remote fingerd  */
90 	if (lflag)
91 		send(s, "/W ", 3, 0);
92 	/* send the name followed by <CR><LF> */
93 	send(s, name, strlen(name), 0);
94 	send(s, "\r\n", 2, 0);
95 
96 	/*
97 	 * Read from the remote system; once we're connected, we assume some
98 	 * data.  If none arrives, we hang until the user interrupts.
99 	 *
100 	 * If we see a <CR> or a <CR> with the high bit set, treat it as
101 	 * a newline; if followed by a newline character, only output one
102 	 * newline.
103 	 *
104 	 * Otherwise, all high bits are stripped; if it isn't printable and
105 	 * it isn't a space, we can simply set the 7th bit.  Every ASCII
106 	 * character with bit 7 set is printable.
107 	 */
108 	lastc = 0;
109 	while (recv(s, &c, 1, 0) == 1) {
110 		c &= 0x7f;
111 		if (c == 0x0d) {
112 			if (lastc == '\r')	/* ^M^M - skip dupes */
113 				continue;
114 			c = '\n';
115 			lastc = '\r';
116 		} else {
117 			if (!isprint(c) && !isspace(c))
118 				c |= 0x40;
119 			if (lastc != '\r' || c != '\n')
120 				lastc = c;
121 			else {
122 				lastc = '\n';
123 				continue;
124 			}
125 		}
126 		putchar(c);
127 	}
128 	if (lastc != '\n')
129 		putchar('\n');
130 	putchar('\n');
131 	(void)closesocket(s);
132 }
133