Subject: bin/3778: talkd should find the least idle terminal
To: None <gnats-bugs@gnats.netbsd.org>
From: Eric Fischer <eric@fudge.uchicago.edu>
List: netbsd-bugs
Date: 06/23/1997 12:47:13
>Number:         3778
>Category:       bin
>Synopsis:       talkd should find the least idle terminal
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 23 11:05:01 1997
>Last-Modified:
>Originator:     Eric Fischer
>Organization:
The University of Chicago
>Release:        1.2
>Environment:
	
System: NetBSD fudge 1.2 NetBSD 1.2 (FUDGE) #7: Sun Jan 19 16:26:56 CST 1997 eric@fudge:/usr/people/eric/usrsrc/sys/arch/sparc/compile/FUDGE sparc


>Description:
	Talkd is not very smart about which terminal to send a talk
	announcement to if the person talking to you don't specify one
	and you're logged in more than once.  It should choose the 
	most recent terminal you typed something on rather than
	whichever one happens to come first in utmp.
>How-To-Repeat:
	Log in at work.  Go home and dial in.  Wait for someone to
	talk to you, and notice (or fail to notice) that the message
	comes up on your six-hour-idle display at work instead of
	the one you're typing on right now.
>Fix:
	Here is a patch that should make it select the least idle
	terminal:

diff -rc ../../../src/libexec/talkd/process.c ./process.c
*** ../../../src/libexec/talkd/process.c	Sun Aug  1 13:29:34 1993
--- ./process.c	Mon Jun 23 12:39:11 1997
***************
*** 184,189 ****
--- 184,191 ----
  	FILE *fd;
  	struct stat statb;
  	char ftty[20];
+ 	time_t atime = 0;
+ 	int anytty = 0;
  
  	if ((fd = fopen(_PATH_UTMP, "r")) == NULL) {
  		fprintf(stderr, "talkd: can't read %s.\n", _PATH_UTMP);
***************
*** 192,212 ****
  #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
  	status = NOT_HERE;
  	(void) strcpy(ftty, _PATH_DEV);
  	while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
  		if (SCMPN(ubuf.ut_name, name) == 0) {
! 			if (*tty == '\0') {
! 				status = PERMISSION_DENIED;
  				/* no particular tty was requested */
  				(void) strcpy(ftty+5, ubuf.ut_line);
  				if (stat(ftty,&statb) == 0) {
! 					if (!(statb.st_mode & 020))
  						continue;
! 					(void) strcpy(tty, ubuf.ut_line);
! 					status = SUCCESS;
! 					break;
  				}
! 			}
! 			if (strcmp(ubuf.ut_line, tty) == 0) {
  				status = SUCCESS;
  				break;
  			}
--- 194,223 ----
  #define SCMPN(a, b)	strncmp(a, b, sizeof (a))
  	status = NOT_HERE;
  	(void) strcpy(ftty, _PATH_DEV);
+ 
+ 	if (*tty == '\0')
+ 		anytty = 1;
+ 
  	while (fread((char *) &ubuf, sizeof ubuf, 1, fd) == 1)
  		if (SCMPN(ubuf.ut_name, name) == 0) {
! 			if (anytty) {
  				/* no particular tty was requested */
  				(void) strcpy(ftty+5, ubuf.ut_line);
  				if (stat(ftty,&statb) == 0) {
! 					if (!(statb.st_mode & 020)) {
! 						if (status != SUCCESS)
! 							status = 
! 							      PERMISSION_DENIED;
  						continue;
! 					}
! 					/* find the least idle tty */
! 					if (statb.st_atime > atime) {
! 						atime = statb.st_atime;
! 						strcpy(tty, ubuf.ut_line);
! 						status = SUCCESS;
! 					}
  				}
! 			} else if (strcmp(ubuf.ut_line, tty) == 0) {
  				status = SUCCESS;
  				break;
  			}
>Audit-Trail:
>Unformatted: