subr.c revision 1.4 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.4 1994/03/09 05:00:01 cgd Exp $";
37 #endif /* not lint */
38
39 /*
40 * Melbourne getty.
41 */
42 #define USE_OLD_TTY
43 #include <stdlib.h>
44 #include <sgtty.h>
45 #include <unistd.h>
46 #include <string.h>
47
48 #include "gettytab.h"
49 #include "pathnames.h"
50
51 extern struct sgttyb tmode;
52 extern struct tchars tc;
53 extern struct ltchars ltc;
54
55 /*
56 * Get a table entry.
57 */
58 gettable(name, buf)
59 char *name, *buf;
60 {
61 register struct gettystrs *sp;
62 register struct gettynums *np;
63 register struct gettyflags *fp;
64 long n;
65 char *dba[2];
66 dba[0] = _PATH_GETTYTAB;
67 dba[1] = 0;
68
69 if (cgetent(&buf, dba, name) != 0)
70 return;
71
72 for (sp = gettystrs; sp->field; sp++)
73 cgetstr(buf, sp->field, &sp->value);
74 for (np = gettynums; np->field; np++) {
75 if (cgetnum(buf, np->field, &n) == -1)
76 np->set = 0;
77 else {
78 np->set = 1;
79 np->value = n;
80 }
81 }
82 for (fp = gettyflags; fp->field; fp++) {
83 if (cgetcap(buf, fp->field, ':') == NULL)
84 fp->set = 0;
85 else {
86 fp->set = 1;
87 fp->value = 1 ^ fp->invrt;
88 }
89 }
90 #ifdef DEBUG
91 printf("name=\"%s\", buf=\"%s\"\n", name, buf);
92 for (sp = gettystrs; sp->field; sp++)
93 printf("cgetstr: %s=%s\n", sp->field, sp->value);
94 for (np = gettynums; np->field; np++)
95 printf("cgetnum: %s=%d\n", np->field, np->value);
96 for (fp = gettyflags; fp->field; fp++)
97 printf("cgetflags: %s='%c' set='%c'\n", fp->field,
98 fp->value + '0', fp->set + '0');
99 exit(1);
100 #endif /* DEBUG */
101 }
102
103 gendefaults()
104 {
105 register struct gettystrs *sp;
106 register struct gettynums *np;
107 register struct gettyflags *fp;
108
109 for (sp = gettystrs; sp->field; sp++)
110 if (sp->value)
111 sp->defalt = sp->value;
112 for (np = gettynums; np->field; np++)
113 if (np->set)
114 np->defalt = np->value;
115 for (fp = gettyflags; fp->field; fp++)
116 if (fp->set)
117 fp->defalt = fp->value;
118 else
119 fp->defalt = fp->invrt;
120 }
121
122 setdefaults()
123 {
124 register struct gettystrs *sp;
125 register struct gettynums *np;
126 register struct gettyflags *fp;
127
128 for (sp = gettystrs; sp->field; sp++)
129 if (!sp->value)
130 sp->value = sp->defalt;
131 for (np = gettynums; np->field; np++)
132 if (!np->set)
133 np->value = np->defalt;
134 for (fp = gettyflags; fp->field; fp++)
135 if (!fp->set)
136 fp->value = fp->defalt;
137 }
138
139 static char **
140 charnames[] = {
141 &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
142 &SU, &DS, &RP, &FL, &WE, &LN, 0
143 };
144
145 static char *
146 charvars[] = {
147 &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
148 &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
149 &tc.t_eofc, &tc.t_brkc, <c.t_suspc,
150 <c.t_dsuspc, <c.t_rprntc, <c.t_flushc,
151 <c.t_werasc, <c.t_lnextc, 0
152 };
153
154 setchars()
155 {
156 register int i;
157 register char *p;
158
159 for (i = 0; charnames[i]; i++) {
160 p = *charnames[i];
161 if (p && *p)
162 *charvars[i] = *p;
163 else
164 *charvars[i] = '\377';
165 }
166 }
167
168 long
169 setflags(n)
170 {
171 register long f;
172
173 switch (n) {
174 case 0:
175 if (F0set)
176 return(F0);
177 break;
178 case 1:
179 if (F1set)
180 return(F1);
181 break;
182 default:
183 if (F2set)
184 return(F2);
185 break;
186 }
187
188 f = 0;
189
190 if (AP)
191 f |= ANYP;
192 else if (OP)
193 f |= ODDP;
194 else if (EP)
195 f |= EVENP;
196
197 if (UC)
198 f |= LCASE;
199
200 if (NL)
201 f |= CRMOD;
202
203 f |= delaybits();
204
205 if (n == 1) { /* read mode flags */
206 if (RW)
207 f |= RAW;
208 else
209 f |= CBREAK;
210 return (f);
211 }
212
213 if (!HT)
214 f |= XTABS;
215
216 if (n == 0)
217 return (f);
218
219 if (CB)
220 f |= CRTBS;
221
222 if (CE)
223 f |= CRTERA;
224
225 if (CK)
226 f |= CRTKIL;
227
228 if (PE)
229 f |= PRTERA;
230
231 if (EC)
232 f |= ECHO;
233
234 if (XC)
235 f |= CTLECH;
236
237 if (DX)
238 f |= DECCTQ;
239
240 return (f);
241 }
242
243 struct delayval {
244 unsigned delay; /* delay in ms */
245 int bits;
246 };
247
248 /*
249 * below are random guesses, I can't be bothered checking
250 */
251
252 struct delayval crdelay[] = {
253 1, CR1,
254 2, CR2,
255 3, CR3,
256 83, CR1,
257 166, CR2,
258 0, CR3,
259 };
260
261 struct delayval nldelay[] = {
262 1, NL1, /* special, calculated */
263 2, NL2,
264 3, NL3,
265 100, NL2,
266 0, NL3,
267 };
268
269 struct delayval bsdelay[] = {
270 1, BS1,
271 0, 0,
272 };
273
274 struct delayval ffdelay[] = {
275 1, FF1,
276 1750, FF1,
277 0, FF1,
278 };
279
280 struct delayval tbdelay[] = {
281 1, TAB1,
282 2, TAB2,
283 3, XTABS, /* this is expand tabs */
284 100, TAB1,
285 0, TAB2,
286 };
287
288 delaybits()
289 {
290 register f;
291
292 f = adelay(CD, crdelay);
293 f |= adelay(ND, nldelay);
294 f |= adelay(FD, ffdelay);
295 f |= adelay(TD, tbdelay);
296 f |= adelay(BD, bsdelay);
297 return (f);
298 }
299
300 adelay(ms, dp)
301 register ms;
302 register struct delayval *dp;
303 {
304 if (ms == 0)
305 return (0);
306 while (dp->delay && ms > dp->delay)
307 dp++;
308 return (dp->bits);
309 }
310
311 char editedhost[32];
312
313 edithost(pat)
314 register char *pat;
315 {
316 register char *host = HN;
317 register char *res = editedhost;
318
319 if (!pat)
320 pat = "";
321 while (*pat) {
322 switch (*pat) {
323
324 case '#':
325 if (*host)
326 host++;
327 break;
328
329 case '@':
330 if (*host)
331 *res++ = *host++;
332 break;
333
334 default:
335 *res++ = *pat;
336 break;
337
338 }
339 if (res == &editedhost[sizeof editedhost - 1]) {
340 *res = '\0';
341 return;
342 }
343 pat++;
344 }
345 if (*host)
346 strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
347 else
348 *res = '\0';
349 editedhost[sizeof editedhost - 1] = '\0';
350 }
351
352 struct speedtab {
353 int speed;
354 int uxname;
355 } speedtab[] = {
356 50, B50,
357 75, B75,
358 110, B110,
359 134, B134,
360 150, B150,
361 200, B200,
362 300, B300,
363 600, B600,
364 1200, B1200,
365 1800, B1800,
366 2400, B2400,
367 4800, B4800,
368 9600, B9600,
369 19200, EXTA,
370 19, EXTA, /* for people who say 19.2K */
371 38400, EXTB,
372 38, EXTB,
373 7200, EXTB, /* alternative */
374 57600, B57600,
375 115200, B115200,
376 0
377 };
378
379 speed(val)
380 {
381 register struct speedtab *sp;
382
383 if (val <= 15)
384 return (val);
385
386 for (sp = speedtab; sp->speed; sp++)
387 if (sp->speed == val)
388 return (sp->uxname);
389
390 return (B300); /* default in impossible cases */
391 }
392
393 makeenv(env)
394 char *env[];
395 {
396 static char termbuf[128] = "TERM=";
397 register char *p, *q;
398 register char **ep;
399 char *index();
400
401 ep = env;
402 if (TT && *TT) {
403 strcat(termbuf, TT);
404 *ep++ = termbuf;
405 }
406 if (p = EV) {
407 q = p;
408 while (q = index(q, ',')) {
409 *q++ = '\0';
410 *ep++ = p;
411 p = q;
412 }
413 if (*p)
414 *ep++ = p;
415 }
416 *ep = (char *)0;
417 }
418
419 /*
420 * This speed select mechanism is written for the Develcon DATASWITCH.
421 * The Develcon sends a string of the form "B{speed}\n" at a predefined
422 * baud rate. This string indicates the user's actual speed.
423 * The routine below returns the terminal type mapped from derived speed.
424 */
425 struct portselect {
426 char *ps_baud;
427 char *ps_type;
428 } portspeeds[] = {
429 { "B110", "std.110" },
430 { "B134", "std.134" },
431 { "B150", "std.150" },
432 { "B300", "std.300" },
433 { "B600", "std.600" },
434 { "B1200", "std.1200" },
435 { "B2400", "std.2400" },
436 { "B4800", "std.4800" },
437 { "B9600", "std.9600" },
438 { "B19200", "std.19200" },
439 { 0 }
440 };
441
442 char *
443 portselector()
444 {
445 char c, baud[20], *type = "default";
446 register struct portselect *ps;
447 int len;
448
449 alarm(5*60);
450 for (len = 0; len < sizeof (baud) - 1; len++) {
451 if (read(STDIN_FILENO, &c, 1) <= 0)
452 break;
453 c &= 0177;
454 if (c == '\n' || c == '\r')
455 break;
456 if (c == 'B')
457 len = 0; /* in case of leading garbage */
458 baud[len] = c;
459 }
460 baud[len] = '\0';
461 for (ps = portspeeds; ps->ps_baud; ps++)
462 if (strcmp(ps->ps_baud, baud) == 0) {
463 type = ps->ps_type;
464 break;
465 }
466 sleep(2); /* wait for connection to complete */
467 return (type);
468 }
469
470 /*
471 * This auto-baud speed select mechanism is written for the Micom 600
472 * portselector. Selection is done by looking at how the character '\r'
473 * is garbled at the different speeds.
474 */
475 #include <sys/time.h>
476
477 char *
478 autobaud()
479 {
480 int rfds;
481 struct timeval timeout;
482 char c, *type = "9600-baud";
483 int null = 0;
484
485 ioctl(0, TIOCFLUSH, &null);
486 rfds = 1 << 0;
487 timeout.tv_sec = 5;
488 timeout.tv_usec = 0;
489 if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
490 (fd_set *)NULL, &timeout) <= 0)
491 return (type);
492 if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
493 return (type);
494 timeout.tv_sec = 0;
495 timeout.tv_usec = 20;
496 (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
497 (fd_set *)NULL, &timeout);
498 ioctl(0, TIOCFLUSH, &null);
499 switch (c & 0377) {
500
501 case 0200: /* 300-baud */
502 type = "300-baud";
503 break;
504
505 case 0346: /* 1200-baud */
506 type = "1200-baud";
507 break;
508
509 case 015: /* 2400-baud */
510 case 0215:
511 type = "2400-baud";
512 break;
513
514 default: /* 4800-baud */
515 type = "4800-baud";
516 break;
517
518 case 0377: /* 9600-baud */
519 type = "9600-baud";
520 break;
521 }
522 return (type);
523 }
524