[comp.sources.misc] rusers -- users

pkern@utcsri.UUCP (pkern) (09/18/87)

> | If this were posted, would there be any copyright problems?
> | If so, would you rather have a completely re-written version?
> +---------------
> 
> There probably WILL be problems (rwho probably has some AT&T source in it).
> I would suggest all new code, just to keep this newsgroup from being shut
> down by the Lords of UNIX...

Ok. Here's a rewritten version.

--------------------------------------------------------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	makefile
#	ru.c
#	ru.l
# This archive created: Wed Sep 16 11:26:55 1987
# By:	pkern ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'makefile'" '(377 characters)'
if test -f 'makefile'
then
	echo shar: will not over-write existing file "'makefile'"
else
sed 's/^	X//' << \SHAR_EOF > 'makefile'
	X#
	XDESTDIR= /usr/local
	XMANDIR=	/usr/man
	XMSEC=	l
	XCFLAGS=	-O -s
	X
	Xru: ru.o
	X	$(CC) $(CFLAGS) $*.o -o $@
	X
	Xman: ru.l
	X	nroff -man ru.l > ru.nr
	X	more -s ru.nr
	X
	Xinstall: ru
	X	install -c ru $(DESTDIR)
	X	install -c ru.l $(MANDIR)/man$(MSEC)/ru.$(MSEC)
	X	ln $(DESTDIR)/ru $(DESTDIR)/rusers
	X	ln $(MANDIR)/man$(MSEC)/ru.$(MSEC) $(MANDIR)/man$(MSEC)/rusers.$(MSEC)
	X
	Xclean:
	X	-rm -f *.o a.out *.nr
SHAR_EOF
if test 377 -ne "`wc -c < 'makefile'`"
then
	echo shar: error transmitting "'makefile'" '(should have been 377 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ru.c'" '(4317 characters)'
if test -f 'ru.c'
then
	echo shar: will not over-write existing file "'ru.c'"
