[comp.unix.questions] write/talk detection

irick@ecn.purdue.edu (GarBear Irick) (10/30/90)

OK, I have an easy one for you wizards out there (Dan???  Dave???:)...

Is there any way, using sh, C, black magic, etc. to detect when another user
has done a write or a talk-request to yor terminal?  I would like to write a 
small program to check for them when I am away from my machine and have the
program send back a small reply, something like "irick is not here, leave mail."
My terminal is usually idle in my dorm room (thank GOD for Data-Over-Voice!!),
so I end up with people paging me and thinking I am ignoring them.  (People
too stupid to check idle time... :-)

I've considered somthing like "csh | filter_to_grep_for_writes | tee /dev/tty",
but that seems messy.  I am sure pty will do it (right Dan?), but alas we don't
have pty installed at our site.  Any ideas are welcome, preferably e-mail.
Thanks in advance to all you UNIX-ninjas out there with solutions!


-- 
Gary A. Irick,  Purdue University | "You can log out any time you like,
INTERNET: irick@en.ecn.purdue.edu |  But you can never leave!"
UUCP:     ...!pur-ee!irick        |       (apologies to The Eagles)

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/30/90)

In article <1990Oct29.195519.24411@ecn.purdue.edu> irick@ecn.purdue.edu (GarBear Irick) writes:
> OK, I have an easy one for you wizards out there (Dan???  Dave???:)...

Can tell this guy hasn't been around too long. :-)

> Is there any way, using sh, C, black magic, etc. to detect when another user
> has done a write or a talk-request to yor terminal?

Not reliably (except with black magic). The best solution is to modify
write and talk to do something intelligent when they can't get through.
As an example, enclosed is talkanswer, a quick kludge to new BSD talk to
have it record a message (and send it through the mail) whenever the
target isn't logged on. It also works for someone who's just turned
messages off. 

> "csh | filter_to_grep_for_writes | tee /dev/tty",

The problem with this sort of solution is that talk and write don't
allow intelligent multiplexing. Sure, a human can parse several outputs
from different sources without any clues, but a program will have a hard
time separating the talk invitation from other tty activity. That's the
price you pay for non-modular (immodular?) design.

> I am sure pty will do it (right Dan?), but alas we don't
> have pty installed at our site.

Yes, pty can handle csh's insistence on talking to a terminal. But it
can't fix an interface that *assumes* interactivity. The normal mode of
multiplexing tty outputs is exactly such an interface.

Oh, btw, talkanswer depends on pty. Maybe you can convince your sysadmin
to install them both...

