xref: /csrg-svn/libexec/talkd/talkd.c (revision 16467)
1 #ifndef lint
2 static	char sccsid[] = "@(#)talkd.c	1.3 (Berkeley) 05/11/84";
3 #endif
4 
5 /*
6  * The top level of the daemon, the format is heavily borrowed
7  * from rwhod.c. Basically: find out who and where you are;
8  * disconnect all descriptors and ttys, and then endless
9  * loop on waiting for and processing requests
10  */
11 #include <stdio.h>
12 #include <errno.h>
13 #include <signal.h>
14 
15 #include "ctl.h"
16 
17 struct	sockaddr_in sin = { AF_INET };
18 
19 CTL_MSG		request;
20 CTL_RESPONSE	response;
21 
22 int	sockt;
23 int	debug = 0;
24 FILE	*debugout;
25 int	timeout();
26 long	lastmsgtime;
27 
28 char	hostname[32];
29 
30 #define TIMEOUT 30
31 #define MAXIDLE 120
32 
33 main(argc, argv)
34 	int argc;
35 	char *argv[];
36 {
37 	struct sockaddr_in from;
38 	int fromlen, cc;
39 
40 	if (debug)
41 		debugout = (FILE *)fopen ("/usr/tmp/talkd.msgs", "w");
42 
43 	if (getuid()) {
44 		fprintf(stderr, "Talkd : not super user\n");
45 		exit(1);
46 	}
47 	gethostname(hostname, sizeof (hostname));
48 	(void) chdir("/dev");
49 	signal(SIGALRM, timeout);
50 	alarm(TIMEOUT);
51 	for (;;) {
52 		extern int errno;
53 
54 		fromlen = sizeof(from);
55 		cc = recvfrom(0, (char *)&request, sizeof (request), 0,
56 		    &from, &fromlen);
57 		if (cc != sizeof(request)) {
58 			if (cc < 0 && errno != EINTR)
59 			perror("recvfrom");
60 			continue;
61 		}
62 		lastmsgtime = time(0);
63 		swapmsg(&request);
64 		if (debug) print_request(&request, fp);
65 		process_request(&request, &response);
66 		/* can block here, is this what I want? */
67 		cc = sendto(sockt, (char *) &response,
68 		    sizeof (response), 0, &request.ctl_addr,
69 		    sizeof (request.ctl_addr));
70 		if (cc != sizeof(response))
71 			perror("sendto");
72 	}
73 	if (debug) close (debugout);
74 }
75 
76 timeout()
77 {
78 
79 	if (time(0) - lastmsgtime >= MAXIDLE)
80 		exit(0);
81 	alarm(TIMEOUT);
82 }
83 
84 #define swapshort(a) (((a << 8) | ((unsigned short) a >> 8)) & 0xffff)
85 #define swaplong(a) ((swapshort(a) << 16) | (swapshort(((unsigned)a >> 16))))
86 
87 /*
88  * heuristic to detect if need to swap bytes
89  */
90 
91 swapmsg(req)
92 	CTL_MSG *req;
93 {
94 	if (req->ctl_addr.sin_family == swapshort(AF_INET)) {
95 		req->id_num = swaplong(req->id_num);
96 		req->pid = swaplong(req->pid);
97 		req->addr.sin_family = swapshort(req->addr.sin_family);
98 		req->ctl_addr.sin_family =
99 			swapshort(req->ctl_addr.sin_family);
100 	}
101 }
102