119054Sdist /* 219054Sdist * Copyright (c) 1980 Regents of the University of California. 319054Sdist * All rights reserved. The Berkeley software License Agreement 419054Sdist * specifies the terms and conditions for redistribution. 519054Sdist */ 619054Sdist 713795Ssam #ifndef lint 819054Sdist char copyright[] = 919054Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1019054Sdist All rights reserved.\n"; 1119054Sdist #endif not lint 1213795Ssam 1319054Sdist #ifndef lint 14*44567Smarc static char sccsid[] = "@(#)main.c 5.10 (Berkeley) 06/28/90"; 1519054Sdist #endif not lint 1619054Sdist 1713795Ssam /* 1813795Ssam * getty -- adapt to terminal speed on dialup, and call login 1913795Ssam * 2013795Ssam * Melbourne getty, June 83, kre. 2113795Ssam */ 2213795Ssam 2342459Smarc #define USE_OLD_TTY 2442459Smarc #include <sys/param.h> 2542459Smarc #include <sys/signal.h> 2642459Smarc #include <sys/file.h> 2713795Ssam #include <sgtty.h> 2813795Ssam #include <ctype.h> 2913795Ssam #include <setjmp.h> 3018543Sralph #include <syslog.h> 3142459Smarc #include <ctype.h> 3213795Ssam #include "gettytab.h" 3342459Smarc #include "pathnames.h" 3413795Ssam 3518543Sralph extern char **environ; 3618543Sralph 3713795Ssam struct sgttyb tmode = { 3813795Ssam 0, 0, CERASE, CKILL, 0 3913795Ssam }; 4013795Ssam struct tchars tc = { 4113795Ssam CINTR, CQUIT, CSTART, 4213795Ssam CSTOP, CEOF, CBRK, 4313795Ssam }; 4413795Ssam struct ltchars ltc = { 4513795Ssam CSUSP, CDSUSP, CRPRNT, 4613795Ssam CFLUSH, CWERASE, CLNEXT 4713795Ssam }; 4813795Ssam 4913795Ssam int crmod; 5013795Ssam int upper; 5113795Ssam int lower; 5213795Ssam int digit; 5313795Ssam 5442459Smarc char hostname[MAXHOSTNAMELEN]; 5513795Ssam char name[16]; 5642459Smarc char dev[] = _PATH_DEV; 5718543Sralph char ttyn[32]; 5813795Ssam char *portselector(); 5918543Sralph char *ttyname(); 6013795Ssam 6113828Skre #define OBUFSIZ 128 6213795Ssam #define TABBUFSIZ 512 6313795Ssam 6413795Ssam char defent[TABBUFSIZ]; 6513795Ssam char defstrs[TABBUFSIZ]; 6613795Ssam char tabent[TABBUFSIZ]; 6713795Ssam char tabstrs[TABBUFSIZ]; 6813795Ssam 6913795Ssam char *env[128]; 7013795Ssam 7113795Ssam char partab[] = { 7213795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 7313795Ssam 0202,0004,0003,0205,0005,0206,0201,0001, 7413795Ssam 0201,0001,0001,0201,0001,0201,0201,0001, 7513795Ssam 0001,0201,0201,0001,0201,0001,0001,0201, 7613795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 7713795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 7813795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 7913795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 8013795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 8113795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 8213795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 8313795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 8413795Ssam 0000,0200,0200,0000,0200,0000,0000,0200, 8513795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 8613795Ssam 0200,0000,0000,0200,0000,0200,0200,0000, 8713795Ssam 0000,0200,0200,0000,0200,0000,0000,0201 8813795Ssam }; 8913795Ssam 9013795Ssam #define ERASE tmode.sg_erase 9113795Ssam #define KILL tmode.sg_kill 9213795Ssam #define EOT tc.t_eofc 9313795Ssam 9413795Ssam jmp_buf timeout; 9513795Ssam 9613795Ssam dingdong() 9713795Ssam { 9813795Ssam 9913795Ssam alarm(0); 10013795Ssam signal(SIGALRM, SIG_DFL); 10113795Ssam longjmp(timeout, 1); 10213795Ssam } 10313795Ssam 10413828Skre jmp_buf intrupt; 10513828Skre 10613828Skre interrupt() 10713828Skre { 10813828Skre 10913828Skre signal(SIGINT, interrupt); 11013828Skre longjmp(intrupt, 1); 11113828Skre } 11213828Skre 11313795Ssam main(argc, argv) 11413795Ssam char *argv[]; 11513795Ssam { 11613795Ssam char *tname; 11713795Ssam long allflags; 11818543Sralph int repcnt = 0; 11913795Ssam 12013828Skre signal(SIGINT, SIG_IGN); 12113795Ssam /* 12213795Ssam signal(SIGQUIT, SIG_DFL); 12313795Ssam */ 12424890Seric openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH); 12513795Ssam gethostname(hostname, sizeof(hostname)); 12613795Ssam if (hostname[0] == '\0') 12713795Ssam strcpy(hostname, "Amnesiac"); 12818543Sralph /* 12918543Sralph * The following is a work around for vhangup interactions 13018543Sralph * which cause great problems getting window systems started. 13118543Sralph * If the tty line is "-", we do the old style getty presuming 13218543Sralph * that the file descriptors are already set up for us. 13318543Sralph * J. Gettys - MIT Project Athena. 13418543Sralph */ 13518543Sralph if (argc <= 2 || strcmp(argv[2], "-") == 0) 13625954Sbloom strcpy(ttyn, ttyname(0)); 13718543Sralph else { 138*44567Smarc int i; 139*44567Smarc 14025954Sbloom strcpy(ttyn, dev); 14125954Sbloom strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 14225954Sbloom if (strcmp(argv[0], "+") != 0) { 14318543Sralph chown(ttyn, 0, 0); 144*44567Smarc chmod(ttyn, 0600); 145*44567Smarc revoke(ttyn); 14625553Smckusick /* 14725553Smckusick * Delay the open so DTR stays down long enough to be detected. 14825553Smckusick */ 14925553Smckusick sleep(2); 150*44567Smarc while ((i = open(ttyn, O_RDWR)) == -1) { 15118543Sralph if (repcnt % 10 == 0) { 15224895Seric syslog(LOG_ERR, "%s: %m", ttyn); 15318543Sralph closelog(); 15418543Sralph } 15518543Sralph repcnt++; 15618543Sralph sleep(60); 15718543Sralph } 158*44567Smarc login_tty(i); 15925954Sbloom } 16018543Sralph } 16118543Sralph 16213795Ssam gettable("default", defent, defstrs); 16313795Ssam gendefaults(); 16413795Ssam tname = "default"; 16513795Ssam if (argc > 1) 16613795Ssam tname = argv[1]; 16713795Ssam for (;;) { 16813795Ssam int ldisp = OTTYDISC; 16932209Sbostic int off = 0; 17013795Ssam 17113795Ssam gettable(tname, tabent, tabstrs); 17213828Skre if (OPset || EPset || APset) 17313828Skre APset++, OPset++, EPset++; 17413795Ssam setdefaults(); 17513795Ssam ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ 17632209Sbostic ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ 17732209Sbostic ioctl(0, FIOASYNC, &off); /* ditto for asynchronous mode */ 17813795Ssam if (IS) 17913795Ssam tmode.sg_ispeed = speed(IS); 18013795Ssam else if (SP) 18113795Ssam tmode.sg_ispeed = speed(SP); 18213795Ssam if (OS) 18313795Ssam tmode.sg_ospeed = speed(OS); 18413795Ssam else if (SP) 18513795Ssam tmode.sg_ospeed = speed(SP); 18613795Ssam tmode.sg_flags = setflags(0); 18713795Ssam ioctl(0, TIOCSETP, &tmode); 18813795Ssam setchars(); 18913795Ssam ioctl(0, TIOCSETC, &tc); 19013795Ssam ioctl(0, TIOCSETD, &ldisp); 19113795Ssam if (HC) 19213795Ssam ioctl(0, TIOCHPCL, 0); 19318543Sralph if (AB) { 19418543Sralph extern char *autobaud(); 19518543Sralph 19618543Sralph tname = autobaud(); 19718543Sralph continue; 19818543Sralph } 19913795Ssam if (PS) { 20013795Ssam tname = portselector(); 20113795Ssam continue; 20213795Ssam } 20313795Ssam if (CL && *CL) 20413795Ssam putpad(CL); 20513795Ssam edithost(HE); 20613795Ssam if (IM && *IM) 20713795Ssam putf(IM); 20813795Ssam if (setjmp(timeout)) { 20913795Ssam tmode.sg_ispeed = tmode.sg_ospeed = 0; 21013795Ssam ioctl(0, TIOCSETP, &tmode); 21113795Ssam exit(1); 21213795Ssam } 21313795Ssam if (TO) { 21413795Ssam signal(SIGALRM, dingdong); 21513795Ssam alarm(TO); 21613795Ssam } 21713795Ssam if (getname()) { 21818543Sralph register int i; 21918543Sralph 22018543Sralph oflush(); 22113795Ssam alarm(0); 22213795Ssam signal(SIGALRM, SIG_DFL); 22332308Sbostic if (name[0] == '-') { 22442459Smarc puts("user names may not start with '-'."); 22532308Sbostic continue; 22632308Sbostic } 22713831Ssam if (!(upper || lower || digit)) 22813795Ssam continue; 22913795Ssam allflags = setflags(2); 23013795Ssam tmode.sg_flags = allflags & 0xffff; 23113795Ssam allflags >>= 16; 23213795Ssam if (crmod || NL) 23313795Ssam tmode.sg_flags |= CRMOD; 23413795Ssam if (upper || UC) 23513795Ssam tmode.sg_flags |= LCASE; 23613795Ssam if (lower || LC) 23713795Ssam tmode.sg_flags &= ~LCASE; 23813795Ssam ioctl(0, TIOCSETP, &tmode); 23913795Ssam ioctl(0, TIOCSLTC, <c); 24013795Ssam ioctl(0, TIOCLSET, &allflags); 24113828Skre signal(SIGINT, SIG_DFL); 24218543Sralph for (i = 0; environ[i] != (char *)0; i++) 24318543Sralph env[i] = environ[i]; 24418543Sralph makeenv(&env[i]); 24518543Sralph execle(LO, "login", "-p", name, (char *) 0, env); 24632209Sbostic syslog(LOG_ERR, "%s: %m", LO); 24713795Ssam exit(1); 24813795Ssam } 24913795Ssam alarm(0); 25013795Ssam signal(SIGALRM, SIG_DFL); 25113828Skre signal(SIGINT, SIG_IGN); 25213795Ssam if (NX && *NX) 25313795Ssam tname = NX; 25413795Ssam } 25513795Ssam } 25613795Ssam 25713795Ssam getname() 25813795Ssam { 25913795Ssam register char *np; 26013795Ssam register c; 26113795Ssam char cs; 26213795Ssam 26313828Skre /* 26413831Ssam * Interrupt may happen if we use CBREAK mode 26513828Skre */ 26613828Skre if (setjmp(intrupt)) { 26713828Skre signal(SIGINT, SIG_IGN); 26813828Skre return (0); 26913828Skre } 27013828Skre signal(SIGINT, interrupt); 27113795Ssam tmode.sg_flags = setflags(0); 27213795Ssam ioctl(0, TIOCSETP, &tmode); 27313795Ssam tmode.sg_flags = setflags(1); 27413795Ssam prompt(); 27513885Ssam if (PF > 0) { 27614322Ssam oflush(); 27713885Ssam sleep(PF); 27813885Ssam PF = 0; 27913885Ssam } 28013795Ssam ioctl(0, TIOCSETP, &tmode); 28113795Ssam crmod = 0; 28213795Ssam upper = 0; 28313795Ssam lower = 0; 28413795Ssam digit = 0; 28513795Ssam np = name; 28613795Ssam for (;;) { 28713828Skre oflush(); 28813795Ssam if (read(0, &cs, 1) <= 0) 28913795Ssam exit(0); 29013795Ssam if ((c = cs&0177) == 0) 29113795Ssam return (0); 29213831Ssam if (c == EOT) 29313795Ssam exit(1); 29418543Sralph if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { 29518543Sralph putf("\r\n"); 29613795Ssam break; 29718543Sralph } 29842459Smarc if (islower(c)) 29913795Ssam lower++; 30042459Smarc else if (isupper(c)) 30113795Ssam upper++; 30218543Sralph else if (c == ERASE || c == '#' || c == '\b') { 30313795Ssam if (np > name) { 30413795Ssam np--; 30513795Ssam if (tmode.sg_ospeed >= B1200) 30613795Ssam puts("\b \b"); 30713795Ssam else 30813795Ssam putchr(cs); 30913795Ssam } 31013795Ssam continue; 31113831Ssam } else if (c == KILL || c == '@') { 31213795Ssam putchr(cs); 31313795Ssam putchr('\r'); 31413795Ssam if (tmode.sg_ospeed < B1200) 31513795Ssam putchr('\n'); 31613795Ssam /* this is the way they do it down under ... */ 31713795Ssam else if (np > name) 31813795Ssam puts(" \r"); 31913795Ssam prompt(); 32013795Ssam np = name; 32113795Ssam continue; 32242459Smarc } else if (isdigit(c)) 32313795Ssam digit++; 32418543Sralph if (IG && (c <= ' ' || c > 0176)) 32513795Ssam continue; 32613795Ssam *np++ = c; 32713795Ssam putchr(cs); 32813795Ssam } 32913828Skre signal(SIGINT, SIG_IGN); 33013795Ssam *np = 0; 33113795Ssam if (c == '\r') 33213795Ssam crmod++; 33313795Ssam if (upper && !lower && !LC || UC) 33413795Ssam for (np = name; *np; np++) 33513795Ssam if (isupper(*np)) 33613795Ssam *np = tolower(*np); 33713795Ssam return (1); 33813795Ssam } 33913795Ssam 34013795Ssam static 34113795Ssam short tmspc10[] = { 34213795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 34313795Ssam }; 34413795Ssam 34513795Ssam putpad(s) 34613795Ssam register char *s; 34713795Ssam { 34813795Ssam register pad = 0; 34913795Ssam register mspc10; 35013795Ssam 35113795Ssam if (isdigit(*s)) { 35213795Ssam while (isdigit(*s)) { 35313795Ssam pad *= 10; 35413795Ssam pad += *s++ - '0'; 35513795Ssam } 35613795Ssam pad *= 10; 35713795Ssam if (*s == '.' && isdigit(s[1])) { 35813795Ssam pad += s[1] - '0'; 35913795Ssam s += 2; 36013795Ssam } 36113795Ssam } 36213795Ssam 36313795Ssam puts(s); 36413795Ssam /* 36513795Ssam * If no delay needed, or output speed is 36613795Ssam * not comprehensible, then don't try to delay. 36713795Ssam */ 36813795Ssam if (pad == 0) 36913795Ssam return; 37013795Ssam if (tmode.sg_ospeed <= 0 || 37113795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 37213795Ssam return; 37313795Ssam 37413795Ssam /* 37513795Ssam * Round up by a half a character frame, 37613795Ssam * and then do the delay. 37713795Ssam * Too bad there are no user program accessible programmed delays. 37813795Ssam * Transmitting pad characters slows many 37913795Ssam * terminals down and also loads the system. 38013795Ssam */ 38113795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 38213795Ssam pad += mspc10 / 2; 38313795Ssam for (pad /= mspc10; pad > 0; pad--) 38413795Ssam putchr(*PC); 38513795Ssam } 38613795Ssam 38713795Ssam puts(s) 38813795Ssam register char *s; 38913795Ssam { 39013795Ssam 39113795Ssam while (*s) 39213795Ssam putchr(*s++); 39313795Ssam } 39413795Ssam 39513828Skre char outbuf[OBUFSIZ]; 39613828Skre int obufcnt = 0; 39713828Skre 39813795Ssam putchr(cc) 39913795Ssam { 40013795Ssam char c; 40113795Ssam 40213795Ssam c = cc; 40313795Ssam c |= partab[c&0177] & 0200; 40413795Ssam if (OP) 40513795Ssam c ^= 0200; 40613828Skre if (!UB) { 40713828Skre outbuf[obufcnt++] = c; 40813828Skre if (obufcnt >= OBUFSIZ) 40913828Skre oflush(); 41013828Skre } else 41113828Skre write(1, &c, 1); 41213795Ssam } 41313795Ssam 41413828Skre oflush() 41513828Skre { 41613828Skre if (obufcnt) 41713828Skre write(1, outbuf, obufcnt); 41813828Skre obufcnt = 0; 41913828Skre } 42013828Skre 42113795Ssam prompt() 42213795Ssam { 42313795Ssam 42413795Ssam putf(LM); 42513795Ssam if (CO) 42613795Ssam putchr('\n'); 42713795Ssam } 42813795Ssam 42913795Ssam putf(cp) 43013795Ssam register char *cp; 43113795Ssam { 43242460Smckusick char *slash; 43318543Sralph char datebuffer[60]; 43413795Ssam extern char editedhost[]; 43542460Smckusick extern char *rindex(); 43613795Ssam 43713795Ssam while (*cp) { 43813795Ssam if (*cp != '%') { 43913795Ssam putchr(*cp++); 44013795Ssam continue; 44113795Ssam } 44213795Ssam switch (*++cp) { 44313795Ssam 44418543Sralph case 't': 44518543Sralph slash = rindex(ttyn, '/'); 44618543Sralph if (slash == (char *) 0) 44718543Sralph puts(ttyn); 44818543Sralph else 44918543Sralph puts(&slash[1]); 45018543Sralph break; 45118543Sralph 45213795Ssam case 'h': 45313795Ssam puts(editedhost); 45413795Ssam break; 45513795Ssam 45618543Sralph case 'd': 45718543Sralph get_date(datebuffer); 45818543Sralph puts(datebuffer); 45915713Sralph break; 46015713Sralph 46113795Ssam case '%': 46213795Ssam putchr('%'); 46313795Ssam break; 46413795Ssam } 46513795Ssam cp++; 46613795Ssam } 46713795Ssam } 468