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