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*44640Smarc static char sccsid[] = "@(#)main.c 5.11 (Berkeley) 06/29/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 { 13844567Smarc int i; 13944567Smarc 14025954Sbloom strcpy(ttyn, dev); 14125954Sbloom strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 14225954Sbloom if (strcmp(argv[0], "+") != 0) { 14318543Sralph chown(ttyn, 0, 0); 14444567Smarc chmod(ttyn, 0600); 14544567Smarc revoke(ttyn); 14625553Smckusick /* 14725553Smckusick * Delay the open so DTR stays down long enough to be detected. 14825553Smckusick */ 14925553Smckusick sleep(2); 15044567Smarc 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 } 15844567Smarc 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 if (HC) 19113795Ssam ioctl(0, TIOCHPCL, 0); 19218543Sralph if (AB) { 19318543Sralph extern char *autobaud(); 19418543Sralph 19518543Sralph tname = autobaud(); 19618543Sralph continue; 19718543Sralph } 19813795Ssam if (PS) { 19913795Ssam tname = portselector(); 20013795Ssam continue; 20113795Ssam } 20213795Ssam if (CL && *CL) 20313795Ssam putpad(CL); 20413795Ssam edithost(HE); 20513795Ssam if (IM && *IM) 20613795Ssam putf(IM); 20713795Ssam if (setjmp(timeout)) { 20813795Ssam tmode.sg_ispeed = tmode.sg_ospeed = 0; 20913795Ssam ioctl(0, TIOCSETP, &tmode); 21013795Ssam exit(1); 21113795Ssam } 21213795Ssam if (TO) { 21313795Ssam signal(SIGALRM, dingdong); 21413795Ssam alarm(TO); 21513795Ssam } 21613795Ssam if (getname()) { 21718543Sralph register int i; 21818543Sralph 21918543Sralph oflush(); 22013795Ssam alarm(0); 22113795Ssam signal(SIGALRM, SIG_DFL); 22232308Sbostic if (name[0] == '-') { 22342459Smarc puts("user names may not start with '-'."); 22432308Sbostic continue; 22532308Sbostic } 22613831Ssam if (!(upper || lower || digit)) 22713795Ssam continue; 22813795Ssam allflags = setflags(2); 22913795Ssam tmode.sg_flags = allflags & 0xffff; 23013795Ssam allflags >>= 16; 23113795Ssam if (crmod || NL) 23213795Ssam tmode.sg_flags |= CRMOD; 23313795Ssam if (upper || UC) 23413795Ssam tmode.sg_flags |= LCASE; 23513795Ssam if (lower || LC) 23613795Ssam tmode.sg_flags &= ~LCASE; 23713795Ssam ioctl(0, TIOCSETP, &tmode); 23813795Ssam ioctl(0, TIOCSLTC, <c); 23913795Ssam ioctl(0, TIOCLSET, &allflags); 24013828Skre signal(SIGINT, SIG_DFL); 24118543Sralph for (i = 0; environ[i] != (char *)0; i++) 24218543Sralph env[i] = environ[i]; 24318543Sralph makeenv(&env[i]); 244*44640Smarc 245*44640Smarc /* 246*44640Smarc * this is what login was doing anyway. 247*44640Smarc * soon we rewrite getty completely. 248*44640Smarc */ 249*44640Smarc set_ttydefaults(0); 25018543Sralph execle(LO, "login", "-p", name, (char *) 0, env); 25132209Sbostic syslog(LOG_ERR, "%s: %m", LO); 25213795Ssam exit(1); 25313795Ssam } 25413795Ssam alarm(0); 25513795Ssam signal(SIGALRM, SIG_DFL); 25613828Skre signal(SIGINT, SIG_IGN); 25713795Ssam if (NX && *NX) 25813795Ssam tname = NX; 25913795Ssam } 26013795Ssam } 26113795Ssam 26213795Ssam getname() 26313795Ssam { 26413795Ssam register char *np; 26513795Ssam register c; 26613795Ssam char cs; 26713795Ssam 26813828Skre /* 26913831Ssam * Interrupt may happen if we use CBREAK mode 27013828Skre */ 27113828Skre if (setjmp(intrupt)) { 27213828Skre signal(SIGINT, SIG_IGN); 27313828Skre return (0); 27413828Skre } 27513828Skre signal(SIGINT, interrupt); 27613795Ssam tmode.sg_flags = setflags(0); 27713795Ssam ioctl(0, TIOCSETP, &tmode); 27813795Ssam tmode.sg_flags = setflags(1); 27913795Ssam prompt(); 28013885Ssam if (PF > 0) { 28114322Ssam oflush(); 28213885Ssam sleep(PF); 28313885Ssam PF = 0; 28413885Ssam } 28513795Ssam ioctl(0, TIOCSETP, &tmode); 28613795Ssam crmod = 0; 28713795Ssam upper = 0; 28813795Ssam lower = 0; 28913795Ssam digit = 0; 29013795Ssam np = name; 29113795Ssam for (;;) { 29213828Skre oflush(); 29313795Ssam if (read(0, &cs, 1) <= 0) 29413795Ssam exit(0); 29513795Ssam if ((c = cs&0177) == 0) 29613795Ssam return (0); 29713831Ssam if (c == EOT) 29813795Ssam exit(1); 29918543Sralph if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { 30018543Sralph putf("\r\n"); 30113795Ssam break; 30218543Sralph } 30342459Smarc if (islower(c)) 30413795Ssam lower++; 30542459Smarc else if (isupper(c)) 30613795Ssam upper++; 30718543Sralph else if (c == ERASE || c == '#' || c == '\b') { 30813795Ssam if (np > name) { 30913795Ssam np--; 31013795Ssam if (tmode.sg_ospeed >= B1200) 31113795Ssam puts("\b \b"); 31213795Ssam else 31313795Ssam putchr(cs); 31413795Ssam } 31513795Ssam continue; 31613831Ssam } else if (c == KILL || c == '@') { 31713795Ssam putchr(cs); 31813795Ssam putchr('\r'); 31913795Ssam if (tmode.sg_ospeed < B1200) 32013795Ssam putchr('\n'); 32113795Ssam /* this is the way they do it down under ... */ 32213795Ssam else if (np > name) 32313795Ssam puts(" \r"); 32413795Ssam prompt(); 32513795Ssam np = name; 32613795Ssam continue; 32742459Smarc } else if (isdigit(c)) 32813795Ssam digit++; 32918543Sralph if (IG && (c <= ' ' || c > 0176)) 33013795Ssam continue; 33113795Ssam *np++ = c; 33213795Ssam putchr(cs); 33313795Ssam } 33413828Skre signal(SIGINT, SIG_IGN); 33513795Ssam *np = 0; 33613795Ssam if (c == '\r') 33713795Ssam crmod++; 33813795Ssam if (upper && !lower && !LC || UC) 33913795Ssam for (np = name; *np; np++) 34013795Ssam if (isupper(*np)) 34113795Ssam *np = tolower(*np); 34213795Ssam return (1); 34313795Ssam } 34413795Ssam 34513795Ssam static 34613795Ssam short tmspc10[] = { 34713795Ssam 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 34813795Ssam }; 34913795Ssam 35013795Ssam putpad(s) 35113795Ssam register char *s; 35213795Ssam { 35313795Ssam register pad = 0; 35413795Ssam register mspc10; 35513795Ssam 35613795Ssam if (isdigit(*s)) { 35713795Ssam while (isdigit(*s)) { 35813795Ssam pad *= 10; 35913795Ssam pad += *s++ - '0'; 36013795Ssam } 36113795Ssam pad *= 10; 36213795Ssam if (*s == '.' && isdigit(s[1])) { 36313795Ssam pad += s[1] - '0'; 36413795Ssam s += 2; 36513795Ssam } 36613795Ssam } 36713795Ssam 36813795Ssam puts(s); 36913795Ssam /* 37013795Ssam * If no delay needed, or output speed is 37113795Ssam * not comprehensible, then don't try to delay. 37213795Ssam */ 37313795Ssam if (pad == 0) 37413795Ssam return; 37513795Ssam if (tmode.sg_ospeed <= 0 || 37613795Ssam tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) 37713795Ssam return; 37813795Ssam 37913795Ssam /* 38013795Ssam * Round up by a half a character frame, 38113795Ssam * and then do the delay. 38213795Ssam * Too bad there are no user program accessible programmed delays. 38313795Ssam * Transmitting pad characters slows many 38413795Ssam * terminals down and also loads the system. 38513795Ssam */ 38613795Ssam mspc10 = tmspc10[tmode.sg_ospeed]; 38713795Ssam pad += mspc10 / 2; 38813795Ssam for (pad /= mspc10; pad > 0; pad--) 38913795Ssam putchr(*PC); 39013795Ssam } 39113795Ssam 39213795Ssam puts(s) 39313795Ssam register char *s; 39413795Ssam { 39513795Ssam 39613795Ssam while (*s) 39713795Ssam putchr(*s++); 39813795Ssam } 39913795Ssam 40013828Skre char outbuf[OBUFSIZ]; 40113828Skre int obufcnt = 0; 40213828Skre 40313795Ssam putchr(cc) 40413795Ssam { 40513795Ssam char c; 40613795Ssam 40713795Ssam c = cc; 40813795Ssam c |= partab[c&0177] & 0200; 40913795Ssam if (OP) 41013795Ssam c ^= 0200; 41113828Skre if (!UB) { 41213828Skre outbuf[obufcnt++] = c; 41313828Skre if (obufcnt >= OBUFSIZ) 41413828Skre oflush(); 41513828Skre } else 41613828Skre write(1, &c, 1); 41713795Ssam } 41813795Ssam 41913828Skre oflush() 42013828Skre { 42113828Skre if (obufcnt) 42213828Skre write(1, outbuf, obufcnt); 42313828Skre obufcnt = 0; 42413828Skre } 42513828Skre 42613795Ssam prompt() 42713795Ssam { 42813795Ssam 42913795Ssam putf(LM); 43013795Ssam if (CO) 43113795Ssam putchr('\n'); 43213795Ssam } 43313795Ssam 43413795Ssam putf(cp) 43513795Ssam register char *cp; 43613795Ssam { 43742460Smckusick char *slash; 43818543Sralph char datebuffer[60]; 43913795Ssam extern char editedhost[]; 44042460Smckusick extern char *rindex(); 44113795Ssam 44213795Ssam while (*cp) { 44313795Ssam if (*cp != '%') { 44413795Ssam putchr(*cp++); 44513795Ssam continue; 44613795Ssam } 44713795Ssam switch (*++cp) { 44813795Ssam 44918543Sralph case 't': 45018543Sralph slash = rindex(ttyn, '/'); 45118543Sralph if (slash == (char *) 0) 45218543Sralph puts(ttyn); 45318543Sralph else 45418543Sralph puts(&slash[1]); 45518543Sralph break; 45618543Sralph 45713795Ssam case 'h': 45813795Ssam puts(editedhost); 45913795Ssam break; 46013795Ssam 46118543Sralph case 'd': 46218543Sralph get_date(datebuffer); 46318543Sralph puts(datebuffer); 46415713Sralph break; 46515713Sralph 46613795Ssam case '%': 46713795Ssam putchr('%'); 46813795Ssam break; 46913795Ssam } 47013795Ssam cp++; 47113795Ssam } 47213795Ssam } 473