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