xref: /netbsd-src/usr.bin/finger/net.c (revision f8d0e3558c60c653b3b348397109ca7190ae71ae)
1*f8d0e355Slukem /*	$NetBSD: net.c,v 1.23 2009/04/12 06:18:54 lukem Exp $	*/
29d225a17Stls 
361f28255Scgd /*
4987dbad8Smrg  * Copyright (c) 1989, 1993
5987dbad8Smrg  *	The Regents of the University of California.  All rights reserved.
661f28255Scgd  *
761f28255Scgd  * This code is derived from software contributed to Berkeley by
861f28255Scgd  * Tony Nardo of the Johns Hopkins University/Applied Physics Lab.
961f28255Scgd  *
1061f28255Scgd  * Redistribution and use in source and binary forms, with or without
1161f28255Scgd  * modification, are permitted provided that the following conditions
1261f28255Scgd  * are met:
1361f28255Scgd  * 1. Redistributions of source code must retain the above copyright
1461f28255Scgd  *    notice, this list of conditions and the following disclaimer.
1561f28255Scgd  * 2. Redistributions in binary form must reproduce the above copyright
1661f28255Scgd  *    notice, this list of conditions and the following disclaimer in the
1761f28255Scgd  *    documentation and/or other materials provided with the distribution.
1889aaa1bbSagc  * 3. Neither the name of the University nor the names of its contributors
1961f28255Scgd  *    may be used to endorse or promote products derived from this software
2061f28255Scgd  *    without specific prior written permission.
2161f28255Scgd  *
2261f28255Scgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2361f28255Scgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2461f28255Scgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2561f28255Scgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2661f28255Scgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2761f28255Scgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2861f28255Scgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2961f28255Scgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3061f28255Scgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3161f28255Scgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3261f28255Scgd  * SUCH DAMAGE.
3361f28255Scgd  */
3461f28255Scgd 
35987dbad8Smrg #include <sys/cdefs.h>
3661f28255Scgd #ifndef lint
37987dbad8Smrg #if 0
38987dbad8Smrg static char sccsid[] = "@(#)net.c	8.4 (Berkeley) 4/28/95";
39987dbad8Smrg #else
40*f8d0e355Slukem __RCSID("$NetBSD: net.c,v 1.23 2009/04/12 06:18:54 lukem Exp $");
41987dbad8Smrg #endif
4261f28255Scgd #endif /* not lint */
4361f28255Scgd 
4461f28255Scgd #include <sys/types.h>
4561f28255Scgd #include <sys/socket.h>
46987dbad8Smrg 
4761f28255Scgd #include <netinet/in.h>
48987dbad8Smrg 
49504e402fSmycroft #include <arpa/inet.h>
50987dbad8Smrg 
5161f28255Scgd #include <netdb.h>
528bff4369Schristos #include <time.h>
53987dbad8Smrg #include <db.h>
54987dbad8Smrg #include <unistd.h>
55987dbad8Smrg #include <pwd.h>
5661f28255Scgd #include <stdio.h>
57fcb1f857Scgd #include <string.h>
5861f28255Scgd #include <ctype.h>
5998a141ccSitojun #include <err.h>
60987dbad8Smrg 
618bff4369Schristos #include "utmpentry.h"
628bff4369Schristos 
633ccb8ba1Slukem #include "finger.h"
643ccb8ba1Slukem #include "extern.h"
6561f28255Scgd 
663ccb8ba1Slukem void
netfinger(char * name)67ee5c979cSperry netfinger(char *name)
6861f28255Scgd {
693ccb8ba1Slukem 	FILE *fp;
703ccb8ba1Slukem 	int c, lastc;
7161f28255Scgd 	int s;
723ccb8ba1Slukem 	char *host;
7398a141ccSitojun 	struct addrinfo hints, *res, *res0;
7498a141ccSitojun 	int error;
75*f8d0e355Slukem 	const char *emsg = NULL;
7661f28255Scgd 
773ccb8ba1Slukem 	lastc = 0;
783ccb8ba1Slukem 	if (!(host = strrchr(name, '@')))
7961f28255Scgd 		return;
80f6d87734Spk 	*host++ = '\0';
8198a141ccSitojun 	memset(&hints, 0, sizeof(hints));
8298a141ccSitojun 	hints.ai_family = PF_UNSPEC;
8398a141ccSitojun 	hints.ai_socktype = SOCK_STREAM;
8498a141ccSitojun 	hints.ai_flags = AI_CANONNAME;
8598a141ccSitojun 	error = getaddrinfo(host, "finger", &hints, &res0);
8698a141ccSitojun 	if (error) {
8798a141ccSitojun 		warnx("%s: %s", gai_strerror(error), host);
8861f28255Scgd 		return;
8961f28255Scgd 	}
9098a141ccSitojun 
9198a141ccSitojun 	s = -1;
9298a141ccSitojun 	for (res = res0; res; res = res->ai_next) {
9398a141ccSitojun 		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
9498a141ccSitojun 		if (s < 0) {
9598a141ccSitojun 			emsg = "socket";
9698a141ccSitojun 			continue;
9761f28255Scgd 		}
9898a141ccSitojun 
9998a141ccSitojun 		if (connect(s, res->ai_addr, res->ai_addrlen)) {
10098a141ccSitojun 			close(s);
10198a141ccSitojun 			s = -1;
10298a141ccSitojun 			emsg = "connect";
10398a141ccSitojun 			continue;
10498a141ccSitojun 		}
10598a141ccSitojun 
10698a141ccSitojun 		break;
10798a141ccSitojun 	}
10898a141ccSitojun 	if (s < 0) {
10998a141ccSitojun 		if (emsg != NULL)
110bbef2fbaSitojun 			warn("%s", emsg);
11161f28255Scgd 		return;
11261f28255Scgd 	}
11361f28255Scgd 
11461f28255Scgd 	/* have network connection; identify the host connected with */
11598a141ccSitojun 	(void)printf("[%s]\n", res0->ai_canonname ? res0->ai_canonname : host);
11661f28255Scgd 
11761f28255Scgd 	/* -l flag for remote fingerd  */
11861f28255Scgd 	if (lflag)
11961f28255Scgd 		write(s, "/W ", 3);
12061f28255Scgd 	/* send the name followed by <CR><LF> */
12161f28255Scgd 	(void)write(s, name, strlen(name));
12261f28255Scgd 	(void)write(s, "\r\n", 2);
12361f28255Scgd 
12461f28255Scgd 	/*
12561f28255Scgd 	 * Read from the remote system; once we're connected, we assume some
12661f28255Scgd 	 * data.  If none arrives, we hang until the user interrupts.
12761f28255Scgd 	 *
128dfb75c5aSkim 	 * If we see a <CR> followed by a newline character, only output
129dfb75c5aSkim 	 * one newline.
13061f28255Scgd 	 *
131dfb75c5aSkim 	 * If a character isn't printable and it isn't a space, we strip the
132dfb75c5aSkim 	 * 8th bit and set the 7th bit.  Every ASCII character with bit 7 set
133dfb75c5aSkim 	 * is printable.
13461f28255Scgd 	 */
1353ccb8ba1Slukem 	if ((fp = fdopen(s, "r")) != NULL)
13661f28255Scgd 		while ((c = getc(fp)) != EOF) {
137540438e5Smycroft 			if (c == '\r') {
138987dbad8Smrg 				if (lastc == '\r')	/* ^M^M - skip dupes */
139540438e5Smycroft 					continue;
14061f28255Scgd 				c = '\n';
14161f28255Scgd 				lastc = '\r';
14261f28255Scgd 			} else {
143b3399fd7Skim 				if (!(eightflag || isprint(c) || isspace(c))) {
144dfb75c5aSkim 					c &= 0x7f;
14561f28255Scgd 					c |= 0x40;
146dfb75c5aSkim 				}
14761f28255Scgd 				if (lastc != '\r' || c != '\n')
14861f28255Scgd 					lastc = c;
14961f28255Scgd 				else {
15061f28255Scgd 					lastc = '\n';
15161f28255Scgd 					continue;
15261f28255Scgd 				}
15361f28255Scgd 			}
15461f28255Scgd 			putchar(c);
15561f28255Scgd 		}
15661f28255Scgd 	if (lastc != '\n')
15761f28255Scgd 		putchar('\n');
15861f28255Scgd 	(void)fclose(fp);
15961f28255Scgd }
160