X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/2d4a74b8fa50e18eb5549b9deebf259ed6d1c425..f5576df6fd6c54ac0836b6cc9634f63a156f325a:/usr/src/usr.bin/login/login.c diff --git a/usr/src/usr.bin/login/login.c b/usr/src/usr.bin/login/login.c index 85f77c0597..e0955381ec 100644 --- a/usr/src/usr.bin/login/login.c +++ b/usr/src/usr.bin/login/login.c @@ -1,44 +1,57 @@ -/* - * Copyright (c) 1980, 1987, 1988 The Regents of the University of California. - * All rights reserved. +/*- + * Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University + * of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #ifndef lint char copyright[] = -"@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\ +"@(#) Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University of California.\n\ All rights reserved.\n"; #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)login.c 5.48 (Berkeley) %G%"; +static char sccsid[] = "@(#)login.c 5.73 (Berkeley) 6/29/91"; #endif /* not lint */ /* * login [ name ] - * login -r hostname (for rlogind) * login -h hostname (for telnetd, etc.) * login -f name (for pre-authenticated login: datakit, xterm, etc.) */ #include -#include #include #include #include #include -#include #include #include @@ -49,7 +62,7 @@ static char sccsid[] = "@(#)login.c 5.48 (Berkeley) %G%"; #include #include #include -#include +#include #include #include "pathnames.h" @@ -60,59 +73,48 @@ static char sccsid[] = "@(#)login.c 5.48 (Berkeley) %G%"; * be patched on machines where it's too small. */ int timeout = 300; +int rootlogin; +#ifdef KERBEROS +int notickets = 1; +char *instance; +char *krbtkfile_env; +int authok; +#endif struct passwd *pwd; int failures; -char term[64], *hostname, *username, *tty; - -struct sgttyb sgttyb; -struct tchars tc = { - CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK -}; -struct ltchars ltc = { - CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT -}; - -char *months[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec" }; - -char *months[] = - { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", - "Sep", "Oct", "Nov", "Dec" }; +char term[64], *envinit[1], *hostname, *username, *tty; main(argc, argv) int argc; char **argv; { - extern int errno, optind; + extern int optind; extern char *optarg, **environ; struct timeval tp; - struct tm *ttp; - struct timeval tp; - struct tm *ttp; struct group *gr; register int ch; register char *p; - int ask, fflag, hflag, pflag, rflag, cnt; - int quietlog, passwd_req, ioctlval, timedout(); - char *domain, *salt, *envinit[1], *ttyn, *pp; + int ask, fflag, hflag, pflag, cnt, uid; + int quietlog, rval; + char *domain, *salt, *ttyn; char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; char localhost[MAXHOSTNAMELEN]; char *ctime(), *ttyname(), *stypeof(), *crypt(), *getpass(); time_t time(); off_t lseek(); + void timedout(); (void)signal(SIGALRM, timedout); (void)alarm((u_int)timeout); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)setpriority(PRIO_PROCESS, 0, 0); - (void)quota(Q_SETUID, 0, 0, 0); + + openlog("login", LOG_ODELAY, LOG_AUTH); /* * -p is used by getty to tell login not to destroy the environment - * -r is used by rlogind to cause the autologin protocol; * -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 @@ -123,30 +125,17 @@ main(argc, argv) else domain = index(localhost, '.'); - openlog("login", LOG_ODELAY, LOG_AUTH); - - fflag = hflag = pflag = rflag = 0; - passwd_req = 1; + fflag = hflag = pflag = 0; uid = getuid(); - while ((ch = getopt(argc, argv, "fh:pr:")) != EOF) + while ((ch = getopt(argc, argv, "fh:p")) != EOF) switch (ch) { case 'f': - if (rflag) { - fprintf(stderr, - "login: only one of -r and -f allowed.\n"); - exit(1); - } fflag = 1; break; case 'h': if (uid) { (void)fprintf(stderr, - "login: -h for super-user only.\n"); - exit(1); - } - if (rflag) { - fprintf(stderr, - "login: only one of -r and -h allowed.\n"); + "login: -h option: %s\n", strerror(EPERM)); exit(1); } hflag = 1; @@ -158,35 +147,12 @@ main(argc, argv) case 'p': pflag = 1; break; - case 'r': - if (hflag || fflag) { - fprintf(stderr, - "login: -f and -h not allowed with -r.\n"); - exit(1); - } - if (getuid()) { - fprintf(stderr, - "login: -r for super-user only.\n"); - exit(1); - } - /* "-r hostname" must be last args */ - if (optind != argc) { - fprintf(stderr, "Syntax error.\n"); - exit(1); - } - rflag = 1; - passwd_req = (doremotelogin(optarg) == -1); - if (domain && (p = index(optarg, '.')) && - !strcmp(p, domain)) - *p = '\0'; - hostname = optarg; - break; case '?': default: if (!uid) syslog(LOG_ERR, "invalid flag %c", ch); (void)fprintf(stderr, - "usage: login [-fp] [username]\n"); + "usage: login [-fp] [-h hostname] [username]\n"); exit(1); } argc -= optind; @@ -196,26 +162,6 @@ main(argc, argv) ask = 0; } else ask = 1; - if (rflag) - ask = 0; - - ioctlval = 0; - (void)ioctl(0, TIOCLSET, &ioctlval); - (void)ioctl(0, TIOCNXCL, 0); - (void)fcntl(0, F_SETFL, ioctlval); - (void)ioctl(0, TIOCGETP, &sgttyb); - - /* - * If talking to an rlogin process, propagate the terminal type and - * baud rate across the network. - */ - if (rflag) - doremoteterm(&sgttyb); - sgttyb.sg_erase = CERASE; - sgttyb.sg_kill = CKILL; - (void)ioctl(0, TIOCSLTC, <c); - (void)ioctl(0, TIOCSETC, &tc); - (void)ioctl(0, TIOCSETP, &sgttyb); for (cnt = getdtablesize(); cnt > 2; cnt--) close(cnt); @@ -231,13 +177,25 @@ main(argc, argv) tty = ttyn; for (cnt = 0;; ask = 1) { - ioctlval = TTYDISC; - (void)ioctl(0, TIOCSETD, &ioctlval); - if (ask) { fflag = 0; getloginname(); } +#ifdef KERBEROS + if ((instance = index(username, '.')) != NULL) { + if (strncmp(instance, ".root", 5) == 0) + rootlogin++; + *instance++ = '\0'; + } else { + rootlogin = 0; + instance = ""; + } +#else + rootlogin = 0; +#endif + if (strlen(username) > UT_NAMESIZE) + username[UT_NAMESIZE] = '\0'; + /* * Note if trying multiple user names; log failures for * previous user name, but don't bother logging one failure @@ -249,39 +207,61 @@ main(argc, argv) failures = 0; } (void)strcpy(tbuf, username); + if (pwd = getpwnam(username)) salt = pwd->pw_passwd; else salt = "xx"; - /* if user not super-user, check for disabled logins */ - if (pwd == NULL || pwd->pw_uid) - checknologin(); - /* - * Disallow automatic login to root; if not invoked by - * root, disallow if the uid's differ. + * if we have a valid account name, and it doesn't have a + * password, or the -f option was specified and the caller + * is root or the caller isn't changing their uid, don't + * authenticate. */ - if (fflag && pwd) { - passwd_req = -#ifndef KERBEROS - pwd->pw_uid == 0 || + if (pwd && (*pwd->pw_passwd == '\0' || + fflag && (uid == 0 || uid == pwd->pw_uid))) + break; + fflag = 0; + if (pwd && pwd->pw_uid == 0) + rootlogin = 1; + + (void)setpriority(PRIO_PROCESS, 0, -4); + + p = getpass("Password:"); + + if (pwd) { +#ifdef KERBEROS + rval = klogin(pwd, instance, localhost, p); + if (rval == 0) + authok = 1; + else if (rval == 1) { + if (pwd->pw_uid != 0) + rootlogin = 0; + rval = strcmp(crypt(p, salt), pwd->pw_passwd); + } +#else + if (pwd->pw_uid != 0) + rootlogin = 0; +#ifdef DES + rval = strcmp(crypt(p, salt), pwd->pw_passwd); +#else + rval = strcmp(p, pwd->pw_passwd); +#endif #endif - (uid && uid != pwd->pw_uid); } + bzero(p, strlen(p)); - /* - * If no pre-authentication and a password exists - * for this user, prompt for one and verify it. - */ - if (!passwd_req || (pwd && !*pwd->pw_passwd)) - break; + (void)setpriority(PRIO_PROCESS, 0, 0); /* - * If trying to log in as root, but with insecure terminal, - * refuse the login attempt. + * If trying to log in as root without Kerberos, + * but with insecure terminal, refuse the login attempt. */ - if (pwd->pw_uid == 0 && !rootterm(tty)) { +#ifdef KERBEROS + if (authok == 0) +#endif + if (pwd && rootlogin && !rootterm(tty)) { (void)fprintf(stderr, "%s login refused on this terminal.\n", pwd->pw_name); @@ -296,13 +276,7 @@ main(argc, argv) continue; } - setpriority(PRIO_PROCESS, 0, -4); - pp = getpass("Password:"); - p = crypt(pp, salt); - setpriority(PRIO_PROCESS, 0, 0); - - (void) bzero(pp, strlen(pp)); - if (pwd && !strcmp(p, pwd->pw_passwd)) + if (pwd && !rval) break; (void)printf("Login incorrect\n"); @@ -311,7 +285,6 @@ main(argc, argv) if (++cnt > 3) { if (cnt >= 10) { badlogin(username); - (void)ioctl(0, TIOCHPCL, (struct sgttyb *)NULL); sleepexit(1); } sleep((u_int)((cnt - 3) * 5)); @@ -321,56 +294,21 @@ main(argc, argv) /* committed to login -- turn off timeout */ (void)alarm((u_int)0); - /* paranoia... */ endpwent(); - if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { - switch(errno) { - case EUSERS: - (void)fprintf(stderr, - "Too many users logged on already.\nTry again later.\n"); - break; - case EPROCLIM: - (void)fprintf(stderr, - "You have too many processes running.\n"); - break; - default: - perror("quota (Q_SETUID)"); - } - sleepexit(0); - } + /* if user not super-user, check for disabled logins */ + if (!rootlogin) + checknologin(); if (chdir(pwd->pw_dir) < 0) { - (void)printf("No directory %s!\n", pwd->pw_dir); + (void)printf("No home directory %s!\n", pwd->pw_dir); if (chdir("/")) exit(0); pwd->pw_dir = "/"; (void)printf("Logging in with home = \"/\".\n"); } -#define TWOWEEKS (14*24*60*60) - if (pwd->pw_change || pwd->pw_expire) - (void)gettimeofday(&tp, (struct timezone *)NULL); - if (pwd->pw_change) - if (tp.tv_sec >= pwd->pw_change) { - printf("Sorry -- your password has expired.\n"); - sleepexit(1); - } - else if (tp.tv_sec - pwd->pw_change < TWOWEEKS) { - ttp = localtime(&pwd->pw_change); - printf("Warning: your password expires on %s %d, 19%d\n", - months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year); - } - if (pwd->pw_expire) - if (tp.tv_sec >= pwd->pw_expire) { - printf("Sorry -- your account has expired.\n"); - sleepexit(1); - } - else if (tp.tv_sec - pwd->pw_expire < TWOWEEKS) { - ttp = localtime(&pwd->pw_expire); - printf("Warning: your account expires on %s %d, 19%d\n", - months[ttp->tm_mon], ttp->tm_mday, ttp->tm_year); - } + quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0; if (pwd->pw_change || pwd->pw_expire) (void)gettimeofday(&tp, (struct timezone *)NULL); @@ -378,32 +316,24 @@ main(argc, argv) if (tp.tv_sec >= pwd->pw_change) { (void)printf("Sorry -- your password has expired.\n"); sleepexit(1); - } - else if (pwd->pw_change - tp.tv_sec < - 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) { - ttp = localtime(&pwd->pw_change); - (void)printf("Warning: your password expires on %s %d, %d\n", - months[ttp->tm_mon], ttp->tm_mday, - TM_YEAR_BASE + ttp->tm_year); - } + } else if (pwd->pw_change - tp.tv_sec < + 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) + (void)printf("Warning: your password expires on %s", + ctime(&pwd->pw_expire)); if (pwd->pw_expire) if (tp.tv_sec >= pwd->pw_expire) { (void)printf("Sorry -- your account has expired.\n"); sleepexit(1); - } - else if (pwd->pw_expire - tp.tv_sec < - 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) { - ttp = localtime(&pwd->pw_expire); - (void)printf("Warning: your account expires on %s %d, %d\n", - months[ttp->tm_mon], ttp->tm_mday, - TM_YEAR_BASE + ttp->tm_year); - } + } else if (pwd->pw_expire - tp.tv_sec < + 2 * DAYSPERWEEK * SECSPERDAY && !quietlog) + (void)printf("Warning: your account expires on %s", + ctime(&pwd->pw_expire)); /* nothing else left to fail -- really log in */ { struct utmp utmp; - bzero((char *)&utmp, sizeof(utmp)); + bzero((void *)&utmp, sizeof(utmp)); (void)time(&utmp.ut_time); strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); if (hostname) @@ -414,21 +344,12 @@ main(argc, argv) dolastlog(quietlog); - if (!hflag && !rflag) { /* XXX */ - static struct winsize win = { 0, 0, 0, 0 }; - - (void)ioctl(0, TIOCSWINSZ, &win); - } - (void)chown(ttyn, pwd->pw_uid, (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); - (void)chmod(ttyn, 0620); (void)setgid(pwd->pw_gid); initgroups(username, pwd->pw_gid); - quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); - if (*pwd->pw_shell == '\0') pwd->pw_shell = _PATH_BSHELL; @@ -440,21 +361,38 @@ main(argc, argv) if (term[0] == '\0') strncpy(term, stypeof(tty), sizeof(term)); (void)setenv("TERM", term, 0); + (void)setenv("LOGNAME", pwd->pw_name, 1); (void)setenv("USER", pwd->pw_name, 1); (void)setenv("PATH", _PATH_DEFPATH, 0); +#ifdef KERBEROS + if (krbtkfile_env) + (void)setenv("KRBTKFILE", krbtkfile_env, 1); +#endif if (tty[sizeof("tty")-1] == 'd') syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); - if (pwd->pw_uid == 0) + /* if fflag is on, assume caller/authenticator has logged root login */ + if (rootlogin && fflag == 0) if (hostname) - syslog(LOG_NOTICE, "ROOT LOGIN ON %s FROM %s", - tty, hostname); + syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s", + username, tty, hostname); else - syslog(LOG_NOTICE, "ROOT LOGIN ON %s", tty); + syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty); + +#ifdef KERBEROS + if (!quietlog && notickets == 1) + (void)printf("Warning: no Kerberos tickets issued.\n"); +#endif if (!quietlog) { struct stat st; + printf("%s%s", + "386BSD Release 0.1 by William and Lynne Jolitz.\n", +"Copyright (c) 1989,1990,1991,1992 William F. Jolitz. All rights reserved.\n\ +Based in part on work by the 386BSD User Community and the\n\ +BSD Networking Software, Release 2 by UCB EECS Department.\n"); + motd(); (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name); if (stat(tbuf, &st) == 0 && st.st_size != 0) @@ -471,22 +409,31 @@ main(argc, argv) strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell); - if (setlogname(pwd->pw_name, strlen(pwd->pw_name)) < 0) - syslog(LOG_ERR, "setlogname() failure: %m"); + if (setlogin(pwd->pw_name) < 0) + syslog(LOG_ERR, "setlogin() failure: %m"); /* discard permissions last so can't get killed and drop core */ - (void)setuid(pwd->pw_uid); + if (rootlogin) + (void) setuid(0); + else + (void) setuid(pwd->pw_uid); execlp(pwd->pw_shell, tbuf, 0); - (void)fprintf(stderr, "login: no shell: %s.\n", strerror(errno)); - exit(0); + (void)fprintf(stderr, "%s: %s\n", pwd->pw_shell, strerror(errno)); + exit(1); } +#ifdef KERBEROS +#define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */ +#else +#define NBUFSIZ (UT_NAMESIZE + 1) +#endif + getloginname() { register int ch; register char *p; - static char nbuf[UT_NAMESIZE + 1]; + static char nbuf[NBUFSIZ]; for (;;) { (void)printf("login: "); @@ -495,7 +442,7 @@ getloginname() badlogin(username); exit(0); } - if (p < nbuf + UT_NAMESIZE) + if (p < nbuf + (NBUFSIZ - 1)) *p++ = ch; } if (p > nbuf) @@ -510,6 +457,7 @@ getloginname() } } +void timedout() { (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout); @@ -530,7 +478,7 @@ motd() { register int fd, nchars; sig_t oldint; - int sigint(); + void sigint(); char tbuf[8192]; if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0) @@ -543,6 +491,7 @@ motd() (void)close(fd); } +void sigint() { longjmp(motdinterrupt, 1); @@ -566,7 +515,6 @@ dolastlog(quiet) struct lastlog ll; int fd; char *ctime(); - char *ctime(); if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) { (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); @@ -584,7 +532,7 @@ dolastlog(quiet) } (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET); } - bzero((char *)&ll, sizeof(ll)); + bzero((void *)&ll, sizeof(ll)); (void)time(&ll.ll_time); strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); if (hostname) @@ -599,12 +547,19 @@ badlogin(name) { if (failures == 0) return; - if (hostname) - syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s, %s", + if (hostname) { + syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s", + failures, failures > 1 ? "S" : "", hostname); + syslog(LOG_AUTHPRIV|LOG_NOTICE, + "%d LOGIN FAILURE%s FROM %s, %s", failures, failures > 1 ? "S" : "", hostname, name); - else - syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s, %s", + } else { + syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s", + failures, failures > 1 ? "S" : "", tty); + syslog(LOG_AUTHPRIV|LOG_NOTICE, + "%d LOGIN FAILURE%s ON %s, %s", failures, failures > 1 ? "S" : "", tty, name); + } } #undef UNKNOWN @@ -619,69 +574,9 @@ stypeof(ttyid) return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN); } -getstr(buf, cnt, err) - char *buf, *err; - int cnt; -{ - char ch; - - do { - if (read(0, &ch, sizeof(ch)) != sizeof(ch)) - exit(1); - if (--cnt < 0) { - (void)fprintf(stderr, "%s too long\r\n", err); - sleepexit(1); - } - *buf++ = ch; - } while (ch); -} - sleepexit(eval) int eval; { sleep((u_int)5); exit(eval); } - -doremotelogin(host) - char *host; -{ - static char lusername[UT_NAMESIZE+1]; - char rusername[UT_NAMESIZE+1]; - - getstr(rusername, sizeof(rusername), "remuser"); - getstr(lusername, sizeof(lusername), "locuser"); - getstr(term, sizeof(term), "Terminal type"); - username = lusername; - pwd = getpwnam(username); - if (pwd == NULL) - return(-1); - return(ruserok(host, (pwd->pw_uid == 0), rusername, username)); -} - -char *speeds[] = { - "0", "50", "75", "110", "134", "150", "200", "300", "600", - "1200", "1800", "2400", "4800", "9600", "19200", "38400", -}; -#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) - -doremoteterm(tp) - struct sgttyb *tp; -{ - register char *cp = index(term, '/'), **cpp; - char *speed; - - if (cp) { - *cp++ = '\0'; - speed = cp; - cp = index(speed, '/'); - if (cp) - *cp++ = '\0'; - for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) - if (strcmp(*cpp, speed) == 0) { - tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; - break; - } - } - tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; -}