|
|
1.1 root 1: /*
2: * Copyright (c) 1983 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: char copyright[] =
22: "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)ruptime.c 5.7 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include <sys/param.h>
31: #include <sys/dir.h>
32: #include <sys/file.h>
33: #include <protocols/rwhod.h>
34: #include <stdio.h>
35:
36: #define NHOSTS 100
37: int nhosts;
38: struct hs {
39: struct whod *hs_wd;
40: int hs_nusers;
41: } hs[NHOSTS];
42: struct whod awhod;
43:
44: #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we))
45: #define down(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60)
46:
47: time_t now;
48: int rflg = 1;
49: int hscmp(), ucmp(), lcmp(), tcmp();
50:
51: main(argc, argv)
52: int argc;
53: char **argv;
54: {
55: extern char *optarg;
56: extern int optind;
57: register struct hs *hsp = hs;
58: register struct whod *wd;
59: register struct whoent *we;
60: register DIR *dirp;
61: struct direct *dp;
62: int aflg, cc, ch, f, i, maxloadav;
63: char buf[sizeof(struct whod)];
64: int (*cmp)() = hscmp;
65: time_t time();
66: char *interval(), *malloc();
67:
68: aflg = 0;
69: maxloadav = -1;
70: while ((ch = getopt(argc, argv, "alrut")) != EOF)
71: switch((char)ch) {
72: case 'a':
73: aflg = 1;
74: break;
75: case 'l':
76: cmp = lcmp;
77: break;
78: case 'r':
79: rflg = -1;
80: break;
81: case 't':
82: cmp = tcmp;
83: break;
84: case 'u':
85: cmp = ucmp;
86: break;
87: default:
88: fprintf(stderr, "usage: ruptime [-alrut]\n");
89: exit(1);
90: }
91:
92: if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) {
93: perror(_PATH_RWHODIR);
94: exit(1);
95: }
96: while (dp = readdir(dirp)) {
97: if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
98: continue;
99: if (nhosts == NHOSTS) {
100: fprintf(stderr, "ruptime: too many hosts\n");
101: exit(1);
102: }
103: f = open(dp->d_name, O_RDONLY, 0);
104: if (f > 0) {
105: cc = read(f, buf, sizeof(struct whod));
106: if (cc >= WHDRSIZE) {
107: /* NOSTRICT */
108: hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);
109: wd = (struct whod *)buf;
110: bcopy(wd, hsp->hs_wd, WHDRSIZE);
111: hsp->hs_nusers = 0;
112: for (i = 0; i < 2; i++)
113: if (wd->wd_loadav[i] > maxloadav)
114: maxloadav = wd->wd_loadav[i];
115: we = (struct whoent *)(buf+cc);
116: while (--we >= wd->wd_we)
117: if (aflg || we->we_idle < 3600)
118: hsp->hs_nusers++;
119: nhosts++; hsp++;
120: }
121: (void)close(f);
122: }
123: }
124: if (!nhosts) {
125: printf("ruptime: no hosts!?!\n");
126: exit(1);
127: }
128: qsort((char *)hs, nhosts, sizeof (hs[0]), cmp);
129: (void)time(&now);
130: for (i = 0; i < nhosts; i++) {
131: hsp = &hs[i];
132: if (down(hsp)) {
133: printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
134: interval(now - hsp->hs_wd->wd_recvtime, "down"));
135: continue;
136: }
137: printf("%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n",
138: hsp->hs_wd->wd_hostname,
139: interval(hsp->hs_wd->wd_sendtime -
140: hsp->hs_wd->wd_boottime, " up"),
141: hsp->hs_nusers,
142: hsp->hs_nusers == 1 ? ", " : "s,",
143: maxloadav >= 1000 ? 5 : 4,
144: hsp->hs_wd->wd_loadav[0] / 100.0,
145: maxloadav >= 1000 ? 5 : 4,
146: hsp->hs_wd->wd_loadav[1] / 100.0,
147: maxloadav >= 1000 ? 5 : 4,
148: hsp->hs_wd->wd_loadav[2] / 100.0);
149: cfree(hsp->hs_wd);
150: }
151: exit(0);
152: }
153:
154: char *
155: interval(tval, updown)
156: time_t tval;
157: char *updown;
158: {
159: static char resbuf[32];
160: int days, hours, minutes;
161:
162: if (tval < 0 || tval > 365*24*60*60) {
163: (void)sprintf(resbuf, " %s ??:??", updown);
164: return(resbuf);
165: }
166: minutes = (tval + 59) / 60; /* round to minutes */
167: hours = minutes / 60; minutes %= 60;
168: days = hours / 24; hours %= 24;
169: if (days)
170: (void)sprintf(resbuf, "%s %2d+%02d:%02d",
171: updown, days, hours, minutes);
172: else
173: (void)sprintf(resbuf, "%s %2d:%02d",
174: updown, hours, minutes);
175: return(resbuf);
176: }
177:
178: hscmp(h1, h2)
179: struct hs *h1, *h2;
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: if (down(h1))
191: if (down(h2))
192: return(tcmp(h1, h2));
193: else
194: return(rflg);
195: else if (down(h2))
196: return(-rflg);
197: else
198: return(rflg *
199: (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]));
200: }
201:
202: /*
203: * Compare according to number of users.
204: */
205: ucmp(h1, h2)
206: struct hs *h1, *h2;
207: {
208: if (down(h1))
209: if (down(h2))
210: return(tcmp(h1, h2));
211: else
212: return(rflg);
213: else if (down(h2))
214: return(-rflg);
215: else
216: return(rflg * (h2->hs_nusers - h1->hs_nusers));
217: }
218:
219: /*
220: * Compare according to uptime.
221: */
222: tcmp(h1, h2)
223: struct hs *h1, *h2;
224: {
225: return(rflg * (
226: (down(h2) ? h2->hs_wd->wd_recvtime - now
227: : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
228: -
229: (down(h1) ? h1->hs_wd->wd_recvtime - now
230: : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
231: ));
232: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.