else
sed 's/^	X//' << \SHAR_EOF > 'ru.c'
	X/*
	X * ru - remote users(1)
	X *	usage: ru [-d domain] [-h host]
	X *
	X *	P. Kern (pkern@utcsri)
	X *	Tue Sep 15 1987
	X */
	X
	X#include <stdio.h>
	X#include <sys/types.h>
	X#include <sys/stat.h>
	X#include <sys/dir.h>
	X#include <sys/file.h>
	X#include <netdb.h>
	X
	X#define MINSTR	8		/* minimum string length */
	X#define HNSZ	32		/* hostname length */
	X#define RWFSZ	HNSZ+5		/* spool-file name length */
	X#define MRGN	12		/* 12 space "tab" */
	X#define RWPERIOD	300	/* 5 minute rwho refresh period */
	X
	Xstruct rw_utmp {
	X	char tty[MINSTR];	/* user's tty */
	X	char name[MINSTR];	/* user's login */
	X	long time;		/* login time */
	X	int idle;		/* idle time */
	X} rut;
	X
	Xstruct rw_hdr {
	X	char pad[4];		/* ignore first 4 bytes */
	X	int sent, rcvd;		/* time sent,  time rec'vd */
	X	char host[HNSZ];	/* host's name */
	X	int loadav[3];		/* load averages */
	X	int boot;		/* boot date */
	X} hdr;
	X
	X#define HDRSIZE	sizeof(hdr)
	X#define RUTSIZE sizeof(rut)
	X#define RWHODIR "/usr/spool/rwho"
	X
	Xchar *prog, *domain, *host;
	Xint dflg, hflg, errflg;
	Xlong now;
	X
	Xmain(argc, argv)
	Xint argc;
	Xchar *argv[];
	X{
	X	int n, fd;
	X	char *p, *nbuf, *rbuf, *s;
	X	DIR *dirp;
	X	struct direct *dp;
	X	struct stat sbuf;
	X	extern char *malloc();
	X	extern rwfcmp(), rutcmp();
	X	extern int optind;
	X	extern char *optarg;
	X
	X	prog = argv[0];
	X	now = time(0);
	X
	X	while ((n = getopt(argc, argv, "d:h:")) != EOF)
	X		switch(n) {
	X		case 'd':
	X			dflg++;
	X			domain = optarg;
	X			break;
	X		case 'h':
	X			hflg++;
	X			host = optarg;
	X			break;
	X		default:
	X			errflg++;
	X		}
	X	if (errflg) {
	X		fprintf(stderr, "Usage: %s [-d <domain>] [-h <host>]\n", prog);
	X		exit(1);
	X	}
	X		/* cd RWHODIR */
	X	if (chdir(RWHODIR) < 0) {
	X		write(2, "chdir: ", 7);
	X		perror(RWHODIR);
	X		exit(1);
	X	}
	X	if (hflg) {
	X		struct hostent *h, *gethostbyname();
	X
	X		/*
	X		 * try to get host's proper name
	X		 * and try to find the proper spool file
	X		 */
	X		if((h = gethostbyname(host)) == NULL) {
	X			perror(host);
	X			exit(1);
	X		}
	X		nbuf = malloc(strlen(h->h_name)+5);
	X		sprintf(nbuf, "whod.%s", h->h_name);
	X		if ((fd = open(nbuf, O_RDONLY)) < 0) {
	X			char **s;
	X			/*
	X			 * can't find file related to h_name
	X			 * try the aliases instead.
	X			 */
	X			s = h->h_aliases;
	X			while(*s) {
	X				free(nbuf);
	X				nbuf = malloc(strlen(*s)+5);
	X				sprintf(nbuf, "whod.%s", *s);
	X				if ((fd = open(nbuf, O_RDONLY)) < 0)
	X					break;
	X				s++;
	X			}
	X			if (*s == NULL) {
	X				fprintf(stderr,  "%s: no data\n",  host);
	X				exit(1);
	X			}
	X		}
	X		if (fstat(fd, &sbuf) < 0) {
	X			write(2, "fstat: ", 7);
	X			perror(nbuf);
	X			exit(1);
	X		}
	X		n = sbuf.st_size - HDRSIZE;
	X		goto doit;	/* skip dir searching */
	X	}
	X
	X	/*
	X	 * read "." directory (assuming chdir() worked), 
	X	 * get and sort all files with the "whod." prefix.
	X	 */
	X	if ((dirp = opendir(".")) == NULL) {
	X		perror(RWHODIR);
	X		exit(1);
	X	}
	X	if (stat(".", &sbuf) < 0) { 
	X		write(2, "stat: ", 6);
	X		perror(RWHODIR);
	X		exit(1);
	X	}
	X	p = nbuf = malloc((unsigned)sbuf.st_size);
	X	n = 0;
	X	while (dp = readdir(dirp)) {
	X		strncpy(p, dp->d_name, dp->d_namlen);
	X		*(p+dp->d_namlen) = '\0';
	X		if (strncmp(p, "whod.", 5) == 0 &&
	X		   (!dflg || strcmp(rindex(p,'.')+1,domain) == 0)) {
	X			p += RWFSZ,  n++;
	X		}
	X	}
	X	*p = '\0';
	X	closedir(dirp);
	X	qsort(nbuf, n, RWFSZ, rwfcmp);
	X	/*
	X	 * process each "whod." file in nbuf list.
	X	 */
	X	while (nbuf < p) {
	X		if ((fd = open(nbuf, O_RDONLY)) < 0) {
	X			perror(nbuf);
	X			exit(1);
	X		}
	X		if (fstat(fd, &sbuf) < 0) {
	X			write(2, "fstat: ", 7);
	X			perror(nbuf);
	X			exit(1);
	X		}
	X		if (n = sbuf.st_size-HDRSIZE) {
	Xdoit:			if ((rbuf = malloc((unsigned)n)) == 0) {
	X				perror(prog);
	X				exit(1);
	X			}
	X			n = read(fd, (char *)&hdr, HDRSIZE);
	X			if (hflg || now-hdr.rcvd <= RWPERIOD) {
	X				n = read(fd,rbuf,sbuf.st_size-HDRSIZE);
	X				qsort(rbuf, n/RUTSIZE, RUTSIZE, rutcmp);
	X				burp(nbuf, rbuf, n);
	X			}
	X		}
	X		free(rbuf);
	X		close(fd);
	X		if (hflg)
	X			exit(0);
	X		nbuf += RWFSZ;
	X	}
	X}
	X
	Xrwfcmp(p, q)
	Xchar *p, *q;
	X{
	X	return(strncmp(p, q, RWFSZ));
	X}
	X
	Xrutcmp(p, q)
	Xregister struct rw_utmp *p, *q;
	X{
	X	return(strncmp(p->name, q->name, MINSTR));
	X} 
	X
	X/*
	X * print "host:       user1 user2 ... "
	X */
	Xburp(s, r, n)
	Xregister char *s,  *r;
	Xint n;
	X{	
	X	s += 5;		/* skip "whod." prefix */
	X	if (now-hdr.rcvd > RWPERIOD)	/* mark overdue hosts */
	X		printf("%.*s:%*s", MRGN, s, MRGN+1-strlen(s), "*");
	X	else
	X		printf("%.*s:%*s", MRGN, s, MRGN+1-strlen(s), " ");
	X	for (s = r; s < (r+n); s += sizeof(rut))
	X		printf(" %.*s", MINSTR, s+MINSTR);
	X	printf("\n");
	X}
SHAR_EOF
if test 4317 -ne "`wc -c < 'ru.c'`"
then
	echo shar: error transmitting "'ru.c'" '(should have been 4317 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ru.l'" '(1025 characters)'
if test -f 'ru.l'
then
	echo shar: will not over-write existing file "'ru.l'"
else
sed 's/^	X//' << \SHAR_EOF > 'ru.l'
	X.TH RUSERS local
	X.UC
	X.SH NAME
	Xrusers \- compact list of users on all "visible" systems
	X.SH SYNOPSIS
	X.B /usr/local/rusers [-d domain] [-h host]
	X.SH DESCRIPTION
	X.I Rusers
	Xlists the login names of the users currently on all visible systems
	Xin a compact,
	Xone-line-per-host format.
	XSystems with no users are not listed.
	XUsing the -d option makes
	X.I rusers
	Xlist only the login names of the users on visible systems
	Xin the specified domain.  Using the -h option makes
	X.I rusers
	Xlist only the login names of the users currently on the specified host.
	XWhen the -h option is used and a "*" appears after the hostname,
	Xthe rest of the output line may be incorrect because
	Xthe rwho data was over 5 minutes old.
	XA "visible system" is any system from which rwho packets
	Xare being received.
	X.SH HISTORY
	XOriginally created by altering 
	X.I users(1)
	Xwith pieces from
	X.I rwho(1).
	XRewritten to try to eliminate borrowed source.
	X.SH AUTHOR
	XP. Kern, U. of Toronto, pkern@utcsri.uucp
	X.SH FILES
	X/usr/spool/rwho/whod.*
	X.SH SEE ALSO
	Xusers(1), rwho(1)
SHAR_EOF
if test 1025 -ne "`wc -c < 'ru.l'`"
then
	echo shar: error transmitting "'ru.l'" '(should have been 1025 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0