|
|
1.1 root 1: /*
2: * Rec'd from Lauren Weinstein, 7-16-84.
3: * Read a user name from a terminal.
4: * Attempt to determine the proper line
5: * speed and mode. Call login. This version
6: * explicitly sets all sgtty and tchars values
7: * to allow proper resetting of the console device.
8: *
9: * Responds to explicitly set erase and kill chars,
10: * and ALSO to (erase == '#') and (kill == '@').
11: *
12: * Compile -s -n -i
13: */
14:
15: #include <stdio.h>
16: #include <ctype.h>
17: #include <sgtty.h>
18: #if NEWTTYS
19: #include <sys/tty.h>
20: #endif
21: #include <sys/deftty.h>
22: #include <signal.h>
23: #include <sys/stat.h>
24:
25: #define FALSE 0
26: #define TRUE 1
27:
28: #define MAXTIME 60 /* Maximum attempt time in seconds */
29: #define NTYPE (sizeof stypes/sizeof stypes[0])
30: #define GMODE (ECHO|XTABS|CRT|CRMOD)
31: #define LA36M GMODE /* Should have LA36 delays w/a */
32: #define MAXNAME 50 /* Maximum characters in a name */
33: #define LOGMSG "/etc/logmsg" /* alternate login msg file */
34:
35: char defm[] = "\n\r\7Coherent login: "; /* default login prompt */
36:
37: int xflags; /* Extra flags to set */
38: char remote = FALSE; /* TRUE for remote tty line */
39: int timeout(); /* forward declaration */
40:
41: /*
42: * Structure for each speed table.
43: * The 's_nindex' entry is the next
44: * indent in the current table to
45: * use (for fixed-speed entries, it
46: * should be always 0).
47: */
48: struct stable {
49: char s_nindex;
50: int s_mode;
51: char s_ispeed;
52: char s_ospeed;
53: char *s_lmsg;
54: };
55:
56: /*
57: * Fixed-speed tables.
58: */
59: struct stable sA[] = {0, GMODE, B50, B50, defm};
60: struct stable sB[] = {0, GMODE, B75, B75, defm};
61: struct stable sC[] = {0, GMODE, B110, B110, defm};
62: struct stable sD[] = {0, GMODE, B134, B134, defm};
63: struct stable sE[] = {0, GMODE, B150, B150, defm};
64: struct stable sF[] = {0, GMODE, B200, B200, defm};
65: struct stable sG[] = {0, GMODE, B300, B300, defm};
66: struct stable sH[] = {0, GMODE, B600, B600, defm};
67: struct stable sI[] = {0, GMODE, B1200, B1200, defm};
68: struct stable sJ[] = {0, GMODE, B1800, B1800, defm};
69: struct stable sK[] = {0, GMODE, B2000, B2000, defm};
70: struct stable sL[] = {0, GMODE, B2400, B2400, defm};
71: struct stable sM[] = {0, GMODE, B3600, B3600, defm};
72: struct stable sN[] = {0, GMODE, B4800, B4800, defm};
73: struct stable sO[] = {0, GMODE, B7200, B7200, defm};
74: struct stable sP[] = {0, GMODE, B9600, B9600, defm};
75: struct stable sQ[] = {0, GMODE, B19200, B19200, defm};
76: struct stable sR[] = {0, GMODE, EXTA, EXTA, defm};
77: struct stable sS[] = {0, GMODE, EXTB, EXTB, defm};
78:
79: /*
80: * Variable-speed tables.
81: */
82: struct stable sdash[] = { /* TTY 33 */
83: 0, GMODE, B110, B110, defm
84: };
85:
86: struct stable s0[] = { /* Default--various terminals */
87: 1, GMODE, B300, B300, defm,
88: 2, GMODE, B1200, B1200, defm,
89: 3, GMODE, B150, B150, defm,
90: 0, GMODE, B110, B110, defm
91: };
92:
93: struct stable s1[] = { /* 150 baud TTY 37 */
94: 0, GMODE, B150, B150, defm
95: };
96:
97: struct stable s2[] = { /* 9600 baud - Tek 4104 */
98: 0, GMODE, B9600, B9600, defm
99: };
100:
101: struct stable s3[] = { /* v22.bis & 212 datasets (2400,1200,300) */
102: 1, GMODE, B2400, B2400, defm,
103: 2, GMODE, B1200, B1200, defm,
104: 0, GMODE, B300, B300, defm
105: };
106:
107: struct stable s5[] = { /* Reverse of 's3' */
108: 1, GMODE, B300, B300, defm,
109: 0, GMODE, B1200, B1200, defm
110: };
111:
112: struct stable s4[] = { /* LA36 (needs its delays) */
113: 0, LA36M, B300, B300, defm
114: };
115:
116: struct stable s9[] = { /* 212 with auto speed select via CTS */
117: 1, GMODE, B1200, B1200, defm, /* 1200 */
118: 2, GMODE, B300, B300, defm, /* then 300 */
119: 0, GMODE, B110, B110, defm /* then 110 */
120: };
121:
122: /*
123: * This table is used to map
124: * a speed character argument, passed
125: * to "getty" from "init", into a speed
126: * table base.
127: */
128: struct stypes {
129: int s_name;
130: struct stable *s_ptr;
131: } stypes[] = {
132: '-', sdash,
133: '0', s0,
134: '1', s1,
135: '2', s2,
136: '3', s3,
137: '4', s4,
138: '5', s5,
139: '9', s9, /* 212 with auto speed select */
140: 'A', sA,
141: 'B', sB,
142: 'C', sC,
143: 'D', sD,
144: 'E', sE,
145: 'F', sF,
146: 'G', sG,
147: 'H', sH,
148: 'I', sI,
149: 'J', sJ,
150: 'K', sK,
151: 'L', sL,
152: 'M', sM,
153: 'N', sN,
154: 'O', sO,
155: 'P', sP,
156: 'Q', sQ,
157: 'R', sR,
158: 'S', sS
159: };
160:
161: /*
162: * Default sgtty and tchars settings.
163: */
164:
165: struct sgttyb defsgt = { /* Initial sgtty */
166: DEF_SG_ISPEED,
167: DEF_SG_OSPEED,
168: DEF_SG_ERASE,
169: DEF_SG_KILL,
170: DEF_SG_FLAGS
171: };
172:
173: struct tchars deftch = { /* Initial tchars */
174: DEF_T_INTRC,
175: DEF_T_QUITC,
176: DEF_T_STARTC,
177: DEF_T_STOPC,
178: DEF_T_EOFC,
179: DEF_T_BRKC
180: };
181:
182:
183: main(argc, argv)
184: char *argv[];
185: {
186: register struct stable *sp;
187: register struct stable *stpp;
188: register struct stypes *stp;
189: register int index;
190: char name[MAXNAME];
191: char *ttyn; /* pointer to current tty name */
192: extern char *ttyname();
193:
194: if (argc != 2) {
195: write(1, "Usage: /etc/getty baudtype\r\n", 28);
196: slexit(1); /* error exit */
197: }
198:
199: signal(SIGINT, SIG_IGN); /* ignore int and quit */
200: signal(SIGQUIT, SIG_IGN);
201:
202: if ((ttyn = ttyname(1)) == NULL) /* get current tty name */
203: { write(1, "getty: can't get tty name!\r\n", 28);
204: slexit(1); /* error exit */
205: }
206: if (chmod(ttyn, 04000) < 0) /* setuid bit to indicate line in use */
207: { write(1, "getty: can't chmod!\r\n", 21);
208: slexit(1); /* error exit */
209: }
210:
211: #if NEWTTYS
212: if (argv[0][0] == '-' && argv[0][1] == 'r') {
213: remote = TRUE;
214: signal(SIGALRM, &timeout); /* catch alarm timeouts */
215: alarm(MAXTIME); /* timeout interval */
216: }
217: #endif
218:
219: stpp = s0;
220: if (argc > 1) {
221: for (stp = stypes; stp < &stypes[NTYPE]; stp++)
222: if (*argv[1] == stp->s_name) {
223: stpp = stp->s_ptr;
224: break;
225: }
226: }
227: for (index=0; ; index=sp->s_nindex) {
228: sp = &stpp[index];
229: xflags = 0;
230: /* a '9' indicates autospeed mode for first index only */
231: dostty(sp, RAW, 0, (index == 0 && stp->s_name == '9'));
232: if (readname(name, sp) != 0)
233: break;
234: }
235: #if NEWTTYS
236: alarm(0); /* turn off login alarm timeout */
237: #endif
238: dostty(sp, 0, RAW, 0); /* set sgtty modes */
239: ioctl(1, TIOCSETC, &deftch); /* set tchars modes */
240: execl("/bin/login", (remote) ? "-r" : "-", name, NULL);
241: slexit(1);
242: }
243:
244: /*
245: * Do a "stty" on the terminal.
246: * The erase and kill characters come
247: * from the defaults in "defsgt".
248: * The speeds and the basic mode come
249: * from the "stable" pointed to by
250: * "sp". The "on" and "off" masks
251: * change the modes.
252: * If "automode" is non-zero, 212 auto speed
253: * mode has been selected.
254: */
255: dostty(stabp, on, off, automode)
256: register struct stable *stabp;
257: {
258: #if NEWTTYS
259: unsigned msr;
260:
261: if (automode) /* 212 auto speed mode? */
262: if (ioctl(1, TIOCRMSR, &msr) == 0) /* get modem status register */
263: stabp->s_ispeed = stabp->s_ospeed
264: = ((msr & MSRCTS) ? B1200 : B300); /* CTS high means 1200 */
265: #endif
266:
267: defsgt.sg_ispeed = stabp->s_ispeed;
268: defsgt.sg_ospeed = stabp->s_ospeed;
269: defsgt.sg_flags = stabp->s_mode;
270: defsgt.sg_flags |= xflags|on;
271: defsgt.sg_flags &= ~off;
272: ioctl(1, TIOCSETP, &defsgt); /* set modes */
273: }
274:
275: /*
276: * Read a name from the terminal.
277: * Return true if you get a name, or false
278: * if the speed should be cycled. Use the
279: * editing characters from the initial
280: * defaults.
281: */
282: readname(s, sp)
283: char *s;
284: struct stable *sp;
285: {
286: register char *cp;
287: register int c;
288: register int seenupper;
289: register int seenlower;
290: FILE *msgfp;
291: char last;
292:
293: loop:
294: seenlower = 0;
295: seenupper = 0;
296: xflags = 0;
297: if ((msgfp = fopen(LOGMSG, "r")) != NULL) {
298: /* Read from login message file. */
299: for (last = '\n'; (c = fgetc(msgfp)) != EOF; last = c) {
300: if (last == '\n')
301: write(1, "\r", 1);
302: write(1, &last, 1);
303: }
304: if (last != '\n')
305: write(1, &last, 1);
306: fclose(msgfp);
307: } else
308: write(1, sp->s_lmsg, strlen(sp->s_lmsg)); /* use standard msg */
309:
310: cp = s;
311: for (;;) {
312: if ((c = getchar() & 0x7F) == 0)
313: return(0); /* break advances speed table */
314: if (c==' ' || c=='\t' || c=='\f')
315: continue; /* ignore this char */
316: if (c == deftch.t_eofc) /* EOF returns to init */
317: slexit(1);
318: if (c == defsgt.sg_kill || c == '@') /* kill this line */
319: { write(1, "\r\n", 2);
320: seenupper = seenlower = 0;
321: xflags = 0;
322: cp = s;
323: continue;
324: }
325: if (c == defsgt.sg_erase || c == '#') /* erase this char */
326: { if (sp != s)
327: --cp;
328: continue;
329: }
330: if (c == '\n')
331: { putchar('\r');
332: break;
333: }
334: if (c == '\r')
335: { putchar('\n');
336: xflags |= CRMOD;
337: break;
338: }
339: if (isupper(c))
340: seenupper = 1;
341: else if (islower(c))
342: seenlower = 1;
343: if (cp < s+MAXNAME)
344: *cp++ = c;
345: }
346: if (cp == s)
347: goto loop;
348: *cp = 0;
349: if (seenupper!=0 && seenlower==0)
350: { xflags |= LCASE;
351: for (cp=s; *cp!=0; ++cp)
352: { if (isupper(*cp))
353: *cp = tolower(*cp);
354: }
355: }
356: return(1);
357: }
358:
359: /* login attempt timeout routine */
360: timeout()
361: {
362: printf("\r\n"); /* neatness */
363: slexit(1); /* terminate and try force hangup */
364: }
365:
366: /* sleep to make sure output has flushed, then exit */
367: slexit(status)
368: {
369: sleep(3);
370: exit(status);
371: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.