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