Subject: stty and lastcomm bugs (#372)
Index:	ucb/lastcomm.c,bin/stty/stty.c 2.11BSD

Description:
	When stty(1) was updated to handle new options in 369-371 a bug
	was introduced that would cause stty to coredump if an invalid
	option was specified.

	lastcomm(1) doesn't properly filter commands based upon the
	tty or user criteria specified on the command line.

Repeat-By:
	stty cr0
	Segmentation fault (core dumped)

	lastcomm sms

	the latter should only show commands that I issued, instead it
	shows all commands (ignoring the specified username).

Fix:
	In stty there were two problems.  The first was failing to increment
	the table index when stepping thru the tables.  The second was more
	of an efficiency loss than a real bug - when a match is detected the
	scans of the other tables should be bypassed.

	When lastcomm was updated earlier in the year to use 'getopt' the
	argument handling later on in the program was not adjusted properly.

	Both fixes are small and easily installed.  Cut where indicated, saving
	to a file (/tmp/372).  Then:

		patch -p0 < /tmp/372
		cd /usr/src/bin/stty
		make 
		make install
		make clean

		cd /usr/src/ucb
		make lastcomm
		install -s -m 755 -o bin lastcomm /usr/ucb/lastcomm

	As always this and previous updates to 2.11BSD are available via
	anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the
	directory /pub/2.11BSD.

-------------------------------cut here-------------------------
*** /usr/src/ucb/lastcomm.c.old	Fri Feb 14 22:11:31 1997
--- /usr/src/ucb/lastcomm.c	Wed May  7 20:36:42 1997
***************
*** 9,15 ****
  "@(#) Copyright (c) 1980 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)lastcomm.c	5.2.3 (2.11BSD GTE) 1997/2/14";
  #endif
  
  /*
--- 9,15 ----
  "@(#) Copyright (c) 1980 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)lastcomm.c	5.2.4 (2.11BSD GTE) 1997/5/7";
  #endif
  
  /*
***************
*** 82,88 ****
  			     cp++)
  				if (!isascii(*cp) || iscntrl(*cp))
  					*cp = '?';
! 			if (argc > 1 && !ok(argc, argv, acp))
  				continue;
  			x = expand(acp->ac_utime) + expand(acp->ac_stime);
  			printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
--- 82,88 ----
  			     cp++)
  				if (!isascii(*cp) || iscntrl(*cp))
  					*cp = '?';
! 			if (*argv && !ok(argv, acp))
  				continue;
  			x = expand(acp->ac_utime) + expand(acp->ac_stime);
  			printf("%-*.*s %s %-*s %-*s %6.2f secs %.16s\n",
***************
*** 128,146 ****
  	return (flags);
  }
  
! ok(argc, argv, acp)
! 	int argc;
  	register char *argv[];
  	register struct acct *acp;
  {
! 	register int j;
! 
! 	for (j = 1; j < argc; j++)
! 		if (strcmp(getname(acp->ac_uid), argv[j]) &&
! 		    strcmp(getdev(acp->ac_tty), argv[j]) &&
! 		    strncmp(acp->ac_comm, argv[j], fldsiz(acct, ac_comm)))
! 			break;
! 	return (j == argc);
  }
  
  /* should be done with nameserver or database */
--- 128,146 ----
  	return (flags);
  }
  
! ok(argv, acp)
  	register char *argv[];
  	register struct acct *acp;
  {
! 	do {
! 		if (!strcmp(getname(acp->ac_uid), *argv))
! 			return(1);
! 		if (!strcmp(getdev(acp->ac_tty), *argv))
! 			return(1);
! 		if (!strncmp(acp->ac_comm, *argv, fldsiz(acct, ac_comm)))
! 			return(1);
! 	} while (*++argv);
! 	return (0);
  }
  
  /* should be done with nameserver or database */
*** /usr/src/bin/stty/stty.c.old	Fri May  2 17:51:17 1997
--- /usr/src/bin/stty/stty.c	Wed May  7 20:53:52 1997
***************
*** 9,15 ****
  "@(#) Copyright (c) 1980 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)stty.c	5.4.2 (2.11BSD GTE) 1997/5/2";
  #endif
  
  /*
--- 9,15 ----
  "@(#) Copyright (c) 1980 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)stty.c	5.4.3 (2.11BSD GTE) 1997/5/7";
  #endif
  
  /*
***************
*** 322,349 ****
  			printf("unknown\n");
  			exit(1);
  		}
! 		for	(i = 0; modes[0].string; i++)
  			{
  			if	(eq(modes[i].string))
  				{
  				mode.sg_flags &= ~modes[i].reset;
  				mode.sg_flags |= modes[i].set;
  				}
  			}
! 		for	(i = 0; lmodes[0].string; i++)
  			{
  			if	(eq(lmodes[i].string))
  				{
  				lmode &= ~lmodes[i].reset;
  				lmode |= lmodes[i].set;
  				}
  			}
! 		for	(i = 0; mmodes[0].string; i++)
  			{
  			if	(eq(mmodes[i].string))
  				{
  				nmstate &= ~mmodes[i].reset;
  				nmstate |= mmodes[i].set;
  				}
  			}
  		if(arg)
--- 322,352 ----
  			printf("unknown\n");
  			exit(1);
  		}
! 		for	(i = 0; modes[i].string; i++)
  			{
  			if	(eq(modes[i].string))
  				{
  				mode.sg_flags &= ~modes[i].reset;
  				mode.sg_flags |= modes[i].set;
+ 				goto cont;
  				}
  			}
! 		for	(i = 0; lmodes[i].string; i++)
  			{
  			if	(eq(lmodes[i].string))
  				{
  				lmode &= ~lmodes[i].reset;
  				lmode |= lmodes[i].set;
+ 				goto cont;
  				}
  			}
! 		for	(i = 0; mmodes[i].string; i++)
  			{
  			if	(eq(mmodes[i].string))
  				{
  				nmstate &= ~mmodes[i].reset;
  				nmstate |= mmodes[i].set;
+ 				goto cont;
  				}
  			}
  		if(arg)
***************
*** 367,382 ****
  eq(string)
  char *string;
  {
- 	register int i;
  
! 	if(!arg)
  		return(0);
! 	i = 0;
! loop:
! 	if(arg[i] != string[i])
  		return(0);
- 	if(arg[i++] != '\0')
- 		goto loop;
  	arg = 0;
  	return(1);
  }
--- 370,380 ----
  eq(string)
  char *string;
  {
  
! 	if	(!arg)
  		return(0);
! 	if	(strcmp(arg, string))
  		return(0);
  	arg = 0;
  	return(1);
  }
*** /VERSION.old	Sun May  4 21:11:47 1997
--- /VERSION	Wed May  7 20:06:21 1997
***************
*** 1,5 ****
! Current Patch Level: 371
! Date: May 4, 1997
  
  2.11 BSD
  ============
--- 1,5 ----
! Current Patch Level: 372
! Date: May 7, 1997
  
  2.11 BSD
  ============
