4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
42 #include <sys/param.h>
49 #include <protocols/rwhod.h>
54 static int hostslim
= HOSTLIM
;
60 static int hscmp(), ucmp(), lcmp(), tcmp();
62 #define RWHODIR "/var/spool/rwho"
64 static char *interval();
69 #define down(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60)
73 main(int argc
, char **argv
)
110 (void) fprintf(stderr
, "Usage: %s [ -alrtu ]"
111 " (choose at most one of l, t, or u)\n",
116 if ((hs
= malloc(hostslim
* sizeof (struct hs
))) == NULL
) {
117 (void) fprintf(stderr
, "initial hs malloc failed\n");
121 if ((buf
= malloc(sizeof (struct whod
))) == NULL
) {
122 (void) fprintf(stderr
, "initial buf malloc failed\n");
126 if (chdir(RWHODIR
) < 0) {
135 while (dp
= readdir(dirp
)) {
138 if (strncmp(dp
->d_name
, "whod.", 5))
140 if (nhosts
== hostslim
) {
142 * We trust that the file system's limit on the number
143 * of files in a directory will kick in long before
146 hostslim
= hostslim
<< 1;
149 * hsp points into an area about to be moved,
150 * so we first remember its offset into hs[],
151 * then restore it after realloc() has moved
155 hs
= reallocarray(hs
, hostslim
, sizeof (struct hs
));
157 (void) fprintf(stderr
, "too many hosts\n");
162 f
= open(dp
->d_name
, O_RDONLY
);
164 int whdrsize
= sizeof (*buf
) - sizeof (buf
->wd_we
);
166 cc
= read(f
, buf
, sizeof (struct whod
));
167 if (cc
>= whdrsize
) {
168 hsp
->hs_wd
= malloc(whdrsize
);
170 bcopy((char *)buf
, (char *)hsp
->hs_wd
,
173 for (i
= 0; i
< 2; i
++)
174 if (wd
->wd_loadav
[i
] > maxloadav
)
175 maxloadav
= wd
->wd_loadav
[i
];
176 /* LINTED: pointer alignment */
177 we
= (struct whoent
*)(((char *)buf
)+cc
);
178 while (--we
>= wd
->wd_we
)
179 if (aflg
|| we
->we_idle
< 3600)
187 qsort((char *)hs
, nhosts
, sizeof (hs
[0]), cmp
);
189 (void) printf("no hosts!?!\n");
192 for (i
= 0; i
< nhosts
; i
++) {
195 (void) printf("%-12s%s\n", hsp
->hs_wd
->wd_hostname
,
196 interval((int)(now
- hsp
->hs_wd
->wd_recvtime
),
200 (void) printf("%-12s%s, %4d user%s load %*.2f,"
202 hsp
->hs_wd
->wd_hostname
,
203 interval(hsp
->hs_wd
->wd_sendtime
-
204 hsp
->hs_wd
->wd_boottime
, " up"),
206 hsp
->hs_nusers
== 1 ? ", " : "s,",
207 maxloadav
>= 1000 ? 5 : 4,
208 hsp
->hs_wd
->wd_loadav
[0] / 100.0,
209 maxloadav
>= 1000 ? 5 : 4,
210 hsp
->hs_wd
->wd_loadav
[1] / 100.0,
211 maxloadav
>= 1000 ? 5 : 4,
212 hsp
->hs_wd
->wd_loadav
[2] / 100.0);
220 interval(int time
, char *updown
)
222 static char resbuf
[32];
223 int days
, hours
, minutes
;
225 if (time
< 0 || time
> 10*365*24*60*60) {
226 (void) sprintf(resbuf
, " %s ??:??", updown
);
229 minutes
= (time
+ 59) / 60; /* round to minutes */
230 hours
= minutes
/ 60; minutes
%= 60;
231 days
= hours
/ 24; hours
%= 24;
233 (void) sprintf(resbuf
, "%s %2d+%02d:%02d",
234 updown
, days
, hours
, minutes
);
236 (void) sprintf(resbuf
, "%s %2d:%02d",
237 updown
, hours
, minutes
);
242 hscmp(struct hs
*h1
, struct hs
*h2
)
245 return (rflg
* strcmp(h1
->hs_wd
->wd_hostname
, h2
->hs_wd
->wd_hostname
));
249 * Compare according to load average.
252 lcmp(struct hs
*h1
, struct hs
*h2
)
257 return (tcmp(h1
, h2
));
264 (h2
->hs_wd
->wd_loadav
[0] - h1
->hs_wd
->wd_loadav
[0]));
268 * Compare according to number of users.
271 ucmp(struct hs
*h1
, struct hs
*h2
)
276 return (tcmp(h1
, h2
));
282 return (rflg
* (h2
->hs_nusers
- h1
->hs_nusers
));
286 * Compare according to uptime.
289 tcmp(struct hs
*h1
, struct hs
*h2
)
293 (down(h2
) ? h2
->hs_wd
->wd_recvtime
- now
:
294 h2
->hs_wd
->wd_sendtime
- h2
->hs_wd
->wd_boottime
)
296 (down(h1
) ? h1
->hs_wd
->wd_recvtime
- now
:
297 h1
->hs_wd
->wd_sendtime
- h1
->hs_wd
->wd_boottime
)));