subr.c revision 1.7 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.3 mycroft /*static char sccsid[] = "from: @(#)subr.c 5.10 (Berkeley) 2/26/91";*/
36 1.7 pk static char rcsid[] = "$Id: subr.c,v 1.7 1994/04/28 22:12:31 pk Exp $";
37 1.1 cgd #endif /* not lint */
38 1.1 cgd
39 1.1 cgd /*
40 1.1 cgd * Melbourne getty.
41 1.1 cgd */
42 1.7 pk #define COMPAT_43
43 1.4 cgd #include <stdlib.h>
44 1.1 cgd #include <unistd.h>
45 1.1 cgd #include <string.h>
46 1.7 pk #include <termios.h>
47 1.7 pk #include <sys/ioctl.h>
48 1.4 cgd
49 1.1 cgd #include "gettytab.h"
50 1.4 cgd #include "pathnames.h"
51 1.1 cgd
52 1.7 pk extern struct termios tmode;
53 1.1 cgd
54 1.7 pk static void compatflags __P((long));
55 1.1 cgd /*
56 1.1 cgd * Get a table entry.
57 1.1 cgd */
58 1.4 cgd gettable(name, buf)
59 1.4 cgd char *name, *buf;
60 1.1 cgd {
61 1.1 cgd register struct gettystrs *sp;
62 1.1 cgd register struct gettynums *np;
63 1.1 cgd register struct gettyflags *fp;
64 1.4 cgd long n;
65 1.4 cgd char *dba[2];
66 1.4 cgd dba[0] = _PATH_GETTYTAB;
67 1.4 cgd dba[1] = 0;
68 1.1 cgd
69 1.4 cgd if (cgetent(&buf, dba, name) != 0)
70 1.1 cgd return;
71 1.1 cgd
72 1.1 cgd for (sp = gettystrs; sp->field; sp++)
73 1.4 cgd cgetstr(buf, sp->field, &sp->value);
74 1.1 cgd for (np = gettynums; np->field; np++) {
75 1.4 cgd if (cgetnum(buf, np->field, &n) == -1)
76 1.1 cgd np->set = 0;
77 1.1 cgd else {
78 1.1 cgd np->set = 1;
79 1.1 cgd np->value = n;
80 1.1 cgd }
81 1.1 cgd }
82 1.1 cgd for (fp = gettyflags; fp->field; fp++) {
83 1.4 cgd if (cgetcap(buf, fp->field, ':') == NULL)
84 1.1 cgd fp->set = 0;
85 1.1 cgd else {
86 1.1 cgd fp->set = 1;
87 1.4 cgd fp->value = 1 ^ fp->invrt;
88 1.1 cgd }
89 1.1 cgd }
90 1.4 cgd #ifdef DEBUG
91 1.4 cgd printf("name=\"%s\", buf=\"%s\"\n", name, buf);
92 1.4 cgd for (sp = gettystrs; sp->field; sp++)
93 1.4 cgd printf("cgetstr: %s=%s\n", sp->field, sp->value);
94 1.4 cgd for (np = gettynums; np->field; np++)
95 1.4 cgd printf("cgetnum: %s=%d\n", np->field, np->value);
96 1.4 cgd for (fp = gettyflags; fp->field; fp++)
97 1.4 cgd printf("cgetflags: %s='%c' set='%c'\n", fp->field,
98 1.4 cgd fp->value + '0', fp->set + '0');
99 1.4 cgd exit(1);
100 1.4 cgd #endif /* DEBUG */
101 1.1 cgd }
102 1.1 cgd
103 1.1 cgd gendefaults()
104 1.1 cgd {
105 1.1 cgd register struct gettystrs *sp;
106 1.1 cgd register struct gettynums *np;
107 1.1 cgd register struct gettyflags *fp;
108 1.1 cgd
109 1.1 cgd for (sp = gettystrs; sp->field; sp++)
110 1.1 cgd if (sp->value)
111 1.1 cgd sp->defalt = sp->value;
112 1.1 cgd for (np = gettynums; np->field; np++)
113 1.1 cgd if (np->set)
114 1.1 cgd np->defalt = np->value;
115 1.1 cgd for (fp = gettyflags; fp->field; fp++)
116 1.1 cgd if (fp->set)
117 1.1 cgd fp->defalt = fp->value;
118 1.1 cgd else
119 1.1 cgd fp->defalt = fp->invrt;
120 1.1 cgd }
121 1.1 cgd
122 1.1 cgd setdefaults()
123 1.1 cgd {
124 1.1 cgd register struct gettystrs *sp;
125 1.1 cgd register struct gettynums *np;
126 1.1 cgd register struct gettyflags *fp;
127 1.1 cgd
128 1.1 cgd for (sp = gettystrs; sp->field; sp++)
129 1.1 cgd if (!sp->value)
130 1.1 cgd sp->value = sp->defalt;
131 1.1 cgd for (np = gettynums; np->field; np++)
132 1.1 cgd if (!np->set)
133 1.1 cgd np->value = np->defalt;
134 1.1 cgd for (fp = gettyflags; fp->field; fp++)
135 1.1 cgd if (!fp->set)
136 1.1 cgd fp->value = fp->defalt;
137 1.1 cgd }
138 1.1 cgd
139 1.1 cgd static char **
140 1.1 cgd charnames[] = {
141 1.1 cgd &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
142 1.1 cgd &SU, &DS, &RP, &FL, &WE, &LN, 0
143 1.1 cgd };
144 1.1 cgd
145 1.1 cgd static char *
146 1.1 cgd charvars[] = {
147 1.7 pk &tmode.c_cc[VERASE], &tmode.c_cc[VKILL], &tmode.c_cc[VINTR],
148 1.7 pk &tmode.c_cc[VQUIT], &tmode.c_cc[VSTART], &tmode.c_cc[VSTOP],
149 1.7 pk &tmode.c_cc[VEOF], &tmode.c_cc[VEOL], &tmode.c_cc[VSUSP],
150 1.7 pk &tmode.c_cc[VDSUSP], &tmode.c_cc[VREPRINT], &tmode.c_cc[VDISCARD],
151 1.7 pk &tmode.c_cc[VWERASE], &tmode.c_cc[VLNEXT], 0
152 1.1 cgd };
153 1.1 cgd
154 1.1 cgd setchars()
155 1.1 cgd {
156 1.1 cgd register int i;
157 1.1 cgd register char *p;
158 1.1 cgd
159 1.1 cgd for (i = 0; charnames[i]; i++) {
160 1.1 cgd p = *charnames[i];
161 1.1 cgd if (p && *p)
162 1.1 cgd *charvars[i] = *p;
163 1.1 cgd else
164 1.1 cgd *charvars[i] = '\377';
165 1.1 cgd }
166 1.1 cgd }
167 1.1 cgd
168 1.7 pk void
169 1.1 cgd setflags(n)
170 1.1 cgd {
171 1.7 pk register tcflag_t iflag, oflag, cflag, lflag;
172 1.1 cgd
173 1.7 pk #ifdef COMPAT_43
174 1.1 cgd switch (n) {
175 1.1 cgd case 0:
176 1.7 pk if (F0set) {
177 1.7 pk compatflags(F0);
178 1.7 pk return;
179 1.7 pk }
180 1.1 cgd break;
181 1.1 cgd case 1:
182 1.7 pk if (F1set) {
183 1.7 pk compatflags(F1);
184 1.7 pk return;
185 1.7 pk }
186 1.1 cgd break;
187 1.1 cgd default:
188 1.7 pk if (F2set) {
189 1.7 pk compatflags(F2);
190 1.7 pk return;
191 1.7 pk }
192 1.1 cgd break;
193 1.1 cgd }
194 1.7 pk #endif
195 1.1 cgd
196 1.7 pk switch (n) {
197 1.7 pk case 0:
198 1.7 pk if (C0set && I0set && L0set && O0set) {
199 1.7 pk tmode.c_cflag = C0;
200 1.7 pk tmode.c_iflag = I0;
201 1.7 pk tmode.c_lflag = L0;
202 1.7 pk tmode.c_oflag = O0;
203 1.7 pk return;
204 1.7 pk }
205 1.7 pk break;
206 1.7 pk case 1:
207 1.7 pk if (C1set && I1set && L1set && O1set) {
208 1.7 pk tmode.c_cflag = C1;
209 1.7 pk tmode.c_iflag = I1;
210 1.7 pk tmode.c_lflag = L1;
211 1.7 pk tmode.c_oflag = O1;
212 1.7 pk return;
213 1.7 pk }
214 1.7 pk break;
215 1.7 pk default:
216 1.7 pk if (C2set && I2set && L2set && O2set) {
217 1.7 pk tmode.c_cflag = C2;
218 1.7 pk tmode.c_iflag = I2;
219 1.7 pk tmode.c_lflag = L2;
220 1.7 pk tmode.c_oflag = O2;
221 1.7 pk return;
222 1.7 pk }
223 1.7 pk break;
224 1.7 pk }
225 1.1 cgd
226 1.7 pk iflag = (BRKINT|ICRNL|IMAXBEL|IXON|IXANY);
227 1.7 pk oflag = (OPOST|ONLCR|OXTABS);
228 1.7 pk cflag = (CREAD);
229 1.7 pk lflag = (ICANON|ISIG|IEXTEN);
230 1.7 pk
231 1.7 pk if (NP) {
232 1.7 pk iflag |= IGNPAR;
233 1.7 pk cflag |= CS8;
234 1.7 pk } else if (AP) {
235 1.7 pk iflag |= IGNPAR|ISTRIP;
236 1.7 pk cflag |= CS7;
237 1.7 pk } else if (OP) {
238 1.7 pk iflag |= INPCK|ISTRIP;
239 1.7 pk cflag |= PARENB|PARODD|CS7;
240 1.7 pk } else if (EP) {
241 1.7 pk iflag |= INPCK|ISTRIP;
242 1.7 pk cflag |= PARENB|CS7;
243 1.7 pk }
244 1.1 cgd
245 1.7 pk #if 0
246 1.1 cgd if (UC)
247 1.1 cgd f |= LCASE;
248 1.7 pk #endif
249 1.1 cgd
250 1.7 pk if (HC)
251 1.7 pk cflag |= HUPCL;
252 1.7 pk
253 1.7 pk if (NL) {
254 1.7 pk iflag |= ICRNL;
255 1.7 pk oflag |= ONLCR;
256 1.7 pk }
257 1.1 cgd
258 1.7 pk #ifdef XXX_DELAY
259 1.1 cgd f |= delaybits();
260 1.7 pk #endif
261 1.1 cgd
262 1.1 cgd if (n == 1) { /* read mode flags */
263 1.7 pk if (RW) {
264 1.7 pk iflag = 0;
265 1.7 pk oflag = 0;
266 1.7 pk cflag = CREAD|CS8;
267 1.7 pk lflag = 0;
268 1.7 pk } else {
269 1.7 pk lflag &= ~ICANON;
270 1.7 pk }
271 1.7 pk goto out;
272 1.1 cgd }
273 1.1 cgd
274 1.1 cgd if (!HT)
275 1.7 pk oflag |= OXTABS;
276 1.1 cgd
277 1.1 cgd if (n == 0)
278 1.7 pk goto out;
279 1.1 cgd
280 1.7 pk #if 0
281 1.1 cgd if (CB)
282 1.1 cgd f |= CRTBS;
283 1.7 pk #endif
284 1.1 cgd
285 1.1 cgd if (CE)
286 1.7 pk lflag |= ECHOE;
287 1.1 cgd
288 1.1 cgd if (CK)
289 1.7 pk lflag |= ECHOKE;
290 1.1 cgd
291 1.1 cgd if (PE)
292 1.7 pk lflag |= ECHOPRT;
293 1.1 cgd
294 1.1 cgd if (EC)
295 1.7 pk lflag |= ECHO;
296 1.1 cgd
297 1.1 cgd if (XC)
298 1.7 pk lflag |= ECHOCTL;
299 1.1 cgd
300 1.1 cgd if (DX)
301 1.7 pk lflag |= IXANY;
302 1.5 cgd
303 1.6 cgd if (MB)
304 1.7 pk cflag |= MDMBUF;
305 1.1 cgd
306 1.7 pk out:
307 1.7 pk tmode.c_iflag = iflag;
308 1.7 pk tmode.c_oflag = oflag;
309 1.7 pk tmode.c_cflag = cflag;
310 1.7 pk tmode.c_lflag = lflag;
311 1.7 pk }
312 1.7 pk
313 1.7 pk #ifdef COMPAT_43
314 1.7 pk /*
315 1.7 pk * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
316 1.7 pk */
317 1.7 pk void
318 1.7 pk compatflags(flags)
319 1.7 pk register long flags;
320 1.7 pk {
321 1.7 pk register tcflag_t iflag, oflag, cflag, lflag;
322 1.7 pk
323 1.7 pk iflag = (BRKINT|ICRNL|IMAXBEL|IXON|IXANY);
324 1.7 pk oflag = (OPOST|ONLCR|OXTABS);
325 1.7 pk cflag = (CREAD);
326 1.7 pk lflag = (ICANON|ISIG|IEXTEN);
327 1.7 pk
328 1.7 pk if (flags & RAW) {
329 1.7 pk iflag &= IXOFF|IXANY;
330 1.7 pk oflag &= ~OPOST;
331 1.7 pk lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN);
332 1.7 pk } else {
333 1.7 pk iflag |= BRKINT|IXON|IMAXBEL;
334 1.7 pk oflag |= OPOST;
335 1.7 pk lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */
336 1.7 pk if (flags & XTABS)
337 1.7 pk oflag |= OXTABS;
338 1.7 pk else
339 1.7 pk oflag &= ~OXTABS;
340 1.7 pk if (flags & CBREAK)
341 1.7 pk lflag &= ~ICANON;
342 1.7 pk else
343 1.7 pk lflag |= ICANON;
344 1.7 pk if (flags&CRMOD) {
345 1.7 pk iflag |= ICRNL;
346 1.7 pk oflag |= ONLCR;
347 1.7 pk } else {
348 1.7 pk iflag &= ~ICRNL;
349 1.7 pk oflag &= ~ONLCR;
350 1.7 pk }
351 1.7 pk }
352 1.7 pk if (flags&ECHO)
353 1.7 pk lflag |= ECHO;
354 1.7 pk else
355 1.7 pk lflag &= ~ECHO;
356 1.7 pk
357 1.7 pk if (flags&(RAW|LITOUT|PASS8)) {
358 1.7 pk cflag &= ~(CSIZE|PARENB);
359 1.7 pk cflag |= CS8;
360 1.7 pk if ((flags&(RAW|PASS8)) == 0)
361 1.7 pk iflag |= ISTRIP;
362 1.7 pk else
363 1.7 pk iflag &= ~ISTRIP;
364 1.7 pk } else {
365 1.7 pk cflag &= ~CSIZE;
366 1.7 pk cflag |= CS7|PARENB;
367 1.7 pk iflag |= ISTRIP;
368 1.7 pk }
369 1.7 pk if ((flags&(EVENP|ODDP)) == EVENP) {
370 1.7 pk iflag |= INPCK;
371 1.7 pk cflag &= ~PARODD;
372 1.7 pk } else if ((flags&(EVENP|ODDP)) == ODDP) {
373 1.7 pk iflag |= INPCK;
374 1.7 pk cflag |= PARODD;
375 1.7 pk } else
376 1.7 pk iflag &= ~INPCK;
377 1.7 pk if (flags&LITOUT)
378 1.7 pk oflag &= ~OPOST; /* move earlier ? */
379 1.7 pk if (flags&TANDEM)
380 1.7 pk iflag |= IXOFF;
381 1.7 pk else
382 1.7 pk iflag &= ~IXOFF;
383 1.7 pk
384 1.7 pk if (flags&CRTERA)
385 1.7 pk lflag |= ECHOE;
386 1.7 pk else
387 1.7 pk lflag &= ~ECHOE;
388 1.7 pk if (flags&CRTKIL)
389 1.7 pk lflag |= ECHOKE;
390 1.7 pk else
391 1.7 pk lflag &= ~ECHOKE;
392 1.7 pk if (flags&PRTERA)
393 1.7 pk lflag |= ECHOPRT;
394 1.7 pk else
395 1.7 pk lflag &= ~ECHOPRT;
396 1.7 pk if (flags&CTLECH)
397 1.7 pk lflag |= ECHOCTL;
398 1.7 pk else
399 1.7 pk lflag &= ~ECHOCTL;
400 1.7 pk if ((flags&DECCTQ) == 0)
401 1.7 pk lflag |= IXANY;
402 1.7 pk else
403 1.7 pk lflag &= ~IXANY;
404 1.7 pk if (flags & MDMBUF)
405 1.7 pk cflag |= MDMBUF;
406 1.7 pk else
407 1.7 pk cflag &= ~MDMBUF;
408 1.7 pk if (flags&NOHANG)
409 1.7 pk cflag &= ~HUPCL;
410 1.7 pk else
411 1.7 pk cflag |= HUPCL;
412 1.7 pk lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH);
413 1.7 pk lflag |= flags&(TOSTOP|FLUSHO|PENDIN|NOFLSH);
414 1.7 pk if (flags&(LITOUT|PASS8)) {
415 1.7 pk iflag &= ~ISTRIP;
416 1.7 pk cflag &= ~(CSIZE|PARENB);
417 1.7 pk cflag |= CS8;
418 1.7 pk if (flags&LITOUT)
419 1.7 pk oflag &= ~OPOST;
420 1.7 pk if ((flags&(PASS8|RAW)) == 0)
421 1.7 pk iflag |= ISTRIP;
422 1.7 pk } else if ((flags&RAW) == 0) {
423 1.7 pk cflag &= ~CSIZE;
424 1.7 pk cflag |= CS7|PARENB;
425 1.7 pk oflag |= OPOST;
426 1.7 pk }
427 1.7 pk
428 1.7 pk tmode.c_iflag = iflag;
429 1.7 pk tmode.c_oflag = oflag;
430 1.7 pk tmode.c_cflag = cflag;
431 1.7 pk tmode.c_lflag = lflag;
432 1.1 cgd }
433 1.7 pk #endif
434 1.1 cgd
435 1.7 pk #ifdef XXX_DELAY
436 1.1 cgd struct delayval {
437 1.1 cgd unsigned delay; /* delay in ms */
438 1.1 cgd int bits;
439 1.1 cgd };
440 1.1 cgd
441 1.1 cgd /*
442 1.1 cgd * below are random guesses, I can't be bothered checking
443 1.1 cgd */
444 1.1 cgd
445 1.1 cgd struct delayval crdelay[] = {
446 1.1 cgd 1, CR1,
447 1.1 cgd 2, CR2,
448 1.1 cgd 3, CR3,
449 1.1 cgd 83, CR1,
450 1.1 cgd 166, CR2,
451 1.1 cgd 0, CR3,
452 1.1 cgd };
453 1.1 cgd
454 1.1 cgd struct delayval nldelay[] = {
455 1.1 cgd 1, NL1, /* special, calculated */
456 1.1 cgd 2, NL2,
457 1.1 cgd 3, NL3,
458 1.1 cgd 100, NL2,
459 1.1 cgd 0, NL3,
460 1.1 cgd };
461 1.1 cgd
462 1.1 cgd struct delayval bsdelay[] = {
463 1.1 cgd 1, BS1,
464 1.1 cgd 0, 0,
465 1.1 cgd };
466 1.1 cgd
467 1.1 cgd struct delayval ffdelay[] = {
468 1.1 cgd 1, FF1,
469 1.1 cgd 1750, FF1,
470 1.1 cgd 0, FF1,
471 1.1 cgd };
472 1.1 cgd
473 1.1 cgd struct delayval tbdelay[] = {
474 1.1 cgd 1, TAB1,
475 1.1 cgd 2, TAB2,
476 1.1 cgd 3, XTABS, /* this is expand tabs */
477 1.1 cgd 100, TAB1,
478 1.1 cgd 0, TAB2,
479 1.1 cgd };
480 1.1 cgd
481 1.1 cgd delaybits()
482 1.1 cgd {
483 1.1 cgd register f;
484 1.1 cgd
485 1.1 cgd f = adelay(CD, crdelay);
486 1.1 cgd f |= adelay(ND, nldelay);
487 1.1 cgd f |= adelay(FD, ffdelay);
488 1.1 cgd f |= adelay(TD, tbdelay);
489 1.1 cgd f |= adelay(BD, bsdelay);
490 1.1 cgd return (f);
491 1.1 cgd }
492 1.1 cgd
493 1.1 cgd adelay(ms, dp)
494 1.1 cgd register ms;
495 1.1 cgd register struct delayval *dp;
496 1.1 cgd {
497 1.1 cgd if (ms == 0)
498 1.1 cgd return (0);
499 1.1 cgd while (dp->delay && ms > dp->delay)
500 1.1 cgd dp++;
501 1.1 cgd return (dp->bits);
502 1.1 cgd }
503 1.7 pk #endif
504 1.1 cgd
505 1.1 cgd char editedhost[32];
506 1.1 cgd
507 1.1 cgd edithost(pat)
508 1.1 cgd register char *pat;
509 1.1 cgd {
510 1.1 cgd register char *host = HN;
511 1.1 cgd register char *res = editedhost;
512 1.1 cgd
513 1.1 cgd if (!pat)
514 1.1 cgd pat = "";
515 1.1 cgd while (*pat) {
516 1.1 cgd switch (*pat) {
517 1.1 cgd
518 1.1 cgd case '#':
519 1.1 cgd if (*host)
520 1.1 cgd host++;
521 1.1 cgd break;
522 1.1 cgd
523 1.1 cgd case '@':
524 1.1 cgd if (*host)
525 1.1 cgd *res++ = *host++;
526 1.1 cgd break;
527 1.1 cgd
528 1.1 cgd default:
529 1.1 cgd *res++ = *pat;
530 1.1 cgd break;
531 1.1 cgd
532 1.1 cgd }
533 1.1 cgd if (res == &editedhost[sizeof editedhost - 1]) {
534 1.1 cgd *res = '\0';
535 1.1 cgd return;
536 1.1 cgd }
537 1.1 cgd pat++;
538 1.1 cgd }
539 1.1 cgd if (*host)
540 1.1 cgd strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
541 1.1 cgd else
542 1.1 cgd *res = '\0';
543 1.1 cgd editedhost[sizeof editedhost - 1] = '\0';
544 1.1 cgd }
545 1.1 cgd
546 1.1 cgd struct speedtab {
547 1.1 cgd int speed;
548 1.1 cgd int uxname;
549 1.1 cgd } speedtab[] = {
550 1.1 cgd 50, B50,
551 1.1 cgd 75, B75,
552 1.1 cgd 110, B110,
553 1.1 cgd 134, B134,
554 1.1 cgd 150, B150,
555 1.1 cgd 200, B200,
556 1.1 cgd 300, B300,
557 1.1 cgd 600, B600,
558 1.1 cgd 1200, B1200,
559 1.1 cgd 1800, B1800,
560 1.1 cgd 2400, B2400,
561 1.1 cgd 4800, B4800,
562 1.1 cgd 9600, B9600,
563 1.1 cgd 19200, EXTA,
564 1.1 cgd 19, EXTA, /* for people who say 19.2K */
565 1.1 cgd 38400, EXTB,
566 1.1 cgd 38, EXTB,
567 1.1 cgd 7200, EXTB, /* alternative */
568 1.2 cgd 57600, B57600,
569 1.2 cgd 115200, B115200,
570 1.1 cgd 0
571 1.1 cgd };
572 1.1 cgd
573 1.1 cgd speed(val)
574 1.1 cgd {
575 1.1 cgd register struct speedtab *sp;
576 1.1 cgd
577 1.1 cgd if (val <= 15)
578 1.1 cgd return (val);
579 1.1 cgd
580 1.1 cgd for (sp = speedtab; sp->speed; sp++)
581 1.1 cgd if (sp->speed == val)
582 1.1 cgd return (sp->uxname);
583 1.1 cgd
584 1.1 cgd return (B300); /* default in impossible cases */
585 1.1 cgd }
586 1.1 cgd
587 1.1 cgd makeenv(env)
588 1.1 cgd char *env[];
589 1.1 cgd {
590 1.1 cgd static char termbuf[128] = "TERM=";
591 1.1 cgd register char *p, *q;
592 1.1 cgd register char **ep;
593 1.1 cgd char *index();
594 1.1 cgd
595 1.1 cgd ep = env;
596 1.1 cgd if (TT && *TT) {
597 1.1 cgd strcat(termbuf, TT);
598 1.1 cgd *ep++ = termbuf;
599 1.1 cgd }
600 1.1 cgd if (p = EV) {
601 1.1 cgd q = p;
602 1.1 cgd while (q = index(q, ',')) {
603 1.1 cgd *q++ = '\0';
604 1.1 cgd *ep++ = p;
605 1.1 cgd p = q;
606 1.1 cgd }
607 1.1 cgd if (*p)
608 1.1 cgd *ep++ = p;
609 1.1 cgd }
610 1.1 cgd *ep = (char *)0;
611 1.1 cgd }
612 1.1 cgd
613 1.1 cgd /*
614 1.1 cgd * This speed select mechanism is written for the Develcon DATASWITCH.
615 1.1 cgd * The Develcon sends a string of the form "B{speed}\n" at a predefined
616 1.1 cgd * baud rate. This string indicates the user's actual speed.
617 1.1 cgd * The routine below returns the terminal type mapped from derived speed.
618 1.1 cgd */
619 1.1 cgd struct portselect {
620 1.1 cgd char *ps_baud;
621 1.1 cgd char *ps_type;
622 1.1 cgd } portspeeds[] = {
623 1.1 cgd { "B110", "std.110" },
624 1.1 cgd { "B134", "std.134" },
625 1.1 cgd { "B150", "std.150" },
626 1.1 cgd { "B300", "std.300" },
627 1.1 cgd { "B600", "std.600" },
628 1.1 cgd { "B1200", "std.1200" },
629 1.1 cgd { "B2400", "std.2400" },
630 1.1 cgd { "B4800", "std.4800" },
631 1.1 cgd { "B9600", "std.9600" },
632 1.1 cgd { "B19200", "std.19200" },
633 1.1 cgd { 0 }
634 1.1 cgd };
635 1.1 cgd
636 1.1 cgd char *
637 1.1 cgd portselector()
638 1.1 cgd {
639 1.1 cgd char c, baud[20], *type = "default";
640 1.1 cgd register struct portselect *ps;
641 1.1 cgd int len;
642 1.1 cgd
643 1.1 cgd alarm(5*60);
644 1.1 cgd for (len = 0; len < sizeof (baud) - 1; len++) {
645 1.1 cgd if (read(STDIN_FILENO, &c, 1) <= 0)
646 1.1 cgd break;
647 1.1 cgd c &= 0177;
648 1.1 cgd if (c == '\n' || c == '\r')
649 1.1 cgd break;
650 1.1 cgd if (c == 'B')
651 1.1 cgd len = 0; /* in case of leading garbage */
652 1.1 cgd baud[len] = c;
653 1.1 cgd }
654 1.1 cgd baud[len] = '\0';
655 1.1 cgd for (ps = portspeeds; ps->ps_baud; ps++)
656 1.1 cgd if (strcmp(ps->ps_baud, baud) == 0) {
657 1.1 cgd type = ps->ps_type;
658 1.1 cgd break;
659 1.1 cgd }
660 1.1 cgd sleep(2); /* wait for connection to complete */
661 1.1 cgd return (type);
662 1.1 cgd }
663 1.1 cgd
664 1.1 cgd /*
665 1.1 cgd * This auto-baud speed select mechanism is written for the Micom 600
666 1.1 cgd * portselector. Selection is done by looking at how the character '\r'
667 1.1 cgd * is garbled at the different speeds.
668 1.1 cgd */
669 1.1 cgd #include <sys/time.h>
670 1.1 cgd
671 1.1 cgd char *
672 1.1 cgd autobaud()
673 1.1 cgd {
674 1.1 cgd int rfds;
675 1.1 cgd struct timeval timeout;
676 1.1 cgd char c, *type = "9600-baud";
677 1.1 cgd int null = 0;
678 1.1 cgd
679 1.1 cgd ioctl(0, TIOCFLUSH, &null);
680 1.1 cgd rfds = 1 << 0;
681 1.1 cgd timeout.tv_sec = 5;
682 1.1 cgd timeout.tv_usec = 0;
683 1.1 cgd if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
684 1.1 cgd (fd_set *)NULL, &timeout) <= 0)
685 1.1 cgd return (type);
686 1.1 cgd if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
687 1.1 cgd return (type);
688 1.1 cgd timeout.tv_sec = 0;
689 1.1 cgd timeout.tv_usec = 20;
690 1.1 cgd (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
691 1.1 cgd (fd_set *)NULL, &timeout);
692 1.1 cgd ioctl(0, TIOCFLUSH, &null);
693 1.1 cgd switch (c & 0377) {
694 1.1 cgd
695 1.1 cgd case 0200: /* 300-baud */
696 1.1 cgd type = "300-baud";
697 1.1 cgd break;
698 1.1 cgd
699 1.1 cgd case 0346: /* 1200-baud */
700 1.1 cgd type = "1200-baud";
701 1.1 cgd break;
702 1.1 cgd
703 1.1 cgd case 015: /* 2400-baud */
704 1.1 cgd case 0215:
705 1.1 cgd type = "2400-baud";
706 1.1 cgd break;
707 1.1 cgd
708 1.1 cgd default: /* 4800-baud */
709 1.1 cgd type = "4800-baud";
710 1.1 cgd break;
711 1.1 cgd
712 1.1 cgd case 0377: /* 9600-baud */
713 1.1 cgd type = "9600-baud";
714 1.1 cgd break;
715 1.1 cgd }
716 1.1 cgd return (type);
717 1.1 cgd }
718