1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1988 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40 /*LINTLIBRARY*/
41
42 #include <stdio.h>
43 #include <sys/types.h>
44 #include <fcntl.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <errno.h>
49 #include <zone.h>
50 #include "curses_inc.h"
51
52 #define TERMPATH "/usr/share/lib/terminfo/"
53 #define TERMPATHLEN 512
54
55 extern bool _use_env; /* in curses.c */
56
57 chtype bit_attributes[NUM_ATTRIBUTES] = {
58 A_STANDOUT,
59 A_UNDERLINE,
60 A_ALTCHARSET,
61 A_REVERSE,
62 A_BLINK,
63 A_DIM,
64 A_BOLD,
65 A_INVIS,
66 A_PROTECT
67 };
68
69 char *Def_term = "unknown", /* default terminal type */
70 term_parm_err[32], ttytype[BUFSIZ], _frst_tblstr[1400];
71
72 TERMINAL _first_term, *cur_term = &_first_term;
73 struct _bool_struct _frst_bools, *cur_bools = &_frst_bools;
74 struct _num_struct _frst_nums, *cur_nums = &_frst_nums;
75 struct _str_struct _frst_strs, *cur_strs = &_frst_strs;
76
77 /* _called_before is used/cleared by delterm.c and restart.c */
78 char _called_before = 0;
79 short term_errno = -1;
80
81 #ifdef SYSV
82 int prog_istermios = -1;
83 int shell_istermios = -1;
84 #endif
85
86 #ifdef DUMPTI
87 extern char *boolfnames[], *boolnames[], *boolcodes[],
88 *numfnames[], *numnames[], *numcodes[],
89 *strfnames[], *strnames[], *strcodes[];
90
91 main(int argc, char **argv) /* FOR DEBUG ONLY */
92 {
93 if (argc > 1)
94 setupterm(argv[1], 1, (int *)0);
95 else
96 setupterm((char *)0, 1, (int *)0);
97 return (0);
98 }
99
100 _Pr(int ch) /* FOR DEBUG ONLY */
101 {
102 if (ch >= 0200) {
103 printf("M-");
104 ch -= 0200;
105 }
106 if ((ch < ' ') || (ch == 0177))
107 printf("^%c", ch ^ 0100);
108 else
109 printf("%c", ch);
110 }
111
112 _Sprint(int n, char *string) /* FOR DEBUG ONLY */
113 {
114 int ch;
115
116 if (n == -1) {
117 printf(".\n");
118 return;
119 }
120 printf(", string = '");
121 while (ch = *string++)
122 _Pr(ch&0377);
123
124 printf("'.\n");
125 }
126
127 _Mprint(int n, char *memory) /* FOR DEBUG ONLY */
128 {
129 unsigned char ch;
130
131 while (ch = *memory++, n-- > 0)
132 _Pr(ch&0377);
133 }
134
135 #define _Vr2getshi() _Vr2getsh(ip-2)
136
137 #if vax || pdp11
138 #define _Vr2getsh(ip) (* (short *)(ip))
139 #endif /* vax || pdp11 */
140
141 #ifndef _Vr2getsh
142 /*
143 * Here is a more portable version, which does not assume byte ordering
144 * in shorts, sign extension, etc.
145 */
146 _Vr2getsh(char *p)
147 {
148 int rv;
149
150 if (*p == (char)0377)
151 return (-1);
152 rv = (unsigned char) *p++;
153 rv += (unsigned char) *p * 256;
154 return (rv);
155 }
156 #endif /* _Vr2getsh */
157
158 #endif /* DUMPTI */
159
160 #define _Getshi() _Getsh(ip); ip += 2
161
162 /*
163 * "function" to get a short from a pointer. The short is in a standard
164 * format: two bytes, the first is the low order byte, the second is
165 * the high order byte (base 256). The only negative numbers allowed are
166 * -1 and -2, which are represented as 255,255 and 255,254 This format
167 * happens to be the same as the hardware on the pdp-11, vax, and 386,
168 * making it fast and convenient and small to do this on a pdp-11.
169 */
170
171 #if vax || pdp11 || i386
172 #define _Getsh(ip) (* (short *)ip)
173 #endif /* vax || pdp11 */
174 /*
175 * The following macro is partly due to Mike Laman, laman@sdcsvax
176 * NCR @ Torrey Pines. - Tony Hansen
177 */
178 #if u3b || u3b15 || u3b2 || m68000
179 #define _Getsh(ip) ((short)(*((unsigned char *)ip) | (*(ip+1) << 8)))
180 #endif /* u3b || u3b15 || u3b2 || m68000 */
181
182 #ifndef _Getsh
183 /*
184 * Here is a more portable version, which does not assume byte ordering
185 * in shorts, sign extension, etc. For the sake of the porters,
186 * two alternative implementations, for the machines that don't have
187 * casting to "unsigned char", are also given, but commented out.
188 * Not ANSI C implementation assumes that the * C preprocessor does
189 * sign-extension the same as on the machine being compiled for.
190 */
191 static int
192 _Getsh(char *p)
193 {
194 int rv, rv2;
195
196 rv = (unsigned char) p[0];
197 rv2 = (unsigned char) p[1];
198
199 /* the following stuff is only for porting. See the comment above */
200
201 #ifdef FOR_PORTING
202 #if CHAR_MIN < 0
203 rv = (*p++) & 0377;
204 rv2 = (*p) & 0377;
205 #else /* CHAR_MIN < 0 */
206 rv = *p++;
207 rv2 = *p;
208 #endif /* CHAR_MIN < 0 */
209
210 #endif /* FOR_PORTING */
211
212 if ((rv2 == 0377) && ((rv == 0377) || (rv == 0376)))
213 return (-1);
214 return (rv + (rv2 * 256));
215 }
216 #endif /* _Getsh */
217
218 /*
219 * setupterm: low level routine to dig up terminfo from database
220 * and read it in. Parms are terminal type (0 means use getenv("TERM"),
221 * file descriptor all output will go to (for ioctls), and a pointer
222 * to an int into which the error return code goes (0 means to bomb
223 * out with an error message if there's an error). Thus,
224 * setupterm((char *)0, 1, (int *)0) is a reasonable way for a simple
225 * program to set up.
226 */
227 int
228 setupterm(char *term, int filenum, int *errret)
229 /* filenum - This is a UNIX file descriptor, not a stdio ptr. */
230 {
231 char tiebuf[4096];
232 char fname[TERMPATHLEN];
233 char *ip;
234 char *cp;
235 int n, tfd;
236 char *lcp, *ccp, **on_sequences, **str_array;
237 int snames, nbools, nints, nstrs, sstrtab;
238 char *strtab;
239 #ifdef DUMPTI
240 int Vr2val;
241 #endif /* DUMPTI */
242
243 (void) mbgetwidth();
244
245 if (term == NULL)
246 term = getenv("TERM");
247
248 if (term == NULL || *term == '\0')
249 term = Def_term;
250
251 tfd = -1;
252 errno = 0; /* ehr3 */
253
254 if (errret != 0)
255 *errret = -1;
256
257 if (((cp = getenv("TERMINFO")) != 0) && *cp) {
258 /* $TERMINFO/?/$TERM */
259 if (snprintf(fname, sizeof (fname),
260 "%s/%c/%s", cp, *term, term) >= sizeof (fname)) {
261 term_errno = TERMINFO_TOO_LONG;
262 goto out_err;
263 }
264
265 tfd = open(fname, 0);
266 #ifdef DUMPTI
267 printf("looking in file %s\n", fname);
268 #endif /* DUMPTI */
269 if ((tfd < 0) && (errno == EACCES))
270 goto cant_read;
271 }
272
273 if (tfd < 0) {
274 const char *zroot = zone_get_nroot();
275 /* /usr/share/lib/terminfo/?/$TERM */
276 if (snprintf(fname, sizeof (fname),
277 "%s/%s/%c/%s", zroot == NULL ? "" : zroot, TERMPATH,
278 *term, term) >= sizeof (fname)) {
279 term_errno = TERMINFO_TOO_LONG;
280 goto out_err;
281 }
282
283 tfd = open(fname, 0);
284 #ifdef DUMPTI
285 printf("looking in file %s\n", fname);
286 #endif /* DUMPTI */
287
288 }
289
290 if (tfd < 0) {
291 if (errno == EACCES) {
292 cant_read:
293 term_errno = NOT_READABLE;
294 } else {
295 if (access(TERMPATH, 0) == -1)
296 term_errno = UNACCESSIBLE;
297 else {
298 term_errno = NO_TERMINAL;
299 if (errret != 0)
300 *errret = 0;
301 }
302 }
303 /*
304 * if the length of the specified terminal name is longer
305 * than 31, it will be chopped after the 31st byte.
306 * This should be a rare case.
307 */
308 (void) strncpy(term_parm_err, term, 31);
309 term_parm_err[31] = '\0';
310 goto out_err;
311 }
312
313 /* LINTED */
314 n = (int)read(tfd, tiebuf, sizeof (tiebuf));
315 (void) close(tfd);
316
317 if (n <= 0) {
318 corrupt:
319 term_errno = CORRUPTED;
320 goto out_err;
321 } else
322 if (n == sizeof (tiebuf)) {
323 term_errno = ENTRY_TOO_LONG;
324 goto out_err;
325 }
326 cp = ttytype;
327 ip = tiebuf;
328
329 /* Pick up header */
330 snames = _Getshi();
331 #ifdef DUMPTI
332 Vr2val = _Vr2getshi();
333 printf("Magic number = %d, %#o [%d, %#o].\n", snames,
334 snames, Vr2val, Vr2val);
335 #endif /* DUMPTI */
336 if (snames != MAGNUM)
337 goto corrupt;
338 snames = _Getshi();
339 #ifdef DUMPTI
340 Vr2val = _Vr2getshi();
341 printf("Size of names = %d, %#o [%d, %#o].\n", snames,
342 snames, Vr2val, Vr2val);
343 #endif /* DUMPTI */
344
345 nbools = _Getshi();
346 #ifdef DUMPTI
347 Vr2val = _Vr2getshi();
348 printf("Number of bools = %d, %#o [%d, %#o].\n", nbools,
349 nbools, Vr2val, Vr2val);
350 #endif /* DUMPTI */
351
352 nints = _Getshi();
353 #ifdef DUMPTI
354 Vr2val = _Vr2getshi();
355 printf("Number of ints = %d, %#o [%d, %#o].\n", nints, nints,
356 Vr2val, Vr2val);
357 #endif /* DUMPTI */
358
359 nstrs = _Getshi();
360 #ifdef DUMPTI
361 Vr2val = _Vr2getshi();
362 printf("Number of strings = %d, %#o [%d, %#o].\n", nstrs, nstrs,
363 Vr2val, Vr2val);
364 #endif /* DUMPTI */
365
366 sstrtab = _Getshi();
367 #ifdef DUMPTI
368 Vr2val = _Vr2getshi();
369 printf("Size of string table = %d, %#o [%d, %#o].\n", sstrtab,
370 sstrtab, Vr2val, Vr2val);
371 printf("Names are: %.*s.\n", snames, ip);
372 #endif /* DUMPTI */
373
374 /* allocate all of the space */
375 strtab = NULL;
376 if (_called_before) {
377 /* 2nd or more times through */
378 if ((cur_term = (TERMINAL *)
379 calloc(sizeof (TERMINAL), 1)) == NULL)
380 goto badmalloc;
381 if ((cur_bools = (struct _bool_struct *)
382 calloc(sizeof (struct _bool_struct), 1)) == NULL)
383 goto freeterminal;
384 if ((cur_nums = (struct _num_struct *)
385 calloc(sizeof (struct _num_struct), 1)) == NULL)
386 goto freebools;
387 if ((cur_strs = (struct _str_struct *)
388 calloc(sizeof (struct _str_struct), 1)) == NULL) {
389 freenums:
390 free((char *)cur_nums);
391 freebools:
392 free((char *)cur_bools);
393 freeterminal:
394 free((char *)cur_term);
395 badmalloc:
396 term_errno = TERM_BAD_MALLOC;
397 #ifdef DEBUG
398 strcpy(term_parm_err, "setupterm");
399 #endif /* DEBUG */
400 out_err:
401 if (errret == 0) {
402 termerr();
403 exit(-term_errno);
404 } else
405 return (ERR);
406 }
407 } else {
408 /* First time through */
409 _called_before = TRUE;
410 cur_term = &_first_term;
411 cur_bools = &_frst_bools;
412 cur_nums = &_frst_nums;
413 cur_strs = &_frst_strs;
414 if (sstrtab < sizeof (_frst_tblstr))
415 strtab = _frst_tblstr;
416 }
417
418 if (strtab == NULL) {
419 if ((strtab = (char *)malloc((unsigned)sstrtab)) == NULL) {
420 if (cur_strs != &_frst_strs)
421 free((char *)cur_strs);
422 goto freenums;
423 }
424 }
425
426 /* no more catchable errors */
427 if (errret)
428 *errret = 1;
429
430 (void) strncpy(cur_term->_termname, term, 14);
431 /* In case the name is exactly 15 characters */
432 cur_term->_termname[14] = '\0';
433 cur_term->_bools = cur_bools;
434 cur_term->_nums = cur_nums;
435 cur_term->_strs = cur_strs;
436 cur_term->_strtab = strtab;
437 cur_term->sgr_mode = cur_term->sgr_faked = A_NORMAL;
438
439 if (filenum == 1 && !isatty(filenum))
440 filenum = 2; /* Allow output redirect */
441 /* LINTED */
442 cur_term->Filedes = (short)filenum;
443 _blast_keys(cur_term);
444 cur_term->_iwait = cur_term->fl_typeahdok = cur_term->_chars_on_queue =
445 cur_term->_fl_rawmode = cur_term->_ungotten = 0;
446 cur_term->_cursorstate = 1;
447 cur_term->_delay = cur_term->_inputfd = cur_term->_check_fd = -1;
448 (void) memset((char *)cur_term->_regs, 0, 26 * sizeof (short));
449
450 #ifndef DUMPTI
451 (void) def_shell_mode();
452 /* This is a useful default for PROGTTY, too */
453 #ifdef SYSV
454 if (shell_istermios < 0) {
455 int i;
456
457 SHELLTTY.c_lflag = SHELLTTYS.c_lflag;
458 SHELLTTY.c_oflag = SHELLTTYS.c_oflag;
459 SHELLTTY.c_iflag = SHELLTTYS.c_iflag;
460 SHELLTTY.c_cflag = SHELLTTYS.c_cflag;
461 for (i = 0; i < NCC; i++)
462 SHELLTTY.c_cc[i] = SHELLTTYS.c_cc[i];
463 PROGTTY = SHELLTTY;
464 prog_istermios = -1;
465
466 PROGTTYS.c_lflag = PROGTTY.c_lflag;
467 PROGTTYS.c_oflag = PROGTTY.c_oflag;
468 PROGTTYS.c_iflag = PROGTTY.c_iflag;
469 PROGTTYS.c_cflag = PROGTTY.c_cflag;
470 for (i = 0; i < NCC; i++)
471 PROGTTYS.c_cc[i] = PROGTTY.c_cc[i];
472 } else {
473 PROGTTYS = SHELLTTYS;
474 prog_istermios = 0;
475 }
476 #else /* SYSV */
477 PROGTTY = SHELLTTY;
478 #endif /* SYSV */
479 #endif /* DUMPTI */
480
481 /* Skip names of terminals */
482 (void) memcpy((char *)cp, (char *)ip, (snames * sizeof (*cp)));
483 ip += snames;
484
485 /*
486 * Pull out the booleans.
487 * The for loop below takes care of a new curses with an old tic
488 * file and visa-versa. nbools says how many bools the tic file has.
489 * So, we only loop for as long as there are bools to read.
490 * However, if this is an old curses that doesn't have all the
491 * bools that this new tic has dumped, then the extra if
492 * "if (cp < fp)" says that if we are going to read into our structure
493 * passed its size don't do it but we still need to keep bumping
494 * up the pointer of what we read in from the terminfo file.
495 */
496 {
497 char *fp = &cur_bools->Sentinel;
498 char s;
499 #ifdef DUMPTI
500 int tempindex = 0;
501 #endif /* DUMPTI */
502 cp = &cur_bools->_auto_left_margin;
503 while (nbools--) {
504 s = *ip++;
505 #ifdef DUMPTI
506 printf("Bool %s [%s] (%s) = %d.\n",
507 boolfnames[tempindex], boolnames[tempindex],
508 boolcodes[tempindex], s);
509 tempindex++;
510 #endif /* DUMPTI */
511 if (cp < fp)
512 *cp++ = s & 01;
513 }
514 if (cp < fp)
515 (void) memset(cp, 0, ((fp - cp) * sizeof (bool)));
516 }
517
518 /* Force proper alignment */
519 if (((unsigned long) ip) & 1)
520 ip++;
521
522 /*
523 * Pull out the numbers.
524 */
525 {
526 short *sp = &cur_nums->_columns;
527 short *fp = &cur_nums->Sentinel;
528 int s;
529 #ifdef DUMPTI
530 int tempindex = 0;
531 #endif /* DUMPTI */
532
533 while (nints--) {
534 s = _Getshi();
535 #ifdef DUMPTI
536 Vr2val = _Vr2getshi();
537 printf("Num %s [%s] (%s) = %d [%d].\n",
538 numfnames[tempindex], numnames[tempindex],
539 numcodes[tempindex], s, Vr2val);
540 tempindex++;
541 #endif /* DUMPTI */
542 if (sp < fp)
543 if (s < 0)
544 *sp++ = -1;
545 else
546 /* LINTED */
547 *sp++ = (short)s;
548 }
549 if (sp < fp)
550 (void) memset((char *)sp, '\377',
551 ((fp - sp) * sizeof (short)));
552 }
553
554 if (_use_env) {
555 /*
556 * This ioctl defines the window size and overrides what
557 * it says in terminfo.
558 */
559 {
560 struct winsize w;
561
562 if (ioctl(filenum, TIOCGWINSZ, &w) != -1) {
563 if (w.ws_row != 0)
564 cur_nums->_lines = w.ws_row;
565 if (w.ws_col != 0)
566 cur_nums->_columns = w.ws_col;
567 #ifdef DUMPTI
568 printf("ioctl TIOCGWINSZ override: "
569 "(lines, columns) = (%d, %d)\n",
570 w.ws_row, w.ws_col);
571 #endif /* DUMPTI */
572 }
573 }
574
575 /*
576 * Check $LINES and $COLUMNS.
577 */
578 {
579 int ilines, icolumns;
580
581 lcp = getenv("LINES");
582 ccp = getenv("COLUMNS");
583 if (lcp)
584 if ((ilines = atoi(lcp)) > 0) {
585 /* LINTED */
586 cur_nums->_lines = (short)ilines;
587 #ifdef DUMPTI
588 printf("$LINES override: lines = %d\n",
589 ilines);
590 #endif /* DUMPTI */
591 }
592 if (ccp)
593 if ((icolumns = atoi(ccp)) > 0) {
594 /* LINTED */
595 cur_nums->_columns = (short)icolumns;
596 #ifdef DUMPTI
597 printf("$COLUMNS override: columns = "
598 "%d\n", icolumns);
599 #endif /* DUMPTI */
600 }
601 }
602 }
603
604 /* Pull out the strings. */
605 {
606 char **pp = &cur_strs->strs._back_tab;
607 char **fp = &cur_strs->strs4.Sentinel;
608 #ifdef DUMPTI
609 int tempindex = 0;
610 char *startstr = ip + sizeof (short) *
611 nstrs;
612
613 printf("string table = '");
614 _Mprint(sstrtab, startstr);
615 printf("'\n");
616 #endif /* DUMPTI */
617
618 while (nstrs--) {
619 n = _Getshi();
620 #ifdef DUMPTI
621 Vr2val = _Vr2getshi();
622 printf("String %s [%s] (%s) offset = %d [%d]",
623 strfnames[tempindex], strnames[tempindex],
624 strcodes[tempindex], n, Vr2val);
625 tempindex++;
626 #endif /* DUMPTI */
627 if (pp < fp) {
628 #ifdef DUMPTI
629 _Sprint(n, startstr+n);
630 #endif /* DUMPTI */
631 if (n < 0)
632 *pp++ = NULL;
633 else
634 *pp++ = strtab + n;
635 }
636 #ifdef DUMPTI
637 else
638 _Sprint(-1, (char *)0);
639 #endif /* DUMPTI */
640 }
641 if (pp < fp)
642 (void) memset((char *)pp, 0, ((fp - pp) * sizeof (charptr)));
643 }
644
645 (void) memcpy(strtab, ip, sstrtab);
646
647 #ifndef DUMPTI
648
649 /*
650 * If tabs are being expanded in software, turn this off
651 * so output won't get messed up. Also, don't use tab
652 * or backtab, even if the terminal has them, since the
653 * user might not have hardware tabs set right.
654 */
655 #ifdef SYSV
656 if ((PROGTTYS.c_oflag & TABDLY) == TAB3) {
657 PROGTTYS.c_oflag &= ~TABDLY;
658 (void) reset_prog_mode();
659 goto next;
660 }
661 #else /* SYSV */
662 if ((PROGTTY.sg_flags & XTABS) == XTABS) {
663 PROGTTY.sg_flags &= ~XTABS;
664 (void) reset_prog_mode();
665 goto next;
666 }
667 #endif /* SYSV */
668 if (dest_tabs_magic_smso) {
669 next:
670 cur_strs->strs2._tab = cur_strs->strs._back_tab = NULL;
671 }
672
673 #ifdef LTILDE
674 ioctl(cur_term -> Filedes, TIOCLGET, &n);
675 #endif /* LTILDE */
676 #endif /* DUMPTI */
677
678 #ifdef _VR2_COMPAT_CODE
679 (void) memcpy(&cur_term->_b1, &cur_bools->_auto_left_margin,
680 (char *)&cur_term->_c1 - (char *)&cur_term->_b1);
681 (void) memcpy((char *)&cur_term->_c1, (char *)&cur_nums->_columns,
682 (char *)&cur_term->_Vr2_Astrs._s1 - (char *)&cur_term->_c1);
683 (void) memcpy((char *)&cur_term->_Vr2_Astrs._s1,
684 (char *)&cur_strs->strs._back_tab,
685 (char *)&cur_term->Filedes - (char *)&cur_term->_Vr2_Astrs._s1);
686 #endif /* _VR2_COMPAT_CODE */
687
688 on_sequences = cur_term->turn_on_seq;
689 str_array = (char **)cur_strs;
690 {
691 static char offsets[] = {
692 35, /* enter_standout_mode, */
693 36, /* enter_underline_mode, */
694 25, /* enter_alt_charset_mode, */
695 34, /* enter_reverse_mode, */
696 26, /* enter_blink_mode, */
697 30, /* enter_dim_mode, */
698 27, /* enter_bold_mode, */
699 32, /* enter_secure_mode, */
700 33, /* enter_protected_mode, */
701 };
702
703 for (n = 0; n < NUM_ATTRIBUTES; n++) {
704 if ((on_sequences[n] = str_array[offsets[n]]) != 0)
705 cur_term->bit_vector |= bit_attributes[n];
706 }
707 }
708
709 if (!(set_attributes)) {
710 static char faked_attrs[] = { 1, 3, 4, 6 },
711 offsets[] = {
712 43, /* exit_standout_mode, */
713 44, /* exit_underline_mode, */
714 38, /* exit_alt_charset_mode, */
715 };
716 char **off_sequences = cur_term->turn_off_seq;
717 int i;
718
719 if ((max_attributes == -1) && (ceol_standout_glitch ||
720 (magic_cookie_glitch >= 0)))
721 max_attributes = 1;
722
723 /* Figure out what attributes need to be faked. */
724 /* See vidupdate.c */
725
726 for (n = 0; n < sizeof (faked_attrs); n++) {
727 if (on_sequences[0] != NULL) {
728 if ((!on_sequences[i = faked_attrs[n]]) ||
729 (strcmp(on_sequences[i],
730 on_sequences[0]) == 0)) {
731 cur_term->sgr_faked |=
732 bit_attributes[i];
733 }
734 } else {
735 if (!on_sequences[i = faked_attrs[n]]) {
736 cur_term->sgr_faked |=
737 bit_attributes[i];
738 }
739 }
740 }
741
742 cur_term->check_turn_off = A_STANDOUT | A_UNDERLINE |
743 A_ALTCHARSET;
744
745 for (n = 0; n < sizeof (offsets); n++) {
746 if ((!(off_sequences[n] = str_array[offsets[n]])) ||
747 ((n > 0) && off_sequences[0] &&
748 (strcmp(off_sequences[n], off_sequences[0]) ==
749 0)) || ((n == 2) && (exit_attribute_mode) &&
750 (strcmp(exit_attribute_mode, off_sequences[n]) ==
751 0))) {
752 cur_term->check_turn_off &= ~bit_attributes[n];
753 }
754 }
755 }
756 cur_term->cursor_seq[0] = cursor_invisible;
757 cur_term->cursor_seq[1] = cursor_normal;
758 cur_term->cursor_seq[2] = cursor_visible;
759 cur_term->_pairs_tbl = (_Color_pair *) NULL;
760 cur_term->_color_tbl = (_Color *) NULL;
761
762 return (OK);
763 }
764
765 void
766 _blast_keys(TERMINAL *terminal)
767 {
768 terminal->_keys = NULL;
769 terminal->internal_keys = NULL;
770 terminal->_ksz = terminal->_first_macro = 0;
771 terminal->_lastkey_ordered = terminal->_lastmacro_ordered = -1;
772 (void) memset((char *)terminal->funckeystarter, 0, 0400 *
773 sizeof (bool));
774 }
775
776 #ifndef DUMPTI
777
778 int
779 reset_prog_mode(void)
780 {
781 #ifdef SYSV
782 if (_BRS(PROGTTYS)) {
783 if (prog_istermios < 0) {
784 int i;
785
786 PROGTTY.c_lflag = PROGTTYS.c_lflag;
787 PROGTTY.c_oflag = PROGTTYS.c_oflag;
788 PROGTTY.c_iflag = PROGTTYS.c_iflag;
789 PROGTTY.c_cflag = PROGTTYS.c_cflag;
790 for (i = 0; i < NCC; i++)
791 PROGTTY.c_cc[i] = PROGTTYS.c_cc[i];
792 (void) ioctl(cur_term -> Filedes, TCSETAW, &PROGTTY);
793 } else
794 (void) ioctl(cur_term -> Filedes, TCSETSW, &PROGTTYS);
795 }
796 #else /* SYSV */
797 if (_BR(PROGTTY))
798 (void) ioctl(cur_term -> Filedes, TIOCSETN, &PROGTTY);
799 #endif /* SYSV */
800
801 #ifdef LTILDE
802 ioctl(cur_term -> Filedes, TIOCLGET, &cur_term -> oldlmode);
803 cur_term -> newlmode = cur_term -> oldlmode & ~LTILDE;
804 if (cur_term -> newlmode != cur_term -> oldlmode)
805 ioctl(cur_term -> Filedes, TIOCLSET, &cur_term -> newlmode);
806 #endif /* LTILDE */
807 #ifdef DIOCSETT
808 if (cur_term -> old.st_termt == 0)
809 ioctl(cur_term->Filedes, DIOCGETT, &cur_term -> old);
810 cur_term -> new = cur_term -> old;
811 cur_term -> new.st_termt = 0;
812 cur_term -> new.st_flgs |= TM_SET;
813 ioctl(cur_term->Filedes, DIOCSETT, &cur_term -> new);
814 #endif /* DIOCSETT */
815 return (OK);
816 }
817
818 int
819 def_shell_mode(void)
820 {
821 #ifdef SYSV
822 if ((shell_istermios =
823 ioctl(cur_term -> Filedes, TCGETS, &SHELLTTYS)) < 0) {
824 int i;
825
826 (void) ioctl(cur_term -> Filedes, TCGETA, &SHELLTTY);
827 SHELLTTYS.c_lflag = SHELLTTY.c_lflag;
828 SHELLTTYS.c_oflag = SHELLTTY.c_oflag;
829 SHELLTTYS.c_iflag = SHELLTTY.c_iflag;
830 SHELLTTYS.c_cflag = SHELLTTY.c_cflag;
831 for (i = 0; i < NCC; i++)
832 SHELLTTYS.c_cc[i] = SHELLTTY.c_cc[i];
833 }
834 #else /* SYSV */
835 (void) ioctl(cur_term -> Filedes, TIOCGETP, &SHELLTTY);
836 #endif /* SYSV */
837 return (OK);
838 }
839
840 #endif /* DUMPTI */