143653Sbostic /*- 236515Sbostic * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. 336515Sbostic * All rights reserved. 436515Sbostic * 543653Sbostic * %sccs.include.redist.c% 619843Sdist */ 719843Sdist 812678Ssam #ifndef lint 919843Sdist char copyright[] = 1036515Sbostic "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\ 1119843Sdist All rights reserved.\n"; 1236515Sbostic #endif /* not lint */ 1312678Ssam 1419843Sdist #ifndef lint 15*43674Sbostic static char sccsid[] = "@(#)login.c 5.60 (Berkeley) 06/24/90"; 1636515Sbostic #endif /* not lint */ 1719843Sdist 181043Sbill /* 191043Sbill * login [ name ] 2031695Skarels * login -h hostname (for telnetd, etc.) 2131695Skarels * login -f name (for pre-authenticated login: datakit, xterm, etc.) 221043Sbill */ 231043Sbill 2412984Ssam #include <sys/param.h> 2512687Ssam #include <sys/stat.h> 2612687Ssam #include <sys/time.h> 2712687Ssam #include <sys/resource.h> 2816453Sroot #include <sys/file.h> 2939271Skfall #include <sgtty.h> 3012687Ssam 311043Sbill #include <utmp.h> 321043Sbill #include <signal.h> 3312678Ssam #include <errno.h> 3416453Sroot #include <ttyent.h> 3516453Sroot #include <syslog.h> 3626862Smckusick #include <grp.h> 3736460Sbostic #include <pwd.h> 3836515Sbostic #include <setjmp.h> 3936460Sbostic #include <stdio.h> 4042063Sbostic #include <string.h> 4137203Sbostic #include <tzfile.h> 4237203Sbostic #include "pathnames.h" 431043Sbill 4436460Sbostic #define TTYGRPNAME "tty" /* name of group to own ttys */ 4526862Smckusick 4612687Ssam /* 4736460Sbostic * This bounds the time given to login. Not a define so it can 4836460Sbostic * be patched on machines where it's too small. 4912687Ssam */ 5031509Sbostic int timeout = 300; 5143653Sbostic #ifdef KERBEROS 5243653Sbostic int notickets = 1; 5343653Sbostic #endif 546005Swnj 5536647Skarels struct passwd *pwd; 5636647Skarels int failures; 5740490Sbostic char term[64], *envinit[1], *hostname, *username, *tty; 586005Swnj 5936647Skarels struct sgttyb sgttyb; 6036647Skarels struct tchars tc = { 6113074Ssam CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 621365Sbill }; 6336647Skarels struct ltchars ltc = { 6443653Sbostic CSUSP, CDSUSP, CRPRNT, CDISCARD, CWERASE, CLNEXT 6513074Ssam }; 661365Sbill 671043Sbill main(argc, argv) 6836460Sbostic int argc; 6936460Sbostic char **argv; 701043Sbill { 7143653Sbostic extern int optind; 7236460Sbostic extern char *optarg, **environ; 7336880Sbostic struct timeval tp; 7436460Sbostic struct group *gr; 7536460Sbostic register int ch; 7636647Skarels register char *p; 7739271Skfall int ask, fflag, hflag, pflag, cnt, uid; 78*43674Sbostic int quietlog, ioctlval, rval; 7943653Sbostic char *domain, *salt, *ttyn; 8037692Sbostic char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; 8138034Skfall char localhost[MAXHOSTNAMELEN]; 8236880Sbostic char *ctime(), *ttyname(), *stypeof(), *crypt(), *getpass(); 8336460Sbostic time_t time(); 8436460Sbostic off_t lseek(); 8543653Sbostic void timedout(); 861043Sbill 8736460Sbostic (void)signal(SIGALRM, timedout); 8836460Sbostic (void)alarm((u_int)timeout); 8936460Sbostic (void)signal(SIGQUIT, SIG_IGN); 9036460Sbostic (void)signal(SIGINT, SIG_IGN); 9136460Sbostic (void)setpriority(PRIO_PROCESS, 0, 0); 9236460Sbostic 9342502Sbostic openlog("login", LOG_ODELAY, LOG_AUTH); 9442502Sbostic 9512687Ssam /* 9618549Ssam * -p is used by getty to tell login not to destroy the environment 9731695Skarels * -f is used to skip a second login authentication 9836523Skarels * -h is used by other servers to pass the name of the remote 9936523Skarels * host to login so that it may be placed in utmp and wtmp 10012687Ssam */ 10138034Skfall domain = NULL; 10238034Skfall if (gethostname(localhost, sizeof(localhost)) < 0) 10338034Skfall syslog(LOG_ERR, "couldn't get local hostname: %m"); 10438034Skfall else 10538034Skfall domain = index(localhost, '.'); 10636460Sbostic 10737203Sbostic fflag = hflag = pflag = 0; 10839271Skfall uid = getuid(); 10937203Sbostic while ((ch = getopt(argc, argv, "fh:p")) != EOF) 11036515Sbostic switch (ch) { 11136460Sbostic case 'f': 11236460Sbostic fflag = 1; 11336460Sbostic break; 11436460Sbostic case 'h': 11539271Skfall if (uid) { 11637203Sbostic (void)fprintf(stderr, 11736460Sbostic "login: -h for super-user only.\n"); 11832313Sbostic exit(1); 11931695Skarels } 12036460Sbostic hflag = 1; 12136460Sbostic if (domain && (p = index(optarg, '.')) && 12236553Sbostic strcasecmp(p, domain) == 0) 12336460Sbostic *p = 0; 12436460Sbostic hostname = optarg; 12536460Sbostic break; 12636460Sbostic case 'p': 12718549Ssam pflag = 1; 12836460Sbostic break; 12936460Sbostic case '?': 13036460Sbostic default: 13139271Skfall if (!uid) 13239271Skfall syslog(LOG_ERR, "invalid flag %c", ch); 13337203Sbostic (void)fprintf(stderr, 13437203Sbostic "usage: login [-fp] [username]\n"); 13536460Sbostic exit(1); 13618549Ssam } 13736460Sbostic argc -= optind; 13836460Sbostic argv += optind; 13936549Sbostic if (*argv) { 14036647Skarels username = *argv; 14143653Sbostic if (strlen(username) > UT_NAMESIZE) 14243653Sbostic username[UT_NAMESIZE] = '\0'; 14336549Sbostic ask = 0; 14436647Skarels } else 14536549Sbostic ask = 1; 14636460Sbostic 14736460Sbostic ioctlval = 0; 14836460Sbostic (void)ioctl(0, TIOCLSET, &ioctlval); 14936460Sbostic (void)ioctl(0, TIOCNXCL, 0); 15036515Sbostic (void)fcntl(0, F_SETFL, ioctlval); 15136515Sbostic (void)ioctl(0, TIOCGETP, &sgttyb); 15236515Sbostic sgttyb.sg_erase = CERASE; 15336515Sbostic sgttyb.sg_kill = CKILL; 15436460Sbostic (void)ioctl(0, TIOCSLTC, <c); 15536460Sbostic (void)ioctl(0, TIOCSETC, &tc); 15636515Sbostic (void)ioctl(0, TIOCSETP, &sgttyb); 15736460Sbostic 15836460Sbostic for (cnt = getdtablesize(); cnt > 2; cnt--) 15936460Sbostic close(cnt); 16036460Sbostic 1611043Sbill ttyn = ttyname(0); 16237692Sbostic if (ttyn == NULL || *ttyn == '\0') { 16337692Sbostic (void)sprintf(tname, "%s??", _PATH_TTY); 16437692Sbostic ttyn = tname; 16537692Sbostic } 16636460Sbostic if (tty = rindex(ttyn, '/')) 16736460Sbostic ++tty; 16836460Sbostic else 16916453Sroot tty = ttyn; 17036460Sbostic 17136549Sbostic for (cnt = 0;; ask = 1) { 17238602Sbostic ioctlval = TTYDISC; 17336460Sbostic (void)ioctl(0, TIOCSETD, &ioctlval); 17436460Sbostic 17536549Sbostic if (ask) { 17636515Sbostic fflag = 0; 17736460Sbostic getloginname(); 17836515Sbostic } 17936647Skarels /* 18039271Skfall * Note if trying multiple user names; log failures for 18139271Skfall * previous user name, but don't bother logging one failure 18236647Skarels * for nonexistent name (mistyped username). 18336647Skarels */ 18436647Skarels if (failures && strcmp(tbuf, username)) { 18536647Skarels if (failures > (pwd ? 0 : 1)) 18636549Sbostic badlogin(tbuf); 18736647Skarels failures = 0; 18836549Sbostic } 18936647Skarels (void)strcpy(tbuf, username); 19043659Sbostic 19136515Sbostic if (pwd = getpwnam(username)) 19236515Sbostic salt = pwd->pw_passwd; 19343659Sbostic else 19443659Sbostic salt = "xx"; 19536460Sbostic 19612687Ssam /* 197*43674Sbostic * if we have a valid account name, and it doesn't have a 198*43674Sbostic * password, or the -f option was specified and the caller 199*43674Sbostic * is root or the caller isn't changing their uid, don't 200*43674Sbostic * authenticate. 20112687Ssam */ 202*43674Sbostic if (pwd && (*pwd->pw_passwd == '\0' || 203*43674Sbostic fflag && (uid == 0 || uid == pwd->pw_uid))) 20436460Sbostic break; 20512687Ssam 20639271Skfall /* 20739271Skfall * If trying to log in as root, but with insecure terminal, 20839271Skfall * refuse the login attempt. 20939271Skfall */ 21043659Sbostic if (pwd && pwd->pw_uid == 0 && !rootterm(tty)) { 21139271Skfall (void)fprintf(stderr, 21239271Skfall "%s login refused on this terminal.\n", 21339271Skfall pwd->pw_name); 21439271Skfall if (hostname) 21539271Skfall syslog(LOG_NOTICE, 21639271Skfall "LOGIN %s REFUSED FROM %s ON TTY %s", 21739271Skfall pwd->pw_name, hostname, tty); 21839271Skfall else 21939271Skfall syslog(LOG_NOTICE, 22039271Skfall "LOGIN %s REFUSED ON TTY %s", 22139271Skfall pwd->pw_name, tty); 22239271Skfall continue; 22339271Skfall } 22439271Skfall 22543653Sbostic (void)setpriority(PRIO_PROCESS, 0, -4); 22643659Sbostic 22743653Sbostic p = getpass("Password:"); 22836608Skfall 22943659Sbostic if (pwd) { 23043653Sbostic #ifdef KERBEROS 23143659Sbostic rval = klogin(pwd, localhost, p); 23243659Sbostic if (rval == 1) 23343659Sbostic rval = strcmp(crypt(p, salt), pwd->pw_passwd); 23443659Sbostic #else 23543653Sbostic rval = strcmp(crypt(p, salt), pwd->pw_passwd); 23637203Sbostic #endif 23743659Sbostic } 23843653Sbostic bzero(p, strlen(p)); 23943659Sbostic 24043659Sbostic (void)setpriority(PRIO_PROCESS, 0, 0); 24143659Sbostic 24243659Sbostic if (pwd && !rval) 24336460Sbostic break; 24436460Sbostic 24543659Sbostic (void)printf("Login incorrect\n"); 24636647Skarels failures++; 24736549Sbostic /* we allow 10 tries, but after 3 we start backing off */ 24836549Sbostic if (++cnt > 3) { 24936549Sbostic if (cnt >= 10) { 25036549Sbostic badlogin(username); 25136549Sbostic (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL); 25236549Sbostic sleepexit(1); 25336549Sbostic } 25436549Sbostic sleep((u_int)((cnt - 3) * 5)); 2552822Swnj } 25636460Sbostic } 2571043Sbill 25836460Sbostic /* committed to login -- turn off timeout */ 25936460Sbostic (void)alarm((u_int)0); 26036460Sbostic 26137692Sbostic /* paranoia... */ 26237692Sbostic endpwent(); 26337692Sbostic 26443663Sbostic /* if user not super-user, check for disabled logins */ 26543663Sbostic if (pwd->pw_uid) 26643663Sbostic checknologin(); 26743663Sbostic 26836515Sbostic if (chdir(pwd->pw_dir) < 0) { 26937203Sbostic (void)printf("No directory %s!\n", pwd->pw_dir); 27036515Sbostic if (chdir("/")) 27136515Sbostic exit(0); 27236515Sbostic pwd->pw_dir = "/"; 27337203Sbostic (void)printf("Logging in with home = \"/\".\n"); 27436515Sbostic } 27536515Sbostic 27637203Sbostic quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; 27737203Sbostic 27836880Sbostic if (pwd->pw_change || pwd->pw_expire) 27936880Sbostic (void)gettimeofday(&tp, (struct timezone *)NULL); 28036880Sbostic if (pwd->pw_change) 28136880Sbostic if (tp.tv_sec >= pwd->pw_change) { 28237203Sbostic (void)printf("Sorry -- your password has expired.\n"); 28336880Sbostic sleepexit(1); 28436880Sbostic } 28538216Sbostic else if (pwd->pw_change - tp.tv_sec < 28643660Sbostic 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) 28743660Sbostic (void)printf("Warning: your password expires on %s", 28843660Sbostic ctime(&pwd->pw_expire)); 28936880Sbostic if (pwd->pw_expire) 29036880Sbostic if (tp.tv_sec >= pwd->pw_expire) { 29137203Sbostic (void)printf("Sorry -- your account has expired.\n"); 29236880Sbostic sleepexit(1); 29336880Sbostic } 29438216Sbostic else if (pwd->pw_expire - tp.tv_sec < 29543660Sbostic 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) 29643660Sbostic (void)printf("Warning: your account expires on %s", 29743660Sbostic ctime(&pwd->pw_expire)); 29836880Sbostic 29936515Sbostic /* nothing else left to fail -- really log in */ 30036460Sbostic { 30136460Sbostic struct utmp utmp; 30236460Sbostic 30343653Sbostic bzero((void *)&utmp, sizeof(utmp)); 30436460Sbostic (void)time(&utmp.ut_time); 30536460Sbostic strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); 30636591Sbostic if (hostname) 30736591Sbostic strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); 30836460Sbostic strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); 30936460Sbostic login(&utmp); 31036460Sbostic } 31136460Sbostic 31236549Sbostic dolastlog(quietlog); 31336460Sbostic 31437203Sbostic if (!hflag) { /* XXX */ 31536460Sbostic static struct winsize win = { 0, 0, 0, 0 }; 31636460Sbostic 31736460Sbostic (void)ioctl(0, TIOCSWINSZ, &win); 31836460Sbostic } 31936460Sbostic 32036460Sbostic (void)chown(ttyn, pwd->pw_uid, 32136460Sbostic (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); 32236460Sbostic (void)chmod(ttyn, 0620); 32336460Sbostic (void)setgid(pwd->pw_gid); 32436460Sbostic 32536460Sbostic initgroups(username, pwd->pw_gid); 32636460Sbostic 32736515Sbostic if (*pwd->pw_shell == '\0') 32837203Sbostic pwd->pw_shell = _PATH_BSHELL; 32936515Sbostic 33036460Sbostic /* destroy environment unless user has requested preservation */ 33118549Ssam if (!pflag) 33218549Ssam environ = envinit; 33336515Sbostic (void)setenv("HOME", pwd->pw_dir, 1); 33436515Sbostic (void)setenv("SHELL", pwd->pw_shell, 1); 33518549Ssam if (term[0] == '\0') 33636647Skarels strncpy(term, stypeof(tty), sizeof(term)); 33736515Sbostic (void)setenv("TERM", term, 0); 33836515Sbostic (void)setenv("USER", pwd->pw_name, 1); 33937252Sbostic (void)setenv("PATH", _PATH_DEFPATH, 0); 34018549Ssam 34116453Sroot if (tty[sizeof("tty")-1] == 'd') 34218549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 34318549Ssam if (pwd->pw_uid == 0) 34436460Sbostic if (hostname) 34536647Skarels syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s", 34636549Sbostic tty, hostname); 34725230Smckusick else 34836647Skarels syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty); 34936460Sbostic 35043653Sbostic #ifdef KERBEROS 35143653Sbostic if (!quietlog && notickets == 1) 35243653Sbostic (void)printf("Warning: no Kerberos tickets issued.\n"); 35343653Sbostic #endif 35443653Sbostic 3556329Swnj if (!quietlog) { 35617664Sserge struct stat st; 35718549Ssam 35836460Sbostic motd(); 35937203Sbostic (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name); 36036460Sbostic if (stat(tbuf, &st) == 0 && st.st_size != 0) 36137203Sbostic (void)printf("You have %smail.\n", 36236460Sbostic (st.st_mtime > st.st_atime) ? "new " : ""); 3632822Swnj } 36436460Sbostic 36536460Sbostic (void)signal(SIGALRM, SIG_DFL); 36636460Sbostic (void)signal(SIGQUIT, SIG_DFL); 36736460Sbostic (void)signal(SIGINT, SIG_DFL); 36836460Sbostic (void)signal(SIGTSTP, SIG_IGN); 36936460Sbostic 37036460Sbostic tbuf[0] = '-'; 37136460Sbostic strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ? 37236460Sbostic p + 1 : pwd->pw_shell); 37337203Sbostic 37440009Ssklower if (setlogin(pwd->pw_name) < 0) 37540009Ssklower syslog(LOG_ERR, "setlogin() failure: %m"); 37637692Sbostic 37737203Sbostic /* discard permissions last so can't get killed and drop core */ 37837203Sbostic (void)setuid(pwd->pw_uid); 37937203Sbostic 38036460Sbostic execlp(pwd->pw_shell, tbuf, 0); 38137203Sbostic (void)fprintf(stderr, "login: no shell: %s.\n", strerror(errno)); 3821043Sbill exit(0); 3831043Sbill } 3841043Sbill 38536460Sbostic getloginname() 38612687Ssam { 38736460Sbostic register int ch; 38836460Sbostic register char *p; 38936460Sbostic static char nbuf[UT_NAMESIZE + 1]; 39012687Ssam 39136460Sbostic for (;;) { 39237203Sbostic (void)printf("login: "); 39336515Sbostic for (p = nbuf; (ch = getchar()) != '\n'; ) { 39436549Sbostic if (ch == EOF) { 39536549Sbostic badlogin(username); 39612687Ssam exit(0); 39736549Sbostic } 39836515Sbostic if (p < nbuf + UT_NAMESIZE) 39936460Sbostic *p++ = ch; 40012687Ssam } 40136460Sbostic if (p > nbuf) 40236460Sbostic if (nbuf[0] == '-') 40337203Sbostic (void)fprintf(stderr, 40436460Sbostic "login names may not start with '-'.\n"); 40536460Sbostic else { 40636460Sbostic *p = '\0'; 40736460Sbostic username = nbuf; 40836515Sbostic break; 40936460Sbostic } 41012687Ssam } 41112687Ssam } 41212687Ssam 41343653Sbostic void 41412687Ssam timedout() 41512687Ssam { 41637203Sbostic (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout); 41712687Ssam exit(0); 41812687Ssam } 41912687Ssam 42036647Skarels rootterm(ttyn) 42136647Skarels char *ttyn; 4221043Sbill { 42336460Sbostic struct ttyent *t; 4246466Swnj 42536647Skarels return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE); 4261043Sbill } 4271043Sbill 42836515Sbostic jmp_buf motdinterrupt; 42936515Sbostic 43036460Sbostic motd() 4312822Swnj { 43236515Sbostic register int fd, nchars; 43338726Skfall sig_t oldint; 43438726Skfall int sigint(); 43536515Sbostic char tbuf[8192]; 4362822Swnj 43737203Sbostic if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0) 43836460Sbostic return; 43936460Sbostic oldint = signal(SIGINT, sigint); 44036515Sbostic if (setjmp(motdinterrupt) == 0) 44136515Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 44236515Sbostic (void)write(fileno(stdout), tbuf, nchars); 44336460Sbostic (void)signal(SIGINT, oldint); 44436515Sbostic (void)close(fd); 44536460Sbostic } 44636460Sbostic 44736460Sbostic sigint() 44836460Sbostic { 44936515Sbostic longjmp(motdinterrupt, 1); 45036460Sbostic } 45136460Sbostic 45236460Sbostic checknologin() 45336460Sbostic { 45436460Sbostic register int fd, nchars; 45536515Sbostic char tbuf[8192]; 45636460Sbostic 45737203Sbostic if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) { 45836460Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 45936460Sbostic (void)write(fileno(stdout), tbuf, nchars); 46036460Sbostic sleepexit(0); 4612822Swnj } 4622822Swnj } 4632822Swnj 46436549Sbostic dolastlog(quiet) 46536460Sbostic int quiet; 4661043Sbill { 46736460Sbostic struct lastlog ll; 46836460Sbostic int fd; 46936880Sbostic char *ctime(); 4701043Sbill 47137203Sbostic if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { 47236515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 47336460Sbostic if (!quiet) { 47436460Sbostic if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && 47536460Sbostic ll.ll_time != 0) { 47637203Sbostic (void)printf("Last login: %.*s ", 47736460Sbostic 24-5, (char *)ctime(&ll.ll_time)); 47836460Sbostic if (*ll.ll_host != '\0') 47937203Sbostic (void)printf("from %.*s\n", 48036460Sbostic sizeof(ll.ll_host), ll.ll_host); 48136460Sbostic else 48237203Sbostic (void)printf("on %.*s\n", 48336460Sbostic sizeof(ll.ll_line), ll.ll_line); 48436460Sbostic } 48536515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 48636460Sbostic } 48743653Sbostic bzero((void *)&ll, sizeof(ll)); 48836460Sbostic (void)time(&ll.ll_time); 48936460Sbostic strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 49036591Sbostic if (hostname) 49136591Sbostic strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); 49236460Sbostic (void)write(fd, (char *)&ll, sizeof(ll)); 49336460Sbostic (void)close(fd); 4941043Sbill } 4951043Sbill } 4961043Sbill 49736549Sbostic badlogin(name) 49836549Sbostic char *name; 49936549Sbostic { 50036647Skarels if (failures == 0) 50136549Sbostic return; 50236549Sbostic if (hostname) 50336647Skarels syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s", 50436647Skarels failures, failures > 1 ? "S" : "", hostname, name); 50536549Sbostic else 50636647Skarels syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s", 50736647Skarels failures, failures > 1 ? "S" : "", tty, name); 50836549Sbostic } 50936549Sbostic 5102822Swnj #undef UNKNOWN 51136460Sbostic #define UNKNOWN "su" 5121043Sbill 5131043Sbill char * 51436647Skarels stypeof(ttyid) 51536647Skarels char *ttyid; 5161043Sbill { 51736460Sbostic struct ttyent *t; 5181043Sbill 51936647Skarels return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); 5201043Sbill } 5216005Swnj 52236460Sbostic sleepexit(eval) 52336460Sbostic int eval; 52426862Smckusick { 52536460Sbostic sleep((u_int)5); 52636460Sbostic exit(eval); 52726862Smckusick } 528