Commit | Line | Data |
---|---|---|
22e155fc | 1 | /* |
e8dcae5f KB |
2 | * Copyright (c) 1983 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
6d936b27 | 5 | * %sccs.include.redist.c% |
22e155fc DF |
6 | */ |
7 | ||
8 | #ifndef lint | |
9 | char copyright[] = | |
e8dcae5f | 10 | "@(#) Copyright (c) 1983 The Regents of the University of California.\n\ |
22e155fc | 11 | All rights reserved.\n"; |
e8dcae5f | 12 | #endif /* not lint */ |
22e155fc | 13 | |
be0e2d23 | 14 | #ifndef lint |
6e9687a6 | 15 | static char sccsid[] = "@(#)ruptime.c 5.8 (Berkeley) %G%"; |
e8dcae5f | 16 | #endif /* not lint */ |
be0e2d23 | 17 | |
ed0072ae | 18 | #include <sys/param.h> |
7123e2dc | 19 | #include <sys/dir.h> |
e8dcae5f | 20 | #include <sys/file.h> |
6e9687a6 | 21 | #include <sys/errno.h> |
5a7285fa | 22 | #include <protocols/rwhod.h> |
e8dcae5f | 23 | #include <stdio.h> |
6e9687a6 KB |
24 | #include <stdlib.h> |
25 | #include <string.h> | |
be0e2d23 | 26 | |
6e9687a6 | 27 | size_t nhosts, hspace = 20; |
e8dcae5f | 28 | struct hs { |
be0e2d23 BJ |
29 | struct whod *hs_wd; |
30 | int hs_nusers; | |
6e9687a6 | 31 | } *hs; |
be0e2d23 | 32 | struct whod awhod; |
be0e2d23 | 33 | |
6e9687a6 | 34 | #define ISDOWN(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60) |
be0e2d23 BJ |
35 | #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we)) |
36 | ||
6e9687a6 KB |
37 | time_t now; |
38 | int rflg = 1; | |
39 | int hscmp(), ucmp(), lcmp(), tcmp(); | |
508c25be | 40 | |
be0e2d23 BJ |
41 | main(argc, argv) |
42 | int argc; | |
43 | char **argv; | |
44 | { | |
e8dcae5f KB |
45 | extern char *optarg; |
46 | extern int optind; | |
6e9687a6 | 47 | register struct hs *hsp; |
be0e2d23 BJ |
48 | register struct whod *wd; |
49 | register struct whoent *we; | |
e8dcae5f KB |
50 | register DIR *dirp; |
51 | struct direct *dp; | |
52 | int aflg, cc, ch, f, i, maxloadav; | |
53 | char buf[sizeof(struct whod)]; | |
508c25be | 54 | int (*cmp)() = hscmp; |
e8dcae5f | 55 | time_t time(); |
6e9687a6 | 56 | char *interval(); |
e8dcae5f KB |
57 | |
58 | aflg = 0; | |
e8dcae5f KB |
59 | while ((ch = getopt(argc, argv, "alrut")) != EOF) |
60 | switch((char)ch) { | |
61 | case 'a': | |
62 | aflg = 1; | |
63 | break; | |
64 | case 'l': | |
65 | cmp = lcmp; | |
66 | break; | |
67 | case 'r': | |
68 | rflg = -1; | |
69 | break; | |
70 | case 't': | |
71 | cmp = tcmp; | |
72 | break; | |
73 | case 'u': | |
74 | cmp = ucmp; | |
75 | break; | |
76 | default: | |
6e9687a6 | 77 | (void)fprintf(stderr, "usage: ruptime [-alrut]\n"); |
e8dcae5f KB |
78 | exit(1); |
79 | } | |
be0e2d23 | 80 | |
435e8dff | 81 | if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) { |
6e9687a6 KB |
82 | (void)fprintf(stderr, "ruptime: %s: %s.\n", |
83 | _PATH_RWHODIR, strerror(errno)); | |
be0e2d23 BJ |
84 | exit(1); |
85 | } | |
6e9687a6 KB |
86 | morehosts(); |
87 | hsp = hs; | |
88 | maxloadav = -1; | |
b9484359 | 89 | while (dp = readdir(dirp)) { |
e8dcae5f | 90 | if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5)) |
be0e2d23 | 91 | continue; |
6e9687a6 KB |
92 | if ((f = open(dp->d_name, O_RDONLY, 0)) < 0) { |
93 | (void)fprintf(stderr, "ruptime: %s: %s\n", | |
94 | dp->d_name, strerror(errno)); | |
95 | continue; | |
be0e2d23 | 96 | } |
6e9687a6 KB |
97 | cc = read(f, buf, sizeof(struct whod)); |
98 | (void)close(f); | |
99 | if (cc < WHDRSIZE) | |
100 | continue; | |
101 | if (nhosts == hspace) { | |
102 | morehosts(); | |
103 | hsp = hs + nhosts; | |
be0e2d23 | 104 | } |
6e9687a6 KB |
105 | /* NOSTRICT */ |
106 | hsp->hs_wd = malloc((size_t)WHDRSIZE); | |
107 | wd = (struct whod *)buf; | |
108 | bcopy((char *)wd, (char *)hsp->hs_wd, (size_t)WHDRSIZE); | |
109 | hsp->hs_nusers = 0; | |
110 | for (i = 0; i < 2; i++) | |
111 | if (wd->wd_loadav[i] > maxloadav) | |
112 | maxloadav = wd->wd_loadav[i]; | |
113 | we = (struct whoent *)(buf+cc); | |
114 | while (--we >= wd->wd_we) | |
115 | if (aflg || we->we_idle < 3600) | |
116 | hsp->hs_nusers++; | |
117 | nhosts++; | |
118 | hsp++; | |
be0e2d23 | 119 | } |
e8dcae5f | 120 | if (!nhosts) { |
6e9687a6 | 121 | (void)printf("ruptime: no hosts in %s.\n", _PATH_RWHODIR); |
be0e2d23 BJ |
122 | exit(1); |
123 | } | |
e8dcae5f KB |
124 | qsort((char *)hs, nhosts, sizeof (hs[0]), cmp); |
125 | (void)time(&now); | |
be0e2d23 BJ |
126 | for (i = 0; i < nhosts; i++) { |
127 | hsp = &hs[i]; | |
6e9687a6 KB |
128 | if (ISDOWN(hsp)) { |
129 | (void)printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname, | |
be0e2d23 BJ |
130 | interval(now - hsp->hs_wd->wd_recvtime, "down")); |
131 | continue; | |
132 | } | |
6e9687a6 KB |
133 | (void)printf( |
134 | "%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n", | |
be0e2d23 | 135 | hsp->hs_wd->wd_hostname, |
6e9687a6 KB |
136 | interval((time_t)hsp->hs_wd->wd_sendtime - |
137 | (time_t)hsp->hs_wd->wd_boottime, " up"), | |
be0e2d23 BJ |
138 | hsp->hs_nusers, |
139 | hsp->hs_nusers == 1 ? ", " : "s,", | |
acf8f1b2 BJ |
140 | maxloadav >= 1000 ? 5 : 4, |
141 | hsp->hs_wd->wd_loadav[0] / 100.0, | |
142 | maxloadav >= 1000 ? 5 : 4, | |
143 | hsp->hs_wd->wd_loadav[1] / 100.0, | |
144 | maxloadav >= 1000 ? 5 : 4, | |
145 | hsp->hs_wd->wd_loadav[2] / 100.0); | |
6e9687a6 | 146 | free((void *)hsp->hs_wd); |
be0e2d23 BJ |
147 | } |
148 | exit(0); | |
149 | } | |
150 | ||
151 | char * | |
e8dcae5f KB |
152 | interval(tval, updown) |
153 | time_t tval; | |
be0e2d23 BJ |
154 | char *updown; |
155 | { | |
156 | static char resbuf[32]; | |
157 | int days, hours, minutes; | |
158 | ||
e8dcae5f KB |
159 | if (tval < 0 || tval > 365*24*60*60) { |
160 | (void)sprintf(resbuf, " %s ??:??", updown); | |
161 | return(resbuf); | |
be0e2d23 | 162 | } |
e8dcae5f | 163 | minutes = (tval + 59) / 60; /* round to minutes */ |
be0e2d23 BJ |
164 | hours = minutes / 60; minutes %= 60; |
165 | days = hours / 24; hours %= 24; | |
166 | if (days) | |
e8dcae5f | 167 | (void)sprintf(resbuf, "%s %2d+%02d:%02d", |
be0e2d23 BJ |
168 | updown, days, hours, minutes); |
169 | else | |
e8dcae5f | 170 | (void)sprintf(resbuf, "%s %2d:%02d", |
be0e2d23 | 171 | updown, hours, minutes); |
e8dcae5f | 172 | return(resbuf); |
be0e2d23 BJ |
173 | } |
174 | ||
6e9687a6 KB |
175 | /* alphabetical comparison */ |
176 | hscmp(a1, a2) | |
177 | void *a1, *a2; | |
be0e2d23 | 178 | { |
6e9687a6 KB |
179 | struct hs *h1 = a1, *h2 = a2; |
180 | ||
e8dcae5f | 181 | return(rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname)); |
be0e2d23 | 182 | } |
508c25be | 183 | |
6e9687a6 KB |
184 | /* load average comparison */ |
185 | lcmp(a1, a2) | |
186 | void *a1, *a2; | |
508c25be | 187 | { |
6e9687a6 KB |
188 | register struct hs *h1 = a1, *h2 = a2; |
189 | ||
190 | if (ISDOWN(h1)) | |
191 | if (ISDOWN(h2)) | |
192 | return(tcmp(a1, a2)); | |
508c25be | 193 | else |
e8dcae5f | 194 | return(rflg); |
6e9687a6 | 195 | else if (ISDOWN(h2)) |
e8dcae5f | 196 | return(-rflg); |
508c25be | 197 | else |
e8dcae5f | 198 | return(rflg * |
44bbb118 | 199 | (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0])); |
508c25be EC |
200 | } |
201 | ||
6e9687a6 KB |
202 | /* number of users comparison */ |
203 | ucmp(a1, a2) | |
204 | void *a1, *a2; | |
508c25be | 205 | { |
6e9687a6 KB |
206 | register struct hs *h1 = a1, *h2 = a2; |
207 | ||
208 | if (ISDOWN(h1)) | |
209 | if (ISDOWN(h2)) | |
210 | return(tcmp(a1, a2)); | |
508c25be | 211 | else |
e8dcae5f | 212 | return(rflg); |
6e9687a6 | 213 | else if (ISDOWN(h2)) |
e8dcae5f | 214 | return(-rflg); |
508c25be | 215 | else |
e8dcae5f | 216 | return(rflg * (h2->hs_nusers - h1->hs_nusers)); |
508c25be EC |
217 | } |
218 | ||
6e9687a6 KB |
219 | /* uptime comparison */ |
220 | tcmp(a1, a2) | |
221 | void *a1, *a2; | |
508c25be | 222 | { |
6e9687a6 KB |
223 | register struct hs *h1 = a1, *h2 = a2; |
224 | ||
e8dcae5f | 225 | return(rflg * ( |
6e9687a6 | 226 | (ISDOWN(h2) ? h2->hs_wd->wd_recvtime - now |
de3b21e8 | 227 | : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime) |
508c25be | 228 | - |
6e9687a6 | 229 | (ISDOWN(h1) ? h1->hs_wd->wd_recvtime - now |
de3b21e8 | 230 | : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime) |
44bbb118 | 231 | )); |
508c25be | 232 | } |
6e9687a6 KB |
233 | |
234 | morehosts() | |
235 | { | |
236 | hs = realloc((char *)hs, (hspace *= 2) * sizeof(*hs)); | |
237 | if (hs == NULL) { | |
238 | (void)fprintf(stderr, "ruptime: %s.\n", strerror(ENOMEM)); | |
239 | exit(1); | |
240 | } | |
241 | } |