Annotation of src/usr.bin/ruptime/ruptime.c, Revision 1.1
1.1 ! deraadt 1: /*
! 2: * Copyright (c) 1983 The Regents of the University of California.
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: * 3. All advertising materials mentioning features or use of this software
! 14: * must display the following acknowledgement:
! 15: * This product includes software developed by the University of
! 16: * California, Berkeley and its contributors.
! 17: * 4. Neither the name of the University nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: */
! 33:
! 34: #ifndef lint
! 35: char copyright[] =
! 36: "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
! 37: All rights reserved.\n";
! 38: #endif /* not lint */
! 39:
! 40: #ifndef lint
! 41: /*static char sccsid[] = "from: @(#)ruptime.c 5.8 (Berkeley) 7/21/90";*/
! 42: static char rcsid[] = "$Id: ruptime.c,v 1.4 1994/04/05 02:18:43 cgd Exp $";
! 43: #endif /* not lint */
! 44:
! 45: #include <sys/param.h>
! 46: #include <sys/file.h>
! 47: #include <dirent.h>
! 48: #include <protocols/rwhod.h>
! 49: #include <stdio.h>
! 50: #include <stdlib.h>
! 51: #include <string.h>
! 52: #include <errno.h>
! 53:
! 54: size_t nhosts, hspace = 20;
! 55: struct hs {
! 56: struct whod *hs_wd;
! 57: int hs_nusers;
! 58: } *hs;
! 59: struct whod awhod;
! 60:
! 61: #define ISDOWN(h) (now - (h)->hs_wd->wd_recvtime > 11 * 60)
! 62: #define WHDRSIZE (sizeof (awhod) - sizeof (awhod.wd_we))
! 63:
! 64: time_t now;
! 65: int rflg = 1;
! 66: int hscmp(), ucmp(), lcmp(), tcmp();
! 67:
! 68: main(argc, argv)
! 69: int argc;
! 70: char **argv;
! 71: {
! 72: extern char *optarg;
! 73: extern int optind;
! 74: register struct hs *hsp;
! 75: register struct whod *wd;
! 76: register struct whoent *we;
! 77: register DIR *dirp;
! 78: struct dirent *dp;
! 79: int aflg, cc, ch, f, i, maxloadav;
! 80: char buf[sizeof(struct whod)];
! 81: int (*cmp)() = hscmp;
! 82: time_t time();
! 83: char *interval();
! 84:
! 85: aflg = 0;
! 86: while ((ch = getopt(argc, argv, "alrut")) != EOF)
! 87: switch((char)ch) {
! 88: case 'a':
! 89: aflg = 1;
! 90: break;
! 91: case 'l':
! 92: cmp = lcmp;
! 93: break;
! 94: case 'r':
! 95: rflg = -1;
! 96: break;
! 97: case 't':
! 98: cmp = tcmp;
! 99: break;
! 100: case 'u':
! 101: cmp = ucmp;
! 102: break;
! 103: default:
! 104: (void)fprintf(stderr, "usage: ruptime [-alrut]\n");
! 105: exit(1);
! 106: }
! 107:
! 108: if (chdir(_PATH_RWHODIR) || (dirp = opendir(".")) == NULL) {
! 109: (void)fprintf(stderr, "ruptime: %s: %s.\n",
! 110: _PATH_RWHODIR, strerror(errno));
! 111: exit(1);
! 112: }
! 113: morehosts();
! 114: hsp = hs;
! 115: maxloadav = -1;
! 116: while (dp = readdir(dirp)) {
! 117: if (dp->d_ino == 0 || strncmp(dp->d_name, "whod.", 5))
! 118: continue;
! 119: if ((f = open(dp->d_name, O_RDONLY, 0)) < 0) {
! 120: (void)fprintf(stderr, "ruptime: %s: %s\n",
! 121: dp->d_name, strerror(errno));
! 122: continue;
! 123: }
! 124: cc = read(f, buf, sizeof(struct whod));
! 125: (void)close(f);
! 126: if (cc < WHDRSIZE)
! 127: continue;
! 128: if (nhosts == hspace) {
! 129: morehosts();
! 130: hsp = hs + nhosts;
! 131: }
! 132: /* NOSTRICT */
! 133: hsp->hs_wd = malloc((size_t)WHDRSIZE);
! 134: wd = (struct whod *)buf;
! 135: bcopy((char *)wd, (char *)hsp->hs_wd, (size_t)WHDRSIZE);
! 136: hsp->hs_nusers = 0;
! 137: for (i = 0; i < 2; i++)
! 138: if (wd->wd_loadav[i] > maxloadav)
! 139: maxloadav = wd->wd_loadav[i];
! 140: we = (struct whoent *)(buf+cc);
! 141: while (--we >= wd->wd_we)
! 142: if (aflg || we->we_idle < 3600)
! 143: hsp->hs_nusers++;
! 144: nhosts++;
! 145: hsp++;
! 146: }
! 147: if (!nhosts) {
! 148: (void)printf("ruptime: no hosts in %s.\n", _PATH_RWHODIR);
! 149: exit(1);
! 150: }
! 151: (void)time(&now);
! 152: qsort((char *)hs, nhosts, sizeof (hs[0]), cmp);
! 153: for (i = 0; i < nhosts; i++) {
! 154: hsp = &hs[i];
! 155: if (ISDOWN(hsp)) {
! 156: (void)printf("%-12.12s%s\n", hsp->hs_wd->wd_hostname,
! 157: interval(now - hsp->hs_wd->wd_recvtime, "down"));
! 158: continue;
! 159: }
! 160: (void)printf(
! 161: "%-12.12s%s, %4d user%s load %*.2f, %*.2f, %*.2f\n",
! 162: hsp->hs_wd->wd_hostname,
! 163: interval((time_t)hsp->hs_wd->wd_sendtime -
! 164: (time_t)hsp->hs_wd->wd_boottime, " up"),
! 165: hsp->hs_nusers,
! 166: hsp->hs_nusers == 1 ? ", " : "s,",
! 167: maxloadav >= 1000 ? 5 : 4,
! 168: hsp->hs_wd->wd_loadav[0] / 100.0,
! 169: maxloadav >= 1000 ? 5 : 4,
! 170: hsp->hs_wd->wd_loadav[1] / 100.0,
! 171: maxloadav >= 1000 ? 5 : 4,
! 172: hsp->hs_wd->wd_loadav[2] / 100.0);
! 173: free((void *)hsp->hs_wd);
! 174: }
! 175: exit(0);
! 176: }
! 177:
! 178: char *
! 179: interval(tval, updown)
! 180: time_t tval;
! 181: char *updown;
! 182: {
! 183: static char resbuf[32];
! 184: int days, hours, minutes;
! 185:
! 186: if (tval < 0 || tval > 365*24*60*60) {
! 187: (void)sprintf(resbuf, " %s ??:??", updown);
! 188: return(resbuf);
! 189: }
! 190: minutes = (tval + 59) / 60; /* round to minutes */
! 191: hours = minutes / 60; minutes %= 60;
! 192: days = hours / 24; hours %= 24;
! 193: if (days)
! 194: (void)sprintf(resbuf, "%s %2d+%02d:%02d",
! 195: updown, days, hours, minutes);
! 196: else
! 197: (void)sprintf(resbuf, "%s %2d:%02d",
! 198: updown, hours, minutes);
! 199: return(resbuf);
! 200: }
! 201:
! 202: /* alphabetical comparison */
! 203: hscmp(a1, a2)
! 204: void *a1, *a2;
! 205: {
! 206: struct hs *h1 = a1, *h2 = a2;
! 207:
! 208: return(rflg * strcmp(h1->hs_wd->wd_hostname, h2->hs_wd->wd_hostname));
! 209: }
! 210:
! 211: /* load average comparison */
! 212: lcmp(a1, a2)
! 213: void *a1, *a2;
! 214: {
! 215: register struct hs *h1 = a1, *h2 = a2;
! 216:
! 217: if (ISDOWN(h1))
! 218: if (ISDOWN(h2))
! 219: return(tcmp(a1, a2));
! 220: else
! 221: return(rflg);
! 222: else if (ISDOWN(h2))
! 223: return(-rflg);
! 224: else
! 225: return(rflg *
! 226: (h2->hs_wd->wd_loadav[0] - h1->hs_wd->wd_loadav[0]));
! 227: }
! 228:
! 229: /* number of users comparison */
! 230: ucmp(a1, a2)
! 231: void *a1, *a2;
! 232: {
! 233: register struct hs *h1 = a1, *h2 = a2;
! 234:
! 235: if (ISDOWN(h1))
! 236: if (ISDOWN(h2))
! 237: return(tcmp(a1, a2));
! 238: else
! 239: return(rflg);
! 240: else if (ISDOWN(h2))
! 241: return(-rflg);
! 242: else
! 243: return(rflg * (h2->hs_nusers - h1->hs_nusers));
! 244: }
! 245:
! 246: /* uptime comparison */
! 247: tcmp(a1, a2)
! 248: void *a1, *a2;
! 249: {
! 250: register struct hs *h1 = a1, *h2 = a2;
! 251:
! 252: return(rflg * (
! 253: (ISDOWN(h2) ? h2->hs_wd->wd_recvtime - now
! 254: : h2->hs_wd->wd_sendtime - h2->hs_wd->wd_boottime)
! 255: -
! 256: (ISDOWN(h1) ? h1->hs_wd->wd_recvtime - now
! 257: : h1->hs_wd->wd_sendtime - h1->hs_wd->wd_boottime)
! 258: ));
! 259: }
! 260:
! 261: morehosts()
! 262: {
! 263: hs = realloc((char *)hs, (hspace *= 2) * sizeof(*hs));
! 264: if (hs == NULL) {
! 265: (void)fprintf(stderr, "ruptime: %s.\n", strerror(ENOMEM));
! 266: exit(1);
! 267: }
! 268: }