1 #ifndef lint 2 static char sccsid[] = "@(#)ruptime.c 4.6 82/11/14"; 3 #endif 4 5 #include <sys/param.h> 6 #include <stdio.h> 7 #include <dir.h> 8 #include <utmp.h> 9 #include "rwhod.h" 10 11 DIR *etc; 12 13 #define NHOSTS 100 14 int nhosts; 15 struct hs { 16 struct whod *hs_wd; 17 int hs_nusers; 18 } hs[NHOSTS]; 19 struct whod awhod; 20 int hscmp(), ucmp(), lcmp(), tcmp(); 21 22 #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we)) 23 24 char *interval(); 25 int now; 26 char *malloc(), *sprintf(); 27 int aflg; 28 29 #define down(h) (now - (h)->hs_wd->wd_recvtime > 5 * 60) 30 31 main(argc, argv) 32 int argc; 33 char **argv; 34 { 35 struct direct *dp; 36 int f, i, t; 37 char buf[BUFSIZ]; int cc; 38 register struct hs *hsp = hs; 39 register struct whod *wd; 40 register struct whoent *we; 41 int maxloadav = 0; 42 int (*cmp)() = hscmp; 43 44 time(&t); 45 argc--, argv++; 46 again: 47 if (!strcmp(*argv, "-a")) { 48 aflg++; 49 argc--, argv++; 50 goto again; 51 } 52 if (!strcmp(*argv, "-l")) { 53 cmp = lcmp; 54 argc--, argv++; 55 goto again; 56 } 57 if (!strcmp(*argv, "-u")) { 58 cmp = ucmp; 59 argc--, argv++; 60 goto again; 61 } 62 if (!strcmp(*argv, "-t")) { 63 cmp = tcmp; 64 argc--, argv++; 65 goto again; 66 } 67 if (chdir("/etc") < 0) { 68 perror("/etc"); 69 exit(1); 70 } 71 etc = opendir("."); 72 if (etc == NULL) { 73 perror("/etc"); 74 exit(1); 75 } 76 while (dp = readdir(etc)) { 77 if (dp->d_ino == 0) 78 continue; 79 if (strncmp(dp->d_name, "whod.", 5)) 80 continue; 81 if (nhosts == NHOSTS) { 82 fprintf(stderr, "too many hosts\n"); 83 exit(1); 84 } 85 f = open(dp->d_name, 0); 86 if (f > 0) { 87 cc = read(f, buf, BUFSIZ); 88 if (cc >= WHDRSIZE) { 89 hsp->hs_wd = (struct whod *)malloc(WHDRSIZE); 90 wd = (struct whod *)buf; 91 bcopy(buf, hsp->hs_wd, WHDRSIZE); 92 hsp->hs_nusers = 0; 93 for (i = 0; i < 2; i++) 94 if (wd->wd_loadav[i] > maxloadav) 95 maxloadav = wd->wd_loadav[i]; 96 we = (struct whoent *)(buf+cc); 97 while (--we >= wd->wd_we) 98 if (aflg || we->we_idle < 3600) 99 hsp->hs_nusers++; 100 nhosts++; hsp++; 101 } 102 } 103 (void) close(f); 104 } 105 (void) time(&now); 106 qsort((char *)hs, nhosts, sizeof (hs[0]), cmp); 107 if (nhosts == 0) { 108 printf("no hosts!?!\n"); 109 exit(1); 110 } 111 for (i = 0; i < nhosts; i++) { 112 hsp = &hs[i]; 113 if (down(hsp)) { 114 printf("%-8.8s%s\n", hsp->hs_wd->wd_hostname, 115 interval(now - hsp->hs_wd->wd_recvtime, "down")); 116 continue; 117 } 118 printf("%-8.8s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n", 119 hsp->hs_wd->wd_hostname, 120 interval(hsp->hs_wd->wd_sendtime - 121 hsp->hs_wd->wd_boottime, " up"), 122 hsp->hs_nusers, 123 hsp->hs_nusers == 1 ? ", " : "s,", 124 maxloadav >= 1000 ? 5 : 4, 125 hsp->hs_wd->wd_loadav[0] / 100.0, 126 maxloadav >= 1000 ? 5 : 4, 127 hsp->hs_wd->wd_loadav[1] / 100.0, 128 maxloadav >= 1000 ? 5 : 4, 129 hsp->hs_wd->wd_loadav[2] / 100.0); 130 cfree(hsp->hs_wd); 131 } 132 exit(0); 133 } 134 135 char * 136 interval(time, updown) 137 int time; 138 char *updown; 139 { 140 static char resbuf[32]; 141 int days, hours, minutes; 142 143 if (time < 0 || time > 3*30*24*60*60) { 144 (void) sprintf(resbuf, " %s ??:??", updown); 145 return (resbuf); 146 } 147 minutes = (time + 59) / 60; /* round to minutes */ 148 hours = minutes / 60; minutes %= 60; 149 days = hours / 24; hours %= 24; 150 if (days) 151 (void) sprintf(resbuf, "%s %2d+%02d:%02d", 152 updown, days, hours, minutes); 153 else 154 (void) sprintf(resbuf, " %s %2d:%02d", 155 updown, hours, minutes); 156 return (resbuf); 157 } 158 159 hscmp(h1, h2) 160 struct hs *h1, *h2; 161 { 162 163 return (strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname)); 164 } 165 166 /* 167 * Compare according to load average. 168 */ 169 lcmp(h1, h2) 170 struct hs *h1, *h2; 171 { 172 173 if (down(h1)) 174 if (down(h2)) 175 return (tcmp(h1, h2)); 176 else 177 return (1); 178 else if (down(h2)) 179 return (-1); 180 else 181 return (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]); 182 } 183 184 /* 185 * Compare according to number of users. 186 */ 187 ucmp(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 (1); 196 else if (down(h2)) 197 return (-1); 198 else 199 return (h2->hs_nusers - h1->hs_nusers); 200 } 201 202 /* 203 * Compare according to uptime. 204 */ 205 tcmp(h1, h2) 206 struct hs *h1, *h2; 207 { 208 long t1, t2; 209 210 return ( 211 (down(h2) ? h2->hs_wd->wd_recvtime - now 212 : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime) 213 - 214 (down(h1) ? h1->hs_wd->wd_recvtime - now 215 : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime) 216 ); 217 } 218