xref: /original-bsd/libexec/talkd/talkd.c (revision 6219b5e8)
1 #ifndef lint
2 static	char sccsid[] = "@(#)talkd.c	1.4 (Berkeley) 12/20/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);
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 }
74 
75 timeout()
76 {
77 
78 	if (time(0) - lastmsgtime >= MAXIDLE)
79 		exit(0);
80 	alarm(TIMEOUT);
81 }
82 
83 /*
84  * heuristic to detect if need to swap bytes
85  */
86 
87 swapmsg(req)
88 	CTL_MSG *req;
89 {
90 	if (req->ctl_addr.sin_family == ntohs(AF_INET)) {
91 		req->id_num = ntohl(req->id_num);
92 		req->pid = ntohl(req->pid);
93 		req->addr.sin_family = ntohs(req->addr.sin_family);
94 		req->ctl_addr.sin_family =
95 			ntohs(req->ctl_addr.sin_family);
96 	}
97 }
98