hook for ps driver and untimeout stuff for lucas drivers
[unix-history] / usr / src / usr.sbin / rwhod / rwhod.c
CommitLineData
52b4fb0c 1#ifndef lint
76886f32 2static char sccsid[] = "@(#)rwhod.c 4.3 82/04/20";
52b4fb0c
BJ
3#endif
4
5#include <stdio.h>
6#include <signal.h>
7#include <sys/types.h>
8#include <net/in.h>
9#include <sys/socket.h>
10#include <errno.h>
11#include <utmp.h>
12#include "rwhod.h"
13#include <sys/stat.h>
14#include <nlist.h>
15#include <sys/ioctl.h>
16
17struct sockaddr_in sin = { AF_INET, IPPORT_WHOSERVER };
18
19extern errno;
20
21char *localnet = "localnet";
22char *myname = "myname";
23
24struct nlist nl[] = {
25#define NL_AVENRUN 0
26 { "_avenrun" },
27#define NL_BOOTIME 1
28 { "_bootime" },
29 0
30};
31
32struct whod mywd;
33int s, utmpf, kmemf = -1;
34
35int onalrm();
36char *strcpy(), *sprintf();
37long lseek();
38int getkmem();
39
40main()
41{
42 struct sockaddr_in from;
43 char path[64];
44 int addr;
45
46#ifndef DEBUG
47 if (fork())
48 exit(0);
49 { int s;
50 for (s = 0; s < 10; s++)
51 (void) close(s);
52 (void) open("/", 0);
53 (void) dup2(0, 1);
54 (void) dup2(0, 2);
55 s = open("/dev/tty", 2);
56 if (s >= 0) {
57 ioctl(s, TIOCNOTTY, 0);
58 (void) close(s);
59 }
60 }
61#endif
62 (void) chdir("/dev");
63 (void) signal(SIGHUP, getkmem);
64 if (getuid()) {
65 fprintf(stderr, "not super user\n");
66 exit(1);
67 }
68 addr = rhost(&localnet);
69 if (addr == -1) {
70 fprintf(stderr, "no localnet for whod\n");
71 exit(1);
72 }
73 sin.sin_addr.s_addr = addr;
74 if (rhost(&myname) == -1) {
75 fprintf(stderr, "don't know my name\n");
76 exit(1);
77 }
78 strncpy(mywd.wd_hostname, myname, sizeof (mywd.wd_hostname) - 1);
79 utmpf = open("/etc/utmp", 0);
80 if (utmpf < 0) {
81 (void) close(creat("/etc/utmp", 0644));
82 utmpf = open("/etc/utmp", 0);
83 }
84 if (utmpf < 0) {
85 perror("/etc/utmp");
86 exit(1);
87 }
88 getkmem();
89#ifdef vax
90 sin.sin_port = htons(sin.sin_port);
91#endif
92again:
93 if ((s = socket(SOCK_DGRAM, 0, &sin, 0)) < 0) {
94 perror("socket");
95 sleep(5);
96 goto again;
97 }
98 sigset(SIGALRM, onalrm);
99 onalrm();
100 for (;;) {
101 struct whod wd;
102 int cc, whod;
103
104 cc = receive(s, &from, (char *)&wd, sizeof (struct whod));
105 if (cc <= 0) {
106 if (cc < 0 && errno != EINTR)
107 perror("receive");
108 continue;
109 }
110#ifdef vax
111 from.sin_port = ntohs(from.sin_port);
112#endif
113 if (from.sin_port != IPPORT_WHOSERVER) {
114 printf("bad from port %d\n", from.sin_port);
115 continue;
116 }
117/*
118 if (rhost(&wd.wd_hostname) == -1) {
119 printf("unknown host %s\n", wd.wd_hostname);
120 continue;
121 }
122*/
123 (void) sprintf(path, "/etc/whod.%s", wd.wd_hostname);
124 whod = creat(path, 0666);
125 if (whod < 0) {
126 printf("can't create %s\n", path);
127 continue;
128 }
129 (void) time(&wd.wd_recvtime);
130 (void) write(whod, (char *)&wd, cc);
131 (void) close(whod);
132 }
133}
134
135int utmptime;
136int utmpent;
76886f32 137struct utmp utmp[100];
52b4fb0c
BJ
138int alarmcount;
139
140onalrm()
141{
142 register int i;
143 struct stat stb;
76886f32 144 register struct whoent *we = mywd.wd_we, *wlast;
52b4fb0c
BJ
145 int cc;
146 double avenrun[3];
147 time_t now = time(0);
148
149 if (alarmcount % 10 == 0)
150 getkmem();
151 alarmcount++;
152 (void) fstat(utmpf, &stb);
153 if (stb.st_mtime != utmptime) {
154 (void) lseek(utmpf, (long)0, 0);
155 cc = read(utmpf, (char *)utmp, sizeof (utmp));
156 if (cc < 0) {
157 perror("/etc/utmp");
158 return;
159 }
76886f32 160 wlast = &mywd.wd_we[(1024 / sizeof (struct whoent)) - 1];
52b4fb0c
BJ
161 utmpent = cc / sizeof (struct utmp);
162 for (i = 0; i < utmpent; i++)
163 if (utmp[i].ut_name[0]) {
164 we->we_utmp = utmp[i];
76886f32
SL
165 if (we >= wlast)
166 break;
52b4fb0c
BJ
167 we++;
168 }
169 utmpent = we - mywd.wd_we;
170 }
171 we = mywd.wd_we;
172 for (i = 0; i < utmpent; i++) {
173 if (stat(we->we_utmp.ut_line, &stb) >= 0)
174 we->we_idle = now - stb.st_atime;
175 we++;
176 }
177 (void) lseek(kmemf, (long)nl[NL_AVENRUN].n_value, 0);
178 (void) read(kmemf, (char *)avenrun, sizeof (avenrun));
179 for (i = 0; i < 3; i++)
180 mywd.wd_loadav[i] = avenrun[i] * 100;
181 cc = (char *)we - (char *)&mywd;
182 (void) time(&mywd.wd_sendtime);
183 send(s, &sin, (char *)&mywd, cc);
184 (void) alarm(60);
185}
186
187getkmem()
188{
189 struct nlist *nlp;
190
191 signal(SIGHUP, getkmem);
192 if (kmemf >= 0)
193 (void) close(kmemf);
194loop:
195 for (nlp = &nl[sizeof (nl) / sizeof (nl[0])]; --nlp >= nl; ) {
196 nlp->n_value = 0;
197 nlp->n_type = 0;
198 }
199 nlist("/vmunix", nl);
200 if (nl[0].n_value == 0) {
201 fprintf(stderr, "/vmunix namelist botch\n");
202 sleep(300);
203 goto loop;
204 }
205 kmemf = open("/dev/kmem", 0);
206 if (kmemf < 0) {
207 perror("/dev/kmem");
208 sleep(300);
209 goto loop;
210 }
211 (void) lseek(kmemf, (long)nl[NL_BOOTIME].n_value, 0);
212 (void) read(kmemf, (char *)&mywd.wd_bootime, sizeof (mywd.wd_bootime));
213}