|
|
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.7 (Berkeley) 10/1/87";
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: 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: ioctl(0, TIOCSETD, &ldisp);
191: if (HC)
192: ioctl(0, TIOCHPCL, 0);
193: if (AB) {
194: extern char *autobaud();
195:
196: tname = autobaud();
197: continue;
198: }
199: if (PS) {
200: tname = portselector();
201: continue;
202: }
203: if (CL && *CL)
204: putpad(CL);
205: edithost(HE);
206: if (IM && *IM)
207: putf(IM);
208: if (setjmp(timeout)) {
209: tmode.sg_ispeed = tmode.sg_ospeed = 0;
210: ioctl(0, TIOCSETP, &tmode);
211: exit(1);
212: }
213: if (TO) {
214: signal(SIGALRM, dingdong);
215: alarm(TO);
216: }
217: if (getname()) {
218: register int i;
219:
220: oflush();
221: alarm(0);
222: signal(SIGALRM, SIG_DFL);
223: if (name[0] == '-') {
224: puts("login names may not start with '-'.");
225: continue;
226: }
227: if (!(upper || lower || digit))
228: continue;
229: allflags = setflags(2);
230: tmode.sg_flags = allflags & 0xffff;
231: allflags >>= 16;
232: if (crmod || NL)
233: tmode.sg_flags |= CRMOD;
234: if (upper || UC)
235: tmode.sg_flags |= LCASE;
236: if (lower || LC)
237: tmode.sg_flags &= ~LCASE;
238: ioctl(0, TIOCSETP, &tmode);
239: ioctl(0, TIOCSLTC, <c);
240: ioctl(0, TIOCLSET, &allflags);
241: signal(SIGINT, SIG_DFL);
242: for (i = 0; environ[i] != (char *)0; i++)
243: env[i] = environ[i];
244: makeenv(&env[i]);
245: execle(LO, "login", "-p", name, (char *) 0, env);
246: syslog(LOG_ERR, "%s: %m", LO);
247: exit(1);
248: }
249: alarm(0);
250: signal(SIGALRM, SIG_DFL);
251: signal(SIGINT, SIG_IGN);
252: if (NX && *NX)
253: tname = NX;
254: }
255: }
256:
257: getname()
258: {
259: register char *np;
260: register c;
261: char cs;
262:
263: /*
264: * Interrupt may happen if we use CBREAK mode
265: */
266: if (setjmp(intrupt)) {
267: signal(SIGINT, SIG_IGN);
268: return (0);
269: }
270: signal(SIGINT, interrupt);
271: tmode.sg_flags = setflags(0);
272: ioctl(0, TIOCSETP, &tmode);
273: tmode.sg_flags = setflags(1);
274: prompt();
275: if (PF > 0) {
276: oflush();
277: sleep(PF);
278: PF = 0;
279: }
280: ioctl(0, TIOCSETP, &tmode);
281: crmod = 0;
282: upper = 0;
283: lower = 0;
284: digit = 0;
285: np = name;
286: for (;;) {
287: oflush();
288: if (read(0, &cs, 1) <= 0)
289: exit(0);
290: if ((c = cs&0177) == 0)
291: return (0);
292: if (c == EOT)
293: exit(1);
294: if (c == '\r' || c == '\n' || np >= &name[sizeof name]) {
295: putf("\r\n");
296: break;
297: }
298: if (c >= 'a' && c <= 'z')
299: lower++;
300: else if (c >= 'A' && c <= 'Z')
301: upper++;
302: else if (c == ERASE || c == '#' || c == '\b') {
303: if (np > name) {
304: np--;
305: if (tmode.sg_ospeed >= B1200)
306: puts("\b \b");
307: else
308: putchr(cs);
309: }
310: continue;
311: } else if (c == KILL || c == '@') {
312: putchr(cs);
313: putchr('\r');
314: if (tmode.sg_ospeed < B1200)
315: putchr('\n');
316: /* this is the way they do it down under ... */
317: else if (np > name)
318: puts(" \r");
319: prompt();
320: np = name;
321: continue;
322: } else if (c >= '0' && c <= '9')
323: digit++;
324: if (IG && (c <= ' ' || c > 0176))
325: continue;
326: *np++ = c;
327: putchr(cs);
328: }
329: signal(SIGINT, SIG_IGN);
330: *np = 0;
331: if (c == '\r')
332: crmod++;
333: if (upper && !lower && !LC || UC)
334: for (np = name; *np; np++)
335: if (isupper(*np))
336: *np = tolower(*np);
337: return (1);
338: }
339:
340: static
341: short tmspc10[] = {
342: 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15
343: };
344:
345: putpad(s)
346: register char *s;
347: {
348: register pad = 0;
349: register mspc10;
350:
351: if (isdigit(*s)) {
352: while (isdigit(*s)) {
353: pad *= 10;
354: pad += *s++ - '0';
355: }
356: pad *= 10;
357: if (*s == '.' && isdigit(s[1])) {
358: pad += s[1] - '0';
359: s += 2;
360: }
361: }
362:
363: puts(s);
364: /*
365: * If no delay needed, or output speed is
366: * not comprehensible, then don't try to delay.
367: */
368: if (pad == 0)
369: return;
370: if (tmode.sg_ospeed <= 0 ||
371: tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
372: return;
373:
374: /*
375: * Round up by a half a character frame,
376: * and then do the delay.
377: * Too bad there are no user program accessible programmed delays.
378: * Transmitting pad characters slows many
379: * terminals down and also loads the system.
380: */
381: mspc10 = tmspc10[tmode.sg_ospeed];
382: pad += mspc10 / 2;
383: for (pad /= mspc10; pad > 0; pad--)
384: putchr(*PC);
385: }
386:
387: puts(s)
388: register char *s;
389: {
390:
391: while (*s)
392: putchr(*s++);
393: }
394:
395: char outbuf[OBUFSIZ];
396: int obufcnt = 0;
397:
398: putchr(cc)
399: {
400: char c;
401:
402: c = cc;
403: c |= partab[c&0177] & 0200;
404: if (OP)
405: c ^= 0200;
406: if (!UB) {
407: outbuf[obufcnt++] = c;
408: if (obufcnt >= OBUFSIZ)
409: oflush();
410: } else
411: write(1, &c, 1);
412: }
413:
414: oflush()
415: {
416: if (obufcnt)
417: write(1, outbuf, obufcnt);
418: obufcnt = 0;
419: }
420:
421: prompt()
422: {
423:
424: putf(LM);
425: if (CO)
426: putchr('\n');
427: }
428:
429: putf(cp)
430: register char *cp;
431: {
432: char *ttyn, *slash;
433: char datebuffer[60];
434: extern char editedhost[];
435: extern char *ttyname(), *rindex();
436:
437: while (*cp) {
438: if (*cp != '%') {
439: putchr(*cp++);
440: continue;
441: }
442: switch (*++cp) {
443:
444: case 't':
445: ttyn = ttyname(0);
446: slash = rindex(ttyn, '/');
447: if (slash == (char *) 0)
448: puts(ttyn);
449: else
450: puts(&slash[1]);
451: break;
452:
453: case 'h':
454: puts(editedhost);
455: break;
456:
457: case 'd':
458: get_date(datebuffer);
459: puts(datebuffer);
460: break;
461:
462: case '%':
463: putchr('%');
464: break;
465: }
466: cp++;
467: }
468: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.