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