119843Sdist /* 231695Skarels * 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*32313Sbostic static char sccsid[] = "@(#)login.c 5.20 (Berkeley) 10/01/87"; 1519843Sdist #endif not lint 1619843Sdist 171043Sbill /* 181043Sbill * login [ name ] 1931695Skarels * login -r hostname (for rlogind) 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/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; 10231695Skarels 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; 11831695Skarels * -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) { 12631695Skarels if (rflag || hflag || fflag) { 12731695Skarels printf("Other options not allowed with -r\n"); 12824712Sbloom exit(1); 12924712Sbloom } 130*32313Sbostic if (argv[2] == 0) 131*32313Sbostic exit(1); 13224712Sbloom rflag = 1; 13324712Sbloom usererr = doremotelogin(argv[2]); 13429992Skarels if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) 13529992Skarels *p = 0; 13612687Ssam SCPYN(utmp.ut_host, argv[2]); 13724712Sbloom argc -= 2; 13824712Sbloom argv += 2; 13924712Sbloom continue; 1406197Sroot } 14131695Skarels if (strcmp(argv[1], "-h") == 0) { 14231695Skarels if (getuid() == 0) { 14331695Skarels if (rflag || hflag) { 14431695Skarels printf("Only one of -r and -h allowed\n"); 14531695Skarels exit(1); 14631695Skarels } 14731695Skarels hflag = 1; 14831695Skarels if ((p = index(argv[2], '.')) && 14931695Skarels strcmp(p, domain) == 0) 15031695Skarels *p = 0; 15131695Skarels SCPYN(utmp.ut_host, argv[2]); 15231695Skarels } 15331695Skarels argc -= 2; 15431695Skarels argv += 2; 15531695Skarels continue; 15631695Skarels } 15731695Skarels if (strcmp(argv[1], "-f") == 0 && argc > 2) { 15831695Skarels if (rflag) { 15931695Skarels printf("Only one of -r and -f allowed\n"); 16024712Sbloom exit(1); 16124712Sbloom } 16231695Skarels fflag = 1; 16331695Skarels SCPYN(utmp.ut_name, argv[2]); 16424712Sbloom argc -= 2; 16524712Sbloom argv += 2; 16624712Sbloom continue; 1676197Sroot } 16818549Ssam if (strcmp(argv[1], "-p") == 0) { 16918549Ssam argc--; 17018549Ssam argv++; 17118549Ssam pflag = 1; 17224712Sbloom continue; 17318549Ssam } 17424712Sbloom break; 1756005Swnj } 17613074Ssam ioctl(0, TIOCLSET, &zero); 1771547Sbill ioctl(0, TIOCNXCL, 0); 1786329Swnj ioctl(0, FIONBIO, &zero); 1796329Swnj ioctl(0, FIOASYNC, &zero); 18013074Ssam ioctl(0, TIOCGETP, &ttyb); 18112687Ssam /* 18212687Ssam * If talking to an rlogin process, 18312687Ssam * propagate the terminal type and 18412687Ssam * baud rate across the network. 18512687Ssam */ 18612687Ssam if (rflag) 18712687Ssam doremoteterm(term, &ttyb); 18826482Skarels ttyb.sg_erase = CERASE; 18926482Skarels ttyb.sg_kill = CKILL; 19013074Ssam ioctl(0, TIOCSLTC, <c); 19113074Ssam ioctl(0, TIOCSETC, &tc); 19213074Ssam ioctl(0, TIOCSETP, &ttyb); 19324849Smckusick for (t = getdtablesize(); t > 2; t--) 1941043Sbill close(t); 1951043Sbill ttyn = ttyname(0); 19625426Sbloom if (ttyn == (char *)0 || *ttyn == '\0') 1971043Sbill ttyn = "/dev/tty??"; 19816453Sroot tty = rindex(ttyn, '/'); 19916453Sroot if (tty == NULL) 20016453Sroot tty = ttyn; 20116453Sroot else 20216453Sroot tty++; 20324852Seric openlog("login", LOG_ODELAY, LOG_AUTH); 20416453Sroot t = 0; 20525163Sbloom invalid = FALSE; 2062822Swnj do { 2072822Swnj ldisc = 0; 2082822Swnj ioctl(0, TIOCSETD, &ldisc); 20931695Skarels if (fflag == 0) 21031695Skarels SCPYN(utmp.ut_name, ""); 21112687Ssam /* 21212687Ssam * Name specified, take it. 21312687Ssam */ 21412687Ssam if (argc > 1) { 2152822Swnj SCPYN(utmp.ut_name, argv[1]); 2162822Swnj argc = 0; 2171043Sbill } 21812687Ssam /* 21912687Ssam * If remote login take given name, 22012687Ssam * otherwise prompt user for something. 22112687Ssam */ 22225163Sbloom if (rflag && !invalid) 2239867Ssam SCPYN(utmp.ut_name, lusername); 224*32313Sbostic else { 22512687Ssam getloginname(&utmp); 226*32313Sbostic if (utmp.ut_name[0] == '-') { 227*32313Sbostic puts("login names may not start with '-'."); 228*32313Sbostic invalid = TRUE; 229*32313Sbostic continue; 230*32313Sbostic } 231*32313Sbostic } 23225163Sbloom invalid = FALSE; 2332822Swnj if (!strcmp(pwd->pw_shell, "/bin/csh")) { 2342822Swnj ldisc = NTTYDISC; 2352822Swnj ioctl(0, TIOCSETD, &ldisc); 2362822Swnj } 23731695Skarels if (fflag) { 23831695Skarels int uid = getuid(); 23931695Skarels 24031695Skarels if (uid != 0 && uid != pwd->pw_uid) 24131695Skarels fflag = 0; 24231695Skarels /* 24331695Skarels * Disallow automatic login for root. 24431695Skarels */ 24531695Skarels if (pwd->pw_uid == 0) 24631695Skarels fflag = 0; 24731695Skarels } 24812687Ssam /* 24912687Ssam * If no remote login authentication and 25012687Ssam * a password exists for this user, prompt 25112687Ssam * for one and verify it. 25212687Ssam */ 25331695Skarels if (usererr == -1 && fflag == 0 && *pwd->pw_passwd != '\0') { 25412687Ssam char *pp; 25512687Ssam 25612687Ssam setpriority(PRIO_PROCESS, 0, -4); 25712687Ssam pp = getpass("Password:"); 25812687Ssam namep = crypt(pp, pwd->pw_passwd); 25912687Ssam setpriority(PRIO_PROCESS, 0, 0); 26012687Ssam if (strcmp(namep, pwd->pw_passwd)) 26112687Ssam invalid = TRUE; 2622822Swnj } 26312687Ssam /* 26412687Ssam * If user not super-user, check for logins disabled. 26512687Ssam */ 2662822Swnj if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { 2672822Swnj while ((c = getc(nlfd)) != EOF) 2682822Swnj putchar(c); 2692822Swnj fflush(stdout); 2702822Swnj sleep(5); 2712822Swnj exit(0); 2722822Swnj } 27312687Ssam /* 27412687Ssam * If valid so far and root is logging in, 27512687Ssam * see if root logins on this terminal are permitted. 27612687Ssam */ 27716453Sroot if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) { 27825230Smckusick if (utmp.ut_host[0]) 27925230Smckusick syslog(LOG_CRIT, 28025230Smckusick "ROOT LOGIN REFUSED ON %s FROM %.*s", 28125230Smckusick tty, HMAX, utmp.ut_host); 28225230Smckusick else 28325230Smckusick syslog(LOG_CRIT, 28425230Smckusick "ROOT LOGIN REFUSED ON %s", tty); 2852822Swnj invalid = TRUE; 2862822Swnj } 2872822Swnj if (invalid) { 2881043Sbill printf("Login incorrect\n"); 28916453Sroot if (++t >= 5) { 29025230Smckusick if (utmp.ut_host[0]) 29131695Skarels syslog(LOG_ERR, 29231695Skarels "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", 29325230Smckusick tty, HMAX, utmp.ut_host, 29425230Smckusick NMAX, utmp.ut_name); 29525230Smckusick else 29631695Skarels syslog(LOG_ERR, 29731695Skarels "REPEATED LOGIN FAILURES ON %s, %.*s", 29825230Smckusick tty, NMAX, utmp.ut_name); 29916453Sroot ioctl(0, TIOCHPCL, (struct sgttyb *) 0); 30018549Ssam close(0), close(1), close(2); 30116453Sroot sleep(10); 30216453Sroot exit(1); 30316453Sroot } 3041043Sbill } 3052822Swnj if (*pwd->pw_shell == '\0') 3062822Swnj pwd->pw_shell = "/bin/sh"; 3072822Swnj if (chdir(pwd->pw_dir) < 0 && !invalid ) { 3082822Swnj if (chdir("/") < 0) { 3092822Swnj printf("No directory!\n"); 3102822Swnj invalid = TRUE; 3112822Swnj } else { 31212687Ssam printf("No directory! %s\n", 31312687Ssam "Logging in with home=/"); 3142822Swnj pwd->pw_dir = "/"; 3152822Swnj } 3161043Sbill } 31712687Ssam /* 31812687Ssam * Remote login invalid must have been because 31912687Ssam * of a restriction of some sort, no extra chances. 32012687Ssam */ 32124712Sbloom if (!usererr && invalid) 3226005Swnj exit(1); 3232822Swnj } while (invalid); 32412687Ssam /* committed to login turn off timeout */ 32512687Ssam alarm(0); 3261043Sbill 32721083Smckusick if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { 32812678Ssam if (errno == EUSERS) 32912678Ssam printf("%s.\n%s.\n", 33012678Ssam "Too many users logged on already", 33112678Ssam "Try again later"); 33212678Ssam else if (errno == EPROCLIM) 33312678Ssam printf("You have too many processes running.\n"); 33412678Ssam else 33517664Sserge perror("quota (Q_SETUID)"); 33612678Ssam sleep(5); 33712678Ssam exit(0); 33812678Ssam } 3391043Sbill time(&utmp.ut_time); 3401043Sbill t = ttyslot(); 34116453Sroot if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { 3421043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 34316453Sroot SCPYN(utmp.ut_line, tty); 3441043Sbill write(f, (char *)&utmp, sizeof(utmp)); 3451043Sbill close(f); 3461043Sbill } 34716453Sroot if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { 3481043Sbill write(f, (char *)&utmp, sizeof(utmp)); 3491043Sbill close(f); 3501043Sbill } 35116453Sroot quietlog = access(qlog, F_OK) == 0; 35216453Sroot if ((f = open(lastlog, O_RDWR)) >= 0) { 3532822Swnj struct lastlog ll; 3542822Swnj 3552822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 3562822Swnj if (read(f, (char *) &ll, sizeof ll) == sizeof ll && 35712687Ssam ll.ll_time != 0 && !quietlog) { 35812687Ssam printf("Last login: %.*s ", 35912687Ssam 24-5, (char *)ctime(&ll.ll_time)); 36012687Ssam if (*ll.ll_host != '\0') 36112687Ssam printf("from %.*s\n", 36212687Ssam sizeof (ll.ll_host), ll.ll_host); 36312687Ssam else 36412687Ssam printf("on %.*s\n", 36512687Ssam sizeof (ll.ll_line), ll.ll_line); 3662822Swnj } 3672822Swnj lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); 3682822Swnj time(&ll.ll_time); 36916453Sroot SCPYN(ll.ll_line, tty); 37012687Ssam SCPYN(ll.ll_host, utmp.ut_host); 3712822Swnj write(f, (char *) &ll, sizeof ll); 3722822Swnj close(f); 3732822Swnj } 37427056Skarels chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid)); 37524849Smckusick if (!hflag && !rflag) /* XXX */ 37618549Ssam ioctl(0, TIOCSWINSZ, &win); 37726862Smckusick chmod(ttyn, 0620); 3781043Sbill setgid(pwd->pw_gid); 3796878Smckusick strncpy(name, utmp.ut_name, NMAX); 3806878Smckusick name[NMAX] = '\0'; 3819224Ssam initgroups(name, pwd->pw_gid); 38212678Ssam quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); 3831043Sbill setuid(pwd->pw_uid); 38430606Sbostic 38518549Ssam /* destroy environment unless user has asked to preserve it */ 38618549Ssam if (!pflag) 38718549Ssam environ = envinit; 38830606Sbostic setenv("HOME", pwd->pw_dir, 1); 38930606Sbostic setenv("SHELL", pwd->pw_shell, 1); 39018549Ssam if (term[0] == '\0') 39118549Ssam strncpy(term, stypeof(tty), sizeof(term)); 39230606Sbostic setenv("TERM", term, 0); 39330606Sbostic setenv("USER", pwd->pw_name, 1); 39430606Sbostic setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0); 39518549Ssam 3961043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 3971043Sbill namep = pwd->pw_shell; 3981043Sbill else 3991043Sbill namep++; 4001043Sbill strcat(minusnam, namep); 40116453Sroot if (tty[sizeof("tty")-1] == 'd') 40218549Ssam syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); 40318549Ssam if (pwd->pw_uid == 0) 40425230Smckusick if (utmp.ut_host[0]) 40525230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", 40625230Smckusick tty, HMAX, utmp.ut_host); 40725230Smckusick else 40825230Smckusick syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); 4096329Swnj if (!quietlog) { 41017664Sserge struct stat st; 41118549Ssam 4122822Swnj showmotd(); 4132822Swnj strcat(maildir, pwd->pw_name); 41417664Sserge if (stat(maildir, &st) == 0 && st.st_size != 0) 41517664Sserge printf("You have %smail.\n", 41618549Ssam (st.st_mtime > st.st_atime) ? "new " : ""); 4172822Swnj } 41812687Ssam signal(SIGALRM, SIG_DFL); 4191043Sbill signal(SIGQUIT, SIG_DFL); 4201043Sbill signal(SIGINT, SIG_DFL); 4213935Sroot signal(SIGTSTP, SIG_IGN); 4221043Sbill execlp(pwd->pw_shell, minusnam, 0); 4232822Swnj perror(pwd->pw_shell); 4241043Sbill printf("No shell\n"); 4251043Sbill exit(0); 4261043Sbill } 4271043Sbill 42812687Ssam getloginname(up) 42912687Ssam register struct utmp *up; 43012687Ssam { 43112687Ssam register char *namep; 43212712Ssam char c; 43312687Ssam 43412687Ssam while (up->ut_name[0] == '\0') { 43514897Sedward namep = up->ut_name; 43612712Ssam printf("login: "); 43712687Ssam while ((c = getchar()) != '\n') { 43812687Ssam if (c == ' ') 43912687Ssam c = '_'; 44012687Ssam if (c == EOF) 44112687Ssam exit(0); 44212687Ssam if (namep < up->ut_name+NMAX) 44312687Ssam *namep++ = c; 44412687Ssam } 44512687Ssam } 44614897Sedward strncpy(lusername, up->ut_name, NMAX); 44714897Sedward lusername[NMAX] = 0; 44814897Sedward if ((pwd = getpwnam(lusername)) == NULL) 44912687Ssam pwd = &nouser; 45012687Ssam } 45112687Ssam 45212687Ssam timedout() 45312687Ssam { 45412687Ssam 45512687Ssam printf("Login timed out after %d seconds\n", timeout); 45612687Ssam exit(0); 45712687Ssam } 45812687Ssam 4591043Sbill int stopmotd; 4601043Sbill catch() 4611043Sbill { 4626466Swnj 4631043Sbill signal(SIGINT, SIG_IGN); 4641043Sbill stopmotd++; 4651043Sbill } 4661043Sbill 4672822Swnj rootterm(tty) 4686466Swnj char *tty; 4692822Swnj { 47016453Sroot register struct ttyent *t; 4712822Swnj 47216453Sroot if ((t = getttynam(tty)) != NULL) { 47316453Sroot if (t->ty_status & TTY_SECURE) 47416453Sroot return (1); 4752822Swnj } 47616453Sroot return (0); 4772822Swnj } 4782822Swnj 4791043Sbill showmotd() 4801043Sbill { 4811043Sbill FILE *mf; 4821043Sbill register c; 4831043Sbill 4841043Sbill signal(SIGINT, catch); 48516453Sroot if ((mf = fopen("/etc/motd", "r")) != NULL) { 4862822Swnj while ((c = getc(mf)) != EOF && stopmotd == 0) 4871043Sbill putchar(c); 4881043Sbill fclose(mf); 4891043Sbill } 4901043Sbill signal(SIGINT, SIG_IGN); 4911043Sbill } 4921043Sbill 4932822Swnj #undef UNKNOWN 4941043Sbill #define UNKNOWN "su" 4951043Sbill 4961043Sbill char * 4971043Sbill stypeof(ttyid) 49812687Ssam char *ttyid; 4991043Sbill { 50016453Sroot register struct ttyent *t; 5011043Sbill 50216453Sroot if (ttyid == NULL || (t = getttynam(ttyid)) == NULL) 5031043Sbill return (UNKNOWN); 50416453Sroot return (t->ty_type); 5051043Sbill } 5066005Swnj 50712687Ssam doremotelogin(host) 50812687Ssam char *host; 50912687Ssam { 51012687Ssam getstr(rusername, sizeof (rusername), "remuser"); 51112687Ssam getstr(lusername, sizeof (lusername), "locuser"); 51218549Ssam getstr(term, sizeof(term), "Terminal type"); 51313470Ssam if (getuid()) { 51413470Ssam pwd = &nouser; 51524712Sbloom return(-1); 51613470Ssam } 51712687Ssam pwd = getpwnam(lusername); 51813470Ssam if (pwd == NULL) { 51913470Ssam pwd = &nouser; 52024712Sbloom return(-1); 52113470Ssam } 52224712Sbloom return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername)); 52312687Ssam } 52412687Ssam 5256005Swnj getstr(buf, cnt, err) 5266005Swnj char *buf; 5276005Swnj int cnt; 5286005Swnj char *err; 5296005Swnj { 5306005Swnj char c; 5316005Swnj 5326005Swnj do { 5336005Swnj if (read(0, &c, 1) != 1) 5346005Swnj exit(1); 5356005Swnj if (--cnt < 0) { 5366005Swnj printf("%s too long\r\n", err); 5376005Swnj exit(1); 5386005Swnj } 5396005Swnj *buf++ = c; 5406005Swnj } while (c != 0); 5416005Swnj } 5426329Swnj 54312687Ssam char *speeds[] = 54412687Ssam { "0", "50", "75", "110", "134", "150", "200", "300", 54512687Ssam "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; 54612687Ssam #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0])) 54712687Ssam 54812687Ssam doremoteterm(term, tp) 54912687Ssam char *term; 55012687Ssam struct sgttyb *tp; 55112687Ssam { 55218549Ssam register char *cp = index(term, '/'), **cpp; 55318549Ssam char *speed; 55412687Ssam 55512687Ssam if (cp) { 55618549Ssam *cp++ = '\0'; 55718549Ssam speed = cp; 55818549Ssam cp = index(speed, '/'); 55918549Ssam if (cp) 56018549Ssam *cp++ = '\0'; 56118549Ssam for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) 56218549Ssam if (strcmp(*cpp, speed) == 0) { 56318549Ssam tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; 56412687Ssam break; 56512687Ssam } 56612687Ssam } 56712687Ssam tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; 56812687Ssam } 56918549Ssam 57027056Skarels tty_gid(default_gid) 57126876Smckusick int default_gid; 57226862Smckusick { 57326862Smckusick struct group *getgrnam(), *gr; 57426876Smckusick int gid = default_gid; 57526862Smckusick 57627056Skarels gr = getgrnam(TTYGRPNAME); 57726862Smckusick if (gr != (struct group *) 0) 57826862Smckusick gid = gr->gr_gid; 57926862Smckusick 58026862Smckusick endgrent(); 58126862Smckusick 58226876Smckusick return (gid); 58326862Smckusick } 584