xref: /illumos-gate/usr/src/cmd/cmd-inet/usr.sbin/in.fingerd.c (revision 7c478bd95313f5f23a4c958a745db2134aa0324)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 1989 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*
31*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley 4.3 BSD
32*7c478bd9Sstevel@tonic-gate  * under license from the Regents of the University of California.
33*7c478bd9Sstevel@tonic-gate  */
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate /*
38*7c478bd9Sstevel@tonic-gate  * Finger server.
39*7c478bd9Sstevel@tonic-gate  */
40*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
41*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
43*7c478bd9Sstevel@tonic-gate #include <stdio.h>
44*7c478bd9Sstevel@tonic-gate #include <ctype.h>
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #define	MAXARGS 10
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate main(argc, argv)
49*7c478bd9Sstevel@tonic-gate 	char *argv[];
50*7c478bd9Sstevel@tonic-gate {
51*7c478bd9Sstevel@tonic-gate 	register char *sp;
52*7c478bd9Sstevel@tonic-gate 	char line[512];
53*7c478bd9Sstevel@tonic-gate 	struct sockaddr_storage sin;
54*7c478bd9Sstevel@tonic-gate 	pid_t pid, w;
55*7c478bd9Sstevel@tonic-gate 	int i, p[2], status;
56*7c478bd9Sstevel@tonic-gate 	FILE *fp;
57*7c478bd9Sstevel@tonic-gate 	char *av[MAXARGS + 1];
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate 	i = sizeof (sin);
60*7c478bd9Sstevel@tonic-gate 	if (getpeername(0, (struct sockaddr *)&sin, &i) < 0)
61*7c478bd9Sstevel@tonic-gate 		fatal(argv[0], "getpeername");
62*7c478bd9Sstevel@tonic-gate 	line[0] = '\0';
63*7c478bd9Sstevel@tonic-gate 	if (fgets(line, sizeof (line), stdin) == NULL)
64*7c478bd9Sstevel@tonic-gate 		exit(1);
65*7c478bd9Sstevel@tonic-gate 	sp = line;
66*7c478bd9Sstevel@tonic-gate 	av[0] = "finger";
67*7c478bd9Sstevel@tonic-gate 	i = 1;
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 	/* skip past leading white space */
70*7c478bd9Sstevel@tonic-gate 	while (isspace(*sp))
71*7c478bd9Sstevel@tonic-gate 		sp++;
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	/*
74*7c478bd9Sstevel@tonic-gate 	 * The finger protocol says a "/W" switch means verbose output.
75*7c478bd9Sstevel@tonic-gate 	 * We explicitly set either the "long" or "short" output flags
76*7c478bd9Sstevel@tonic-gate 	 * to the finger program so that we don't have to know what what
77*7c478bd9Sstevel@tonic-gate 	 * the "finger" program's default is.
78*7c478bd9Sstevel@tonic-gate 	 */
79*7c478bd9Sstevel@tonic-gate 	if (*sp == '/' && (sp[1] == 'W' || sp[1] == 'w')) {
80*7c478bd9Sstevel@tonic-gate 		sp += 2;
81*7c478bd9Sstevel@tonic-gate 		av[i++] = "-l";
82*7c478bd9Sstevel@tonic-gate 	} else {
83*7c478bd9Sstevel@tonic-gate 		av[i++] = "-s";
84*7c478bd9Sstevel@tonic-gate 	}
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate 	/* look for username arguments */
87*7c478bd9Sstevel@tonic-gate 	while (i < MAXARGS) {
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate 		/* skip over leading white space */
90*7c478bd9Sstevel@tonic-gate 		while (isspace(*sp))
91*7c478bd9Sstevel@tonic-gate 			sp++;
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate 		/* check for end of "command line" */
94*7c478bd9Sstevel@tonic-gate 		if (*sp == '\0')
95*7c478bd9Sstevel@tonic-gate 			break;
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate 		/* pick up another name argument */
98*7c478bd9Sstevel@tonic-gate 		av[i++] = sp;
99*7c478bd9Sstevel@tonic-gate 		while ((*sp != '\0') && !isspace(*sp))
100*7c478bd9Sstevel@tonic-gate 			sp++;
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate 		/* check again for end of "command line" */
103*7c478bd9Sstevel@tonic-gate 		if (*sp == '\0')
104*7c478bd9Sstevel@tonic-gate 			break;
105*7c478bd9Sstevel@tonic-gate 		else
106*7c478bd9Sstevel@tonic-gate 			*sp++ = '\0';
107*7c478bd9Sstevel@tonic-gate 	}
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	av[i] = (char *)0;
110*7c478bd9Sstevel@tonic-gate 	if (pipe(p) < 0)
111*7c478bd9Sstevel@tonic-gate 		fatal(argv[0], "pipe");
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	if ((pid = fork()) == 0) {
114*7c478bd9Sstevel@tonic-gate 		close(p[0]);
115*7c478bd9Sstevel@tonic-gate 		if (p[1] != 1) {
116*7c478bd9Sstevel@tonic-gate 			dup2(p[1], 1);
117*7c478bd9Sstevel@tonic-gate 			close(p[1]);
118*7c478bd9Sstevel@tonic-gate 		}
119*7c478bd9Sstevel@tonic-gate 		execv("/usr/bin/finger", av);
120*7c478bd9Sstevel@tonic-gate 		printf("No local finger program found\n");
121*7c478bd9Sstevel@tonic-gate 		fflush(stdout);
122*7c478bd9Sstevel@tonic-gate 		_exit(1);
123*7c478bd9Sstevel@tonic-gate 	}
124*7c478bd9Sstevel@tonic-gate 	if (pid == (pid_t)-1)
125*7c478bd9Sstevel@tonic-gate 		fatal(argv[0], "fork");
126*7c478bd9Sstevel@tonic-gate 	close(p[1]);
127*7c478bd9Sstevel@tonic-gate 	if ((fp = fdopen(p[0], "r")) == NULL)
128*7c478bd9Sstevel@tonic-gate 		fatal(argv[0], "fdopen");
129*7c478bd9Sstevel@tonic-gate 	while ((i = getc(fp)) != EOF) {
130*7c478bd9Sstevel@tonic-gate 		if (i == '\n')
131*7c478bd9Sstevel@tonic-gate 			putchar('\r');
132*7c478bd9Sstevel@tonic-gate 		putchar(i);
133*7c478bd9Sstevel@tonic-gate 	}
134*7c478bd9Sstevel@tonic-gate 	fclose(fp);
135*7c478bd9Sstevel@tonic-gate 	while ((w = wait(&status)) != pid && w != (pid_t)-1)
136*7c478bd9Sstevel@tonic-gate 		;
137*7c478bd9Sstevel@tonic-gate 	return (0);
138*7c478bd9Sstevel@tonic-gate }
139*7c478bd9Sstevel@tonic-gate 
140*7c478bd9Sstevel@tonic-gate fatal(prog, s)
141*7c478bd9Sstevel@tonic-gate 	char *prog, *s;
142*7c478bd9Sstevel@tonic-gate {
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: ", prog);
145*7c478bd9Sstevel@tonic-gate 	perror(s);
146*7c478bd9Sstevel@tonic-gate 	exit(1);
147*7c478bd9Sstevel@tonic-gate }
148