[4973] in Athena Bugs
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