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