rup.c revision 2343
12343Scsgr/*-
22343Scsgr * Copyright (c) 1993, John Brezak
32343Scsgr * All rights reserved.
42343Scsgr *
52343Scsgr * Redistribution and use in source and binary forms, with or without
62343Scsgr * modification, are permitted provided that the following conditions
72343Scsgr * are met:
82343Scsgr * 1. Redistributions of source code must retain the above copyright
92343Scsgr *    notice, this list of conditions and the following disclaimer.
102343Scsgr * 2. Redistributions in binary form must reproduce the above copyright
112343Scsgr *    notice, this list of conditions and the following disclaimer in the
122343Scsgr *    documentation and/or other materials provided with the distribution.
132343Scsgr * 3. All advertising materials mentioning features or use of this software
142343Scsgr *    must display the following acknowledgement:
152343Scsgr *	This product includes software developed by the University of
162343Scsgr *	California, Berkeley and its contributors.
172343Scsgr * 4. Neither the name of the University nor the names of its contributors
182343Scsgr *    may be used to endorse or promote products derived from this software
192343Scsgr *    without specific prior written permission.
202343Scsgr *
212343Scsgr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
222343Scsgr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
232343Scsgr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
242343Scsgr * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
252343Scsgr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
262343Scsgr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
272343Scsgr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
282343Scsgr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
292343Scsgr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
302343Scsgr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
312343Scsgr * SUCH DAMAGE.
322343Scsgr */
332343Scsgr
342343Scsgr#ifndef lint
352343Scsgrstatic char rcsid[] = "$Id: rup.c,v 1.3 1994/04/10 10:42:28 csgr Exp $";
362343Scsgr#endif /* not lint */
372343Scsgr
382343Scsgr#include <stdio.h>
392343Scsgr#include <stdlib.h>
402343Scsgr#include <string.h>
412343Scsgr#include <time.h>
422343Scsgr#include <sys/param.h>
432343Scsgr#include <sys/socket.h>
442343Scsgr#include <netdb.h>
452343Scsgr#include <rpc/rpc.h>
462343Scsgr#include <arpa/inet.h>
472343Scsgr
482343Scsgr#undef FSHIFT			/* Use protocol's shift and scale values */
492343Scsgr#undef FSCALE
502343Scsgr#include <rpcsvc/rstat.h>
512343Scsgr
522343Scsgr#define HOST_WIDTH 15
532343Scsgr
542343Scsgrchar *argv0;
552343Scsgr
562343Scsgrstruct host_list {
572343Scsgr	struct host_list *next;
582343Scsgr	struct in_addr addr;
592343Scsgr} *hosts;
602343Scsgr
612343Scsgrint search_host(struct in_addr addr)
622343Scsgr{
632343Scsgr	struct host_list *hp;
642343Scsgr
652343Scsgr	if (!hosts)
662343Scsgr		return(0);
672343Scsgr
682343Scsgr	for (hp = hosts; hp != NULL; hp = hp->next) {
692343Scsgr		if (hp->addr.s_addr == addr.s_addr)
702343Scsgr			return(1);
712343Scsgr	}
722343Scsgr	return(0);
732343Scsgr}
742343Scsgr
752343Scsgrvoid remember_host(struct in_addr addr)
762343Scsgr{
772343Scsgr	struct host_list *hp;
782343Scsgr
792343Scsgr	if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) {
802343Scsgr		fprintf(stderr, "%s: no memory.\n", argv0);
812343Scsgr		exit(1);
822343Scsgr	}
832343Scsgr	hp->addr.s_addr = addr.s_addr;
842343Scsgr	hp->next = hosts;
852343Scsgr	hosts = hp;
862343Scsgr}
872343Scsgr
882343Scsgrrstat_reply(char *replyp, struct sockaddr_in *raddrp)
892343Scsgr{
902343Scsgr	struct tm *tmp_time;
912343Scsgr	struct tm host_time;
922343Scsgr	struct tm host_uptime;
932343Scsgr	char days_buf[16];
942343Scsgr	char hours_buf[16];
952343Scsgr	struct hostent *hp;
962343Scsgr	char *host;
972343Scsgr	statstime *host_stat = (statstime *)replyp;
982343Scsgr
992343Scsgr	if (search_host(raddrp->sin_addr))
1002343Scsgr		return(0);
1012343Scsgr
1022343Scsgr	hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr,
1032343Scsgr			   sizeof(struct in_addr), AF_INET);
1042343Scsgr	if (hp)
1052343Scsgr		host = hp->h_name;
1062343Scsgr	else
1072343Scsgr		host = inet_ntoa(raddrp->sin_addr);
1082343Scsgr
1092343Scsgr	/* truncate hostname to fit nicely into field */
1102343Scsgr	if (strlen(host) > HOST_WIDTH)
1112343Scsgr		host[HOST_WIDTH] = '\0';
1122343Scsgr
1132343Scsgr	printf("%-*s\t", HOST_WIDTH, host);
1142343Scsgr
1152343Scsgr	tmp_time = localtime((time_t *)&host_stat->curtime.tv_sec);
1162343Scsgr	host_time = *tmp_time;
1172343Scsgr
1182343Scsgr	host_stat->curtime.tv_sec -= host_stat->boottime.tv_sec;
1192343Scsgr
1202343Scsgr	tmp_time = gmtime((time_t *)&host_stat->curtime.tv_sec);
1212343Scsgr	host_uptime = *tmp_time;
1222343Scsgr
1232343Scsgr	if (host_uptime.tm_yday != 0)
1242343Scsgr		sprintf(days_buf, "%3d day%s, ", host_uptime.tm_yday,
1252343Scsgr			(host_uptime.tm_yday > 1) ? "s" : "");
1262343Scsgr	else
1272343Scsgr		days_buf[0] = '\0';
1282343Scsgr
1292343Scsgr	if (host_uptime.tm_hour != 0)
1302343Scsgr		sprintf(hours_buf, "%2d:%02d, ",
1312343Scsgr			host_uptime.tm_hour, host_uptime.tm_min);
1322343Scsgr	else
1332343Scsgr		if (host_uptime.tm_min != 0)
1342343Scsgr			sprintf(hours_buf, "%2d mins, ", host_uptime.tm_min);
1352343Scsgr		else
1362343Scsgr			hours_buf[0] = '\0';
1372343Scsgr
1382343Scsgr	printf(" %2d:%02d%cm  up %9.9s%9.9s load average: %.2f %.2f %.2f\n",
1392343Scsgr		host_time.tm_hour % 12,
1402343Scsgr		host_time.tm_min,
1412343Scsgr		(host_time.tm_hour >= 12) ? 'p' : 'a',
1422343Scsgr		days_buf,
1432343Scsgr		hours_buf,
1442343Scsgr		(double)host_stat->avenrun[0]/FSCALE,
1452343Scsgr		(double)host_stat->avenrun[1]/FSCALE,
1462343Scsgr		(double)host_stat->avenrun[2]/FSCALE);
1472343Scsgr
1482343Scsgr	remember_host(raddrp->sin_addr);
1492343Scsgr	return(0);
1502343Scsgr}
1512343Scsgr
1522343Scsgronehost(char *host)
1532343Scsgr{
1542343Scsgr	CLIENT *rstat_clnt;
1552343Scsgr	statstime host_stat;
1562343Scsgr	struct sockaddr_in addr;
1572343Scsgr	struct hostent *hp;
1582343Scsgr
1592343Scsgr	hp = gethostbyname(host);
1602343Scsgr	if (hp == NULL) {
1612343Scsgr		fprintf(stderr, "%s: unknown host \"%s\"\n",
1622343Scsgr			argv0, host);
1632343Scsgr		return(-1);
1642343Scsgr	}
1652343Scsgr
1662343Scsgr	rstat_clnt = clnt_create(host, RSTATPROG, RSTATVERS_TIME, "udp");
1672343Scsgr	if (rstat_clnt == NULL) {
1682343Scsgr		fprintf(stderr, "%s: %s %s", argv0, host, clnt_spcreateerror(""));
1692343Scsgr		return(-1);
1702343Scsgr	}
1712343Scsgr
1722343Scsgr	bzero((char *)&host_stat, sizeof(host_stat));
1732343Scsgr	if (clnt_call(rstat_clnt, RSTATPROC_STATS, xdr_void, NULL, xdr_statstime, &host_stat, NULL) != RPC_SUCCESS) {
1742343Scsgr		fprintf(stderr, "%s: %s: %s\n", argv0, host, clnt_sperror(rstat_clnt, host));
1752343Scsgr		return(-1);
1762343Scsgr	}
1772343Scsgr
1782343Scsgr	addr.sin_addr.s_addr = *(int *)hp->h_addr;
1792343Scsgr	rstat_reply((char *)&host_stat, &addr);
1802343Scsgr}
1812343Scsgr
1822343Scsgrallhosts()
1832343Scsgr{
1842343Scsgr	statstime host_stat;
1852343Scsgr	enum clnt_stat clnt_stat;
1862343Scsgr
1872343Scsgr	clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
1882343Scsgr				   xdr_void, NULL,
1892343Scsgr				   xdr_statstime, &host_stat, rstat_reply);
1902343Scsgr	if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) {
1912343Scsgr		fprintf(stderr, "%s: %s\n", argv0, clnt_sperrno(clnt_stat));
1922343Scsgr		exit(1);
1932343Scsgr	}
1942343Scsgr}
1952343Scsgr
1962343Scsgrusage()
1972343Scsgr{
1982343Scsgr	fprintf(stderr, "Usage: %s [hosts ...]\n", argv0);
1992343Scsgr	exit(1);
2002343Scsgr}
2012343Scsgr
2022343Scsgrmain(int argc, char *argv[])
2032343Scsgr{
2042343Scsgr	int ch;
2052343Scsgr	extern int optind;
2062343Scsgr
2072343Scsgr	if (!(argv0 = rindex(argv[0], '/')))
2082343Scsgr		argv0 = argv[0];
2092343Scsgr	else
2102343Scsgr		argv0++;
2112343Scsgr
2122343Scsgr	while ((ch = getopt(argc, argv, "?")) != -1)
2132343Scsgr		switch (ch) {
2142343Scsgr		default:
2152343Scsgr			usage();
2162343Scsgr			/*NOTREACHED*/
2172343Scsgr		}
2182343Scsgr
2192343Scsgr	setlinebuf(stdout);
2202343Scsgr	if (argc == optind)
2212343Scsgr		allhosts();
2222343Scsgr	else {
2232343Scsgr		for (; optind < argc; optind++)
2242343Scsgr			(void) onehost(argv[optind]);
2252343Scsgr	}
2262343Scsgr	exit(0);
2272343Scsgr}
228