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