BSD 4_3_Net_1 release
[unix-history] / ruptime / ruptime.c
CommitLineData
22e155fc 1/*
e8dcae5f
KB
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 the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22e155fc
DF
16 */
17
18#ifndef lint
19char copyright[] =
e8dcae5f 20"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
22e155fc 21 All rights reserved.\n";
e8dcae5f 22#endif /* not lint */
22e155fc 23
be0e2d23 24#ifndef lint
e3419641 25static char sccsid[] = "@(#)ruptime.c 5.5 (Berkeley) 8/25/88";
e8dcae5f 26#endif /* not lint */
be0e2d23 27
ed0072ae 28#include <sys/param.h>
7123e2dc 29#include <sys/dir.h>
e8dcae5f 30#include <sys/file.h>
5a7285fa 31#include <protocols/rwhod.h>
e8dcae5f 32#include <stdio.h>
be0e2d23
BJ
33
34#define NHOSTS 100
35int nhosts;
e8dcae5f 36struct hs {
be0e2d23
BJ
37 struct whod *hs_wd;
38 int hs_nusers;
39} hs[NHOSTS];
40struct whod awhod;
be0e2d23
BJ
41
42#define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we))
fe77431f 43#define RWHODIR "/usr/spool/rwho"
e8dcae5f 44#define down(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60)
be0e2d23 45
e8dcae5f
KB
46time_t now;
47int rflg = 1;
48int hscmp(), ucmp(), lcmp(), tcmp();
508c25be 49
be0e2d23
BJ
50main(argc, argv)
51 int argc;
52 char **argv;
53{
e8dcae5f
KB
54 extern char *optarg;
55 extern int optind;
be0e2d23
BJ
56 register struct hs *hsp = hs;
57 register struct whod *wd;
58 register struct whoent *we;
e8dcae5f
KB
59 register DIR *dirp;
60 struct direct *dp;
61 int aflg, cc, ch, f, i, maxloadav;
62 char buf[sizeof(struct whod)];
508c25be 63 int (*cmp)() = hscmp;
e8dcae5f
KB
64 time_t time();
65 char *interval(), *malloc();
66
67 aflg = 0;
68 maxloadav = -1;
69 while ((ch = getopt(argc, argv, "alrut")) != EOF)
70 switch((char)ch) {
71 case 'a':
72 aflg = 1;
73 break;
74 case 'l':
75 cmp = lcmp;
76 break;
77 case 'r':
78 rflg = -1;
79 break;
80 case 't':
81 cmp = tcmp;
82 break;
83 case 'u':
84 cmp = ucmp;
85 break;
86 default:
87 fprintf(stderr, "usage: ruptime [-alrut]\n");
88 exit(1);
89 }
be0e2d23 90
e8dcae5f 91 if (chdir(RWHODIR) || (dirp = opendir(".")) == NULL) {
b9484359 92 perror(RWHODIR);
be0e2d23
BJ
93 exit(1);
94 }
b9484359 95 while (dp = readdir(dirp)) {
e8dcae5f 96 if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
be0e2d23
BJ
97 continue;
98 if (nhosts == NHOSTS) {
e8dcae5f 99 fprintf(stderr, "ruptime: too many hosts\n");
be0e2d23
BJ
100 exit(1);
101 }
e8dcae5f 102 f = open(dp->d_name, O_RDONLY, 0);
be0e2d23 103 if (f > 0) {
a39120ab 104 cc = read(f, buf, sizeof(struct whod));
be0e2d23 105 if (cc >= WHDRSIZE) {
e8dcae5f 106 /* NOSTRICT */
be0e2d23
BJ
107 hsp->hs_wd = (struct whod *)malloc(WHDRSIZE);
108 wd = (struct whod *)buf;
e8dcae5f 109 bcopy(wd, hsp->hs_wd, WHDRSIZE);
be0e2d23 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 }
e8dcae5f 120 (void)close(f);
be0e2d23 121 }
be0e2d23 122 }
e8dcae5f
KB
123 if (!nhosts) {
124 printf("ruptime: no hosts!?!\n");
be0e2d23
BJ
125 exit(1);
126 }
e8dcae5f
KB
127 qsort((char *)hs, nhosts, sizeof (hs[0]), cmp);
128 (void)time(&now);
be0e2d23
BJ
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
153char *
e8dcae5f
KB
154interval(tval, updown)
155 time_t tval;
be0e2d23
BJ
156 char *updown;
157{
158 static char resbuf[32];
159 int days, hours, minutes;
160
e8dcae5f
KB
161 if (tval < 0 || tval > 365*24*60*60) {
162 (void)sprintf(resbuf, " %s ??:??", updown);
163 return(resbuf);
be0e2d23 164 }
e8dcae5f 165 minutes = (tval + 59) / 60; /* round to minutes */
be0e2d23
BJ
166 hours = minutes / 60; minutes %= 60;
167 days = hours / 24; hours %= 24;
168 if (days)
e8dcae5f 169 (void)sprintf(resbuf, "%s %2d+%02d:%02d",
be0e2d23
BJ
170 updown, days, hours, minutes);
171 else
e8dcae5f 172 (void)sprintf(resbuf, "%s %2d:%02d",
be0e2d23 173 updown, hours, minutes);
e8dcae5f 174 return(resbuf);
be0e2d23
BJ
175}
176
177hscmp(h1, h2)
178 struct hs *h1, *h2;
179{
e8dcae5f 180 return(rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname));
be0e2d23 181}
508c25be
EC
182
183/*
184 * Compare according to load average.
185 */
186lcmp(h1, h2)
187 struct hs *h1, *h2;
188{
508c25be
EC
189 if (down(h1))
190 if (down(h2))
e8dcae5f 191 return(tcmp(h1, h2));
508c25be 192 else
e8dcae5f 193 return(rflg);
508c25be 194 else if (down(h2))
e8dcae5f 195 return(-rflg);
508c25be 196 else
e8dcae5f 197 return(rflg *
44bbb118 198 (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]));
508c25be
EC
199}
200
201/*
202 * Compare according to number of users.
203 */
204ucmp(h1, h2)
205 struct hs *h1, *h2;
206{
508c25be
EC
207 if (down(h1))
208 if (down(h2))
e8dcae5f 209 return(tcmp(h1, h2));
508c25be 210 else
e8dcae5f 211 return(rflg);
508c25be 212 else if (down(h2))
e8dcae5f 213 return(-rflg);
508c25be 214 else
e8dcae5f 215 return(rflg * (h2->hs_nusers - h1->hs_nusers));
508c25be
EC
216}
217
218/*
219 * Compare according to uptime.
220 */
221tcmp(h1, h2)
222 struct hs *h1, *h2;
223{
e8dcae5f 224 return(rflg * (
508c25be 225 (down(h2) ? h2->hs_wd->wd_recvtime - now
de3b21e8 226 : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
508c25be
EC
227 -
228 (down(h1) ? h1->hs_wd->wd_recvtime - now
de3b21e8 229 : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
44bbb118 230 ));
508c25be 231}