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: #if !defined(lint) && defined(DOSCCS) 8: char copyright[] = 9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: 12: static char sccsid[] = "@(#)ruptime.c 5.3.1 (2.11BSD) 1997/4/18"; 13: #endif 14: 15: #include <sys/param.h> 16: #include <stdio.h> 17: #include <sys/dir.h> 18: #include <protocols/rwhod.h> 19: 20: DIR *dirp; 21: 22: #define NHOSTS 100 23: int nhosts; 24: struct hs { 25: struct whod *hs_wd; 26: int hs_nusers; 27: } hs[NHOSTS]; 28: struct whod awhod; 29: int hscmp(), ucmp(), lcmp(), tcmp(); 30: 31: #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we)) 32: #define RWHODIR "/usr/spool/rwho" 33: 34: char *interval(); 35: time_t now; 36: char *malloc(), *sprintf(); 37: int aflg; 38: int rflg = 1; 39: 40: #define down(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60) 41: 42: main(argc, argv) 43: int argc; 44: char **argv; 45: { 46: struct direct *dp; 47: int f, i; 48: time_t t; 49: char buf[sizeof(struct whod)]; int cc; 50: char *name; 51: register struct hs *hsp = hs; 52: register struct whod *wd; 53: register struct whoent *we; 54: int maxloadav = 0; 55: int (*cmp)() = hscmp; 56: 57: name = *argv; 58: while (*++argv) 59: while (**argv) 60: switch (*(*argv)++) { 61: case 'a': 62: aflg++; 63: break; 64: case 'l': 65: cmp = lcmp; 66: break; 67: case 'u': 68: cmp = ucmp; 69: break; 70: case 't': 71: cmp = tcmp; 72: break; 73: case 'r': 74: rflg = -rflg; 75: break; 76: case '-': 77: break; 78: default: 79: fprintf(stderr, "Usage: %s [ -ar [ lut ] ]\n", 80: name); 81: exit (1); 82: } 83: time(&t); 84: if (chdir(RWHODIR) < 0) { 85: perror(RWHODIR); 86: exit(1); 87: } 88: dirp = opendir("."); 89: if (dirp == NULL) { 90: perror(RWHODIR); 91: exit(1); 92: } 93: while (dp = readdir(dirp)) { 94: if (dp->d_ino == 0) 95: continue; 96: if (strncmp(dp->d_name, "whod.", 5)) 97: continue; 98: if (nhosts == NHOSTS) { 99: fprintf(stderr, "too many hosts\n"); 100: exit(1); 101: } 102: f = open(dp->d_name, 0); 103: if (f > 0) { 104: cc = read(f, buf, sizeof(struct whod)); 105: if (cc >= WHDRSIZE) { 106: hsp->hs_wd = (struct whod *)malloc(WHDRSIZE); 107: wd = (struct whod *)buf; 108: bcopy(buf, 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: } 120: (void) close(f); 121: } 122: (void) time(&now); 123: qsort((char *)hs, nhosts, sizeof (hs[0]), cmp); 124: if (nhosts == 0) { 125: printf("no hosts!?!\n"); 126: exit(1); 127: } 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: 152: char * 153: interval(time, updown) 154: long time; 155: char *updown; 156: { 157: static char resbuf[32]; 158: long days, hours, minutes; 159: 160: if (time < 0 || time > 3L* 365L*24L*60L*60L) { 161: (void) sprintf(resbuf, " %s ??:??", updown); 162: return (resbuf); 163: } 164: minutes = (time + 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 %3ld+%02ld:%02ld", 169: updown, days, hours, minutes); 170: else 171: (void) sprintf(resbuf, "%s %3ld:%02ld", 172: updown, hours, minutes); 173: return (resbuf); 174: } 175: 176: hscmp(h1, h2) 177: struct hs *h1, *h2; 178: { 179: 180: return (rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname)); 181: } 182: 183: /* 184: * Compare according to load average. 185: */ 186: lcmp(h1, h2) 187: struct hs *h1, *h2; 188: { 189: 190: if (down(h1)) 191: if (down(h2)) 192: return (tcmp(h1, h2)); 193: else 194: return (rflg); 195: else if (down(h2)) 196: return (-rflg); 197: else 198: return (rflg * 199: (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0])); 200: } 201: 202: /* 203: * Compare according to number of users. 204: */ 205: ucmp(h1, h2) 206: struct hs *h1, *h2; 207: { 208: 209: if (down(h1)) 210: if (down(h2)) 211: return (tcmp(h1, h2)); 212: else 213: return (rflg); 214: else if (down(h2)) 215: return (-rflg); 216: else 217: return (rflg * (h2->hs_nusers - h1->hs_nusers)); 218: } 219: 220: /* 221: * Compare according to uptime. 222: */ 223: tcmp(h1, h2) 224: struct hs *h1, *h2; 225: { 226: long t1, t2; 227: 228: return (rflg * ( 229: (down(h2) ? h2->hs_wd->wd_recvtime - now 230: : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime) 231: - 232: (down(h1) ? h1->hs_wd->wd_recvtime - now 233: : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime) 234: )); 235: }