Annotation of src/usr.bin/rup/rup.c, Revision 1.1
1.1 ! deraadt 1: /*-
! 2: * Copyright (c) 1993, John Brezak
! 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: static char rcsid[] = "$Id: rup.c,v 1.10 1994/02/05 14:58:14 pk Exp $";
! 36: #endif /* not lint */
! 37:
! 38: #include <stdio.h>
! 39: #include <stdlib.h>
! 40: #include <string.h>
! 41: #include <time.h>
! 42: #include <sys/param.h>
! 43: #include <sys/socket.h>
! 44: #include <netdb.h>
! 45: #include <rpc/rpc.h>
! 46: #include <arpa/inet.h>
! 47: #include <err.h>
! 48:
! 49: #undef FSHIFT /* Use protocol's shift and scale values */
! 50: #undef FSCALE
! 51: #include <rpcsvc/rstat.h>
! 52:
! 53: #define HOST_WIDTH 24
! 54:
! 55: int printtime; /* print the remote host(s)'s time */
! 56:
! 57: struct host_list {
! 58: struct host_list *next;
! 59: struct in_addr addr;
! 60: } *hosts;
! 61:
! 62: int
! 63: search_host(addr)
! 64: struct in_addr addr;
! 65: {
! 66: struct host_list *hp;
! 67:
! 68: if (!hosts)
! 69: return(0);
! 70:
! 71: for (hp = hosts; hp != NULL; hp = hp->next) {
! 72: if (hp->addr.s_addr == addr.s_addr)
! 73: return(1);
! 74: }
! 75: return(0);
! 76: }
! 77:
! 78: void
! 79: remember_host(addr)
! 80: struct in_addr addr;
! 81: {
! 82: struct host_list *hp;
! 83:
! 84: if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) {
! 85: err(1, NULL);
! 86: /* NOTREACHED */
! 87: }
! 88: hp->addr.s_addr = addr.s_addr;
! 89: hp->next = hosts;
! 90: hosts = hp;
! 91: }
! 92:
! 93:
! 94:
! 95: struct rup_data {
! 96: char *host;
! 97: struct statstime statstime;
! 98: };
! 99: struct rup_data *rup_data;
! 100: int rup_data_idx = 0;
! 101: int rup_data_max = 0;
! 102:
! 103: enum sort_type {
! 104: SORT_NONE,
! 105: SORT_HOST,
! 106: SORT_LDAV,
! 107: SORT_UPTIME
! 108: };
! 109: enum sort_type sort_type;
! 110:
! 111: compare(d1, d2)
! 112: struct rup_data *d1;
! 113: struct rup_data *d2;
! 114: {
! 115: switch(sort_type) {
! 116: case SORT_HOST:
! 117: return strcmp(d1->host, d2->host);
! 118: case SORT_LDAV:
! 119: return d1->statstime.avenrun[0]
! 120: - d2->statstime.avenrun[0];
! 121: case SORT_UPTIME:
! 122: return d1->statstime.boottime.tv_sec
! 123: - d2->statstime.boottime.tv_sec;
! 124: default:
! 125: /* something's really wrong here */
! 126: abort();
! 127: }
! 128: }
! 129:
! 130: void
! 131: remember_rup_data(host, st)
! 132: char *host;
! 133: struct statstime *st;
! 134: {
! 135: if (rup_data_idx >= rup_data_max) {
! 136: rup_data_max += 16;
! 137: rup_data = realloc (rup_data,
! 138: rup_data_max * sizeof(struct rup_data));
! 139: if (rup_data == NULL) {
! 140: err (1, NULL);
! 141: /* NOTREACHED */
! 142: }
! 143: }
! 144:
! 145: rup_data[rup_data_idx].host = strdup(host);
! 146: rup_data[rup_data_idx].statstime = *st;
! 147: rup_data_idx++;
! 148: }
! 149:
! 150:
! 151: int
! 152: rstat_reply(replyp, raddrp)
! 153: char *replyp;
! 154: struct sockaddr_in *raddrp;
! 155: {
! 156: struct hostent *hp;
! 157: char *host;
! 158: statstime *host_stat = (statstime *)replyp;
! 159:
! 160: if (!search_host(raddrp->sin_addr)) {
! 161: hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr,
! 162: sizeof(struct in_addr), AF_INET);
! 163:
! 164: if (hp)
! 165: host = hp->h_name;
! 166: else
! 167: host = inet_ntoa(raddrp->sin_addr);
! 168:
! 169: remember_host(raddrp->sin_addr);
! 170:
! 171: if (sort_type != SORT_NONE) {
! 172: remember_rup_data(host, host_stat);
! 173: } else {
! 174: print_rup_data(host, host_stat);
! 175: }
! 176: }
! 177:
! 178: return (0);
! 179: }
! 180:
! 181:
! 182: int
! 183: print_rup_data(host, host_stat)
! 184: char *host;
! 185: statstime *host_stat;
! 186: {
! 187: struct tm *tmp_time;
! 188: struct tm host_time;
! 189: struct tm host_uptime;
! 190: char days_buf[16];
! 191: char hours_buf[16];
! 192:
! 193: printf("%-*.*s", HOST_WIDTH, HOST_WIDTH, host);
! 194:
! 195: tmp_time = localtime((time_t *)&host_stat->curtime.tv_sec);
! 196: host_time = *tmp_time;
! 197:
! 198: host_stat->curtime.tv_sec -= host_stat->boottime.tv_sec;
! 199:
! 200: tmp_time = gmtime((time_t *)&host_stat->curtime.tv_sec);
! 201: host_uptime = *tmp_time;
! 202:
! 203: if (host_uptime.tm_yday != 0)
! 204: sprintf(days_buf, "%3d day%s, ", host_uptime.tm_yday,
! 205: (host_uptime.tm_yday > 1) ? "s" : "");
! 206: else
! 207: days_buf[0] = '\0';
! 208:
! 209: if (host_uptime.tm_hour != 0)
! 210: sprintf(hours_buf, "%2d:%02d, ",
! 211: host_uptime.tm_hour, host_uptime.tm_min);
! 212: else
! 213: if (host_uptime.tm_min != 0)
! 214: sprintf(hours_buf, "%2d mins, ", host_uptime.tm_min);
! 215: else
! 216: hours_buf[0] = '\0';
! 217:
! 218: if (printtime)
! 219: printf(" %2d:%02d%cm", host_time.tm_hour % 12,
! 220: host_time.tm_min,
! 221: (host_time.tm_hour >= 12) ? 'p' : 'a');
! 222:
! 223: printf(" up %9.9s%9.9s load average: %.2f %.2f %.2f\n",
! 224: days_buf, hours_buf,
! 225: (double)host_stat->avenrun[0]/FSCALE,
! 226: (double)host_stat->avenrun[1]/FSCALE,
! 227: (double)host_stat->avenrun[2]/FSCALE);
! 228:
! 229: return(0);
! 230: }
! 231:
! 232:
! 233: void
! 234: onehost(host)
! 235: char *host;
! 236: {
! 237: CLIENT *rstat_clnt;
! 238: statstime host_stat;
! 239: static struct timeval timeout = {25, 0};
! 240:
! 241: rstat_clnt = clnt_create(host, RSTATPROG, RSTATVERS_TIME, "udp");
! 242: if (rstat_clnt == NULL) {
! 243: warnx("%s", clnt_spcreateerror(host));
! 244: return;
! 245: }
! 246:
! 247: bzero((char *)&host_stat, sizeof(host_stat));
! 248: if (clnt_call(rstat_clnt, RSTATPROC_STATS, xdr_void, NULL, xdr_statstime, &host_stat, timeout) != RPC_SUCCESS) {
! 249: warnx("%s", clnt_sperror(rstat_clnt, host));
! 250: return;
! 251: }
! 252:
! 253: print_rup_data(host, &host_stat);
! 254: clnt_destroy(rstat_clnt);
! 255: }
! 256:
! 257: void
! 258: allhosts()
! 259: {
! 260: statstime host_stat;
! 261: enum clnt_stat clnt_stat;
! 262: size_t i;
! 263:
! 264: if (sort_type != SORT_NONE) {
! 265: printf("collecting responses...");
! 266: fflush(stdout);
! 267: }
! 268:
! 269: clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
! 270: xdr_void, NULL,
! 271: xdr_statstime, &host_stat, rstat_reply);
! 272: if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) {
! 273: warnx("%s", clnt_sperrno(clnt_stat));
! 274: exit(1);
! 275: }
! 276:
! 277: if (sort_type != SORT_NONE) {
! 278: putchar('\n');
! 279: qsort(rup_data, rup_data_idx, sizeof(struct rup_data), compare);
! 280:
! 281: for (i = 0; i < rup_data_idx; i++) {
! 282: print_rup_data(rup_data[i].host, &rup_data[i].statstime);
! 283: }
! 284: }
! 285: }
! 286:
! 287:
! 288: main(argc, argv)
! 289: int argc;
! 290: char *argv[];
! 291: {
! 292: int ch;
! 293: extern int optind;
! 294:
! 295: sort_type = SORT_NONE;
! 296: while ((ch = getopt(argc, argv, "dhlt")) != -1)
! 297: switch (ch) {
! 298: case 'd':
! 299: printtime = 1;
! 300: break;
! 301: case 'h':
! 302: sort_type = SORT_HOST;
! 303: break;
! 304: case 'l':
! 305: sort_type = SORT_LDAV;
! 306: break;
! 307: case 't':
! 308: sort_type = SORT_UPTIME;
! 309: break;
! 310: default:
! 311: usage();
! 312: /*NOTREACHED*/
! 313: }
! 314:
! 315: setlinebuf(stdout);
! 316:
! 317: if (argc == optind)
! 318: allhosts();
! 319: else {
! 320: for (; optind < argc; optind++)
! 321: onehost(argv[optind]);
! 322: }
! 323:
! 324: exit(0);
! 325: }
! 326:
! 327:
! 328: usage()
! 329: {
! 330: fprintf(stderr, "Usage: rup [-dhlt] [hosts ...]\n");
! 331: exit(1);
! 332: }