Annotation of src/usr.bin/tset/set.c, Revision 1.1
1.1 ! deraadt 1: /* $NetBSD: set.c,v 1.6 1994/12/07 05:08:10 jtc Exp $ */
! 2:
! 3: /*-
! 4: * Copyright (c) 1991, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by the University of
! 18: * California, Berkeley and its contributors.
! 19: * 4. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35:
! 36: #ifndef lint
! 37: #if 0
! 38: static char sccsid[] = "@(#)set.c 8.2 (Berkeley) 2/28/94";
! 39: #endif
! 40: static char rcsid[] = "$NetBSD: set.c,v 1.6 1994/12/07 05:08:10 jtc Exp $";
! 41: #endif /* not lint */
! 42:
! 43: #include <termios.h>
! 44: #include <unistd.h>
! 45: #include <stdio.h>
! 46: #include "extern.h"
! 47:
! 48: #define CHK(val, dft) (val <= 0 ? dft : val)
! 49:
! 50: int set_tabs __P((void));
! 51:
! 52: /*
! 53: * Reset the terminal mode bits to a sensible state. Very useful after
! 54: * a child program dies in raw mode.
! 55: */
! 56: void
! 57: reset_mode()
! 58: {
! 59: tcgetattr(STDERR_FILENO, &mode);
! 60:
! 61: #if defined(VDISCARD) && defined(CDISCARD)
! 62: mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD);
! 63: #endif
! 64: mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF);
! 65: mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE);
! 66: #if defined(VFLUSH) && defined(CFLUSH)
! 67: mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH);
! 68: #endif
! 69: mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR);
! 70: mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL);
! 71: #if defined(VLNEXT) && defined(CLNEXT)
! 72: mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT);
! 73: #endif
! 74: mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT);
! 75: #if defined(VREPRINT) && defined(CRPRNT)
! 76: mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT);
! 77: #endif
! 78: mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART);
! 79: mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP);
! 80: mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP);
! 81: #if defined(VWERASE) && defined(CWERASE)
! 82: mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE);
! 83: #endif
! 84:
! 85: mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR
! 86: #ifdef IUCLC
! 87: | IUCLC
! 88: #endif
! 89: #ifdef IXANY
! 90: | IXANY
! 91: #endif
! 92: | IXOFF);
! 93:
! 94: mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON
! 95: #ifdef IMAXBEL
! 96: | IMAXBEL
! 97: #endif
! 98: );
! 99:
! 100: mode.c_oflag &= ~(0
! 101: #ifdef OLCUC
! 102: | OLCUC
! 103: #endif
! 104: #ifdef OCRNL
! 105: | OCRNL
! 106: #endif
! 107: #ifdef ONOCR
! 108: | ONOCR
! 109: #endif
! 110: #ifdef ONLRET
! 111: | ONLRET
! 112: #endif
! 113: #ifdef OFILL
! 114: | OFILL
! 115: #endif
! 116: #ifdef OFDEL
! 117: | OFDEL
! 118: #endif
! 119: #ifdef NLDLY
! 120: | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY
! 121: #endif
! 122: );
! 123:
! 124: mode.c_oflag |= (OPOST
! 125: #ifdef ONLCR
! 126: | ONLCR
! 127: #endif
! 128: );
! 129:
! 130: mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
! 131: mode.c_cflag |= (CS8 | CREAD);
! 132: mode.c_lflag &= ~(ECHONL | NOFLSH | TOSTOP
! 133: #ifdef ECHOPTR
! 134: | ECHOPRT
! 135: #endif
! 136: #ifdef XCASE
! 137: | XCASE
! 138: #endif
! 139: );
! 140:
! 141: mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK
! 142: #ifdef ECHOCTL
! 143: | ECHOCTL
! 144: #endif
! 145: #ifdef ECHOKE
! 146: | ECHOKE
! 147: #endif
! 148: );
! 149:
! 150: tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
! 151: }
! 152:
! 153: /*
! 154: * Determine the erase, interrupt, and kill characters from the termcap
! 155: * entry and command line and update their values in 'mode'.
! 156: */
! 157: void
! 158: set_control_chars()
! 159: {
! 160: char *bp, *p, bs_char, buf[1024];
! 161:
! 162: bp = buf;
! 163: p = tgetstr("kb", &bp);
! 164: if (p == NULL || p[1] != '\0')
! 165: p = tgetstr("bc", &bp);
! 166: if (p != NULL && p[1] == '\0')
! 167: bs_char = p[0];
! 168: else if (tgetflag("bs"))
! 169: bs_char = CTRL('h');
! 170: else
! 171: bs_char = 0;
! 172:
! 173: if (erasechar == 0 && !tgetflag("os") && mode.c_cc[VERASE] != CERASE) {
! 174: if (tgetflag("bs") || bs_char != 0)
! 175: erasechar = -1;
! 176: }
! 177: if (erasechar < 0)
! 178: erasechar = (bs_char != 0) ? bs_char : CTRL('h');
! 179:
! 180: if (mode.c_cc[VERASE] == 0 || erasechar != 0)
! 181: mode.c_cc[VERASE] = erasechar ? erasechar : CERASE;
! 182:
! 183: if (mode.c_cc[VINTR] == 0 || intrchar != 0)
! 184: mode.c_cc[VINTR] = intrchar ? intrchar : CINTR;
! 185:
! 186: if (mode.c_cc[VKILL] == 0 || killchar != 0)
! 187: mode.c_cc[VKILL] = killchar ? killchar : CKILL;
! 188: }
! 189:
! 190: /*
! 191: * Set up various conversions in 'mode', including parity, tabs, returns,
! 192: * echo, and case, according to the termcap entry. If the program we're
! 193: * running was named with a leading upper-case character, map external
! 194: * uppercase to internal lowercase.
! 195: */
! 196: void
! 197: set_conversions(usingupper)
! 198: int usingupper;
! 199: {
! 200: if (tgetflag("UC") || usingupper) {
! 201: #ifdef IUCLC
! 202: mode.c_iflag |= IUCLC;
! 203: mode.c_oflag |= OLCUC;
! 204: #endif
! 205: } else if (tgetflag("LC")) {
! 206: #ifdef IUCLC
! 207: mode.c_iflag &= ~IUCLC;
! 208: mode.c_oflag &= ~OLCUC;
! 209: #endif
! 210: }
! 211: mode.c_iflag &= ~(PARMRK | INPCK);
! 212: mode.c_lflag |= ICANON;
! 213: if (tgetflag("EP")) {
! 214: mode.c_cflag |= PARENB;
! 215: mode.c_cflag &= ~PARODD;
! 216: }
! 217: if (tgetflag("OP")) {
! 218: mode.c_cflag |= PARENB;
! 219: mode.c_cflag |= PARODD;
! 220: }
! 221:
! 222: #ifdef ONLCR
! 223: mode.c_oflag |= ONLCR;
! 224: #endif
! 225: mode.c_iflag |= ICRNL;
! 226: mode.c_lflag |= ECHO;
! 227: mode.c_oflag |= OXTABS;
! 228: if (tgetflag("NL")) { /* Newline, not linefeed. */
! 229: #ifdef ONLCR
! 230: mode.c_oflag &= ~ONLCR;
! 231: #endif
! 232: mode.c_iflag &= ~ICRNL;
! 233: }
! 234: if (tgetflag("HD")) /* Half duplex. */
! 235: mode.c_lflag &= ~ECHO;
! 236: if (tgetflag("pt")) /* Print tabs. */
! 237: mode.c_oflag &= ~OXTABS;
! 238: mode.c_lflag |= (ECHOE | ECHOK);
! 239: }
! 240:
! 241: /* Output startup string. */
! 242: void
! 243: set_init()
! 244: {
! 245: char *bp, buf[1024];
! 246: int settle;
! 247:
! 248: bp = buf;
! 249: if (tgetstr("pc", &bp) != 0) /* Get/set pad character. */
! 250: PC = buf[0];
! 251:
! 252: #ifdef TAB3
! 253: if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
! 254: oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
! 255: tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode);
! 256: }
! 257: #endif
! 258: settle = set_tabs();
! 259:
! 260: if (isreset) {
! 261: bp = buf;
! 262: if (tgetstr("rs", &bp) != 0 || tgetstr("is", &bp) != 0) {
! 263: tputs(buf, 0, outc);
! 264: settle = 1;
! 265: }
! 266: bp = buf;
! 267: if (tgetstr("rf", &bp) != 0 || tgetstr("if", &bp) != 0) {
! 268: cat(buf);
! 269: settle = 1;
! 270: }
! 271: }
! 272:
! 273: if (settle) {
! 274: (void)putc('\r', stderr);
! 275: (void)fflush(stderr);
! 276: (void)sleep(1); /* Settle the terminal. */
! 277: }
! 278: }
! 279:
! 280: /*
! 281: * Set the hardware tabs on the terminal, using the ct (clear all tabs),
! 282: * st (set one tab) and ch (horizontal cursor addressing) capabilities.
! 283: * This is done before if and is, so they can patch in case we blow this.
! 284: * Return nonzero if we set any tab stops, zero if not.
! 285: */
! 286: int
! 287: set_tabs()
! 288: {
! 289: int c;
! 290: char *capsp, *clear_tabs;
! 291: char *set_column, *set_pos, *set_tab, *tg_out;
! 292: char caps[1024];
! 293:
! 294: capsp = caps;
! 295: set_tab = tgetstr("st", &capsp);
! 296:
! 297: if (set_tab && (clear_tabs = tgetstr("ct", &capsp))) {
! 298: (void)putc('\r', stderr); /* Force to left margin. */
! 299: tputs(clear_tabs, 0, outc);
! 300: }
! 301:
! 302: set_column = tgetstr("ch", &capsp);
! 303: set_pos = set_column ? NULL : tgetstr("cm", &capsp);
! 304:
! 305: if (set_tab) {
! 306: for (c = 8; c < columns; c += 8) {
! 307: /*
! 308: * Get to the right column. "OOPS" is returned by
! 309: * tgoto() if it can't do the job. (*snarl*)
! 310: */
! 311: tg_out = "OOPS";
! 312: if (set_column)
! 313: tg_out = tgoto(set_column, 0, c);
! 314: if (*tg_out == 'O' && set_pos)
! 315: tg_out = tgoto(set_pos, c, lines - 1);
! 316: if (*tg_out != 'O')
! 317: tputs(tg_out, 1, outc);
! 318: else
! 319: (void)fprintf(stderr, "%s", " ");
! 320: /* Set the tab. */
! 321: tputs(set_tab, 0, outc);
! 322: }
! 323: putc('\r', stderr);
! 324: return (1);
! 325: }
! 326: return (0);
! 327: }