xref: /csrg-svn/libexec/talkd/talkd.c (revision 17567)
116366Skarels #ifndef lint
2*17567Sbloom static	char sccsid[] = "@(#)talkd.c	1.4 (Berkeley) 12/20/84";
316366Skarels #endif
416360Skarels 
516366Skarels /*
616366Skarels  * The top level of the daemon, the format is heavily borrowed
716366Skarels  * from rwhod.c. Basically: find out who and where you are;
816366Skarels  * disconnect all descriptors and ttys, and then endless
916366Skarels  * loop on waiting for and processing requests
1016360Skarels  */
1116360Skarels #include <stdio.h>
1216360Skarels #include <errno.h>
1316366Skarels #include <signal.h>
1416360Skarels 
1516366Skarels #include "ctl.h"
1616360Skarels 
1716360Skarels struct	sockaddr_in sin = { AF_INET };
1816360Skarels 
1916366Skarels CTL_MSG		request;
2016366Skarels CTL_RESPONSE	response;
2116360Skarels 
2216366Skarels int	sockt;
2316366Skarels int	debug = 0;
2416467Slayer FILE	*debugout;
2516366Skarels int	timeout();
2616366Skarels long	lastmsgtime;
2716360Skarels 
2816366Skarels char	hostname[32];
2916360Skarels 
3016366Skarels #define TIMEOUT 30
3116366Skarels #define MAXIDLE 120
3216366Skarels 
3316366Skarels main(argc, argv)
3416366Skarels 	int argc;
3516366Skarels 	char *argv[];
3616360Skarels {
3716366Skarels 	struct sockaddr_in from;
3816366Skarels 	int fromlen, cc;
3916467Slayer 
4016467Slayer 	if (debug)
4116467Slayer 		debugout = (FILE *)fopen ("/usr/tmp/talkd.msgs", "w");
4216360Skarels 
4316366Skarels 	if (getuid()) {
4416366Skarels 		fprintf(stderr, "Talkd : not super user\n");
4516366Skarels 		exit(1);
4616360Skarels 	}
4716366Skarels 	gethostname(hostname, sizeof (hostname));
4816366Skarels 	(void) chdir("/dev");
4916366Skarels 	signal(SIGALRM, timeout);
5016366Skarels 	alarm(TIMEOUT);
5116366Skarels 	for (;;) {
5216366Skarels 		extern int errno;
5316360Skarels 
5416366Skarels 		fromlen = sizeof(from);
5516366Skarels 		cc = recvfrom(0, (char *)&request, sizeof (request), 0,
5616366Skarels 		    &from, &fromlen);
5716366Skarels 		if (cc != sizeof(request)) {
5816366Skarels 			if (cc < 0 && errno != EINTR)
5916366Skarels 			perror("recvfrom");
6016366Skarels 			continue;
6116366Skarels 		}
6216366Skarels 		lastmsgtime = time(0);
6316467Slayer 		swapmsg(&request);
64*17567Sbloom 		if (debug) print_request(&request);
6516366Skarels 		process_request(&request, &response);
6616360Skarels 		/* can block here, is this what I want? */
6716366Skarels 		cc = sendto(sockt, (char *) &response,
6816366Skarels 		    sizeof (response), 0, &request.ctl_addr,
6916366Skarels 		    sizeof (request.ctl_addr));
7016366Skarels 		if (cc != sizeof(response))
7116366Skarels 			perror("sendto");
7216360Skarels 	}
7316360Skarels }
7416360Skarels 
7516366Skarels timeout()
7616360Skarels {
7716360Skarels 
7816366Skarels 	if (time(0) - lastmsgtime >= MAXIDLE)
7916366Skarels 		exit(0);
8016366Skarels 	alarm(TIMEOUT);
8116360Skarels }
8216467Slayer 
8316467Slayer /*
8416467Slayer  * heuristic to detect if need to swap bytes
8516467Slayer  */
8616467Slayer 
8716467Slayer swapmsg(req)
8816467Slayer 	CTL_MSG *req;
8916467Slayer {
90*17567Sbloom 	if (req->ctl_addr.sin_family == ntohs(AF_INET)) {
91*17567Sbloom 		req->id_num = ntohl(req->id_num);
92*17567Sbloom 		req->pid = ntohl(req->pid);
93*17567Sbloom 		req->addr.sin_family = ntohs(req->addr.sin_family);
9416467Slayer 		req->ctl_addr.sin_family =
95*17567Sbloom 			ntohs(req->ctl_addr.sin_family);
9616467Slayer 	}
9716467Slayer }
98