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*42459Smarc static char sccsid[] = "@(#)main.c 5.8 (Berkeley) 05/30/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 23*42459Smarc #define USE_OLD_TTY 24*42459Smarc #include <sys/param.h> 25*42459Smarc #include <sys/signal.h> 26*42459Smarc #include <sys/file.h> 2713795Ssam #include <sgtty.h> 2813795Ssam #include <ctype.h> 2913795Ssam #include <setjmp.h> 3018543Sralph #include <syslog.h> 31*42459Smarc #include <ctype.h> 3213795Ssam #include "gettytab.h" 33*42459Smarc #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 54*42459Smarc char hostname[MAXHOSTNAMELEN]; 5513795Ssam char name[16]; 56*42459Smarc 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 { 13825954Sbloom strcpy(ttyn, dev); 13925954Sbloom strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); 14025954Sbloom if (strcmp(argv[0], "+") != 0) { 14118543Sralph chown(ttyn, 0, 0); 14218543Sralph chmod(ttyn, 0622); 14325553Smckusick /* 14425553Smckusick * Delay the open so DTR stays down long enough to be detected. 14525553Smckusick */ 14625553Smckusick sleep(2); 14718543Sralph while (open(ttyn, O_RDWR) != 0) { 14818543Sralph if (repcnt % 10 == 0) { 14924895Seric syslog(LOG_ERR, "%s: %m", ttyn); 15018543Sralph closelog(); 15118543Sralph } 15218543Sralph repcnt++; 15318543Sralph sleep(60); 15418543Sralph } 15518543Sralph signal(SIGHUP, SIG_IGN); 15618543Sralph vhangup(); 15718543Sralph (void) open(ttyn, O_RDWR); 15818543Sralph close(0); 15918543Sralph dup(1); 16018543Sralph dup(0); 16118543Sralph signal(SIGHUP, SIG_DFL); 162*42459Smarc if (ioctl(0, TIOCSCTTY, 0) < 0) 163*42459Smarc syslog(LOG_ERR, "TIOCSCTTY failed %m"); 16425954Sbloom } 16518543Sralph } 16618543Sralph 16713795Ssam gettable("default", defent, defstrs); 16813795Ssam gendefaults(); 16913795Ssam tname = "default"; 17013795Ssam if (argc > 1) 17113795Ssam tname = argv[1]; 17213795Ssam for (;;) { 17313795Ssam int ldisp = OTTYDISC; 17432209Sbostic int off = 0; 17513795Ssam 17613795Ssam gettable(tname, tabent, tabstrs); 17713828Skre if (OPset || EPset || APset) 17813828Skre APset++, OPset++, EPset++; 17913795Ssam setdefaults(); 18013795Ssam ioctl(0, TIOCFLUSH, 0); /* clear out the crap */ 18132209Sbostic ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */ 18232209Sbostic ioctl(0, FIOASYNC, &off); /* ditto for asynchronous mode */ 18313795Ssam if (IS) 18413795Ssam tmode.sg_ispeed = speed(IS); 18513795Ssam else if (SP) 18613795Ssam tmode.sg_ispeed = speed(SP); 18713795Ssam if (OS) 18813795Ssam tmode.sg_ospeed = speed(OS); 18913795Ssam else if (SP) 19013795Ssam tmode.sg_ospeed = speed(SP); 19113795Ssam tmode.sg_flags = setflags(0); 19213795Ssam ioctl(0, TIOCSETP, &tmode); 19313795Ssam setchars(); 19413795Ssam ioctl(0, TIOCSETC, &tc); 19513795Ssam ioctl(0, TIOCSETD, &ldisp); 19613795Ssam if (HC) 19713795Ssam ioctl(0, TIOCHPCL, 0); 19818543Sralph if (AB) { 19918543Sralph extern char *autobaud(); 20018543Sralph 20118543Sralph tname = autobaud(); 20218543Sralph continue; 20318543Sralph } 20413795Ssam if (PS) { 20513795Ssam tname = portselector(); 20613795Ssam continue; 20713795Ssam } 20813795Ssam if (CL && *CL) 20913795Ssam putpad(CL); 21013795Ssam edithost(HE); 21113795Ssam if (IM && *IM) 21213795Ssam putf(IM); 21313795Ssam if (setjmp(timeout)) { 21413795Ssam tmode.sg_ispeed = tmode.sg_ospeed = 0; 21513795Ssam ioctl(0, TIOCSETP, &tmode); 21613795Ssam exit(1); 21713795Ssam } 21813795Ssam if (TO) { 21913795Ssam signal(SIGALRM, dingdong); 22013795Ssam alarm(TO); 22113795Ssam } 22213795Ssam if (getname()) { 22318543Sralph register int i; 22418543Sralph 22518543Sralph oflush(); 22613795Ssam alarm(0); 22713795Ssam signal(SIGALRM, SIG_DFL); 22832308Sbostic if (name[0] == '-') { 229*42459Smarc puts("user names may not start with '-'."); 23032308Sbostic continue; 23132308Sbostic } 23213831Ssam if (!(upper || lower || digit)) 23313795Ssam continue; 23413795Ssam allflags = setflags(2); 23513795Ssam tmode.sg_flags = allflags & 0xffff; 23613795Ssam allflags >>= 16; 23713795Ssam if (crmod || NL) 23813795Ssam tmode.sg_flags |= CRMOD; 23913795Ssam if (upper || UC) 24013795Ssam tmode.sg_flags |= LCASE; 24113795Ssam if (lower || LC) 24213795Ssam tmode.sg_flags &= ~LCASE; 24313795Ssam ioctl(0, TIOCSETP, &tmode); 24413795Ssam ioctl(0, TIOCSLTC, <c); 24513795Ssam ioctl(0, TIOCLSET, &allflags); 24613828Skre signal(SIGINT, SIG_DFL); 24718543Sralph for (i = 0; environ[i] != (char *)0; i++) 24818543Sralph env[i] = environ[i]; 24918543Sralph makeenv(&env[i]); 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 } 303*42459Smarc if (islower(c)) 30413795Ssam lower++; 305*42459Smarc 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; 327*42459Smarc } 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 { 43718543Sralph char *ttyn, *slash; 43818543Sralph char datebuffer[60]; 43913795Ssam extern char editedhost[]; 44018543Sralph extern char *ttyname(), *rindex(); 44113795Ssam 44213795Ssam while (*cp) { 44313795Ssam if (*cp != '%') { 44413795Ssam putchr(*cp++); 44513795Ssam continue; 44613795Ssam } 44713795Ssam switch (*++cp) { 44813795Ssam 44918543Sralph case 't': 45018543Sralph ttyn = ttyname(0); 45118543Sralph slash = rindex(ttyn, '/'); 45218543Sralph if (slash == (char *) 0) 45318543Sralph puts(ttyn); 45418543Sralph else 45518543Sralph puts(&slash[1]); 45618543Sralph break; 45718543Sralph 45813795Ssam case 'h': 45913795Ssam puts(editedhost); 46013795Ssam break; 46113795Ssam 46218543Sralph case 'd': 46318543Sralph get_date(datebuffer); 46418543Sralph puts(datebuffer); 46515713Sralph break; 46615713Sralph 46713795Ssam case '%': 46813795Ssam putchr('%'); 46913795Ssam break; 47013795Ssam } 47113795Ssam cp++; 47213795Ssam } 47313795Ssam } 474