|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)main.c 5.11 (Berkeley) 6/29/90";
15: #endif not lint
16:
17: /*
18: * getty -- adapt to terminal speed on dialup, and call login
19: *
20: * Melbourne getty, June 83, kre.
21: */
22:
23: #define USE_OLD_TTY
24: #include <sys/param.h>
25: #include <sys/signal.h>
26: #include <sys/file.h>
27: #include <sgtty.h>
28: #include <ctype.h>
29: #include <setjmp.h>
30: #include <syslog.h>
31: #include <ctype.h>
32: #include "gettytab.h"
33: #include "pathnames.h"
34:
35: extern char **environ;
36:
37: struct sgttyb tmode = {
38: 0, 0, CERASE, CKILL, 0
39: };
40: struct tchars tc = {
41: CINTR, CQUIT, CSTART,
42: CSTOP, CEOF, CBRK,
43: };
44: struct ltchars ltc = {
45: CSUSP, CDSUSP, CRPRNT,
46: CFLUSH, CWERASE, CLNEXT
47: };
48:
49: int crmod;
50: int upper;
51: int lower;
52: int digit;
53:
54: char hostname[MAXHOSTNAMELEN];
55: char name[16];
56: char dev[] = _PATH_DEV;
57: char ttyn[32];
58: char *portselector();
59: char *ttyname();
60:
61: #define OBUFSIZ 128
62: #define TABBUFSIZ 512
63:
64: char defent[TABBUFSIZ];
65: char defstrs[TABBUFSIZ];
66: char tabent[TABBUFSIZ];
67: char tabstrs[TABBUFSIZ];
68:
69: char *env[128];
70:
71: char partab[] = {
72: 0001,0201,0201,0001,0201,0001,0001,0201,
73: 0202,0004,0003,0205,0005,0206,0201,0001,
74: 0201,0001,0001,0201,0001,0201,0201,0001,
75: 0001,0201,0201,0001,0201,0001,0001,0201,
76: 0200,0000,0000,0200,0000,0200,0200,0000,
77: 0000,0200,0200,0000,0200,0000,0000,0200,
78: 0000,0200,0200,0000,0200,0000,0000,0200,
79: 0200,0000,0000,0200,0000,0200,0200,0000,
80: 0200,0000,0000,0200,0000,0200,0200,0000,
81: 0000,0200,0200,0000,0200,0000,0000,0200,
82: 0000,0200,0200,0000,0200,0000,0000,0200,
83: 0200,0000,0000,0200,0000,0200,0200,0000,
84: 0000,0200,0200,0000,0200,0000,0000,0200,
85: 0200,0000,0000,0200,0000,0200,0200,0000,
86: 0200,0000,0000,0200,0000,0200,0200,0000,
87: 0000,0200,0200,0000,0200,0000,0000,0201
88: };
89:
90: #define ERASE tmode.sg_erase
91: #define KILL tmode.sg_kill
92: #define EOT tc.t_eofc
93:
94: jmp_buf timeout;
95:
96: dingdong()
97: {
98:
99: alarm(0);
100: signal(SIGALRM, SIG_DFL);
101: longjmp(timeout, 1);
102: }
103:
104: jmp_buf intrupt;
105:
106: interrupt()
107: {
108:
109: signal(SIGINT, interrupt);
110: longjmp(intrupt, 1);
111: }
112:
113: main(argc, argv)
114: char *argv[];
115: {
116: char *tname;
117: long allflags;
118: int repcnt = 0;
119:
120: signal(SIGINT, SIG_IGN);
121: /*
122: signal(SIGQUIT, SIG_DFL);
123: */
124: openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH);
125: gethostname(hostname, sizeof(hostname));
126: if (hostname[0] == '\0')
127: strcpy(hostname, "Amnesiac");
128: /*
129: * The following is a work around for vhangup interactions
130: * which cause great problems getting window systems started.
131: * If the tty line is "-", we do the old style getty presuming
132: * that the file descriptors are already set up for us.
133: * J. Gettys - MIT Project Athena.
134: */
135: if (argc <= 2 || strcmp(argv[2], "-") == 0)
136: strcpy(ttyn, ttyname(0));
137: else {
138: int i;
139:
140: strcpy(ttyn, dev);
141: strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
142: if (strcmp(argv[0], "+") != 0) {
143: chown(ttyn, 0, 0);
144: chmod(ttyn, 0600);
145: revoke(ttyn);
146: /*
147: * Delay the open so DTR stays down long enough to be detected.
148: */
149: sleep(2);
150: while ((i = open(ttyn, O_RDWR)) == -1) {
151: if (repcnt % 10 == 0) {
152: syslog(LOG_ERR, "%s: %m", ttyn);
153: closelog();
154: }
155: repcnt++;
156: sleep(60);
157: }
158: login_tty(i);
159: }
160: }
161:
162: gettable("default", defent, defstrs);
163: gendefaults();
164: tname = "default";
165: if (argc > 1)
166: tname = argv[1];
167: for (;;) {
168: int ldisp = OTTYDISC;
169: int off = 0;
170:
171: gettable(tname, tabent, tabstrs);
172: if (OPset || EPset || APset)
173: APset++, OPset++, EPset++;
174: setdefaults();
175: ioctl(0, TIOCFLUSH, 0); /* clear out the crap */
176: ioctl(0, FIONBIO, &off); /* turn off non-blocking mode */
177: ioctl(0, FIOASYNC, &off); /* ditto for asynchronous mode */
178: if (IS)
179: tmode.sg_ispeed = speed(IS);
180: else if (SP)
181: tmode.sg_ispeed = speed(SP);
182: if (OS)
183: tmode.sg_ospeed = speed(OS);
184: else if (SP)
185: tmode.sg_ospeed = speed(SP);
186: tmode.sg_flags = setflags(0);
187: ioctl(0, TIOCSETP, &tmode);
188: setchars();
189: ioctl(0, TIOCSETC, &tc);
190: if (HC)
191: ioctl(0, TIOCHPCL, 0);
192: if (AB) {
193: extern char *autobaud();
194:
195: tname = autobaud();
196: continue;
197: }
198: if (PS) {
199: tname = portselector();
200: continue;
201: }
202: if (CL && *CL)
203: putpad(CL);
204: edithost(HE);
205: if (IM && *IM)
206: putf(IM);
207: if (setjmp(timeout)) {
208: tmode.sg_ispeed = tmode.sg_ospeed = 0;
209: ioctl(0, TIOCSETP, &tmode);
210: exit(1);
211: }
212: if (TO) {
213: signal(SIGALRM, dingdong);
214: alarm(TO);
215: }
216: if (getname()) {
217: register int i;
218:
219: oflush();
220: alarm(0);
221: signal(SIGALRM, SIG_DFL);
222: if (name[0] == '-') {
223: puts("user names may not start with '-'.");
224: continue;
225: }
226: if (!(upper || lower || digit))
227: continue;
228: allflags = setflags(2);
229: tmode.sg_flags = allflags & 0xffff;
230: allflags >>= 16;
231: if (crmod || NL)
232: tmode.sg_flags |= CRMOD;
233: if (upper || UC)
234: tmode.sg_flags |= LCASE;
235: if (lower || LC)
236: tmode.sg_flags &= ~LCASE;
237: ioctl(0, TIOCSETP, &tmode);
238: ioctl(0, TIOCSLTC, <c);
239: ioctl(0, TIOCLSET, &allflags);
240: signal(SIGINT, SIG_DFL);
241: for (i = 0; environ[i] != (char *)0; i++)
242: env[i] = environ[i];
243: makeenv(&env[i]);
244:
245: /*
246: * this is what login was doing anyway.
247: * soon we rewrite getty completely.
248: */
249: set_ttydefaults(0);
250: execle(LO, "login", "-p", name, (char *) 0, env);
251: syslog(LOG_ERR, "%s: %m", LO);
252: exit(1);
253: }
254: alarm(0);
255: signal(SIGALRM, SIG_DFL);
256: signal(SIGINT, SIG_IGN);
257: if (NX && *NX)
258: tname = NX;
259: }
260: }
261:
262: getname()
263: {
264: register char *np;
265: register c;
266: char cs;
267:
268: /*
269: * Interrupt may happen if we use CBREAK mode
270: */
271: if (setjmp(intrupt)) {
272: signal(SIGINT, SIG_IGN);
273: return (0);
274: }
275: signal(SIGINT, interrupt);
276: tmode.sg_flags = setflags(0);
277: ioctl(0, TIOCSETP, &tmode);
278: tmode.sg_flags = setflags(1);
279: prompt();
280: if (PF > 0) {
281: oflush();
282: sleep(PF);
283: PF = 0;
284: }
285: ioctl(0, TIOCSETP, &tmode);
286: crmod = 0;
287: upper = 0;
288: lower = 0;
289: digit = 0;
290: np = name;
291: for (;;) {
292: oflush();
293: if (read(0, &cs, 1) <= 0)
294: exit(0);
295: if ((c = cs&0177) == 0)
296: return (0);
297: if (c == EOT)
298: exit(1);
299: if (c == '\r' || c == '\n' || np >= &name[sizeof name]) {
300: putf("\r\n");
301: break;
302: }
303: if (islower(c))
304: lower++;
305: else if (isupper(c))
306: upper++;
307: else if (c == ERASE || c == '#' || c == '\b') {
308: if (np > name) {
309: np--;
310: if (tmode.sg_ospeed >= B1200)
311: puts("\b \b");
312: else
313: putchr(cs);
314: }
315: continue;
316: } else if (c == KILL || c == '@') {
317: putchr(cs);
318: putchr('\r');
319: if (tmode.sg_ospeed < B1200)
320: putchr('\n');
321: /* this is the way they do it down under ... */
322: else if (np > name)
323: puts(" \r");
324: prompt();
325: np = name;
326: continue;
327: } else if (isdigit(c))
328: digit++;
329: if (IG && (c <= ' ' || c > 0176))
330: continue;
331: *np++ = c;
332: putchr(cs);
333: }
334: signal(SIGINT, SIG_IGN);
335: *np = 0;
336: if (c == '\r')
337: crmod++;
338: if (upper && !lower && !LC || UC)
339: for (np = name; *np; np++)
340: if (isupper(*np))
341: *np = tolower(*np);
342: return (1);
343: }
344:
345: static
346: short tmspc10[] = {
347: 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15
348: };
349:
350: putpad(s)
351: register char *s;
352: {
353: register pad = 0;
354: register mspc10;
355:
356: if (isdigit(*s)) {
357: while (isdigit(*s)) {
358: pad *= 10;
359: pad += *s++ - '0';
360: }
361: pad *= 10;
362: if (*s == '.' && isdigit(s[1])) {
363: pad += s[1] - '0';
364: s += 2;
365: }
366: }
367:
368: puts(s);
369: /*
370: * If no delay needed, or output speed is
371: * not comprehensible, then don't try to delay.
372: */
373: if (pad == 0)
374: return;
375: if (tmode.sg_ospeed <= 0 ||
376: tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
377: return;
378:
379: /*
380: * Round up by a half a character frame,
381: * and then do the delay.
382: * Too bad there are no user program accessible programmed delays.
383: * Transmitting pad characters slows many
384: * terminals down and also loads the system.
385: */
386: mspc10 = tmspc10[tmode.sg_ospeed];
387: pad += mspc10 / 2;
388: for (pad /= mspc10; pad > 0; pad--)
389: putchr(*PC);
390: }
391:
392: puts(s)
393: register char *s;
394: {
395:
396: while (*s)
397: putchr(*s++);
398: }
399:
400: char outbuf[OBUFSIZ];
401: int obufcnt = 0;
402:
403: putchr(cc)
404: {
405: char c;
406:
407: c = cc;
408: c |= partab[c&0177] & 0200;
409: if (OP)
410: c ^= 0200;
411: if (!UB) {
412: outbuf[obufcnt++] = c;
413: if (obufcnt >= OBUFSIZ)
414: oflush();
415: } else
416: write(1, &c, 1);
417: }
418:
419: oflush()
420: {
421: if (obufcnt)
422: write(1, outbuf, obufcnt);
423: obufcnt = 0;
424: }
425:
426: prompt()
427: {
428:
429: putf(LM);
430: if (CO)
431: putchr('\n');
432: }
433:
434: putf(cp)
435: register char *cp;
436: {
437: char *slash;
438: char datebuffer[60];
439: extern char editedhost[];
440: extern char *rindex();
441:
442: while (*cp) {
443: if (*cp != '%') {
444: putchr(*cp++);
445: continue;
446: }
447: switch (*++cp) {
448:
449: case 't':
450: slash = rindex(ttyn, '/');
451: if (slash == (char *) 0)
452: puts(ttyn);
453: else
454: puts(&slash[1]);
455: break;
456:
457: case 'h':
458: puts(editedhost);
459: break;
460:
461: case 'd':
462: get_date(datebuffer);
463: puts(datebuffer);
464: break;
465:
466: case '%':
467: putchr('%');
468: break;
469: }
470: cp++;
471: }
472: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.