klemets@ttds.UUCP (Anders Klemets) (05/06/85)
This program tells you when users log in or out from your machine and from other machines connected to a local network. It can be told to only watch for some users, ttys and hosts in any combination you like. The program was written on a VAX 11/750 with 4.2 BSD and will only work on a 4.2 BSD system in its original form. If you don't have 4.2 BSD you will have to change a little in the makefile, and then it might work. If it does it will ignore a local network, if there's any. -------------------------(Cut here)-------------------------------------------- : This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. echo 'Extracting Makefile' sed 's/^X//' > Makefile << '+ END-OF-FILE Makefile' XFILES = rcheck.o net.o XCFLAGS = -O -DBSD X# If your system doesn't use 4.2BSD remove the two previous lines X# and remove the "#" at the beginning of the following two lines. X# FILES = rcheck.o X# CFLAGS = -O -UBSD X XNAME = rcheck XDESTDIR = /usr/local X Xrcheck : ${FILES} rcheck.h X cc ${CFLAGS} -o ${NAME} ${FILES} X Xrcheck.h : ${FILES} X Xinstall : X mv ${NAME} ${DESTDIR} X mv rcheck.1 /usr/man/manl + END-OF-FILE Makefile chmod 'u=rw,g=r,o=r' 'Makefile' echo ' -rw-r--r-- 1 klemets 392 May 5 22:07 Makefile (as sent)' echo -n ' ' /bin/ls -l Makefile echo 'Extracting net.c' sed 's/^X//' > net.c << '+ END-OF-FILE net.c' X#include "rcheck.h" X#include "/usr/src/etc/rwhod/rwhod.h" X/* The location of the above file may differ. */ Xint rsize = 1024 / sizeof (struct whoent); Xstruct whod rold[MAXHOSTS], rnew[MAXHOSTS]; Xrload (mode) X{ X DIR *dirp; X struct direct *dp; X int fd, x, nr=0; X dirp = opendir ("."); X while (dp = readdir (dirp)) { X if (dp->d_ino == 0) X continue; X if (strncmp (dp->d_name, "whod.", 5)) X continue; X if (strcmp (dp->d_name+5, hostname) == 0) X continue; X fd = open (dp->d_name, 0); X for (x=0; x<rsize; ++x) { X if (mode) X strcpy (rnew[nr].wd_we[x].we_utmp.out_line, "\0"); X else strcpy (rold[nr].wd_we[x].we_utmp.out_line, "\0"); X } X if (mode) X read (fd, &rnew[nr], sizeof (struct whod)); X else read (fd, &rold[nr], sizeof (struct whod)); X close (fd); X ++nr; X } X closedir (dirp); X} X Xrscan () X{ X int x, u; X for (x=0; x<MAXHOSTS; ++x) X for (u = 0; strlen (rold[x].wd_we[u].we_utmp.out_line) && X u < rsize; ++u) X if (find (&rold[x].wd_we[u].we_utmp, &rnew[x])) X printout(rold[x].wd_we[u].we_utmp.out_name, rold[x].wd_we[u].we_utmp.out_line, X rold[x].wd_hostname, "\0", 0); X for (x=0; x <MAXHOSTS; ++x) X for (u = 0; strlen (rnew[x].wd_we[u].we_utmp.out_line) && X u < rsize; ++u) X if (find (&rnew[x].wd_we[u].we_utmp, &rold[x])) X printout(rnew[x].wd_we[u].we_utmp.out_name, rnew[x].wd_we[u].we_utmp.out_line, X rnew[x].wd_hostname, "\0", 1); X for (x=0; x<MAXHOSTS; ++x) X for (u = 0; u < rsize; ++u) { X strcpy (rold[x].wd_we[u].we_utmp.out_name, X rnew[x].wd_we[u].we_utmp.out_name); X strcpy (rold[x].wd_we[u].we_utmp.out_line, X rnew[x].wd_we[u].we_utmp.out_line); X } X} Xfind (a, b) Xstruct outmp *a; Xstruct whod *b; X{ X int x; X char cname[NAMELEN+1]; X strncpy (cname, a->out_name, NAMELEN); X cname[NAMELEN] = '\0'; X for (x = 0; x < rsize; ++x) X if (strcmp(a->out_line, b->wd_we[x].we_utmp.out_line) == 0 X && strncmp(cname, b->wd_we[x].we_utmp.out_name, NAMELEN)==0) X return (0); X return (1); X} + END-OF-FILE net.c chmod 'u=rw,g=r,o=r' 'net.c' echo ' -rw-r--r-- 1 klemets 1979 May 5 22:15 net.c (as sent)' echo -n ' ' /bin/ls -l net.c echo 'Extracting rcheck.1' sed 's/^X//' > rcheck.1 << '+ END-OF-FILE rcheck.1' X.TH RCHECK 1 "18 Mars 1985" X.UC 4 X.SH NAME Xrcheck \- check for users logging in and out from systems on the local network X.SH SYNOPSIS X.B rcheck X[ X.B username ... X] [ X.B \-t tty ... X] [ X.B \-h host ... X] X.SH DESCRIPTION X.I Rcheck Xruns in the background and checks for Xusers logging in and out from machines Xconnected to the local network. XEvery time X.I rcheck Xfinds out that somebody has logged in Xor out, it will print a message on the Xterminal screen, Xtelling the time, Xthe users login-name, Xthe host he is on, Xthe affected tty, Xand the real name of the user, if it is Xpossible to find it in the local machines X/etc/passwd -file. X.PP XIt can be very annoying receiving messages Xall the time on the terminal screen, specially Xwhen editing files... But if you specify one or Xmore X.B usernames Xon the command line, X.I rcheck Xwill only tell you when the specified users log Xin and out. X.br XThe other flags works in a similar way. XThe X.B \-t Xflag takes arguments of tty-names and then it Xwill only tell you when any of the specified Xttys is affected. XThe X.B \-h Xflag accepts arguments which are names of remote Xhosts connected to a local network. As with the Xprevious flags, X.I rcheck Xwill only print messages concearning the specified Xhosts. X.PP X.I Rcheck Xscans the local machine with an X30 second intervall, and the Xremote hosts every X60 seconds. X.I Rcheck Xterminates it self when the calling process is Xterminated. X.SH FILES X.ta 1i X/etc/utmp X.br X/usr/spool/rwho/whod.* X.br X/etc/passwd X.SH "SEE ALSO" Xsysline(1) X.SH AUTHOR XAnders Klemets X (klemets@ttds.UUCP) X.SH BUGS XIf there are two different users with the same X.B username Xon the hosts in the local network, and one of Xthem has an account on the local machine, X.I rcheck Xwill tell you the name of this user even when Xthe other user logs in on "his" machine. XThis, however, is not specially common. X + END-OF-FILE rcheck.1 chmod 'u=rw,g=r,o=r' 'rcheck.1' echo ' -rw-r--r-- 1 klemets 1851 May 5 18:17 rcheck.1 (as sent)' echo -n ' ' /bin/ls -l rcheck.1 echo 'Extracting rcheck.c' sed 's/^X//' > rcheck.c << '+ END-OF-FILE rcheck.c' X/* X * CHECK for users logging in or out on the local and Remote machines. X * Idea stolen from jr by bs X * Idea stolen from bs by klemets@ttds.UUCP X * It should be started with "rcheck &". X * The program is written for 4.2 BSD UNIX. If you don't use 4.2 BSD X * you must change a little in the makefile and then it will work, X * I hope... (It will then ignore the local network.) X */ X X#include "rcheck.h" Xint users, fid; Xstruct utmp old[MAXUSERS], new[MAXUSERS]; X Xmain(argc, argv) Xchar *argv[]; X{ X int x, h=0, p=0, m=0, t=0; X for (x=1; x<argc; ++x) X if (strcmp ("-h", argv[x]) == 0) X m = 1; X else if (strcmp ("-t", argv[x]) == 0) X m = 2; X else { X if (m == 0) { X if (p == MAXUSERS) { X fprintf (stderr, "Too many users specified.\n"); X exit (1); X } X strcpy (allperson[p++], argv[x]); X } X else if (m == 1) { X if (h == MAXHOSTS) { X fprintf (stderr, "Too many hosts specified.\n"); X exit (1); X } X strcpy (allhost[h++], argv[x]); X } X else { X if (t == MAXUSERS) { X fprintf (stderr, "Too many ttys specified.\n"); X exit (1); X } X strcpy (alltty[t++], argv[x]); X } X } X#ifdef BSD X chdir ("/usr/spool/rwho"); X#endif BSD X gethostname (hostname, sizeof hostname); X if ((fid = open("/etc/utmp", 0)) == NULL) { X fprintf (stderr, "Can't open /etc/utmp\n"); X exit (-1); X } X load(old); X#ifdef BSD X rload (0);/* rold */ X#endif BSD X while (getppid() > 1) { X sleep(30); X load(new); X localscan (); X sleep (30); X load (new); X localscan (); X#ifdef BSD X rload (1); X rscan (); X#endif BSD X } X} X Xlocalscan () X{ X for (users--; users>=0; users--) X if (strcmp(old[users].ut_name,new[users].ut_name)) X if (new[users].ut_name[0]=='\0') { X printout (old[users].ut_name, old[users].ut_line, hostname, old[users].ut_host, 0); X old[users].ut_name[0]='\0'; X } X else { X printout (new[users].ut_name, new[users].ut_line, hostname, new[users].ut_host, 1); X strcpy(old[users].ut_name,new[users].ut_name); X strcpy (old[users].ut_line, new[users].ut_line); X strcpy (old[users].ut_host, new[users].ut_host); X } X} Xprintout (name, tty, host, remote, mode) Xchar *name, *tty, *host, *remote; X{ X char *givename(), rtime[10], cname[NAMELEN+1]; X long time (), tim; X int x=0; X strncpy (cname, name, NAMELEN); X cname[NAMELEN] = '\0'; X if (strlen (allperson[0])) { X while (x < MAXUSERS) X if (strncmp (allperson[x], cname, NAMELEN) == 0) X break; X else ++x; X if (x == MAXUSERS) X return (0); X } X x = 0; X if (strlen (allhost[0])) { X while (x < MAXHOSTS) X if (strcmp (allhost[x], host) == 0) X break; X else ++x; X if (x == MAXHOSTS) X return (0); X } X x = 0; X if (strlen (alltty[0])) { X while (x < MAXUSERS) X if (strcmp (alltty[x], tty) == 0) X break; X else ++x; X if (x == MAXUSERS) X return (0); X } X tim = time (0); X strncpy (rtime, ctime (&tim)+11, 5); X rtime[5] = '\0'; X printf ("\r\n*** %s %s@%s%s logged %s %s%s%s ***\7\r\n", rtime, cname, X host, givename (cname), (mode) ? "in on" : "out from", tty, X (strlen (remote)) ? " via " : "\0", (strlen (remote)) ? remote : "\0"); X return (1); X} X Xchar *givename (s) Xchar *s; X{ X struct passwd *getpwname (), *psw; X char *namefix (), *r; X static char str[100]; X if (psw = getpwnam (s)) X if (strlen (r = namefix (psw->pw_gecos, s))) { X strcpy (str, " ("); X strcat (str, r); X strcat (str, ")"); X return (str); X } X return (""); X} Xload(f) Xstruct utmp f[MAXUSERS]; X{ X int i; X users = 0; X lseek (fid, 0, 0); X while (read (fid, (char *) &f[users], sizeof (struct utmp)) > 0) X ++users; X} Xchar *namefix (s, name) Xchar s[], name[]; X{ X int x, i; X char tmp[200]; X for (x=i=0; x<strlen (s); ++x, ++i) { X if (s[x] == ',') { X tmp[i] = '\0'; X return (tmp); X } X if (s[x] == '&') { X strcpy (&tmp[i], name); X if (tmp[i] < 'A' || tmp[i] > 'Z') X tmp[i] -= ' '; X i += strlen (name)-1; X } X else tmp[i] = s[x]; X } X tmp[i] = '\0'; X return (tmp); X} + END-OF-FILE rcheck.c chmod 'u=rw,g=r,o=r' 'rcheck.c' echo ' -rw-r--r-- 1 klemets 3937 May 5 22:12 rcheck.c (as sent)' echo -n ' ' /bin/ls -l rcheck.c echo 'Extracting rcheck.h' sed 's/^X//' > rcheck.h << '+ END-OF-FILE rcheck.h' X#include <stdio.h> X#include <pwd.h> X#include <utmp.h> X#include <sys/types.h> X#include <sys/dir.h> X#define MAXUSERS 64 X#define MAXHOSTS 20 X#define NAMELEN 8 Xchar hostname [32], allperson[MAXUSERS][10], allhost[MAXHOSTS][32], X alltty[MAXUSERS][10]; + END-OF-FILE rcheck.h chmod 'u=rw,g=r,o=r' 'rcheck.h' echo ' -rw-r--r-- 1 klemets 247 May 5 20:15 rcheck.h (as sent)' echo -n ' ' /bin/ls -l rcheck.h exit 0