119843Sdist /* 236515Sbostic * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. 336515Sbostic * All rights reserved. 436515Sbostic * 536515Sbostic * Redistribution and use in source and binary forms are permitted 636515Sbostic * provided that the above copyright notice and this paragraph are 736515Sbostic * duplicated in all such forms and that any documentation, 836515Sbostic * advertising materials, and other materials related to such 936515Sbostic * distribution and use acknowledge that the software was developed 1036515Sbostic * by the University of California, Berkeley. The name of the 1136515Sbostic * University may not be used to endorse or promote products derived 1236515Sbostic * from this software without specific prior written permission. 1336515Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1436515Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1536515Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1619843Sdist */ 1719843Sdist 1812678Ssam #ifndef lint 1919843Sdist char copyright[] = 2036515Sbostic "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\ 2119843Sdist All rights reserved.\n"; 2236515Sbostic #endif /* not lint */ 2312678Ssam 2419843Sdist #ifndef lint 25*36549Sbostic static char sccsid[] = "@(#)login.c 5.27 (Berkeley) 01/15/89"; 2636515Sbostic #endif /* not lint */ 2719843Sdist 281043Sbill /* 291043Sbill * login [ name ] 3031695Skarels * login -h hostname (for telnetd, etc.) 3131695Skarels * login -f name (for pre-authenticated login: datakit, xterm, etc.) 321043Sbill */ 331043Sbill 3412984Ssam #include <sys/param.h> 3512687Ssam #include <sys/quota.h> 3612687Ssam #include <sys/stat.h> 3712687Ssam #include <sys/time.h> 3812687Ssam #include <sys/resource.h> 3916453Sroot #include <sys/file.h> 4036460Sbostic #include <sys/ioctl.h> 4112687Ssam 421043Sbill #include <utmp.h> 431043Sbill #include <signal.h> 441043Sbill #include <lastlog.h> 4512678Ssam #include <errno.h> 4616453Sroot #include <ttyent.h> 4716453Sroot #include <syslog.h> 4826862Smckusick #include <grp.h> 4936460Sbostic #include <pwd.h> 5036515Sbostic #include <setjmp.h> 5136460Sbostic #include <stdio.h> 5236460Sbostic #include <strings.h> 531043Sbill 5436460Sbostic #define TTYGRPNAME "tty" /* name of group to own ttys */ 5526862Smckusick 5636460Sbostic #define MOTDFILE "/etc/motd" 5736460Sbostic #define MAILDIR "/usr/spool/mail" 5836460Sbostic #define NOLOGIN "/etc/nologin" 5936460Sbostic #define HUSHLOGIN ".hushlogin" 6036460Sbostic #define LASTLOG "/usr/adm/lastlog" 6136460Sbostic #define BSHELL "/bin/sh" 622822Swnj 6312687Ssam /* 6436460Sbostic * This bounds the time given to login. Not a define so it can 6536460Sbostic * be patched on machines where it's too small. 6612687Ssam */ 6731509Sbostic int timeout = 300; 686005Swnj 6936460Sbostic struct passwd *pwd; 70*36549Sbostic int repeatcnt; 71*36549Sbostic char term[64], *hostname, *username, *tty; 726005Swnj 7336515Sbostic struct sgttyb sgttyb; 7436460Sbostic struct tchars tc = { 7513074Ssam CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 761365Sbill }; 7736460Sbostic struct ltchars ltc = { 7813074Ssam CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT 7913074Ssam }; 801365Sbill 811043Sbill main(argc, argv) 8236460Sbostic int argc; 8336460Sbostic char **argv; 841043Sbill { 8536460Sbostic extern int errno, optind; 8636460Sbostic extern char *optarg, **environ; 8736460Sbostic struct group *gr; 8836460Sbostic register int ch; 8936460Sbostic register char *p; 90*36549Sbostic int ask, fflag, hflag, pflag, cnt; 9136460Sbostic int quietlog, passwd_req, ioctlval, timedout(); 92*36549Sbostic char *domain, *salt, *envinit[1], *ttyn; 9336460Sbostic char tbuf[MAXPATHLEN + 2]; 9436460Sbostic char *ttyname(), *stypeof(), *crypt(), *getpass(); 9536460Sbostic time_t time(); 9636460Sbostic off_t lseek(); 971043Sbill 9836460Sbostic (void)signal(SIGALRM, timedout); 9936460Sbostic (void)alarm((u_int)timeout); 10036460Sbostic (void)signal(SIGQUIT, SIG_IGN); 10136460Sbostic (void)signal(SIGINT, SIG_IGN); 10236460Sbostic (void)setpriority(PRIO_PROCESS, 0, 0); 10336460Sbostic (void)quota(Q_SETUID, 0, 0, 0); 10436460Sbostic 10512687Ssam /* 10618549Ssam * -p is used by getty to tell login not to destroy the environment 10731695Skarels * -f is used to skip a second login authentication 10836523Skarels * -h is used by other servers to pass the name of the remote 10936523Skarels * host to login so that it may be placed in utmp and wtmp 11012687Ssam */ 11136460Sbostic (void)gethostname(tbuf, sizeof(tbuf)); 11236460Sbostic domain = index(tbuf, '.'); 11336460Sbostic 11436523Skarels fflag = hflag = pflag = 0; 11536460Sbostic passwd_req = 1; 11636523Skarels while ((ch = getopt(argc, argv, "fh:p")) != EOF) 11736515Sbostic switch (ch) { 11836460Sbostic case 'f': 11936460Sbostic fflag = 1; 12036460Sbostic break; 12136460Sbostic case 'h': 12236460Sbostic if (getuid()) { 12336460Sbostic fprintf(stderr, 12436460Sbostic "login: -h for super-user only.\n"); 12532313Sbostic exit(1); 12631695Skarels } 12736460Sbostic hflag = 1; 12836460Sbostic if (domain && (p = index(optarg, '.')) && 12936460Sbostic strcmp(p, domain) == 0) 13036460Sbostic *p = 0; 13136460Sbostic hostname = optarg; 13236460Sbostic break; 13336460Sbostic case 'p': 13418549Ssam pflag = 1; 13536460Sbostic break; 13636460Sbostic case '?': 13736460Sbostic default: 13836515Sbostic fprintf(stderr, "usage: login [-fp] [username]\n"); 13936460Sbostic exit(1); 14018549Ssam } 14136460Sbostic argc -= optind; 14236460Sbostic argv += optind; 143*36549Sbostic if (*argv) { 144*36549Sbostic ask = 0; 14536460Sbostic username = *argv; 146*36549Sbostic } 147*36549Sbostic else 148*36549Sbostic ask = 1; 14936460Sbostic 15036460Sbostic ioctlval = 0; 15136460Sbostic (void)ioctl(0, TIOCLSET, &ioctlval); 15236460Sbostic (void)ioctl(0, TIOCNXCL, 0); 15336515Sbostic (void)fcntl(0, F_SETFL, ioctlval); 15436515Sbostic (void)ioctl(0, TIOCGETP, &sgttyb); 15536515Sbostic sgttyb.sg_erase = CERASE; 15636515Sbostic sgttyb.sg_kill = CKILL; 15736460Sbostic (void)ioctl(0, TIOCSLTC, <c); 15836460Sbostic (void)ioctl(0, TIOCSETC, &tc); 15936515Sbostic (void)ioctl(0, TIOCSETP, &sgttyb); 16036460Sbostic 16136460Sbostic for (cnt = getdtablesize(); cnt > 2; cnt--) 16236460Sbostic close(cnt); 16336460Sbostic 1641043Sbill ttyn = ttyname(0); 16536460Sbostic if (ttyn == NULL || *ttyn == '\0') 1661043Sbill ttyn = "/dev/tty??"; 16736460Sbostic if (tty = rindex(ttyn, '/')) 16836460Sbostic ++tty; 16936460Sbostic else 17016453Sroot tty = ttyn; 17136460Sbostic 17224852Seric openlog("login", LOG_ODELAY, LOG_AUTH); 17336460Sbostic 174*36549Sbostic for (cnt = 0;; ask = 1) { 17536460Sbostic ioctlval = 0; 17636460Sbostic (void)ioctl(0, TIOCSETD, &ioctlval); 17736460Sbostic 178*36549Sbostic if (ask) { 17936515Sbostic fflag = 0; 18036460Sbostic getloginname(); 18136515Sbostic } 182*36549Sbostic /* note if trying multiple login's */ 183*36549Sbostic if (repeatcnt) { 184*36549Sbostic if (strcmp(tbuf, username)) { 185*36549Sbostic badlogin(tbuf); 186*36549Sbostic repeatcnt = 1; 187*36549Sbostic (void)strcpy(tbuf, username); 188*36549Sbostic } 189*36549Sbostic else 190*36549Sbostic ++repeatcnt; 191*36549Sbostic } 192*36549Sbostic else { 193*36549Sbostic repeatcnt = 1; 194*36549Sbostic (void)strcpy(tbuf, username); 195*36549Sbostic } 19636515Sbostic if (pwd = getpwnam(username)) 19736515Sbostic salt = pwd->pw_passwd; 19836515Sbostic else 19936515Sbostic salt = "xx"; 20036460Sbostic 20136460Sbostic /* if user not super-user, check for disabled logins */ 20236515Sbostic if (pwd == NULL || pwd->pw_uid) 20336460Sbostic checknologin(); 20436460Sbostic 20512687Ssam /* 20636515Sbostic * Disallow automatic login to root; if not invoked by 20736515Sbostic * root, disallow if the uid's differ. 20812687Ssam */ 20936515Sbostic if (fflag && pwd) { 21031695Skarels int uid = getuid(); 21131695Skarels 21236515Sbostic passwd_req = pwd->pw_uid == 0 || 21336515Sbostic (uid && uid != pwd->pw_uid); 21431695Skarels } 21536460Sbostic 21612687Ssam /* 21736523Skarels * If no pre-authentication and a password exists 21836460Sbostic * for this user, prompt for one and verify it. 21912687Ssam */ 22036515Sbostic if (!passwd_req || pwd && !*pwd->pw_passwd) 22136460Sbostic break; 22212687Ssam 22336460Sbostic setpriority(PRIO_PROCESS, 0, -4); 22436515Sbostic p = crypt(getpass("Password:"), salt); 22536460Sbostic setpriority(PRIO_PROCESS, 0, 0); 22636515Sbostic if (pwd && !strcmp(p, pwd->pw_passwd)) 22736460Sbostic break; 22836460Sbostic 22936460Sbostic printf("Login incorrect\n"); 230*36549Sbostic /* we allow 10 tries, but after 3 we start backing off */ 231*36549Sbostic if (++cnt > 3) { 232*36549Sbostic if (cnt >= 10) { 233*36549Sbostic badlogin(username); 234*36549Sbostic (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL); 235*36549Sbostic sleepexit(1); 236*36549Sbostic } 237*36549Sbostic sleep((u_int)((cnt - 3) * 5)); 2382822Swnj } 23936460Sbostic } 2401043Sbill 24136460Sbostic /* committed to login -- turn off timeout */ 24236460Sbostic (void)alarm((u_int)0); 24336460Sbostic 244*36549Sbostic /* log any mistakes -- don't count last one */ 245*36549Sbostic --repeatcnt; 246*36549Sbostic badlogin(username); 247*36549Sbostic 24836460Sbostic /* 24936460Sbostic * If valid so far and root is logging in, see if root logins on 25036460Sbostic * this terminal are permitted. 25136460Sbostic */ 252*36549Sbostic if (pwd->pw_uid == 0 && !rootterm()) { 25336460Sbostic if (hostname) 254*36549Sbostic syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s", 255*36549Sbostic tty, hostname); 25612678Ssam else 25736515Sbostic syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty); 25836460Sbostic printf("Login incorrect\n"); 25936460Sbostic sleepexit(1); 26012678Ssam } 2612822Swnj 26236460Sbostic if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { 26336460Sbostic switch(errno) { 26436460Sbostic case EUSERS: 26536460Sbostic fprintf(stderr, 26636460Sbostic "Too many users logged on already.\nTry again later.\n"); 26736460Sbostic break; 26836460Sbostic case EPROCLIM: 26936460Sbostic fprintf(stderr, 27036460Sbostic "You have too many processes running.\n"); 27136460Sbostic break; 27236460Sbostic default: 27336460Sbostic perror("quota (Q_SETUID)"); 2742822Swnj } 27536460Sbostic sleepexit(0); 2762822Swnj } 27736460Sbostic 27836515Sbostic if (chdir(pwd->pw_dir) < 0) { 27936515Sbostic printf("No directory %s!\n", pwd->pw_dir); 28036515Sbostic if (chdir("/")) 28136515Sbostic exit(0); 28236515Sbostic pwd->pw_dir = "/"; 28336515Sbostic printf("Logging in with home = \"/\".\n"); 28436515Sbostic } 28536515Sbostic 28636515Sbostic /* nothing else left to fail -- really log in */ 28736460Sbostic { 28836460Sbostic struct utmp utmp; 28936460Sbostic 29036460Sbostic (void)time(&utmp.ut_time); 29136460Sbostic strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); 29236460Sbostic strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); 29336460Sbostic strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); 29436460Sbostic login(&utmp); 29536460Sbostic } 29636460Sbostic 29736460Sbostic quietlog = access(HUSHLOGIN, F_OK) == 0; 298*36549Sbostic dolastlog(quietlog); 29936460Sbostic 30036523Skarels if (!hflag) { /* XXX */ 30136460Sbostic static struct winsize win = { 0, 0, 0, 0 }; 30236460Sbostic 30336460Sbostic (void)ioctl(0, TIOCSWINSZ, &win); 30436460Sbostic } 30536460Sbostic 30636460Sbostic (void)chown(ttyn, pwd->pw_uid, 30736460Sbostic (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); 30836460Sbostic (void)chmod(ttyn, 0620); 30936460Sbostic (void)setgid(pwd->pw_gid); 31036460Sbostic 31136460Sbostic initgroups(username, pwd->pw_gid); 31236460Sbostic 31312678Ssam quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); 31436460Sbostic (void)setuid(pwd->pw_uid); 31530606Sbostic 31636515Sbostic if (*pwd->pw_shell == '\0') 31736515Sbostic pwd->pw_shell = BSHELL; 31836515Sbostic /* turn on new line discipline for the csh */ 31936515Sbostic else if (!strcmp(pwd->pw_shell, "/bin/csh")) { 32036515Sbostic ioctlval = NTTYDISC; 32136515Sbostic (void)ioctl(0, TIOCSETD, &ioctlval); 32236515Sbostic } 32336515Sbostic 32436460Sbostic /* destroy environment unless user has requested preservation */ 32518549Ssam if (!pflag) 32618549Ssam environ = envinit; 32736515Sbostic (void)setenv("HOME", pwd->pw_dir, 1); 32836515Sbostic (void)setenv("SHELL", pwd->pw_shell, 1); 32918549Ssam if (term[0] == '\0') 330*36549Sbostic strncpy(term, stypeof(), sizeof(term)); 33136515Sbostic (void)setenv("TERM", term, 0); 33236515Sbostic (void)setenv("USER", pwd->pw_name, 1); 33336515Sbostic (void)setenv("PATH", "/usr/ucb:/bin:/usr/bin:", 0); 33418549Ssam 33516453Sroot if (tty[sizeof("tty")-1] == 'd') 33618549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 33718549Ssam if (pwd->pw_uid == 0) 33836460Sbostic if (hostname) 339*36549Sbostic syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s", 340*36549Sbostic tty, hostname); 34125230Smckusick else 34225230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); 34336460Sbostic 3446329Swnj if (!quietlog) { 34517664Sserge struct stat st; 34618549Ssam 34736460Sbostic motd(); 34836460Sbostic (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name); 34936460Sbostic if (stat(tbuf, &st) == 0 && st.st_size != 0) 35017664Sserge printf("You have %smail.\n", 35136460Sbostic (st.st_mtime > st.st_atime) ? "new " : ""); 3522822Swnj } 35336460Sbostic 35436460Sbostic (void)signal(SIGALRM, SIG_DFL); 35536460Sbostic (void)signal(SIGQUIT, SIG_DFL); 35636460Sbostic (void)signal(SIGINT, SIG_DFL); 35736460Sbostic (void)signal(SIGTSTP, SIG_IGN); 35836460Sbostic 35936460Sbostic tbuf[0] = '-'; 36036460Sbostic strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ? 36136460Sbostic p + 1 : pwd->pw_shell); 36236460Sbostic execlp(pwd->pw_shell, tbuf, 0); 36336515Sbostic fprintf(stderr, "login: no shell: "); 3642822Swnj perror(pwd->pw_shell); 3651043Sbill exit(0); 3661043Sbill } 3671043Sbill 36836460Sbostic getloginname() 36912687Ssam { 37036460Sbostic register int ch; 37136460Sbostic register char *p; 37236460Sbostic static char nbuf[UT_NAMESIZE + 1]; 37312687Ssam 37436460Sbostic for (;;) { 37512712Ssam printf("login: "); 37636515Sbostic for (p = nbuf; (ch = getchar()) != '\n'; ) { 377*36549Sbostic if (ch == EOF) { 378*36549Sbostic badlogin(username); 37912687Ssam exit(0); 380*36549Sbostic } 38136515Sbostic if (p < nbuf + UT_NAMESIZE) 38236460Sbostic *p++ = ch; 38312687Ssam } 38436460Sbostic if (p > nbuf) 38536460Sbostic if (nbuf[0] == '-') 38636460Sbostic fprintf(stderr, 38736460Sbostic "login names may not start with '-'.\n"); 38836460Sbostic else { 38936460Sbostic *p = '\0'; 39036460Sbostic username = nbuf; 39136515Sbostic break; 39236460Sbostic } 39312687Ssam } 39412687Ssam } 39512687Ssam 39612687Ssam timedout() 39712687Ssam { 39836460Sbostic fprintf(stderr, "Login timed out after %d seconds\n", timeout); 39912687Ssam exit(0); 40012687Ssam } 40112687Ssam 402*36549Sbostic rootterm() 4031043Sbill { 40436460Sbostic struct ttyent *t; 4056466Swnj 40636460Sbostic return((t = getttynam(tty)) && t->ty_status&TTY_SECURE); 4071043Sbill } 4081043Sbill 40936515Sbostic jmp_buf motdinterrupt; 41036515Sbostic 41136460Sbostic motd() 4122822Swnj { 41336515Sbostic register int fd, nchars; 41436460Sbostic int (*oldint)(), sigint(); 41536515Sbostic char tbuf[8192]; 4162822Swnj 41736515Sbostic if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0) 41836460Sbostic return; 41936460Sbostic oldint = signal(SIGINT, sigint); 42036515Sbostic if (setjmp(motdinterrupt) == 0) 42136515Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 42236515Sbostic (void)write(fileno(stdout), tbuf, nchars); 42336460Sbostic (void)signal(SIGINT, oldint); 42436515Sbostic (void)close(fd); 42536460Sbostic } 42636460Sbostic 42736460Sbostic sigint() 42836460Sbostic { 42936515Sbostic longjmp(motdinterrupt, 1); 43036460Sbostic } 43136460Sbostic 43236460Sbostic checknologin() 43336460Sbostic { 43436460Sbostic register int fd, nchars; 43536515Sbostic char tbuf[8192]; 43636460Sbostic 43736460Sbostic if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) { 43836460Sbostic while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0) 43936460Sbostic (void)write(fileno(stdout), tbuf, nchars); 44036460Sbostic sleepexit(0); 4412822Swnj } 4422822Swnj } 4432822Swnj 444*36549Sbostic dolastlog(quiet) 44536460Sbostic int quiet; 4461043Sbill { 44736460Sbostic struct lastlog ll; 44836460Sbostic int fd; 4491043Sbill 45036460Sbostic if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) { 45136515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 45236460Sbostic if (!quiet) { 45336460Sbostic if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) && 45436460Sbostic ll.ll_time != 0) { 45536460Sbostic printf("Last login: %.*s ", 45636460Sbostic 24-5, (char *)ctime(&ll.ll_time)); 45736460Sbostic if (*ll.ll_host != '\0') 45836460Sbostic printf("from %.*s\n", 45936460Sbostic sizeof(ll.ll_host), ll.ll_host); 46036460Sbostic else 46136460Sbostic printf("on %.*s\n", 46236460Sbostic sizeof(ll.ll_line), ll.ll_line); 46336460Sbostic } 46436515Sbostic (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); 46536460Sbostic } 46636460Sbostic (void)time(&ll.ll_time); 46736460Sbostic strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); 46836460Sbostic strncpy(ll.ll_host, hostname, sizeof(ll.ll_host)); 46936460Sbostic (void)write(fd, (char *)&ll, sizeof(ll)); 47036460Sbostic (void)close(fd); 4711043Sbill } 4721043Sbill } 4731043Sbill 474*36549Sbostic badlogin(name) 475*36549Sbostic char *name; 476*36549Sbostic { 477*36549Sbostic if (!repeatcnt) 478*36549Sbostic return; 479*36549Sbostic if (hostname) 480*36549Sbostic syslog(LOG_ERR, "%d LOGIN FAILURE%s ON %s FROM %s, %s", 481*36549Sbostic repeatcnt, repeatcnt > 1 ? "S" : "", tty, hostname, name); 482*36549Sbostic else 483*36549Sbostic syslog(LOG_ERR, "%d LOGIN FAILURE%s ON %s, %s", 484*36549Sbostic repeatcnt, repeatcnt > 1 ? "S" : "", tty, name); 485*36549Sbostic } 486*36549Sbostic 4872822Swnj #undef UNKNOWN 48836460Sbostic #define UNKNOWN "su" 4891043Sbill 4901043Sbill char * 491*36549Sbostic stypeof() 4921043Sbill { 49336460Sbostic struct ttyent *t; 4941043Sbill 495*36549Sbostic return(tty && (t = getttynam(tty)) ? t->ty_type : UNKNOWN); 4961043Sbill } 4976005Swnj 4986005Swnj getstr(buf, cnt, err) 49936460Sbostic char *buf, *err; 5006005Swnj int cnt; 5016005Swnj { 50236460Sbostic char ch; 5036005Swnj 5046005Swnj do { 50536460Sbostic if (read(0, &ch, sizeof(ch)) != sizeof(ch)) 5066005Swnj exit(1); 5076005Swnj if (--cnt < 0) { 50836460Sbostic fprintf(stderr, "%s too long\r\n", err); 50936460Sbostic sleepexit(1); 5106005Swnj } 51136460Sbostic *buf++ = ch; 51236460Sbostic } while (ch); 5136005Swnj } 5146329Swnj 51536460Sbostic sleepexit(eval) 51636460Sbostic int eval; 51726862Smckusick { 51836460Sbostic sleep((u_int)5); 51936460Sbostic exit(eval); 52026862Smckusick } 521