119843Sdist /* 2*31695Skarels * Copyright (c) 1980,1987 Regents of the University of California. 319843Sdist * All rights reserved. The Berkeley software License Agreement 419843Sdist * specifies the terms and conditions for redistribution. 519843Sdist */ 619843Sdist 712678Ssam #ifndef lint 819843Sdist char copyright[] = 919843Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1019843Sdist All rights reserved.\n"; 1119843Sdist #endif not lint 1212678Ssam 1319843Sdist #ifndef lint 14*31695Skarels static char sccsid[] = "@(#)login.c 5.19 (Berkeley) 06/27/87"; 1519843Sdist #endif not lint 1619843Sdist 171043Sbill /* 181043Sbill * login [ name ] 19*31695Skarels * login -r hostname (for rlogind) 20*31695Skarels * login -h hostname (for telnetd, etc.) 21*31695Skarels * login -f name (for pre-authenticated login: datakit, xterm, etc.) 221043Sbill */ 231043Sbill 2412984Ssam #include <sys/param.h> 2512687Ssam #include <sys/quota.h> 2612687Ssam #include <sys/stat.h> 2712687Ssam #include <sys/time.h> 2812687Ssam #include <sys/resource.h> 2916453Sroot #include <sys/file.h> 3012687Ssam 311043Sbill #include <sgtty.h> 321043Sbill #include <utmp.h> 331043Sbill #include <signal.h> 341043Sbill #include <pwd.h> 351043Sbill #include <stdio.h> 361043Sbill #include <lastlog.h> 3712678Ssam #include <errno.h> 3816453Sroot #include <ttyent.h> 3916453Sroot #include <syslog.h> 4026862Smckusick #include <grp.h> 411043Sbill 4227056Skarels #define TTYGRPNAME "tty" /* name of group to own ttys */ 4327056Skarels #define TTYGID(gid) tty_gid(gid) /* gid that owns all ttys */ 4426862Smckusick 4516453Sroot #define SCMPN(a, b) strncmp(a, b, sizeof(a)) 462822Swnj #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 472822Swnj 486197Sroot #define NMAX sizeof(utmp.ut_name) 4925230Smckusick #define HMAX sizeof(utmp.ut_host) 501043Sbill 512822Swnj #define FALSE 0 522822Swnj #define TRUE -1 532822Swnj 542822Swnj char nolog[] = "/etc/nologin"; 552822Swnj char qlog[] = ".hushlogin"; 561043Sbill char maildir[30] = "/usr/spool/mail/"; 571043Sbill char lastlog[] = "/usr/adm/lastlog"; 589867Ssam struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" }; 591043Sbill struct sgttyb ttyb; 601043Sbill struct utmp utmp; 611043Sbill char minusnam[16] = "-"; 6230606Sbostic char *envinit[1]; /* now set by setenv calls */ 6312687Ssam /* 6412687Ssam * This bounds the time given to login. We initialize it here 6512687Ssam * so it can be patched on machines where it's too small. 6612687Ssam */ 6731509Sbostic int timeout = 300; 686005Swnj 6918549Ssam char term[64]; 706005Swnj 711043Sbill struct passwd *pwd; 7230606Sbostic char *strcat(), *rindex(), *index(); 7312687Ssam int timedout(); 741043Sbill char *ttyname(); 751043Sbill char *crypt(); 761043Sbill char *getpass(); 771043Sbill char *stypeof(); 7812678Ssam extern int errno; 791043Sbill 8013074Ssam struct tchars tc = { 8113074Ssam CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 821365Sbill }; 8313074Ssam struct ltchars ltc = { 8413074Ssam CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT 8513074Ssam }; 861365Sbill 8718549Ssam struct winsize win = { 0, 0, 0, 0 }; 8818549Ssam 896005Swnj int rflag; 9024712Sbloom int usererr = -1; 916197Sroot char rusername[NMAX+1], lusername[NMAX+1]; 926005Swnj char rpassword[NMAX+1]; 936878Smckusick char name[NMAX+1]; 9429992Skarels char me[MAXHOSTNAMELEN]; 956197Sroot char *rhost; 966005Swnj 971043Sbill main(argc, argv) 9812687Ssam char *argv[]; 991043Sbill { 10030606Sbostic extern char **environ; 1011043Sbill register char *namep; 102*31695Skarels int pflag = 0, hflag = 0, fflag = 0, t, f, c; 10312687Ssam int invalid, quietlog; 1042822Swnj FILE *nlfd; 10516453Sroot char *ttyn, *tty; 10618549Ssam int ldisc = 0, zero = 0, i; 10729992Skarels char *p, *domain, *index(); 1081043Sbill 10912687Ssam signal(SIGALRM, timedout); 11012687Ssam alarm(timeout); 1111043Sbill signal(SIGQUIT, SIG_IGN); 1121043Sbill signal(SIGINT, SIG_IGN); 11312687Ssam setpriority(PRIO_PROCESS, 0, 0); 11412678Ssam quota(Q_SETUID, 0, 0, 0); 11512687Ssam /* 11618549Ssam * -p is used by getty to tell login not to destroy the environment 11712687Ssam * -r is used by rlogind to cause the autologin protocol; 118*31695Skarels * -f is used to skip a second login authentication 11912687Ssam * -h is used by other servers to pass the name of the 12012687Ssam * remote host to login so that it may be placed in utmp and wtmp 12112687Ssam */ 12229992Skarels (void) gethostname(me, sizeof(me)); 12329992Skarels domain = index(me, '.'); 12424712Sbloom while (argc > 1) { 12512687Ssam if (strcmp(argv[1], "-r") == 0) { 126*31695Skarels if (rflag || hflag || fflag) { 127*31695Skarels printf("Other options not allowed with -r\n"); 12824712Sbloom exit(1); 12924712Sbloom } 13024712Sbloom rflag = 1; 13124712Sbloom usererr = doremotelogin(argv[2]); 13229992Skarels if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) 13329992Skarels *p = 0; 13412687Ssam SCPYN(utmp.ut_host, argv[2]); 13524712Sbloom argc -= 2; 13624712Sbloom argv += 2; 13724712Sbloom continue; 1386197Sroot } 139*31695Skarels if (strcmp(argv[1], "-h") == 0) { 140*31695Skarels if (getuid() == 0) { 141*31695Skarels if (rflag || hflag) { 142*31695Skarels printf("Only one of -r and -h allowed\n"); 143*31695Skarels exit(1); 144*31695Skarels } 145*31695Skarels hflag = 1; 146*31695Skarels if ((p = index(argv[2], '.')) && 147*31695Skarels strcmp(p, domain) == 0) 148*31695Skarels *p = 0; 149*31695Skarels SCPYN(utmp.ut_host, argv[2]); 150*31695Skarels } 151*31695Skarels argc -= 2; 152*31695Skarels argv += 2; 153*31695Skarels continue; 154*31695Skarels } 155*31695Skarels if (strcmp(argv[1], "-f") == 0 && argc > 2) { 156*31695Skarels if (rflag) { 157*31695Skarels printf("Only one of -r and -f allowed\n"); 15824712Sbloom exit(1); 15924712Sbloom } 160*31695Skarels fflag = 1; 161*31695Skarels SCPYN(utmp.ut_name, argv[2]); 16224712Sbloom argc -= 2; 16324712Sbloom argv += 2; 16424712Sbloom continue; 1656197Sroot } 16618549Ssam if (strcmp(argv[1], "-p") == 0) { 16718549Ssam argc--; 16818549Ssam argv++; 16918549Ssam pflag = 1; 17024712Sbloom continue; 17118549Ssam } 17224712Sbloom break; 1736005Swnj } 17413074Ssam ioctl(0, TIOCLSET, &zero); 1751547Sbill ioctl(0, TIOCNXCL, 0); 1766329Swnj ioctl(0, FIONBIO, &zero); 1776329Swnj ioctl(0, FIOASYNC, &zero); 17813074Ssam ioctl(0, TIOCGETP, &ttyb); 17912687Ssam /* 18012687Ssam * If talking to an rlogin process, 18112687Ssam * propagate the terminal type and 18212687Ssam * baud rate across the network. 18312687Ssam */ 18412687Ssam if (rflag) 18512687Ssam doremoteterm(term, &ttyb); 18626482Skarels ttyb.sg_erase = CERASE; 18726482Skarels ttyb.sg_kill = CKILL; 18813074Ssam ioctl(0, TIOCSLTC, <c); 18913074Ssam ioctl(0, TIOCSETC, &tc); 19013074Ssam ioctl(0, TIOCSETP, &ttyb); 19124849Smckusick for (t = getdtablesize(); t > 2; t--) 1921043Sbill close(t); 1931043Sbill ttyn = ttyname(0); 19425426Sbloom if (ttyn == (char *)0 || *ttyn == '\0') 1951043Sbill ttyn = "/dev/tty??"; 19616453Sroot tty = rindex(ttyn, '/'); 19716453Sroot if (tty == NULL) 19816453Sroot tty = ttyn; 19916453Sroot else 20016453Sroot tty++; 20124852Seric openlog("login", LOG_ODELAY, LOG_AUTH); 20216453Sroot t = 0; 20325163Sbloom invalid = FALSE; 2042822Swnj do { 2052822Swnj ldisc = 0; 2062822Swnj ioctl(0, TIOCSETD, &ldisc); 207*31695Skarels if (fflag == 0) 208*31695Skarels SCPYN(utmp.ut_name, ""); 20912687Ssam /* 21012687Ssam * Name specified, take it. 21112687Ssam */ 21212687Ssam if (argc > 1) { 2132822Swnj SCPYN(utmp.ut_name, argv[1]); 2142822Swnj argc = 0; 2151043Sbill } 21612687Ssam /* 21712687Ssam * If remote login take given name, 21812687Ssam * otherwise prompt user for something. 21912687Ssam */ 22025163Sbloom if (rflag && !invalid) 2219867Ssam SCPYN(utmp.ut_name, lusername); 22224883Smckusick else 22312687Ssam getloginname(&utmp); 22425163Sbloom invalid = FALSE; 2252822Swnj if (!strcmp(pwd->pw_shell, "/bin/csh")) { 2262822Swnj ldisc = NTTYDISC; 2272822Swnj ioctl(0, TIOCSETD, &ldisc); 2282822Swnj } 229*31695Skarels if (fflag) { 230*31695Skarels int uid = getuid(); 231*31695Skarels 232*31695Skarels if (uid != 0 && uid != pwd->pw_uid) 233*31695Skarels fflag = 0; 234*31695Skarels /* 235*31695Skarels * Disallow automatic login for root. 236*31695Skarels */ 237*31695Skarels if (pwd->pw_uid == 0) 238*31695Skarels fflag = 0; 239*31695Skarels } 24012687Ssam /* 24112687Ssam * If no remote login authentication and 24212687Ssam * a password exists for this user, prompt 24312687Ssam * for one and verify it. 24412687Ssam */ 245*31695Skarels if (usererr == -1 && fflag == 0 && *pwd->pw_passwd != '\0') { 24612687Ssam char *pp; 24712687Ssam 24812687Ssam setpriority(PRIO_PROCESS, 0, -4); 24912687Ssam pp = getpass("Password:"); 25012687Ssam namep = crypt(pp, pwd->pw_passwd); 25112687Ssam setpriority(PRIO_PROCESS, 0, 0); 25212687Ssam if (strcmp(namep, pwd->pw_passwd)) 25312687Ssam invalid = TRUE; 2542822Swnj } 25512687Ssam /* 25612687Ssam * If user not super-user, check for logins disabled. 25712687Ssam */ 2582822Swnj if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { 2592822Swnj while ((c = getc(nlfd)) != EOF) 2602822Swnj putchar(c); 2612822Swnj fflush(stdout); 2622822Swnj sleep(5); 2632822Swnj exit(0); 2642822Swnj } 26512687Ssam /* 26612687Ssam * If valid so far and root is logging in, 26712687Ssam * see if root logins on this terminal are permitted. 26812687Ssam */ 26916453Sroot if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) { 27025230Smckusick if (utmp.ut_host[0]) 27125230Smckusick syslog(LOG_CRIT, 27225230Smckusick "ROOT LOGIN REFUSED ON %s FROM %.*s", 27325230Smckusick tty, HMAX, utmp.ut_host); 27425230Smckusick else 27525230Smckusick syslog(LOG_CRIT, 27625230Smckusick "ROOT LOGIN REFUSED ON %s", tty); 2772822Swnj invalid = TRUE; 2782822Swnj } 2792822Swnj if (invalid) { 2801043Sbill printf("Login incorrect\n"); 28116453Sroot if (++t >= 5) { 28225230Smckusick if (utmp.ut_host[0]) 283*31695Skarels syslog(LOG_ERR, 284*31695Skarels "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", 28525230Smckusick tty, HMAX, utmp.ut_host, 28625230Smckusick NMAX, utmp.ut_name); 28725230Smckusick else 288*31695Skarels syslog(LOG_ERR, 289*31695Skarels "REPEATED LOGIN FAILURES ON %s, %.*s", 29025230Smckusick tty, NMAX, utmp.ut_name); 29116453Sroot ioctl(0, TIOCHPCL, (struct sgttyb *) 0); 29218549Ssam close(0), close(1), close(2); 29316453Sroot sleep(10); 29416453Sroot exit(1); 29516453Sroot } 2961043Sbill } 2972822Swnj if (*pwd->pw_shell == '\0') 2982822Swnj pwd->pw_shell = "/bin/sh"; 2992822Swnj if (chdir(pwd->pw_dir) < 0 && !invalid ) { 3002822Swnj if (chdir("/") < 0) { 3012822Swnj printf("No directory!\n"); 3022822Swnj invalid = TRUE; 3032822Swnj } else { 30412687Ssam printf("No directory! %s\n", 30512687Ssam "Logging in with home=/"); 3062822Swnj pwd->pw_dir = "/"; 3072822Swnj } 3081043Sbill } 30912687Ssam /* 31012687Ssam * Remote login invalid must have been because 31112687Ssam * of a restriction of some sort, no extra chances. 31212687Ssam */ 31324712Sbloom if (!usererr && invalid) 3146005Swnj exit(1); 3152822Swnj } while (invalid); 31612687Ssam /* committed to login turn off timeout */ 31712687Ssam alarm(0); 3181043Sbill 31921083Smckusick if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { 32012678Ssam if (errno == EUSERS) 32112678Ssam printf("%s.\n%s.\n", 32212678Ssam "Too many users logged on already", 32312678Ssam "Try again later"); 32412678Ssam else if (errno == EPROCLIM) 32512678Ssam printf("You have too many processes running.\n"); 32612678Ssam else 32717664Sserge perror("quota (Q_SETUID)"); 32812678Ssam sleep(5); 32912678Ssam exit(0); 33012678Ssam } 3311043Sbill time(&utmp.ut_time); 3321043Sbill t = ttyslot(); 33316453Sroot if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { 3341043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 33516453Sroot SCPYN(utmp.ut_line, tty); 3361043Sbill write(f, (char *)&utmp, sizeof(utmp)); 3371043Sbill close(f); 3381043Sbill } 33916453Sroot if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { 3401043Sbill write(f, (char *)&utmp, sizeof(utmp)); 3411043Sbill close(f); 3421043Sbill } 34316453Sroot quietlog = access(qlog, F_OK) == 0; 34416453Sroot if ((f = open(lastlog, O_RDWR)) >= 0) { 3452822Swnj struct lastlog ll; 3462822Swnj 3472822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 3482822Swnj if (read(f, (char *) &ll, sizeof ll) == sizeof ll && 34912687Ssam ll.ll_time != 0 && !quietlog) { 35012687Ssam printf("Last login: %.*s ", 35112687Ssam 24-5, (char *)ctime(&ll.ll_time)); 35212687Ssam if (*ll.ll_host != '\0') 35312687Ssam printf("from %.*s\n", 35412687Ssam sizeof (ll.ll_host), ll.ll_host); 35512687Ssam else 35612687Ssam printf("on %.*s\n", 35712687Ssam sizeof (ll.ll_line), ll.ll_line); 3582822Swnj } 3592822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 3602822Swnj time(&ll.ll_time); 36116453Sroot SCPYN(ll.ll_line, tty); 36212687Ssam SCPYN(ll.ll_host, utmp.ut_host); 3632822Swnj write(f, (char *) &ll, sizeof ll); 3642822Swnj close(f); 3652822Swnj } 36627056Skarels chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid)); 36724849Smckusick if (!hflag && !rflag) /* XXX */ 36818549Ssam ioctl(0, TIOCSWINSZ, &win); 36926862Smckusick chmod(ttyn, 0620); 3701043Sbill setgid(pwd->pw_gid); 3716878Smckusick strncpy(name, utmp.ut_name, NMAX); 3726878Smckusick name[NMAX] = '\0'; 3739224Ssam initgroups(name, pwd->pw_gid); 37412678Ssam quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); 3751043Sbill setuid(pwd->pw_uid); 37630606Sbostic 37718549Ssam /* destroy environment unless user has asked to preserve it */ 37818549Ssam if (!pflag) 37918549Ssam environ = envinit; 38030606Sbostic setenv("HOME", pwd->pw_dir, 1); 38130606Sbostic setenv("SHELL", pwd->pw_shell, 1); 38218549Ssam if (term[0] == '\0') 38318549Ssam strncpy(term, stypeof(tty), sizeof(term)); 38430606Sbostic setenv("TERM", term, 0); 38530606Sbostic setenv("USER", pwd->pw_name, 1); 38630606Sbostic setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0); 38718549Ssam 3881043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 3891043Sbill namep = pwd->pw_shell; 3901043Sbill else 3911043Sbill namep++; 3921043Sbill strcat(minusnam, namep); 39316453Sroot if (tty[sizeof("tty")-1] == 'd') 39418549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 39518549Ssam if (pwd->pw_uid == 0) 39625230Smckusick if (utmp.ut_host[0]) 39725230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", 39825230Smckusick tty, HMAX, utmp.ut_host); 39925230Smckusick else 40025230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); 4016329Swnj if (!quietlog) { 40217664Sserge struct stat st; 40318549Ssam 4042822Swnj showmotd(); 4052822Swnj strcat(maildir, pwd->pw_name); 40617664Sserge if (stat(maildir, &st) == 0 && st.st_size != 0) 40717664Sserge printf("You have %smail.\n", 40818549Ssam (st.st_mtime > st.st_atime) ? "new " : ""); 4092822Swnj } 41012687Ssam signal(SIGALRM, SIG_DFL); 4111043Sbill signal(SIGQUIT, SIG_DFL); 4121043Sbill signal(SIGINT, SIG_DFL); 4133935Sroot signal(SIGTSTP, SIG_IGN); 4141043Sbill execlp(pwd->pw_shell, minusnam, 0); 4152822Swnj perror(pwd->pw_shell); 4161043Sbill printf("No shell\n"); 4171043Sbill exit(0); 4181043Sbill } 4191043Sbill 42012687Ssam getloginname(up) 42112687Ssam register struct utmp *up; 42212687Ssam { 42312687Ssam register char *namep; 42412712Ssam char c; 42512687Ssam 42612687Ssam while (up->ut_name[0] == '\0') { 42714897Sedward namep = up->ut_name; 42812712Ssam printf("login: "); 42912687Ssam while ((c = getchar()) != '\n') { 43012687Ssam if (c == ' ') 43112687Ssam c = '_'; 43212687Ssam if (c == EOF) 43312687Ssam exit(0); 43412687Ssam if (namep < up->ut_name+NMAX) 43512687Ssam *namep++ = c; 43612687Ssam } 43712687Ssam } 43814897Sedward strncpy(lusername, up->ut_name, NMAX); 43914897Sedward lusername[NMAX] = 0; 44014897Sedward if ((pwd = getpwnam(lusername)) == NULL) 44112687Ssam pwd = &nouser; 44212687Ssam } 44312687Ssam 44412687Ssam timedout() 44512687Ssam { 44612687Ssam 44712687Ssam printf("Login timed out after %d seconds\n", timeout); 44812687Ssam exit(0); 44912687Ssam } 45012687Ssam 4511043Sbill int stopmotd; 4521043Sbill catch() 4531043Sbill { 4546466Swnj 4551043Sbill signal(SIGINT, SIG_IGN); 4561043Sbill stopmotd++; 4571043Sbill } 4581043Sbill 4592822Swnj rootterm(tty) 4606466Swnj char *tty; 4612822Swnj { 46216453Sroot register struct ttyent *t; 4632822Swnj 46416453Sroot if ((t = getttynam(tty)) != NULL) { 46516453Sroot if (t->ty_status & TTY_SECURE) 46616453Sroot return (1); 4672822Swnj } 46816453Sroot return (0); 4692822Swnj } 4702822Swnj 4711043Sbill showmotd() 4721043Sbill { 4731043Sbill FILE *mf; 4741043Sbill register c; 4751043Sbill 4761043Sbill signal(SIGINT, catch); 47716453Sroot if ((mf = fopen("/etc/motd", "r")) != NULL) { 4782822Swnj while ((c = getc(mf)) != EOF && stopmotd == 0) 4791043Sbill putchar(c); 4801043Sbill fclose(mf); 4811043Sbill } 4821043Sbill signal(SIGINT, SIG_IGN); 4831043Sbill } 4841043Sbill 4852822Swnj #undef UNKNOWN 4861043Sbill #define UNKNOWN "su" 4871043Sbill 4881043Sbill char * 4891043Sbill stypeof(ttyid) 49012687Ssam char *ttyid; 4911043Sbill { 49216453Sroot register struct ttyent *t; 4931043Sbill 49416453Sroot if (ttyid == NULL || (t = getttynam(ttyid)) == NULL) 4951043Sbill return (UNKNOWN); 49616453Sroot return (t->ty_type); 4971043Sbill } 4986005Swnj 49912687Ssam doremotelogin(host) 50012687Ssam char *host; 50112687Ssam { 50212687Ssam getstr(rusername, sizeof (rusername), "remuser"); 50312687Ssam getstr(lusername, sizeof (lusername), "locuser"); 50418549Ssam getstr(term, sizeof(term), "Terminal type"); 50513470Ssam if (getuid()) { 50613470Ssam pwd = &nouser; 50724712Sbloom return(-1); 50813470Ssam } 50912687Ssam pwd = getpwnam(lusername); 51013470Ssam if (pwd == NULL) { 51113470Ssam pwd = &nouser; 51224712Sbloom return(-1); 51313470Ssam } 51424712Sbloom return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername)); 51512687Ssam } 51612687Ssam 5176005Swnj getstr(buf, cnt, err) 5186005Swnj char *buf; 5196005Swnj int cnt; 5206005Swnj char *err; 5216005Swnj { 5226005Swnj char c; 5236005Swnj 5246005Swnj do { 5256005Swnj if (read(0, &c, 1) != 1) 5266005Swnj exit(1); 5276005Swnj if (--cnt < 0) { 5286005Swnj printf("%s too long\r\n", err); 5296005Swnj exit(1); 5306005Swnj } 5316005Swnj *buf++ = c; 5326005Swnj } while (c != 0); 5336005Swnj } 5346329Swnj 53512687Ssam char *speeds[] = 53612687Ssam { "0", "50", "75", "110", "134", "150", "200", "300", 53712687Ssam "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; 53812687Ssam #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0])) 53912687Ssam 54012687Ssam doremoteterm(term, tp) 54112687Ssam char *term; 54212687Ssam struct sgttyb *tp; 54312687Ssam { 54418549Ssam register char *cp = index(term, '/'), **cpp; 54518549Ssam char *speed; 54612687Ssam 54712687Ssam if (cp) { 54818549Ssam *cp++ = '\0'; 54918549Ssam speed = cp; 55018549Ssam cp = index(speed, '/'); 55118549Ssam if (cp) 55218549Ssam *cp++ = '\0'; 55318549Ssam for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 55418549Ssam if (strcmp(*cpp, speed) == 0) { 55518549Ssam tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; 55612687Ssam break; 55712687Ssam } 55812687Ssam } 55912687Ssam tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; 56012687Ssam } 56118549Ssam 56227056Skarels tty_gid(default_gid) 56326876Smckusick int default_gid; 56426862Smckusick { 56526862Smckusick struct group *getgrnam(), *gr; 56626876Smckusick int gid = default_gid; 56726862Smckusick 56827056Skarels gr = getgrnam(TTYGRPNAME); 56926862Smckusick if (gr != (struct group *) 0) 57026862Smckusick gid = gr->gr_gid; 57126862Smckusick 57226862Smckusick endgrent(); 57326862Smckusick 57426876Smckusick return (gid); 57526862Smckusick } 576