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