xref: /minix3/usr.bin/finger/net.c (revision 406cdd95a6bb64607d1091a36d0958ce7043a81d)
1*406cdd95SThomas Cort /*	$NetBSD: net.c,v 1.23 2009/04/12 06:18:54 lukem Exp $	*/
2*406cdd95SThomas Cort 
3*406cdd95SThomas Cort /*
4*406cdd95SThomas Cort  * Copyright (c) 1989, 1993
5*406cdd95SThomas Cort  *	The Regents of the University of California.  All rights reserved.
6*406cdd95SThomas Cort  *
7*406cdd95SThomas Cort  * This code is derived from software contributed to Berkeley by
8*406cdd95SThomas Cort  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
9*406cdd95SThomas Cort  *
10*406cdd95SThomas Cort  * Redistribution and use in source and binary forms, with or without
11*406cdd95SThomas Cort  * modification, are permitted provided that the following conditions
12*406cdd95SThomas Cort  * are met:
13*406cdd95SThomas Cort  * 1. Redistributions of source code must retain the above copyright
14*406cdd95SThomas Cort  *    notice, this list of conditions and the following disclaimer.
15*406cdd95SThomas Cort  * 2. Redistributions in binary form must reproduce the above copyright
16*406cdd95SThomas Cort  *    notice, this list of conditions and the following disclaimer in the
17*406cdd95SThomas Cort  *    documentation and/or other materials provided with the distribution.
18*406cdd95SThomas Cort  * 3. Neither the name of the University nor the names of its contributors
19*406cdd95SThomas Cort  *    may be used to endorse or promote products derived from this software
20*406cdd95SThomas Cort  *    without specific prior written permission.
21*406cdd95SThomas Cort  *
22*406cdd95SThomas Cort  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23*406cdd95SThomas Cort  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*406cdd95SThomas Cort  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*406cdd95SThomas Cort  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26*406cdd95SThomas Cort  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27*406cdd95SThomas Cort  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28*406cdd95SThomas Cort  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29*406cdd95SThomas Cort  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30*406cdd95SThomas Cort  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31*406cdd95SThomas Cort  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*406cdd95SThomas Cort  * SUCH DAMAGE.
33*406cdd95SThomas Cort  */
34*406cdd95SThomas Cort 
35*406cdd95SThomas Cort #include <sys/cdefs.h>
36*406cdd95SThomas Cort #ifndef lint
37*406cdd95SThomas Cort #if 0
38*406cdd95SThomas Cort static char sccsid[] = "@(#)net.c	8.4 (Berkeley) 4/28/95";
39*406cdd95SThomas Cort #else
40*406cdd95SThomas Cort __RCSID("$NetBSD: net.c,v 1.23 2009/04/12 06:18:54 lukem Exp $");
41*406cdd95SThomas Cort #endif
42*406cdd95SThomas Cort #endif /* not lint */
43*406cdd95SThomas Cort 
44*406cdd95SThomas Cort #include <sys/types.h>
45*406cdd95SThomas Cort #include <sys/socket.h>
46*406cdd95SThomas Cort 
47*406cdd95SThomas Cort #include <netinet/in.h>
48*406cdd95SThomas Cort 
49*406cdd95SThomas Cort #include <arpa/inet.h>
50*406cdd95SThomas Cort 
51*406cdd95SThomas Cort #include <netdb.h>
52*406cdd95SThomas Cort #include <time.h>
53*406cdd95SThomas Cort #include <db.h>
54*406cdd95SThomas Cort #include <unistd.h>
55*406cdd95SThomas Cort #include <pwd.h>
56*406cdd95SThomas Cort #include <stdio.h>
57*406cdd95SThomas Cort #include <string.h>
58*406cdd95SThomas Cort #include <ctype.h>
59*406cdd95SThomas Cort #include <err.h>
60*406cdd95SThomas Cort 
61*406cdd95SThomas Cort #include "utmpentry.h"
62*406cdd95SThomas Cort 
63*406cdd95SThomas Cort #include "finger.h"
64*406cdd95SThomas Cort #include "extern.h"
65*406cdd95SThomas Cort 
66*406cdd95SThomas Cort void
netfinger(char * name)67*406cdd95SThomas Cort netfinger(char *name)
68*406cdd95SThomas Cort {
69*406cdd95SThomas Cort 	FILE *fp;
70*406cdd95SThomas Cort 	int c, lastc;
71*406cdd95SThomas Cort 	int s;
72*406cdd95SThomas Cort 	char *host;
73*406cdd95SThomas Cort 	struct addrinfo hints, *res, *res0;
74*406cdd95SThomas Cort 	int error;
75*406cdd95SThomas Cort 	const char *emsg = NULL;
76*406cdd95SThomas Cort 
77*406cdd95SThomas Cort 	lastc = 0;
78*406cdd95SThomas Cort 	if (!(host = strrchr(name, '@')))
79*406cdd95SThomas Cort 		return;
80*406cdd95SThomas Cort 	*host++ = '\0';
81*406cdd95SThomas Cort 	memset(&hints, 0, sizeof(hints));
82*406cdd95SThomas Cort 	hints.ai_family = PF_UNSPEC;
83*406cdd95SThomas Cort 	hints.ai_socktype = SOCK_STREAM;
84*406cdd95SThomas Cort 	hints.ai_flags = AI_CANONNAME;
85*406cdd95SThomas Cort 	error = getaddrinfo(host, "finger", &hints, &res0);
86*406cdd95SThomas Cort 	if (error) {
87*406cdd95SThomas Cort 		warnx("%s: %s", gai_strerror(error), host);
88*406cdd95SThomas Cort 		return;
89*406cdd95SThomas Cort 	}
90*406cdd95SThomas Cort 
91*406cdd95SThomas Cort 	s = -1;
92*406cdd95SThomas Cort 	for (res = res0; res; res = res->ai_next) {
93*406cdd95SThomas Cort 		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
94*406cdd95SThomas Cort 		if (s < 0) {
95*406cdd95SThomas Cort 			emsg = "socket";
96*406cdd95SThomas Cort 			continue;
97*406cdd95SThomas Cort 		}
98*406cdd95SThomas Cort 
99*406cdd95SThomas Cort 		if (connect(s, res->ai_addr, res->ai_addrlen)) {
100*406cdd95SThomas Cort 			close(s);
101*406cdd95SThomas Cort 			s = -1;
102*406cdd95SThomas Cort 			emsg = "connect";
103*406cdd95SThomas Cort 			continue;
104*406cdd95SThomas Cort 		}
105*406cdd95SThomas Cort 
106*406cdd95SThomas Cort 		break;
107*406cdd95SThomas Cort 	}
108*406cdd95SThomas Cort 	if (s < 0) {
109*406cdd95SThomas Cort 		if (emsg != NULL)
110*406cdd95SThomas Cort 			warn("%s", emsg);
111*406cdd95SThomas Cort 		return;
112*406cdd95SThomas Cort 	}
113*406cdd95SThomas Cort 
114*406cdd95SThomas Cort 	/* have network connection; identify the host connected with */
115*406cdd95SThomas Cort 	(void)printf("[%s]\n", res0->ai_canonname ? res0->ai_canonname : host);
116*406cdd95SThomas Cort 
117*406cdd95SThomas Cort 	/* -l flag for remote fingerd  */
118*406cdd95SThomas Cort 	if (lflag)
119*406cdd95SThomas Cort 		write(s, "/W ", 3);
120*406cdd95SThomas Cort 	/* send the name followed by <CR><LF> */
121*406cdd95SThomas Cort 	(void)write(s, name, strlen(name));
122*406cdd95SThomas Cort 	(void)write(s, "\r\n", 2);
123*406cdd95SThomas Cort 
124*406cdd95SThomas Cort 	/*
125*406cdd95SThomas Cort 	 * Read from the remote system; once we're connected, we assume some
126*406cdd95SThomas Cort 	 * data.  If none arrives, we hang until the user interrupts.
127*406cdd95SThomas Cort 	 *
128*406cdd95SThomas Cort 	 * If we see a <CR> followed by a newline character, only output
129*406cdd95SThomas Cort 	 * one newline.
130*406cdd95SThomas Cort 	 *
131*406cdd95SThomas Cort 	 * If a character isn't printable and it isn't a space, we strip the
132*406cdd95SThomas Cort 	 * 8th bit and set the 7th bit.  Every ASCII character with bit 7 set
133*406cdd95SThomas Cort 	 * is printable.
134*406cdd95SThomas Cort 	 */
135*406cdd95SThomas Cort 	if ((fp = fdopen(s, "r")) != NULL)
136*406cdd95SThomas Cort 		while ((c = getc(fp)) != EOF) {
137*406cdd95SThomas Cort 			if (c == '\r') {
138*406cdd95SThomas Cort 				if (lastc == '\r')	/* ^M^M - skip dupes */
139*406cdd95SThomas Cort 					continue;
140*406cdd95SThomas Cort 				c = '\n';
141*406cdd95SThomas Cort 				lastc = '\r';
142*406cdd95SThomas Cort 			} else {
143*406cdd95SThomas Cort 				if (!(eightflag || isprint(c) || isspace(c))) {
144*406cdd95SThomas Cort 					c &= 0x7f;
145*406cdd95SThomas Cort 					c |= 0x40;
146*406cdd95SThomas Cort 				}
147*406cdd95SThomas Cort 				if (lastc != '\r' || c != '\n')
148*406cdd95SThomas Cort 					lastc = c;
149*406cdd95SThomas Cort 				else {
150*406cdd95SThomas Cort 					lastc = '\n';
151*406cdd95SThomas Cort 					continue;
152*406cdd95SThomas Cort 				}
153*406cdd95SThomas Cort 			}
154*406cdd95SThomas Cort 			putchar(c);
155*406cdd95SThomas Cort 		}
156*406cdd95SThomas Cort 	if (lastc != '\n')
157*406cdd95SThomas Cort 		putchar('\n');
158*406cdd95SThomas Cort 	(void)fclose(fp);
159*406cdd95SThomas Cort }
160