subr.c revision 1.8 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.8 pk static char rcsid[] = "$Id: subr.c,v 1.8 1994/08/15 15:46:44 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.8 pk } else if (OP && !EP) {
235 1.7 pk iflag |= INPCK|ISTRIP;
236 1.7 pk cflag |= PARENB|PARODD|CS7;
237 1.8 pk } else if (EP && !OP) {
238 1.7 pk iflag |= INPCK|ISTRIP;
239 1.7 pk cflag |= PARENB|CS7;
240 1.8 pk } else {
241 1.8 pk /* Other combinations, including `AP' and `EP && OP' */
242 1.8 pk iflag |= IGNPAR|ISTRIP;
243 1.8 pk cflag |= CS7;
244 1.7 pk }
245 1.1 cgd
246 1.7 pk #if 0
247 1.1 cgd if (UC)
248 1.1 cgd f |= LCASE;
249 1.7 pk #endif
250 1.1 cgd
251 1.7 pk if (HC)
252 1.7 pk cflag |= HUPCL;
253 1.7 pk
254 1.7 pk if (NL) {
255 1.7 pk iflag |= ICRNL;
256 1.7 pk oflag |= ONLCR;
257 1.7 pk }
258 1.1 cgd
259 1.7 pk #ifdef XXX_DELAY
260 1.1 cgd f |= delaybits();
261 1.7 pk #endif
262 1.1 cgd
263 1.1 cgd if (n == 1) { /* read mode flags */
264 1.7 pk if (RW) {
265 1.7 pk iflag = 0;
266 1.7 pk oflag = 0;
267 1.7 pk cflag = CREAD|CS8;
268 1.7 pk lflag = 0;
269 1.7 pk } else {
270 1.7 pk lflag &= ~ICANON;
271 1.7 pk }
272 1.7 pk goto out;
273 1.1 cgd }
274 1.1 cgd
275 1.1 cgd if (!HT)
276 1.7 pk oflag |= OXTABS;
277 1.1 cgd
278 1.1 cgd if (n == 0)
279 1.7 pk goto out;
280 1.1 cgd
281 1.7 pk #if 0
282 1.1 cgd if (CB)
283 1.1 cgd f |= CRTBS;
284 1.7 pk #endif
285 1.1 cgd
286 1.1 cgd if (CE)
287 1.7 pk lflag |= ECHOE;
288 1.1 cgd
289 1.1 cgd if (CK)
290 1.7 pk lflag |= ECHOKE;
291 1.1 cgd
292 1.1 cgd if (PE)
293 1.7 pk lflag |= ECHOPRT;
294 1.1 cgd
295 1.1 cgd if (EC)
296 1.7 pk lflag |= ECHO;
297 1.1 cgd
298 1.1 cgd if (XC)
299 1.7 pk lflag |= ECHOCTL;
300 1.1 cgd
301 1.1 cgd if (DX)
302 1.7 pk lflag |= IXANY;
303 1.5 cgd
304 1.6 cgd if (MB)
305 1.7 pk cflag |= MDMBUF;
306 1.1 cgd
307 1.7 pk out:
308 1.7 pk tmode.c_iflag = iflag;
309 1.7 pk tmode.c_oflag = oflag;
310 1.7 pk tmode.c_cflag = cflag;
311 1.7 pk tmode.c_lflag = lflag;
312 1.7 pk }
313 1.7 pk
314 1.7 pk #ifdef COMPAT_43
315 1.7 pk /*
316 1.7 pk * Old TTY => termios, snatched from <sys/kern/tty_compat.c>
317 1.7 pk */
318 1.7 pk void
319 1.7 pk compatflags(flags)
320 1.7 pk register long flags;
321 1.7 pk {
322 1.7 pk register tcflag_t iflag, oflag, cflag, lflag;
323 1.7 pk
324 1.7 pk iflag = (BRKINT|ICRNL|IMAXBEL|IXON|IXANY);
325 1.7 pk oflag = (OPOST|ONLCR|OXTABS);
326 1.7 pk cflag = (CREAD);
327 1.7 pk lflag = (ICANON|ISIG|IEXTEN);
328 1.7 pk
329 1.8 pk if (flags & TANDEM)
330 1.8 pk iflag |= IXOFF;
331 1.8 pk else
332 1.8 pk iflag &= ~IXOFF;
333 1.8 pk if (flags & ECHO)
334 1.8 pk lflag |= ECHO;
335 1.8 pk else
336 1.8 pk lflag &= ~ECHO;
337 1.8 pk if (flags & CRMOD) {
338 1.8 pk iflag |= ICRNL;
339 1.8 pk oflag |= ONLCR;
340 1.8 pk } else {
341 1.8 pk iflag &= ~ICRNL;
342 1.8 pk oflag &= ~ONLCR;
343 1.8 pk }
344 1.8 pk if (flags & XTABS)
345 1.8 pk oflag |= OXTABS;
346 1.8 pk else
347 1.8 pk oflag &= ~OXTABS;
348 1.8 pk
349 1.7 pk if (flags & RAW) {
350 1.8 pk iflag &= IXOFF;
351 1.8 pk lflag &= ~(ISIG|ICANON|IEXTEN);
352 1.7 pk } else {
353 1.7 pk iflag |= BRKINT|IXON|IMAXBEL;
354 1.8 pk lflag |= ISIG|IEXTEN;
355 1.7 pk if (flags & CBREAK)
356 1.7 pk lflag &= ~ICANON;
357 1.7 pk else
358 1.7 pk lflag |= ICANON;
359 1.7 pk }
360 1.7 pk
361 1.8 pk switch (flags & ANYP) {
362 1.8 pk case EVENP:
363 1.8 pk iflag |= INPCK;
364 1.8 pk cflag &= ~PARODD;
365 1.8 pk break;
366 1.8 pk case ODDP:
367 1.8 pk iflag |= INPCK;
368 1.8 pk cflag |= PARODD;
369 1.8 pk break;
370 1.8 pk default:
371 1.8 pk iflag &= ~INPCK;
372 1.8 pk break;
373 1.8 pk }
374 1.8 pk
375 1.8 pk if (flags & (RAW|LITOUT|PASS8)) {
376 1.7 pk cflag &= ~(CSIZE|PARENB);
377 1.7 pk cflag |= CS8;
378 1.8 pk if ((flags & (RAW|PASS8)) == 0)
379 1.7 pk iflag |= ISTRIP;
380 1.7 pk else
381 1.7 pk iflag &= ~ISTRIP;
382 1.8 pk if ((flags & (RAW|LITOUT)) == 0)
383 1.8 pk oflag |= OPOST;
384 1.8 pk else
385 1.8 pk oflag &= ~OPOST;
386 1.7 pk } else {
387 1.7 pk cflag &= ~CSIZE;
388 1.7 pk cflag |= CS7|PARENB;
389 1.7 pk iflag |= ISTRIP;
390 1.8 pk oflag |= OPOST;
391 1.7 pk }
392 1.8 pk
393 1.8 pk if (flags & PRTERA)
394 1.8 pk lflag |= ECHOPRT;
395 1.7 pk else
396 1.8 pk lflag &= ~ECHOPRT;
397 1.8 pk if (flags & CRTERA)
398 1.7 pk lflag |= ECHOE;
399 1.7 pk else
400 1.7 pk lflag &= ~ECHOE;
401 1.8 pk if (flags & MDMBUF)
402 1.8 pk cflag |= MDMBUF;
403 1.8 pk else
404 1.8 pk cflag &= ~MDMBUF;
405 1.8 pk if (flags & NOHANG)
406 1.8 pk cflag &= ~HUPCL;
407 1.8 pk else
408 1.8 pk cflag |= HUPCL;
409 1.8 pk if (flags & CRTKIL)
410 1.7 pk lflag |= ECHOKE;
411 1.7 pk else
412 1.7 pk lflag &= ~ECHOKE;
413 1.8 pk if (flags & CTLECH)
414 1.7 pk lflag |= ECHOCTL;
415 1.7 pk else
416 1.7 pk lflag &= ~ECHOCTL;
417 1.8 pk if ((flags & DECCTQ) == 0)
418 1.7 pk lflag |= IXANY;
419 1.7 pk else
420 1.7 pk lflag &= ~IXANY;
421 1.7 pk lflag &= ~(TOSTOP|FLUSHO|PENDIN|NOFLSH);
422 1.8 pk lflag |= flags & (TOSTOP|FLUSHO|PENDIN|NOFLSH);
423 1.8 pk
424 1.8 pk if (flags & (RAW|LITOUT|PASS8)) {
425 1.7 pk cflag &= ~(CSIZE|PARENB);
426 1.7 pk cflag |= CS8;
427 1.8 pk if ((flags & (RAW|PASS8)) == 0)
428 1.8 pk iflag |= ISTRIP;
429 1.8 pk else
430 1.8 pk iflag &= ~ISTRIP;
431 1.8 pk if ((flags & (RAW|LITOUT)) == 0)
432 1.8 pk oflag |= OPOST;
433 1.8 pk else
434 1.7 pk oflag &= ~OPOST;
435 1.8 pk } else {
436 1.7 pk cflag &= ~CSIZE;
437 1.7 pk cflag |= CS7|PARENB;
438 1.8 pk iflag |= ISTRIP;
439 1.7 pk oflag |= OPOST;
440 1.7 pk }
441 1.7 pk
442 1.7 pk tmode.c_iflag = iflag;
443 1.7 pk tmode.c_oflag = oflag;
444 1.7 pk tmode.c_cflag = cflag;
445 1.7 pk tmode.c_lflag = lflag;
446 1.1 cgd }
447 1.7 pk #endif
448 1.1 cgd
449 1.7 pk #ifdef XXX_DELAY
450 1.1 cgd struct delayval {
451 1.1 cgd unsigned delay; /* delay in ms */
452 1.1 cgd int bits;
453 1.1 cgd };
454 1.1 cgd
455 1.1 cgd /*
456 1.1 cgd * below are random guesses, I can't be bothered checking
457 1.1 cgd */
458 1.1 cgd
459 1.1 cgd struct delayval crdelay[] = {
460 1.1 cgd 1, CR1,
461 1.1 cgd 2, CR2,
462 1.1 cgd 3, CR3,
463 1.1 cgd 83, CR1,
464 1.1 cgd 166, CR2,
465 1.1 cgd 0, CR3,
466 1.1 cgd };
467 1.1 cgd
468 1.1 cgd struct delayval nldelay[] = {
469 1.1 cgd 1, NL1, /* special, calculated */
470 1.1 cgd 2, NL2,
471 1.1 cgd 3, NL3,
472 1.1 cgd 100, NL2,
473 1.1 cgd 0, NL3,
474 1.1 cgd };
475 1.1 cgd
476 1.1 cgd struct delayval bsdelay[] = {
477 1.1 cgd 1, BS1,
478 1.1 cgd 0, 0,
479 1.1 cgd };
480 1.1 cgd
481 1.1 cgd struct delayval ffdelay[] = {
482 1.1 cgd 1, FF1,
483 1.1 cgd 1750, FF1,
484 1.1 cgd 0, FF1,
485 1.1 cgd };
486 1.1 cgd
487 1.1 cgd struct delayval tbdelay[] = {
488 1.1 cgd 1, TAB1,
489 1.1 cgd 2, TAB2,
490 1.1 cgd 3, XTABS, /* this is expand tabs */
491 1.1 cgd 100, TAB1,
492 1.1 cgd 0, TAB2,
493 1.1 cgd };
494 1.1 cgd
495 1.1 cgd delaybits()
496 1.1 cgd {
497 1.1 cgd register f;
498 1.1 cgd
499 1.1 cgd f = adelay(CD, crdelay);
500 1.1 cgd f |= adelay(ND, nldelay);
501 1.1 cgd f |= adelay(FD, ffdelay);
502 1.1 cgd f |= adelay(TD, tbdelay);
503 1.1 cgd f |= adelay(BD, bsdelay);
504 1.1 cgd return (f);
505 1.1 cgd }
506 1.1 cgd
507 1.1 cgd adelay(ms, dp)
508 1.1 cgd register ms;
509 1.1 cgd register struct delayval *dp;
510 1.1 cgd {
511 1.1 cgd if (ms == 0)
512 1.1 cgd return (0);
513 1.1 cgd while (dp->delay && ms > dp->delay)
514 1.1 cgd dp++;
515 1.1 cgd return (dp->bits);
516 1.1 cgd }
517 1.7 pk #endif
518 1.1 cgd
519 1.1 cgd char editedhost[32];
520 1.1 cgd
521 1.1 cgd edithost(pat)
522 1.1 cgd register char *pat;
523 1.1 cgd {
524 1.1 cgd register char *host = HN;
525 1.1 cgd register char *res = editedhost;
526 1.1 cgd
527 1.1 cgd if (!pat)
528 1.1 cgd pat = "";
529 1.1 cgd while (*pat) {
530 1.1 cgd switch (*pat) {
531 1.1 cgd
532 1.1 cgd case '#':
533 1.1 cgd if (*host)
534 1.1 cgd host++;
535 1.1 cgd break;
536 1.1 cgd
537 1.1 cgd case '@':
538 1.1 cgd if (*host)
539 1.1 cgd *res++ = *host++;
540 1.1 cgd break;
541 1.1 cgd
542 1.1 cgd default:
543 1.1 cgd *res++ = *pat;
544 1.1 cgd break;
545 1.1 cgd
546 1.1 cgd }
547 1.1 cgd if (res == &editedhost[sizeof editedhost - 1]) {
548 1.1 cgd *res = '\0';
549 1.1 cgd return;
550 1.1 cgd }
551 1.1 cgd pat++;
552 1.1 cgd }
553 1.1 cgd if (*host)
554 1.1 cgd strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
555 1.1 cgd else
556 1.1 cgd *res = '\0';
557 1.1 cgd editedhost[sizeof editedhost - 1] = '\0';
558 1.1 cgd }
559 1.1 cgd
560 1.1 cgd struct speedtab {
561 1.1 cgd int speed;
562 1.1 cgd int uxname;
563 1.1 cgd } speedtab[] = {
564 1.1 cgd 50, B50,
565 1.1 cgd 75, B75,
566 1.1 cgd 110, B110,
567 1.1 cgd 134, B134,
568 1.1 cgd 150, B150,
569 1.1 cgd 200, B200,
570 1.1 cgd 300, B300,
571 1.1 cgd 600, B600,
572 1.1 cgd 1200, B1200,
573 1.1 cgd 1800, B1800,
574 1.1 cgd 2400, B2400,
575 1.1 cgd 4800, B4800,
576 1.1 cgd 9600, B9600,
577 1.1 cgd 19200, EXTA,
578 1.1 cgd 19, EXTA, /* for people who say 19.2K */
579 1.1 cgd 38400, EXTB,
580 1.1 cgd 38, EXTB,
581 1.1 cgd 7200, EXTB, /* alternative */
582 1.2 cgd 57600, B57600,
583 1.2 cgd 115200, B115200,
584 1.1 cgd 0
585 1.1 cgd };
586 1.1 cgd
587 1.1 cgd speed(val)
588 1.1 cgd {
589 1.1 cgd register struct speedtab *sp;
590 1.1 cgd
591 1.1 cgd if (val <= 15)
592 1.1 cgd return (val);
593 1.1 cgd
594 1.1 cgd for (sp = speedtab; sp->speed; sp++)
595 1.1 cgd if (sp->speed == val)
596 1.1 cgd return (sp->uxname);
597 1.1 cgd
598 1.1 cgd return (B300); /* default in impossible cases */
599 1.1 cgd }
600 1.1 cgd
601 1.1 cgd makeenv(env)
602 1.1 cgd char *env[];
603 1.1 cgd {
604 1.1 cgd static char termbuf[128] = "TERM=";
605 1.1 cgd register char *p, *q;
606 1.1 cgd register char **ep;
607 1.1 cgd char *index();
608 1.1 cgd
609 1.1 cgd ep = env;
610 1.1 cgd if (TT && *TT) {
611 1.1 cgd strcat(termbuf, TT);
612 1.1 cgd *ep++ = termbuf;
613 1.1 cgd }
614 1.1 cgd if (p = EV) {
615 1.1 cgd q = p;
616 1.1 cgd while (q = index(q, ',')) {
617 1.1 cgd *q++ = '\0';
618 1.1 cgd *ep++ = p;
619 1.1 cgd p = q;
620 1.1 cgd }
621 1.1 cgd if (*p)
622 1.1 cgd *ep++ = p;
623 1.1 cgd }
624 1.1 cgd *ep = (char *)0;
625 1.1 cgd }
626 1.1 cgd
627 1.1 cgd /*
628 1.1 cgd * This speed select mechanism is written for the Develcon DATASWITCH.
629 1.1 cgd * The Develcon sends a string of the form "B{speed}\n" at a predefined
630 1.1 cgd * baud rate. This string indicates the user's actual speed.
631 1.1 cgd * The routine below returns the terminal type mapped from derived speed.
632 1.1 cgd */
633 1.1 cgd struct portselect {
634 1.1 cgd char *ps_baud;
635 1.1 cgd char *ps_type;
636 1.1 cgd } portspeeds[] = {
637 1.1 cgd { "B110", "std.110" },
638 1.1 cgd { "B134", "std.134" },
639 1.1 cgd { "B150", "std.150" },
640 1.1 cgd { "B300", "std.300" },
641 1.1 cgd { "B600", "std.600" },
642 1.1 cgd { "B1200", "std.1200" },
643 1.1 cgd { "B2400", "std.2400" },
644 1.1 cgd { "B4800", "std.4800" },
645 1.1 cgd { "B9600", "std.9600" },
646 1.1 cgd { "B19200", "std.19200" },
647 1.1 cgd { 0 }
648 1.1 cgd };
649 1.1 cgd
650 1.1 cgd char *
651 1.1 cgd portselector()
652 1.1 cgd {
653 1.1 cgd char c, baud[20], *type = "default";
654 1.1 cgd register struct portselect *ps;
655 1.1 cgd int len;
656 1.1 cgd
657 1.1 cgd alarm(5*60);
658 1.1 cgd for (len = 0; len < sizeof (baud) - 1; len++) {
659 1.1 cgd if (read(STDIN_FILENO, &c, 1) <= 0)
660 1.1 cgd break;
661 1.1 cgd c &= 0177;
662 1.1 cgd if (c == '\n' || c == '\r')
663 1.1 cgd break;
664 1.1 cgd if (c == 'B')
665 1.1 cgd len = 0; /* in case of leading garbage */
666 1.1 cgd baud[len] = c;
667 1.1 cgd }
668 1.1 cgd baud[len] = '\0';
669 1.1 cgd for (ps = portspeeds; ps->ps_baud; ps++)
670 1.1 cgd if (strcmp(ps->ps_baud, baud) == 0) {
671 1.1 cgd type = ps->ps_type;
672 1.1 cgd break;
673 1.1 cgd }
674 1.1 cgd sleep(2); /* wait for connection to complete */
675 1.1 cgd return (type);
676 1.1 cgd }
677 1.1 cgd
678 1.1 cgd /*
679 1.1 cgd * This auto-baud speed select mechanism is written for the Micom 600
680 1.1 cgd * portselector. Selection is done by looking at how the character '\r'
681 1.1 cgd * is garbled at the different speeds.
682 1.1 cgd */
683 1.1 cgd #include <sys/time.h>
684 1.1 cgd
685 1.1 cgd char *
686 1.1 cgd autobaud()
687 1.1 cgd {
688 1.1 cgd int rfds;
689 1.1 cgd struct timeval timeout;
690 1.1 cgd char c, *type = "9600-baud";
691 1.1 cgd int null = 0;
692 1.1 cgd
693 1.1 cgd ioctl(0, TIOCFLUSH, &null);
694 1.1 cgd rfds = 1 << 0;
695 1.1 cgd timeout.tv_sec = 5;
696 1.1 cgd timeout.tv_usec = 0;
697 1.1 cgd if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
698 1.1 cgd (fd_set *)NULL, &timeout) <= 0)
699 1.1 cgd return (type);
700 1.1 cgd if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
701 1.1 cgd return (type);
702 1.1 cgd timeout.tv_sec = 0;
703 1.1 cgd timeout.tv_usec = 20;
704 1.1 cgd (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
705 1.1 cgd (fd_set *)NULL, &timeout);
706 1.1 cgd ioctl(0, TIOCFLUSH, &null);
707 1.1 cgd switch (c & 0377) {
708 1.1 cgd
709 1.1 cgd case 0200: /* 300-baud */
710 1.1 cgd type = "300-baud";
711 1.1 cgd break;
712 1.1 cgd
713 1.1 cgd case 0346: /* 1200-baud */
714 1.1 cgd type = "1200-baud";
715 1.1 cgd break;
716 1.1 cgd
717 1.1 cgd case 015: /* 2400-baud */
718 1.1 cgd case 0215:
719 1.1 cgd type = "2400-baud";
720 1.1 cgd break;
721 1.1 cgd
722 1.1 cgd default: /* 4800-baud */
723 1.1 cgd type = "4800-baud";
724 1.1 cgd break;
725 1.1 cgd
726 1.1 cgd case 0377: /* 9600-baud */
727 1.1 cgd type = "9600-baud";
728 1.1 cgd break;
729 1.1 cgd }
730 1.1 cgd return (type);
731 1.1 cgd }
732