Commit | Line | Data |
---|---|---|
22e155fc DF |
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 | ||
be0e2d23 | 13 | #ifndef lint |
22e155fc DF |
14 | static char sccsid[] = "@(#)ruptime.c 5.1 (Berkeley) %G%"; |
15 | #endif not lint | |
be0e2d23 | 16 | |
ed0072ae | 17 | #include <sys/param.h> |
be0e2d23 | 18 | #include <stdio.h> |
7123e2dc SL |
19 | #include <sys/dir.h> |
20 | #include "../etc/rwhod/rwhod.h" | |
be0e2d23 | 21 | |
b9484359 | 22 | DIR *dirp; |
be0e2d23 BJ |
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; | |
508c25be | 31 | int hscmp(), ucmp(), lcmp(), tcmp(); |
be0e2d23 BJ |
32 | |
33 | #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we)) | |
fe77431f | 34 | #define RWHODIR "/usr/spool/rwho" |
be0e2d23 BJ |
35 | |
36 | char *interval(); | |
37 | int now; | |
38 | char *malloc(), *sprintf(); | |
39 | int aflg; | |
44bbb118 | 40 | int rflg = 1; |
be0e2d23 | 41 | |
b9484359 | 42 | #define down(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60) |
508c25be | 43 | |
be0e2d23 BJ |
44 | main(argc, argv) |
45 | int argc; | |
46 | char **argv; | |
47 | { | |
48 | struct direct *dp; | |
49 | int f, i, t; | |
a39120ab | 50 | char buf[sizeof(struct whod)]; int cc; |
44bbb118 | 51 | char *name; |
be0e2d23 BJ |
52 | register struct hs *hsp = hs; |
53 | register struct whod *wd; | |
54 | register struct whoent *we; | |
acf8f1b2 | 55 | int maxloadav = 0; |
508c25be | 56 | int (*cmp)() = hscmp; |
be0e2d23 | 57 | |
44bbb118 RC |
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 | } | |
be0e2d23 | 84 | time(&t); |
a82aa56a SL |
85 | if (chdir(RWHODIR) < 0) { |
86 | perror(RWHODIR); | |
be0e2d23 BJ |
87 | exit(1); |
88 | } | |
b9484359 RC |
89 | dirp = opendir("."); |
90 | if (dirp == NULL) { | |
91 | perror(RWHODIR); | |
be0e2d23 BJ |
92 | exit(1); |
93 | } | |
b9484359 | 94 | while (dp = readdir(dirp)) { |
be0e2d23 BJ |
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) { | |
a39120ab | 105 | cc = read(f, buf, sizeof(struct whod)); |
be0e2d23 BJ |
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; | |
acf8f1b2 BJ |
111 | for (i = 0; i < 2; i++) |
112 | if (wd->wd_loadav[i] > maxloadav) | |
113 | maxloadav = wd->wd_loadav[i]; | |
be0e2d23 BJ |
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 | } | |
be0e2d23 | 123 | (void) time(&now); |
508c25be | 124 | qsort((char *)hs, nhosts, sizeof (hs[0]), cmp); |
be0e2d23 BJ |
125 | if (nhosts == 0) { |
126 | printf("no hosts!?!\n"); | |
127 | exit(1); | |
128 | } | |
129 | for (i = 0; i < nhosts; i++) { | |
130 | hsp = &hs[i]; | |
508c25be | 131 | if (down(hsp)) { |
cad6a03e | 132 | printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname, |
be0e2d23 BJ |
133 | interval(now - hsp->hs_wd->wd_recvtime, "down")); |
134 | continue; | |
135 | } | |
cad6a03e | 136 | printf("%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n", |
be0e2d23 BJ |
137 | hsp->hs_wd->wd_hostname, |
138 | interval(hsp->hs_wd->wd_sendtime - | |
de3b21e8 | 139 | hsp->hs_wd->wd_boottime, " up"), |
be0e2d23 BJ |
140 | hsp->hs_nusers, |
141 | hsp->hs_nusers == 1 ? ", " : "s,", | |
acf8f1b2 BJ |
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); | |
be0e2d23 BJ |
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 > 3*30*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 | |
1518ea81 | 172 | (void) sprintf(resbuf, "%s %2d:%02d", |
be0e2d23 BJ |
173 | updown, hours, minutes); |
174 | return (resbuf); | |
175 | } | |
176 | ||
177 | hscmp(h1, h2) | |
178 | struct hs *h1, *h2; | |
179 | { | |
180 | ||
44bbb118 | 181 | return (rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname)); |
be0e2d23 | 182 | } |
508c25be EC |
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 | |
44bbb118 | 195 | return (rflg); |
508c25be | 196 | else if (down(h2)) |
44bbb118 | 197 | return (-rflg); |
508c25be | 198 | else |
44bbb118 RC |
199 | return (rflg * |
200 | (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0])); | |
508c25be EC |
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 | |
44bbb118 | 214 | return (rflg); |
508c25be | 215 | else if (down(h2)) |
44bbb118 | 216 | return (-rflg); |
508c25be | 217 | else |
44bbb118 | 218 | return (rflg * (h2->hs_nusers - h1->hs_nusers)); |
508c25be EC |
219 | } |
220 | ||
221 | /* | |
222 | * Compare according to uptime. | |
223 | */ | |
224 | tcmp(h1, h2) | |
225 | struct hs *h1, *h2; | |
226 | { | |
227 | long t1, t2; | |
228 | ||
44bbb118 | 229 | return (rflg * ( |
508c25be | 230 | (down(h2) ? h2->hs_wd->wd_recvtime - now |
de3b21e8 | 231 | : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime) |
508c25be EC |
232 | - |
233 | (down(h1) ? h1->hs_wd->wd_recvtime - now | |
de3b21e8 | 234 | : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime) |
44bbb118 | 235 | )); |
508c25be | 236 | } |