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.3 (Berkeley) 1/7/86"; 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 > 365*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: }