BSD 4_3_Net_1 release
[unix-history] / getty / subr.c
CommitLineData
8a3f4fd4 1/*
e3419641
C
2 * Copyright (c) 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
8a3f4fd4
DF
16 */
17
3eea9327 18#ifndef lint
e3419641
C
19static char sccsid[] = "@(#)subr.c 5.5 (Berkeley) 2/27/89";
20#endif /* not lint */
3eea9327
SL
21
22/*
23 * Melbourne getty.
24 */
25#include <sgtty.h>
26#include "gettytab.h"
27
28extern struct sgttyb tmode;
29extern struct tchars tc;
30extern struct ltchars ltc;
31
32/*
33 * Get a table entry.
34 */
35gettable(name, buf, area)
36 char *name, *buf, *area;
37{
38 register struct gettystrs *sp;
39 register struct gettynums *np;
40 register struct gettyflags *fp;
41 register n;
42
43 hopcount = 0; /* new lookup, start fresh */
44 if (getent(buf, name) != 1)
45 return;
46
47 for (sp = gettystrs; sp->field; sp++)
48 sp->value = getstr(sp->field, &area);
49 for (np = gettynums; np->field; np++) {
50 n = getnum(np->field);
51 if (n == -1)
52 np->set = 0;
53 else {
54 np->set = 1;
55 np->value = n;
56 }
57 }
58 for (fp = gettyflags; fp->field; fp++) {
59 n = getflag(fp->field);
60 if (n == -1)
61 fp->set = 0;
62 else {
63 fp->set = 1;
64 fp->value = n ^ fp->invrt;
65 }
66 }
67}
68
69gendefaults()
70{
71 register struct gettystrs *sp;
72 register struct gettynums *np;
73 register struct gettyflags *fp;
74
75 for (sp = gettystrs; sp->field; sp++)
76 if (sp->value)
77 sp->defalt = sp->value;
78 for (np = gettynums; np->field; np++)
79 if (np->set)
80 np->defalt = np->value;
81 for (fp = gettyflags; fp->field; fp++)
82 if (fp->set)
83 fp->defalt = fp->value;
84 else
85 fp->defalt = fp->invrt;
86}
87
88setdefaults()
89{
90 register struct gettystrs *sp;
91 register struct gettynums *np;
92 register struct gettyflags *fp;
93
94 for (sp = gettystrs; sp->field; sp++)
95 if (!sp->value)
96 sp->value = sp->defalt;
97 for (np = gettynums; np->field; np++)
98 if (!np->set)
99 np->value = np->defalt;
100 for (fp = gettyflags; fp->field; fp++)
101 if (!fp->set)
102 fp->value = fp->defalt;
103}
104
105static char **
106charnames[] = {
107 &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
108 &SU, &DS, &RP, &FL, &WE, &LN, 0
109};
110
111static char *
112charvars[] = {
113 &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
114 &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
115 &tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
116 &ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
117 &ltc.t_werasc, &ltc.t_lnextc, 0
118};
119
120setchars()
121{
122 register int i;
123 register char *p;
124
125 for (i = 0; charnames[i]; i++) {
126 p = *charnames[i];
127 if (p && *p)
128 *charvars[i] = *p;
129 else
4eaf53e2 130 *charvars[i] = '\377';
3eea9327
SL
131 }
132}
133
134long
135setflags(n)
136{
137 register long f;
138
139 switch (n) {
140 case 0:
141 if (F0set)
142 return(F0);
143 break;
144 case 1:
145 if (F1set)
146 return(F1);
147 break;
148 default:
149 if (F2set)
150 return(F2);
151 break;
152 }
153
154 f = 0;
155
156 if (AP)
157 f |= ANYP;
158 else if (OP)
159 f |= ODDP;
160 else if (EP)
161 f |= EVENP;
162
163 if (UC)
164 f |= LCASE;
165
166 if (NL)
167 f |= CRMOD;
168
169 f |= delaybits();
170
171 if (n == 1) { /* read mode flags */
172 if (RW)
173 f |= RAW;
174 else
175 f |= CBREAK;
176 return (f);
177 }
178
179 if (!HT)
180 f |= XTABS;
181
182 if (n == 0)
183 return (f);
184
185 if (CB)
186 f |= CRTBS;
187
188 if (CE)
189 f |= CRTERA;
190
7f170415
RC
191 if (CK)
192 f |= CRTKIL;
193
3eea9327
SL
194 if (PE)
195 f |= PRTERA;
196
197 if (EC)
198 f |= ECHO;
199
200 if (XC)
201 f |= CTLECH;
202
e5943133
KM
203 if (DX)
204 f |= DECCTQ;
205
3eea9327
SL
206 return (f);
207}
208
209struct delayval {
210 unsigned delay; /* delay in ms */
211 int bits;
212};
213
214/*
215 * below are random guesses, I can't be bothered checking
216 */
217
218struct delayval crdelay[] = {
6974a5da
RE
219 1, CR1,
220 2, CR2,
221 3, CR3,
222 83, CR1,
223 166, CR2,
3eea9327
SL
224 0, CR3,
225};
226
227struct delayval nldelay[] = {
228 1, NL1, /* special, calculated */
6974a5da
RE
229 2, NL2,
230 3, NL3,
231 100, NL2,
3eea9327
SL
232 0, NL3,
233};
234
235struct delayval bsdelay[] = {
6974a5da 236 1, BS1,
3eea9327
SL
237 0, 0,
238};
239
240struct delayval ffdelay[] = {
6974a5da 241 1, FF1,
3eea9327
SL
242 1750, FF1,
243 0, FF1,
244};
245
246struct delayval tbdelay[] = {
6974a5da
RE
247 1, TAB1,
248 2, TAB2,
249 3, XTABS, /* this is expand tabs */
250 100, TAB1,
3eea9327
SL
251 0, TAB2,
252};
253
254delaybits()
255{
256 register f;
257
258 f = adelay(CD, crdelay);
259 f |= adelay(ND, nldelay);
260 f |= adelay(FD, ffdelay);
261 f |= adelay(TD, tbdelay);
262 f |= adelay(BD, bsdelay);
263 return (f);
264}
265
266adelay(ms, dp)
267 register ms;
268 register struct delayval *dp;
269{
270 if (ms == 0)
271 return (0);
272 while (dp->delay && ms > dp->delay)
273 dp++;
274 return (dp->bits);
275}
276
277char editedhost[32];
278
279edithost(pat)
280 register char *pat;
281{
282 register char *host = HN;
283 register char *res = editedhost;
284
285 if (!pat)
286 pat = "";
287 while (*pat) {
288 switch (*pat) {
289
290 case '#':
291 if (*host)
292 host++;
293 break;
294
295 case '@':
296 if (*host)
297 *res++ = *host++;
298 break;
299
300 default:
301 *res++ = *pat;
302 break;
303
304 }
305 if (res == &editedhost[sizeof editedhost - 1]) {
306 *res = '\0';
307 return;
308 }
309 pat++;
310 }
311 if (*host)
312 strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
313 else
314 *res = '\0';
315 editedhost[sizeof editedhost - 1] = '\0';
316}
317
318struct speedtab {
319 int speed;
320 int uxname;
321} speedtab[] = {
322 50, B50,
323 75, B75,
324 110, B110,
325 134, B134,
326 150, B150,
327 200, B200,
328 300, B300,
329 600, B600,
330 1200, B1200,
331 1800, B1800,
332 2400, B2400,
333 4800, B4800,
334 9600, B9600,
335 19200, EXTA,
336 19, EXTA, /* for people who say 19.2K */
337 38400, EXTB,
338 38, EXTB,
339 7200, EXTB, /* alternative */
340 0
341};
342
343speed(val)
344{
345 register struct speedtab *sp;
346
347 if (val <= 15)
ec2b493d 348 return (val);
3eea9327
SL
349
350 for (sp = speedtab; sp->speed; sp++)
351 if (sp->speed == val)
352 return (sp->uxname);
353
354 return (B300); /* default in impossible cases */
355}
356
357makeenv(env)
358 char *env[];
359{
360 static char termbuf[128] = "TERM=";
361 register char *p, *q;
362 register char **ep;
363 char *index();
364
365 ep = env;
366 if (TT && *TT) {
367 strcat(termbuf, TT);
368 *ep++ = termbuf;
369 }
370 if (p = EV) {
371 q = p;
372 while (q = index(q, ',')) {
373 *q++ = '\0';
374 *ep++ = p;
375 p = q;
376 }
377 if (*p)
378 *ep++ = p;
379 }
380 *ep = (char *)0;
381}
382
383/*
384 * This speed select mechanism is written for the Develcon DATASWITCH.
385 * The Develcon sends a string of the form "B{speed}\n" at a predefined
386 * baud rate. This string indicates the user's actual speed.
387 * The routine below returns the terminal type mapped from derived speed.
388 */
389struct portselect {
390 char *ps_baud;
391 char *ps_type;
392} portspeeds[] = {
393 { "B110", "std.110" },
394 { "B134", "std.134" },
395 { "B150", "std.150" },
396 { "B300", "std.300" },
397 { "B600", "std.600" },
398 { "B1200", "std.1200" },
399 { "B2400", "std.2400" },
400 { "B4800", "std.4800" },
401 { "B9600", "std.9600" },
84e05cce 402 { "B19200", "std.19200" },
3eea9327
SL
403 { 0 }
404};
405
406char *
407portselector()
408{
409 char c, baud[20], *type = "default";
410 register struct portselect *ps;
411 int len;
412
413 alarm(5*60);
414 for (len = 0; len < sizeof (baud) - 1; len++) {
415 if (read(0, &c, 1) <= 0)
416 break;
417 c &= 0177;
418 if (c == '\n' || c == '\r')
419 break;
420 if (c == 'B')
421 len = 0; /* in case of leading garbage */
422 baud[len] = c;
423 }
424 baud[len] = '\0';
425 for (ps = portspeeds; ps->ps_baud; ps++)
426 if (strcmp(ps->ps_baud, baud) == 0) {
427 type = ps->ps_type;
428 break;
429 }
430 sleep(2); /* wait for connection to complete */
431 return (type);
432}
ec2b493d
RC
433
434/*
435 * This auto-baud speed select mechanism is written for the Micom 600
436 * portselector. Selection is done by looking at how the character '\r'
437 * is garbled at the different speeds.
438 */
439#include <sys/time.h>
440
441char *
442autobaud()
443{
444 int rfds;
445 struct timeval timeout;
446 char c, *type = "9600-baud";
447 int null = 0;
448
449 ioctl(0, TIOCFLUSH, &null);
450 rfds = 1 << 0;
451 timeout.tv_sec = 5;
452 timeout.tv_usec = 0;
453 if (select(32, &rfds, (int *)0, (int *)0, &timeout) <= 0)
454 return (type);
455 if (read(0, &c, sizeof(char)) != sizeof(char))
456 return (type);
457 timeout.tv_sec = 0;
458 timeout.tv_usec = 20;
459 (void) select(32, (int *)0, (int *)0, (int *)0, &timeout);
460 ioctl(0, TIOCFLUSH, &null);
461 switch (c & 0377) {
462
463 case 0200: /* 300-baud */
464 type = "300-baud";
465 break;
466
467 case 0346: /* 1200-baud */
468 type = "1200-baud";
469 break;
470
471 case 015: /* 2400-baud */
472 case 0215:
473 type = "2400-baud";
474 break;
475
476 default: /* 4800-baud */
477 type = "4800-baud";
478 break;
479
480 case 0377: /* 9600-baud */
481 type = "9600-baud";
482 break;
483 }
484 return (type);
485}