|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ruptime.c 4.14 (Berkeley) 83/07/01";
3: #endif
4:
5: #include <sys/param.h>
6: #include <stdio.h>
7: #include <sys/dir.h>
8: #include "../etc/rwhod/rwhod.h"
9:
10:
11: DIR *etc;
12:
13: #define NHOSTS 100
14: int nhosts;
15: struct hs {
16: struct whod *hs_wd;
17: int hs_nusers;
18: } hs[NHOSTS];
19: struct whod awhod;
20: int hscmp(), ucmp(), lcmp(), tcmp();
21:
22: #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we))
23: #define RWHODIR "/usr/spool/rwho"
24:
25: char *interval();
26: int now;
27: char *malloc(), *sprintf();
28: int aflg;
29:
30: #define down(h) (now - (h)->hs_wd->wd_recvtime > 5 * 60)
31:
32: main(argc, argv)
33: int argc;
34: char **argv;
35: {
36: struct direct *dp;
37: int f, i, t;
38: char buf[sizeof(struct whod)]; int cc;
39: register struct hs *hsp = hs;
40: register struct whod *wd;
41: register struct whoent *we;
42: int maxloadav = 0;
43: int (*cmp)() = hscmp;
44:
45: time(&t);
46: argc--, argv++;
47: again:
48: if (argc && !strcmp(*argv, "-a")) {
49: aflg++;
50: argc--, argv++;
51: goto again;
52: }
53: if (argc && !strcmp(*argv, "-l")) {
54: cmp = lcmp;
55: argc--, argv++;
56: goto again;
57: }
58: if (argc && !strcmp(*argv, "-u")) {
59: cmp = ucmp;
60: argc--, argv++;
61: goto again;
62: }
63: if (argc && !strcmp(*argv, "-t")) {
64: cmp = tcmp;
65: argc--, argv++;
66: goto again;
67: }
68: if (chdir(RWHODIR) < 0) {
69: perror(RWHODIR);
70: exit(1);
71: }
72: etc = opendir(".");
73: if (etc == NULL) {
74: perror("/etc");
75: exit(1);
76: }
77: while (dp = readdir(etc)) {
78: if (dp->d_ino == 0)
79: continue;
80: if (strncmp(dp->d_name, "whod.", 5))
81: continue;
82: if (nhosts == NHOSTS) {
83: fprintf(stderr, "too many hosts\n");
84: exit(1);
85: }
86: f = open(dp->d_name, 0);
87: if (f > 0) {
88: cc = read(f, buf, sizeof(struct whod));
89: if (cc >= WHDRSIZE) {
90: hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);
91: wd = (struct whod *)buf;
92: bcopy(buf, hsp->hs_wd, WHDRSIZE);
93: hsp->hs_nusers = 0;
94: for (i = 0; i < 2; i++)
95: if (wd->wd_loadav[i] > maxloadav)
96: maxloadav = wd->wd_loadav[i];
97: we = (struct whoent *) (buf + cc);
98: while (--we >= wd->wd_we)
99: if (aflg || we->we_idle < 3600)
100: hsp->hs_nusers++;
101: nhosts++; hsp++;
102: }
103: }
104: (void) close(f);
105: }
106: (void) time(&now);
107: qsort((char *)hs, nhosts, sizeof (hs[0]), cmp);
108: if (nhosts == 0) {
109: printf("no hosts!?!\n");
110: exit(1);
111: }
112: for (i = 0; i < nhosts; i++) {
113: hsp = &hs[i];
114: if (down(hsp)) {
115: printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
116: interval(now - hsp->hs_wd->wd_recvtime, "down"));
117: continue;
118: }
119: printf("%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n",
120: hsp->hs_wd->wd_hostname,
121: interval(hsp->hs_wd->wd_sendtime -
122: hsp->hs_wd->wd_boottime, " up"),
123: hsp->hs_nusers,
124: hsp->hs_nusers == 1 ? ", " : "s,",
125: maxloadav >= 1000 ? 5 : 4,
126: hsp->hs_wd->wd_loadav[0] / 100.0,
127: maxloadav >= 1000 ? 5 : 4,
128: hsp->hs_wd->wd_loadav[1] / 100.0,
129: maxloadav >= 1000 ? 5 : 4,
130: hsp->hs_wd->wd_loadav[2] / 100.0);
131: cfree(hsp->hs_wd);
132: }
133: exit(0);
134: }
135:
136: char *
137: interval(time, updown)
138: int time;
139: char *updown;
140: {
141: static char resbuf[32];
142: int days, hours, minutes;
143:
144: if (time < 0 || time > 3*30*24*60*60) {
145: (void) sprintf(resbuf, " %s ??:??", updown);
146: return (resbuf);
147: }
148: minutes = (time + 59) / 60; /* round to minutes */
149: hours = minutes / 60; minutes %= 60;
150: days = hours / 24; hours %= 24;
151: if (days)
152: (void) sprintf(resbuf, "%s %2d+%02d:%02d",
153: updown, days, hours, minutes);
154: else
155: (void) sprintf(resbuf, "%s %2d:%02d",
156: updown, hours, minutes);
157: return (resbuf);
158: }
159:
160: hscmp(h1, h2)
161: struct hs *h1, *h2;
162: {
163:
164: return (strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname));
165: }
166:
167: /*
168: * Compare according to load average.
169: */
170: lcmp(h1, h2)
171: struct hs *h1, *h2;
172: {
173:
174: if (down(h1))
175: if (down(h2))
176: return (tcmp(h1, h2));
177: else
178: return (1);
179: else if (down(h2))
180: return (-1);
181: else
182: return (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]);
183: }
184:
185: /*
186: * Compare according to number of users.
187: */
188: ucmp(h1, h2)
189: struct hs *h1, *h2;
190: {
191:
192: if (down(h1))
193: if (down(h2))
194: return (tcmp(h1, h2));
195: else
196: return (1);
197: else if (down(h2))
198: return (-1);
199: else
200: return (h2->hs_nusers - h1->hs_nusers);
201: }
202:
203: /*
204: * Compare according to uptime.
205: */
206: tcmp(h1, h2)
207: struct hs *h1, *h2;
208: {
209: long t1, t2;
210:
211: return (
212: (down(h2) ? h2->hs_wd->wd_recvtime - now
213: : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
214: -
215: (down(h1) ? h1->hs_wd->wd_recvtime - now
216: : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
217: );
218: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.