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