xref: /csrg-svn/libexec/fingerd/fingerd.c (revision 55083)
122492Sdist /*
235556Sbostic  * Copyright (c) 1983 The Regents of the University of California.
335556Sbostic  * All rights reserved.
435556Sbostic  *
542664Sbostic  * %sccs.include.redist.c%
622492Sdist  */
722492Sdist 
816471Ssam #ifndef lint
922492Sdist char copyright[] =
1035556Sbostic "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
1122492Sdist  All rights reserved.\n";
1235556Sbostic #endif /* not lint */
1316471Ssam 
1422492Sdist #ifndef lint
15*55083Stef static char sccsid[] = "@(#)fingerd.c	5.9 (Berkeley) 07/12/92";
1635556Sbostic #endif /* not lint */
1722492Sdist 
1852435Sbostic #include <errno.h>
1952435Sbostic #include <unistd.h>
2016471Ssam #include <stdio.h>
2152435Sbostic #include <stdlib.h>
2252435Sbostic #include <strings.h>
23*55083Stef #include <syslog.h>
24*55083Stef #include <netdb.h>
25*55083Stef #include <sys/types.h>
26*55083Stef #include <sys/socket.h>
27*55083Stef #include <netinet/in.h>
28*55083Stef #include <arpa/inet.h>
2937269Sbostic #include "pathnames.h"
3016471Ssam 
3152435Sbostic void err __P((const char *, ...));
3252435Sbostic 
3352435Sbostic int
34*55083Stef main(int argc, char **argv)
3516471Ssam {
3636261Sbostic 	register FILE *fp;
3736261Sbostic 	register int ch;
3836261Sbostic 	register char *lp;
3936261Sbostic 	int p[2];
4036261Sbostic #define	ENTRIES	50
4152435Sbostic 	char **ap, *av[ENTRIES + 1], **comp, line[1024];
42*55083Stef 	char *prog = _PATH_FINGER;
43*55083Stef 	struct hostent *hp;
4416471Ssam 	struct sockaddr_in sin;
45*55083Stef 	int sval = sizeof(sin);
46*55083Stef 	int secure=0, logging=0;
47*55083Stef 	extern char *optarg;
4816471Ssam 
49*55083Stef 	openlog("fingerd", LOG_PID|LOG_CONS, LOG_DAEMON);
50*55083Stef 	while ((ch=getopt(argc, argv, "slp:")) != EOF)
51*55083Stef 		switch (ch) {
52*55083Stef 		case 's':
53*55083Stef 			secure++;
54*55083Stef 			break;
55*55083Stef 		case 'l':
56*55083Stef 			logging++;
57*55083Stef 			break;
58*55083Stef 		case 'p':
59*55083Stef 			prog = optarg;
60*55083Stef 			break;
61*55083Stef 		case '?':
62*55083Stef 		default:
63*55083Stef 			syslog(LOG_ERR, "unknown option: %c", ch);
64*55083Stef 		}
6536261Sbostic 
66*55083Stef 	if (logging) {
67*55083Stef 		if (getpeername(0, (struct sockaddr *)&sin, &sval) < 0)
68*55083Stef 			err("getpeername: %s", strerror(errno));
69*55083Stef 		if (hp = gethostbyaddr((char *)&sin.sin_addr.s_addr,
70*55083Stef 				sizeof(sin.sin_addr.s_addr), AF_INET))
71*55083Stef 			lp = hp->h_name;
72*55083Stef 		else
73*55083Stef 			lp = inet_ntoa(sin.sin_addr);
74*55083Stef 		syslog(LOG_NOTICE, "query from %s", lp);
75*55083Stef 	}
76*55083Stef 
7736261Sbostic 	if (!fgets(line, sizeof(line), stdin))
7836199Sbostic 		exit(1);
7952435Sbostic 
8052435Sbostic 	comp = &av[1];
8152435Sbostic 	for (lp = line, ap = &av[2];;) {
8236261Sbostic 		*ap = strtok(lp, " \t\r\n");
83*55083Stef 		if (!*ap) {
84*55083Stef 			if (secure && ap == &av[2]) {
85*55083Stef 				puts("must provide username\r\n");
86*55083Stef 				exit(1);
87*55083Stef 			}
8816471Ssam 			break;
89*55083Stef 		}
90*55083Stef 		if (secure && strchr(*ap, '@')) {
91*55083Stef 			puts("fowarding service denied\r\n");
92*55083Stef 			exit(1);
93*55083Stef 		}
94*55083Stef 
9536261Sbostic 		/* RFC742: "/[Ww]" == "-l" */
9652446Sbostic 		if ((*ap)[0] == '/' && ((*ap)[1] == 'W' || (*ap)[1] == 'w')) {
9752446Sbostic 			av[1] = "-l";
9852446Sbostic 			comp = &av[0];
9952446Sbostic 		}
10052435Sbostic 		else if (++ap == av + ENTRIES)
10136261Sbostic 			break;
10236261Sbostic 		lp = NULL;
10316471Ssam 	}
10436261Sbostic 
105*55083Stef 	if (lp = strrchr(prog, '/'))
106*55083Stef 		*comp = ++lp;
107*55083Stef 	else
108*55083Stef 		*comp = prog;
10916770Sralph 	if (pipe(p) < 0)
11052435Sbostic 		err("pipe: %s", strerror(errno));
11136261Sbostic 
11252435Sbostic 	switch(vfork()) {
11336261Sbostic 	case 0:
11436261Sbostic 		(void)close(p[0]);
11516770Sralph 		if (p[1] != 1) {
11636261Sbostic 			(void)dup2(p[1], 1);
11736261Sbostic 			(void)close(p[1]);
11816770Sralph 		}
119*55083Stef 		execv(prog, comp);
120*55083Stef 		err("execv: %s: %s", prog, strerror(errno));
12116770Sralph 		_exit(1);
12236261Sbostic 	case -1:
12352435Sbostic 		err("fork: %s", strerror(errno));
12416770Sralph 	}
12536261Sbostic 	(void)close(p[1]);
12636261Sbostic 	if (!(fp = fdopen(p[0], "r")))
12752435Sbostic 		err("fdopen: %s", strerror(errno));
12836261Sbostic 	while ((ch = getc(fp)) != EOF) {
12936261Sbostic 		if (ch == '\n')
13016595Sralph 			putchar('\r');
13136261Sbostic 		putchar(ch);
13216595Sralph 	}
13336261Sbostic 	exit(0);
13416471Ssam }
13516471Ssam 
13652435Sbostic #if __STDC__
13752435Sbostic #include <stdarg.h>
13852435Sbostic #else
13952435Sbostic #include <varargs.h>
14052435Sbostic #endif
14152435Sbostic 
14252435Sbostic void
14352435Sbostic #if __STDC__
14452435Sbostic err(const char *fmt, ...)
14552435Sbostic #else
14652435Sbostic err(fmt, va_alist)
14752435Sbostic 	char *fmt;
14852435Sbostic         va_dcl
14952435Sbostic #endif
15016471Ssam {
15152435Sbostic 	va_list ap;
15252435Sbostic #if __STDC__
15352435Sbostic 	va_start(ap, fmt);
15452435Sbostic #else
15552435Sbostic 	va_start(ap);
15652435Sbostic #endif
157*55083Stef 	(void)vsyslog(LOG_ERR, fmt, ap);
15852435Sbostic 	va_end(ap);
15916471Ssam 	exit(1);
16052435Sbostic 	/* NOTREACHED */
16116471Ssam }
162