[net.sources] usr.c: who's using what machine

uggworek@sunybcs.UUCP (Donald Gworek) (06/08/85)

Usr.c shows who is using what machine, for all machines in a
local network.  The default (ie, no arguments) is to list all
users on each machine.  However, usr.c is intended to check 
for certain users, in particular, users with the same prefix.
The output format is:

:::::::::::::
: hostname1 :
:::::::::::::

user1   	user4		user7		user10		user13
user2   	user5		user8		user11
user3   	user6		user9		user12


# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# usr.1 usr.c

echo x - usr.1
sed -e 's/^X//' > "usr.1" << '//E*O*F usr.1//'
X.TH USR 1 "7 June 1985"
X.SH NAME
Xusr \- who's using what machine in the local network
X.SH SYNOPSIS
X.B usr
X[
X.B .. chars- .. username ..
X]
X.SH DESCRIPTION
X.I Usr
Xshows what machines users are logged in on.  Arguments are usernames,
Xor username prefixes.  The default is to show who's logged in
Xon all the machines.
X.PP
XTo check for usernames begining with, say, "foo",
Xinvoke "usr foo-" (note the "\-" wildcard).
X"Usr \-" is the same as "usr".
X.PP
XIf no report has been received from a machine for 5 minutes, then 
X.I usr
Xassumes that machine is down.
X.SH FILES
X.B /usr/spool/rwho/whod.*   
X.B 	info about local machines
X.SH AUTHOR
X.B Don Gworek
X.SH BUGS
X.B If used in during login, 
X.I usr
Xmay or may not show the user invoking the program.
//E*O*F usr.1//

echo x - usr.c
sed -e 's/^X//' > "usr.c" << '//E*O*F usr.c//'
X/*
X *  usr [... chars- ... username ...]
X */
X
X#include <stdio.h>
X#include <sys/param.h>
X#include <sys/dir.h>
X/*
X * use the include or the structs that follow
X *
X * #include ".../etc/rwhod/rwhod.h"
X */
X
Xstruct	outmp {
X	char	out_line[8];
X	char	out_name[8];
X	long	out_time;
X};
Xstruct	whod {
X	char	wd_vers;
X	char	wd_type;
X	char	wd_pad[2];
X	int	wd_sendtime;
X	int	wd_recvtime;
X	char	wd_hostname[32];
X	int	wd_loadav[3];
X	int	wd_boottime;
X	struct	whoent {
X		struct	outmp we_utmp;
X		int	we_idle;
X	} wd_we[1024 / sizeof (struct whoent)];
X};
X
Xstruct	whod wd;
Xstruct outmp outmp;
X
X#define	RWHODIR "/usr/spool/rwho"
X#define	WHDRSIZE (sizeof (wd) - sizeof (wd.wd_we))
X#define NMAX sizeof (outmp.out_name)
X#define HMAX sizeof (wd.wd_hostname)
X#define MAXSTRING NMAX + 1
X#define MAXARGNAMES 30			/* number of args to usr	*/
X#define MAXNAMES 100			/* number of names per machine	*/
X#define REST '-'
X#define TRUE 1
X#define FALSE 0
X
Xchar *malloc ();
Xchar argnames [MAXARGNAMES] [MAXSTRING];
Xchar *names [MAXNAMES];
Xint now, nwlnflg;
XDIR *etc;
X
Xmain (argc, argv)
X  int argc;
X  char *argv[];
X  {
X   struct direct *dp;
X   int argnct, f;
X   argnct = 0;
X   if (argc < 2)
X     {
X      argnames [argnct][0] = REST;		/* no arg default */
X      argnames [argnct++][1] = '\0';
X     }
X   for (; (--argc > 0) && (argnct < MAXARGNAMES); argnct++)
X     (void) strcpy (argnames [argnct], *++argv);
X   if (argnct == MAXARGNAMES)
X     fatal ("Error: MAXARGNAMES %d reached\n", MAXARGNAMES);
X   if (chdir(RWHODIR) < 0)
X     fatal ("%s: Permission denied\n", RWHODIR);
X   if ((etc = opendir (".")) == NULL)
X     fatal ("%s/.: Can't access\n", RWHODIR);
X   (void) time (&now);
X   nwlnflg = FALSE;
X   while (dp = readdir (etc))
X     {
X      if (dp->d_ino == 0)
X        continue;
X      if (strncmp(dp->d_name, "whod.", 5))
X        continue;
X      if ((f=open (dp->d_name, 0)) < 0)
X        continue;
X      process_rwhod (argnct, f);
X      (void) close (f);
X     }
X  }
X
Xscmp (p, q)
X  char **p, **q;
X  {
X   return (strcmp (*p, *q));
X  }
X
Xprocess_rwhod (argnct, f)
X  int argnct, f;
X  {
X   int cc, n, found, i;
X   register struct whod *w = &wd;
X   register struct whoent *we;
X   char host [HMAX], name [MAXSTRING];
X   char **namp = names;
X   cc = read (f, (char *)&wd, sizeof (struct whod));
X   if (cc < WHDRSIZE)
X     return;
X   if (now - w->wd_recvtime > 5 * 60)
X     return;
X   cc -= WHDRSIZE;
X   we = w->wd_we;
X   (void) strncpy (host, w->wd_hostname, HMAX);
X   host [HMAX-1] = '\0';
X   for (n = cc / sizeof(struct whoent); n > 0; n--, we++)
X     {
X      (void) strncpy (name, we->we_utmp.out_name, NMAX);
X      name [NMAX] = '\0';
X      for (i=0, found=FALSE; (i < argnct) && !found; i++)
X        if (found = match (name, argnames[i]))
X          {
X           *namp = malloc (strlen (name) + 1);
X           (void) strcpy (*namp++, name);
X	   if ((namp - names) > MAXNAMES) 			    /* abort */
X	      fatal ("Error: MAXNAMES %d reached\n", MAXNAMES); 
X          }
X     }
X   if (namp > names)
X     print_out (host, namp);
X  }
X
Xprint_out (host, namp)
X  char *host;
X  char **namp;
X  {
X   register char **base, **p;
X   int i, formlen, offset, prcol, tabcol;
X   qsort (names, namp - names, sizeof names[0], scmp);
X   if (nwlnflg)
X       printf ("\n");
X     else nwlnflg = TRUE;
X   for (formlen=i=strlen (host)+4; i-- > 0 ; putchar (':'));
X   printf ("\n: %s :\n", host);
X   while (++i < formlen)
X     printf (":");
X   printf ("\n\n");
X   offset = (namp - names) / 5 + 1;
X   base = names;
X   do {
X        tabcol = prcol = 1;
X	p = base;
X	do {
X	    for (; prcol < tabcol; prcol += 8, printf ("\t"));
X	    printf ("%s", *p);
X	    prcol = tabcol + strlen (*p);
X	    tabcol += 16;
X	   }
X	  while ((p += offset) < namp);
X	printf ("\n");
X      }
X	while (++base < (names + offset));
X  }
X
Xmatch (name, request)
X  char name[], request[];
X  {
X   int i;
X   for (i=0; (name[i] == request[i]) && (name[i] != '\0'); i++);
X   if (request[i] == REST) 
X     return (TRUE);
X   if (((name[i] == '\0') && (request[i] == '\0'))
X       || ((name[i] == ' ') && (request[i] == '\0')))
X     return (TRUE);
X   return (FALSE);
X  }
X
Xfatal (format, argument)
X  char format[], argument[];
X  {
X   fprintf (stderr, format, argument);
X   exit (1);
X  }
//E*O*F usr.c//

exit 0