[alt.sources] Repost of YWHO upon request

james@yunexus.UUCP (James Pierre Lewis) (01/12/89)

Someone on USENET asks to repost YWHO. Here it is. Just cut, compile,
and use it. Thanks.
-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----
/*
 * Functionality:
 *	To provide a better WHO on a SUN local network. It does not use
 *	rwhod and /usr/spool/rwho/rwhod.*, which consume tremendous 
 *	resources, but SUN RPC which proves to provide a high performance
 *	YWHO with less resources.
 * Author:
 *	James P. Lewis		| FREE TO DISTRIBUTE WITH THIS HEADER
 *	York University		| REMAINS INTACT.
 *	4700 Keele Street	|
 *	Downsview, Ontario	|
 *	Canada			|
 *	M3J-1P3			|
 *
 *	...yunexus!james
 * Usage:
 *	% cc -o ywho ywho.c -lrpcsvc
 *	% ywho
 *	% ywho nexus
 *	% ywho yetti
 *	% ywho bigfoot
 * See Also:
 *	/etc/hosts
 * Bugs:
 *	If a client is not available, SUN RPC waits until timeout. The same
 *	is true if you do a PING to a client. I wouldn't call it a bug but
 *	a feature in SUN RPC. In both of these cases, you just press CTRL-C.
 */
 
#include <stdio.h>
#include <utmp.h>
#include <rpc/rpc.h>
#include <rpcsvc/rusers.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>

#define  HST_LEN		31

main(argc, argv)

char	**argv;
int	argc;
{
	extern	char	*ctime();
	char	hst_nam[HST_LEN],
		tmp[BUFSIZ];
	int	addrlen,
		hh,
		i,
		j,
		mm,
		sock = RPC_ANYSOCK,
		ss;
	register	CLIENT	*client;
	struct	hostent	*hp;
	struct	timeval	pertry_timeout,
			total_timeout;
	struct	utmpidlearr	cutmpidlearr;
	struct	sockaddr_in	server_addr;
	enum	clnt_stat	clnt_stat;
	

	if (argc < 2)
		gethostname(hst_nam, HST_LEN);
	else	strcpy(hst_nam, argv[1]);
	
	if ((hp = gethostbyname(hst_nam)) == NULL)
	{
		fprintf(stderr, "can't get addr for %s\n", hst_nam);
		exit(0);
	}
	
	pertry_timeout.tv_sec = 3;
	pertry_timeout.tv_usec = 0;
	addrlen = sizeof(struct sockaddr_in);
	bcopy(hp->h_addr, (caddr_t) &server_addr.sin_addr, hp->h_length);
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = 0;
	
	if ((client = clntudp_create(&server_addr, RUSERSPROG,
		RUSERSVERS_IDLE, pertry_timeout, &sock)) == NULL)
	{
		clnt_pcreateerror("clntudp_create");
		exit(0);
	}
	
	total_timeout.tv_sec = 3;
	total_timeout.tv_usec = 0;
	clnt_stat = clnt_call(client, RUSERSPROC_NAMES, xdr_void, 
		0, xdr_utmpidlearr, &cutmpidlearr, total_timeout);
		
	if (clnt_stat != RPC_SUCCESS)
	{
		clnt_perror(client, argv[0]);
		exit(0);
	}
	
	clnt_destroy(client);
	printf("%-8.8s %-8.8s %-12.12s %-8.8s %s\n",
		"User", "tty", "login", "idle", "host");

	for (i = 0; i < cutmpidlearr.uia_cnt; i++)
	{
		j = cutmpidlearr.uia_arr[i]->ui_utmp.ut_time;

		if (cutmpidlearr.uia_arr[i]->ui_idle == NULL)
			*tmp = NULL;
		else	
		{
			hh = mm = ss = NULL;
			
			if ((ss = cutmpidlearr.uia_arr[i]->ui_idle) > 60)
			{
				mm = ss / 60;
				ss = ss % 60;
			}
			
			if (mm > 60)
			{
				hh = mm / 60;
				mm = mm % 60;
			}

			sprintf(tmp, "%-2.2d:%-2.2d:%-2.2d", hh, mm, ss);
		}
			
		printf("%-8.8s %-8.8s %-12.12s %-8.8s (%s)\n", 
		       cutmpidlearr.uia_arr[i]->ui_utmp.ut_name,
		       cutmpidlearr.uia_arr[i]->ui_utmp.ut_line,
		       ctime(&j)+4,
		       tmp,
		       (*cutmpidlearr.uia_arr[i]->ui_utmp.ut_host) ?
		       cutmpidlearr.uia_arr[i]->ui_utmp.ut_host : hst_nam);
	}
	
	exit(0);
}
-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----Cut-----