xref: /csrg-svn/libexec/talkd/talkd.c (revision 16467)
116366Skarels #ifndef lint
2*16467Slayer static	char sccsid[] = "@(#)talkd.c	1.3 (Berkeley) 05/11/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;
24*16467Slayer 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;
39*16467Slayer 
40*16467Slayer 	if (debug)
41*16467Slayer 		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);
63*16467Slayer 		swapmsg(&request);
64*16467Slayer 		if (debug) print_request(&request, fp);
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 	}
73*16467Slayer 	if (debug) close (debugout);
7416360Skarels }
7516360Skarels 
7616366Skarels timeout()
7716360Skarels {
7816360Skarels 
7916366Skarels 	if (time(0) - lastmsgtime >= MAXIDLE)
8016366Skarels 		exit(0);
8116366Skarels 	alarm(TIMEOUT);
8216360Skarels }
83*16467Slayer 
84*16467Slayer #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff)
85*16467Slayer #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16))))
86*16467Slayer 
87*16467Slayer /*
88*16467Slayer  * heuristic to detect if need to swap bytes
89*16467Slayer  */
90*16467Slayer 
91*16467Slayer swapmsg(req)
92*16467Slayer 	CTL_MSG *req;
93*16467Slayer {
94*16467Slayer 	if (req->ctl_addr.sin_family == swapshort(AF_INET)) {
95*16467Slayer 		req->id_num = swaplong(req->id_num);
96*16467Slayer 		req->pid = swaplong(req->pid);
97*16467Slayer 		req->addr.sin_family = swapshort(req->addr.sin_family);
98*16467Slayer 		req->ctl_addr.sin_family =
99*16467Slayer 			swapshort(req->ctl_addr.sin_family);
100*16467Slayer 	}
101*16467Slayer }
102