---Dan
Difference between Multics and Ada: Multics was ten years *ahead* of its time.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README talkanswer talkdiff
# Wrapped by brnstnd@kramden on Fri Sep 14 12:15:50 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1216 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XThis is talkanswer 1.0, an answering machine for BSD talk. Once you've
Xinstalled it, if anyone talks to a user not logged on to your machine,
Xtalkanswer will answer instead and send the message through normal mail.
XAll the work is done by a shell script that you can easily customize.
X
X
XDon't try to install talkanswer unless you have the new talk. To see if
Xyou have new talk, check for a line containing 518 in /etc/services.
X
XYou need the pty program and setuid utility. pty is available upon
Xrequest to brnstnd@nyu.edu or via anonymous ftp to 128.122.128.22.
Xsetuid is included in the authutil package, which is available from
Xuunet.uu.net:/comp.sources.unix/volume22/auth-utils/part*.
X
XYou need the talkd source to set up talkanswer. If you don't have the
Xsource, get it from uunet.uu.net:/bsd-sources/src/network/talkd.tar.Z.
XApply the patch in talkdiff and recompile.
X
XOnce you've successfully compiled talkd, hide /etc/ntalkd in a safe
Xplace and put the new talkd there.
X
XFinally, put talkanswer into a path that's in inetd's environment. If
Xyou want, change the talkanswer pathname in announce.c for this.
X
XSend comments or complaints to me, Dan Bernstein, at brnstnd@nyu.edu.
XThis is version 1.0, 9/14/90.
END_OF_FILE
if test 1216 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'talkanswer' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'talkanswer'\"
else
echo shar: Extracting \"'talkanswer'\" \(739 characters\)
sed "s/^X//" >'talkanswer' <<'END_OF_FILE'
X#!/bin/sh
XTERM=vt100;export TERM
X{
X  /bin/setuid "$1" touch /tmp/talkans.$$
X  until grep -s stablished /tmp/talkans.$$
X  do
X    sleep 3
X  done
X  /bin/setuid "$1" rm /tmp/talkans.$$
X  echo "This is the talkanswer system, answering for $1."
X  echo "Please leave your name after the beep."
X  echo "<beep>"
X  sleep 300
X  echo ""
X  echo "Thirty seconds left on the tape."
X  sleep 30
X  echo ""
X  echo "Thank you for calling."
X  echo "<beep>"
X  echo x | tr x '\003'
X} | {
X  echo "From: $2@$3"
X  echo "To: $1"
X  echo ""
X  /bin/setuid "$1" /usr/local/pty -dxuR /usr/ucb/talk "$2@$3" 2>&1
X} | {
X  /bin/setuid "$1" awk '{ print }
X/stablished/ { print "established" >"/tmp/talkans.'$$'" }'
X} | /usr/lib/sendmail -f"$2@$3" -F"talkanswer" "$1" &
Xexit 0
END_OF_FILE
if test 739 -ne `wc -c <'talkanswer'`; then
    echo shar: \"'talkanswer'\" unpacked with wrong size!
fi
chmod +x 'talkanswer'
# end of 'talkanswer'
fi
if test -f 'talkdiff' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'talkdiff'\"
else
echo shar: Extracting \"'talkdiff'\" \(1310 characters\)
sed "s/^X//" >'talkdiff' <<'END_OF_FILE'
X*** announce.c.orig	Sat Jun 18 17:10:48 1988
X--- announce.c	Fri Sep 14 11:33:11 1990
X***************
X*** 28,33 ****
X--- 28,34 ----
X  #include <sys/wait.h>
X  #include <errno.h>
X  #include <syslog.h>
X+ #include <pwd.h>
X  
X  #include <protocols/talkd.h>
X  
X***************
X*** 83,88 ****
X--- 84,96 ----
X  	FILE *tf;
X  	struct stat stbuf;
X  
X+ 	if (request->r_tty[0] == '/')
X+ 	 {
X+ 	  /* Answering machine. */
X+ 	  execlp("talkanswer","talkanswer",request->r_name,
X+ 		  request->l_name,remote_machine,(char *) 0);
X+ 	  return(FAILED);
X+ 	 }
X  	(void)sprintf(full_tty, "/dev/%s", request->r_tty);
X  	if (access(full_tty, 0) != 0)
X  		return (FAILED);
X*** process.c.orig	Sat Jun 18 17:10:49 1988
X--- process.c	Fri Sep 14 11:33:06 1990
X***************
X*** 122,129 ****
X  	/* see if the user is logged */
X  	result = find_user(mp->r_name, mp->r_tty);
X  	if (result != SUCCESS) {
X! 		rp->answer = result;
X! 		return;
X  	}
X  #define	satosin(sa)	((struct sockaddr_in *)(sa))
X  	hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr,
X--- 122,129 ----
X  	/* see if the user is logged */
X  	result = find_user(mp->r_name, mp->r_tty);
X  	if (result != SUCCESS) {
X! 	  mp->r_tty[0] = '/';
X! 	  result = SUCCESS;
X  	}
X  #define	satosin(sa)	((struct sockaddr_in *)(sa))
X  	hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr,
END_OF_FILE
if test 1310 -ne `wc -c <'talkdiff'`; then
    echo shar: \"'talkdiff'\" unpacked with wrong size!
fi
# end of 'talkdiff'
fi
echo shar: End of shell archive.
exit 0