[4973] in Athena Bugs

home help back first fref pref prev next nref lref last post

follow-up to getty patches from com.bugs.4bsd

daemon@ATHENA.MIT.EDU (Jonathan I. Kamens)
Tue May 22 23:56:51 1990

Date: Tue, 22 May 90 23:56:33 -0400
From: Jonathan I. Kamens <jik@pit-manager.MIT.EDU>
To: bugs@ATHENA.MIT.EDU
In article <5824@videovax.tv.tek.com>, bart@videovax.tv.tek.com (Bart
Massey) writes:
|> In the above-referenced article, I gave patches to getty to get it to use
|> its tty name argument instead of trying to find it by scanning /dev in
|> ttyname.  This fix was not complete -- the ttyname should also be given as
|> an argument to login, which scans /dev once in ttyname, and again calls
|> ttyname indirectly from ttyslot(3).  Note that even with these fixes, giving
|> a symbolic link as a target in /etc/ttys will not work properly, because
|> chown(2) doesn't follow symbolic links (BTW, why is it that chmod(2) follows
|> symbolic links, but chown does not?  I'm sure there's some good reason...).
|> However, you will get an efficiency win.  Note that fixes to at least
|> telnetd(8) and rlogind(8) should also be provided to feed the appropriate
|> flag to login, but I've been too lazy to do this one so far...
|> 
|> Thus, the patches below do the following:
|> 
|> Getty gives a '-t ttyXX' argument to login now.  This patch is relative
|> to the above-referenced getty patch.
|> 
|> login accepts a '-t ttyXX' argument as the name of its controlling tty now.
|> This saves it some lookups.  The man page is updated to reflect this.
|> 
|> login now sets the environment variable TTY to the basename of its ttyname.
|> 
|> ttyname(3) now uses the environment variable TTY, if present, as a hint
|> to avoid a scan of /dev/ .  Have fun!
|> 
|> 					Bart Massey
|> 					..tektronix!videovax.tv.tek.com!bart
|> 					..tektronix!reed.bitnet!bart
|> 						
|> *** /tmp/,RCSt1028089	Sat May 19 11:58:49 1990
|> --- getty/main.c	Sat May 19 10:28:11 1990
|> ***************
|> *** 52,59 ****
|> --- 52,61 ----
|>   char	dev[] = "/dev/";
|>   char	ctty[] = "/dev/console";
|>   char	ttyn[32];
|> + char	*tty;
|>   char	*portselector();
|>   char	*ttyname();
|> + char	*rindex();
|>   
|>   #define	OBUFSIZ		128
|>   #define	TABBUFSIZ	512
|> ***************
|> *** 129,139 ****
|>   	 * that the file descriptors are already set up for us. 
|>   	 * J. Gettys - MIT Project Athena.
|>   	 */
|> ! 	if (argc <= 2 || strcmp(argv[2], "-") == 0)
|>   	    strcpy(ttyn, ttyname(0));
|> ! 	else {
|>   	    strcpy(ttyn, dev);
|>   	    strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
|>   	    if (strcmp(argv[0], "+") != 0) {
|>   		chown(ttyn, 0, 0);
|>   		chmod(ttyn, 0622);
|> --- 131,147 ----
|>   	 * that the file descriptors are already set up for us. 
|>   	 * J. Gettys - MIT Project Athena.
|>   	 */
|> ! 	if (argc <= 2 || strcmp(argv[2], "-") == 0) {
|>   	    strcpy(ttyn, ttyname(0));
|> ! 	    tty = rindex(ttyn, '/');
|> ! 	    if (tty == (char *) 0)
|> ! 		tty = ttyn;
|> ! 	    else
|> ! 		tty++;
|> ! 	} else {
|>   	    strcpy(ttyn, dev);
|>   	    strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
|> + 	    tty = ttyn + sizeof(dev) - 1;
|>   	    if (strcmp(argv[0], "+") != 0) {
|>   		chown(ttyn, 0, 0);
|>   		chmod(ttyn, 0622);
|> ***************
|> *** 242,248 ****
|>   			for (i = 0; environ[i] != (char *)0; i++)
|>   				env[i] = environ[i];
|>   			makeenv(&env[i]);
|> ! 			execle(LO, "login", "-p", name, (char *) 0, env);
|>   			syslog(LOG_ERR, "%s: %m", LO);
|>   			exit(1);
|>   		}
|> --- 250,257 ----
|>   			for (i = 0; environ[i] != (char *)0; i++)
|>   				env[i] = environ[i];
|>   			makeenv(&env[i]);
|> ! 			execle(LO, "login", "-t", tty,
|> !  			  "-p", name, (char *) 0, env);
|>   			syslog(LOG_ERR, "%s: %m", LO);
|>   			exit(1);
|>   		}
|> ***************
|> *** 432,438 ****
|>   	char *slash;
|>   	char datebuffer[60];
|>   	extern char editedhost[];
|> - 	extern char *rindex();
|>   
|>   	while (*cp) {
|>   		if (*cp != '%') {
|> --- 441,446 ----
|> ***************
|> *** 442,452 ****
|>   		switch (*++cp) {
|>   
|>   		case 't':
|> ! 			slash = rindex(ttyn, '/');
|> ! 			if (slash == (char *) 0)
|> ! 				puts(ttyn);
|> ! 			else
|> ! 				puts(&slash[1]);
|>   			break;
|>   
|>   		case 'h':
|> --- 450,456 ----
|>   		switch (*++cp) {
|>   
|>   		case 't':
|> ! 			puts(tty);
|>   			break;
|>   
|>   		case 'h':
|> *** /tmp/,RCSt1019684	Tue May 22 12:51:50 1990
|> --- login.1	Tue May 22 12:50:30 1990
|> ***************
|> *** 21,26 ****
|> --- 21,29 ----
|>   .B \-h
|>   hostname
|>   ] [
|> + .B \-t
|> + ttyname
|> + ] [
|>   .B \-f
|>   ] [
|>   username
|> ***************
|> *** 108,113 ****
|> --- 111,120 ----
|>   and that no password need be requested.
|>   This option may be used by the superuser
|>   or by the user specified on the command line.
|> + The
|> + .B \-t
|> + option is used with a ttyname (without the implicit leading /dev/) to
|> + indicate the name of the controlling tty of the login.
|>   .SH FILES
|>   .ta \w'/usr/spool/mail/*\ \ 'u
|>   /etc/utmp	accounting
|> *** /tmp/,RCSt1020404	Tue May 22 15:13:45 1990
|> --- login.c	Sat May 19 14:51:23 1990
|> ***************
|> *** 102,108 ****
|>   	int pflag = 0, hflag = 0, fflag = 0, t, f, c;
|>   	int invalid, quietlog;
|>   	FILE *nlfd;
|> ! 	char *ttyn, *tty;
|>   	int ldisc = 0, zero = 0, i;
|>   	char *p, *domain, *index();
|>   
|> --- 102,109 ----
|>   	int pflag = 0, hflag = 0, fflag = 0, t, f, c;
|>   	int invalid, quietlog;
|>   	FILE *nlfd;
|> ! 	char *ttyn, *tty = 0;
|> ! 	static char ttynbuf[14]; /* magic number! think before changing */
|>   	int ldisc = 0, zero = 0, i;
|>   	char *p, *domain, *index();
|>   
|> ***************
|> *** 118,123 ****
|> --- 119,126 ----
|>    	 * -f is used to skip a second login authentication 
|>   	 * -h is used by other servers to pass the name of the
|>   	 * remote host to login so that it may be placed in utmp and wtmp
|> + 	 * -t is used to pass the terminal name (implicit /dev/), thus
|> + 	 * avoiding an expensive and bogus call to ttyname(3).
|>   	 */
|>   	(void) gethostname(me, sizeof(me));
|>   	domain = index(me, '.');
|> ***************
|> *** 138,143 ****
|> --- 141,161 ----
|>   			argv += 2;
|>   			continue;
|>   		}
|> + 		if (strcmp(argv[1], "-t") == 0) {
|> + 			if (argv[2] == 0)
|> + 				exit(1);
|> + 			if (!getuid() && strlen(argv[2]) <= 8) {
|> + 				tty = argv[2];
|> + 				strcpy(ttynbuf, "/dev/");
|> + 				strcat(ttynbuf, tty);
|> + 				ttynbuf[13] = '\0';  /* not necessary, but.. */
|> + 				ttyn = ttynbuf;
|> + 			} else
|> + 				printf("warning: couldn't handle -t %s\n", argv[2]);
|> + 			argc -= 2;
|> + 			argv += 2;
|> + 			continue;
|> + 		}
|>   		if (strcmp(argv[1], "-h") == 0) {
|>   			if (getuid() == 0) {
|>   				if (rflag || hflag) {
|> ***************
|> *** 192,205 ****
|>   	ioctl(0, TIOCSETP, &ttyb);
|>   	for (t = getdtablesize(); t > 2; t--)
|>   		close(t);
|> ! 	ttyn = ttyname(0);
|> ! 	if (ttyn == (char *)0 || *ttyn == '\0')
|> ! 		ttyn = "/dev/tty??";
|> ! 	tty = rindex(ttyn, '/');
|> ! 	if (tty == NULL)
|> ! 		tty = ttyn;
|> ! 	else
|> ! 		tty++;
|>   	openlog("login", LOG_ODELAY, LOG_AUTH);
|>   	t = 0;
|>   	invalid = FALSE;
|> --- 210,225 ----
|>   	ioctl(0, TIOCSETP, &ttyb);
|>   	for (t = getdtablesize(); t > 2; t--)
|>   		close(t);
|> ! 	if( !tty ) {
|> ! 		ttyn = ttyname(0);
|> ! 		if (ttyn == (char *)0 || *ttyn == '\0')
|> ! 			ttyn = "/dev/tty??";
|> ! 		tty = rindex(ttyn, '/');
|> ! 		if (tty == NULL)
|> ! 			tty = ttyn;
|> ! 		else
|> ! 			tty++;
|> ! 	}
|>   	openlog("login", LOG_ODELAY, LOG_AUTH);
|>   	t = 0;
|>   	invalid = FALSE;
|> ***************
|> *** 337,343 ****
|>   		exit(0);
|>   	}
|>   	time(&utmp.ut_time);
|> ! 	t = ttyslot();
|>   	if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) {
|>   		lseek(f, (long)(t*sizeof(utmp)), 0);
|>   		SCPYN(utmp.ut_line, tty);
|> --- 357,363 ----
|>   		exit(0);
|>   	}
|>   	time(&utmp.ut_time);
|> ! 	t = ttynslot(tty);
|>   	if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) {
|>   		lseek(f, (long)(t*sizeof(utmp)), 0);
|>   		SCPYN(utmp.ut_line, tty);
|> ***************
|> *** 392,397 ****
|> --- 412,418 ----
|>   	setenv("TERM", term, 0);
|>   	setenv("USER", pwd->pw_name, 1);
|>   	setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0);
|> + 	setenv("TTY", tty, 1);
|>   
|>   	if ((namep = rindex(pwd->pw_shell, '/')) == NULL)
|>   		namep = pwd->pw_shell;
|> ***************
|> *** 580,583 ****
|> --- 601,627 ----
|>   	endgrent();
|>   
|>   	return (gid);
|> + }
|> + 
|> + 
|> + /*
|> +  * mostly borrowed from ttyslot()
|> +  */
|> + ttynslot(tty)
|> + char *tty;
|> + {
|> + 	register struct ttyent *ty;
|> + 	register s;
|> + 
|> + 	setttyent();
|> + 	s = 0;
|> + 	while ((ty = getttyent()) != NULL) {
|> + 		s++;
|> + 		if (strcmp(ty->ty_name, tty) == 0) {
|> + 			endttyent();
|> + 			return (s);
|> + 		}
|> + 	}
|> + 	endttyent();
|> + 	return (0);
|>   }
|> *** /tmp/,RCSt1028041	Sat May 19 11:50:13 1990
|> --- ttyname.c	Sat May 19 11:15:52 1990
|> ***************
|> *** 12,22 ****
|>   #include <sys/param.h>
|>   #include <sys/dir.h>
|>   #include <sys/stat.h>
|>   
|>   static	char	dev[]	= "/dev/";
|> - char	*strcpy();
|> - char	*strcat();
|>   
|>   char *
|>   ttyname(f)
|>   {
|> --- 12,22 ----
|>   #include <sys/param.h>
|>   #include <sys/dir.h>
|>   #include <sys/stat.h>
|> + #include <strings.h>
|>   
|>   static	char	dev[]	= "/dev/";
|>   
|> + 
|>   char *
|>   ttyname(f)
|>   {
|> ***************
|> *** 24,30 ****
|> --- 24,32 ----
|>   	struct stat tsb;
|>   	register struct direct *db;
|>   	register DIR *df;
|> + 	char *tty;
|>   	static char rbuf[32];
|> + 	extern char *getenv();
|>   
|>   	if (isatty(f)==0)
|>   		return(NULL);
|> ***************
|> *** 32,37 ****
|> --- 34,46 ----
|>   		return(NULL);
|>   	if ((fsb.st_mode&S_IFMT) != S_IFCHR)
|>   		return(NULL);
|> + 	if ((tty = getenv("TTY")) && strlen(tty) == 5 && !index(tty, '/')) {
|> + 		strcpy(rbuf, dev);
|> + 		strcat(rbuf, tty);
|> + 		if (stat(rbuf, &tsb) == 0 &&
|> +  		  tsb.st_dev == fsb.st_dev && tsb.st_ino == fsb.st_ino)
|> + 			return(rbuf);
|> + 	}
|>   	if ((df = opendir(dev)) == NULL)
|>   		return(NULL);
|>   	while ((db = readdir(df)) != NULL) {

Jonathan Kamens			              USnail:
MIT Project Athena				11 Ashford Terrace
jik@Athena.MIT.EDU				Allston, MA  02134
Office: 617-253-8495			      Home: 617-782-0710

home help back first fref pref prev next nref lref last post