fingerd.c revision 1.3
1/*
2 * Copyright (c) 1983 The Regents of the University of California.
3 * 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
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
37 All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41/*static char sccsid[] = "from: @(#)fingerd.c	5.6 (Berkeley) 6/1/90";*/
42static char rcsid[] = "$Id: fingerd.c,v 1.3 1996/06/24 17:41:07 deraadt Exp $";
43#endif /* not lint */
44
45#include <stdio.h>
46#include "pathnames.h"
47
48int
49main(argc, argv)
50	int argc;
51	char *argv[];
52{
53	register FILE *fp;
54	register int ch;
55	register char *lp;
56	int p[2];
57#define	ENTRIES	50
58	char **ap, *av[ENTRIES + 1], line[1024], *strtok();
59	int forward = 1, nvalid;
60	int i, j, l;
61
62#ifdef LOGGING					/* unused for now */
63#include <netinet/in.h>
64	struct sockaddr_in sin;
65	int sval;
66
67	sval = sizeof(sin);
68	if (getpeername(0, &sin, &sval) < 0)
69		fatal("getpeername");
70#endif
71
72	if (argc > 1 && strcmp(argv[1], "-s") == 0)
73		forward = 0;
74
75	if (!fgets(line, sizeof(line), stdin))
76		exit(1);
77
78	av[0] = "finger";
79	for (lp = line, ap = &av[1];;) {
80		*ap = strtok(lp, " \t\r\n");
81		if (!*ap)
82			break;
83		/* RFC742: "/[Ww]" == "-l" */
84		if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w'))
85			*ap = "-l";
86		if (++ap == av + ENTRIES)
87			break;
88		lp = NULL;
89	}
90
91	nvalid = 0;
92	if (av[1] == NULL)
93		nvalid = 1;
94	for (i = 1; av[i];) {
95		if (forward == 0 && strchr(av[i], '@')) {
96			/* no way, delete it! */
97			for (j = i; av[j]; j++)
98				av[j] = av[j+1];
99			if (av[i])
100				continue;
101			break;
102		}
103
104		l = strlen(av[i]);
105		while (av[i][l-1] == '@')
106			av[i][--l] = '\0';
107		if (av[i][0] == '\0')
108			av[i] = NULL;
109		nvalid++;
110		i++;
111	}
112
113	if (pipe(p) < 0)
114		fatal("pipe");
115
116	switch(fork()) {
117	case 0:
118		(void)close(p[0]);
119		if (p[1] != 1) {
120			(void)dup2(p[1], 1);
121			(void)close(p[1]);
122		}
123		if (nvalid)
124			execv(_PATH_FINGER, av);
125		_exit(1);
126	case -1:
127		fatal("fork");
128	}
129	(void)close(p[1]);
130	if (!(fp = fdopen(p[0], "r")))
131		fatal("fdopen");
132	while ((ch = getc(fp)) != EOF) {
133		if (ch == '\n')
134			putchar('\r');
135		putchar(ch);
136	}
137	exit(0);
138}
139
140fatal(msg)
141	char *msg;
142{
143	extern int errno;
144	char *strerror();
145
146	fprintf(stderr, "fingerd: %s: %s\r\n", msg, strerror(errno));
147	exit(1);
148}
149