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