1*9b4eccc9Smlelstv /* $NetBSD: set.c,v 1.18 2015/06/21 08:23:22 mlelstv Exp $ */
2fb937a59Sjtc
3dab5e017Scgd /*-
4fb937a59Sjtc * Copyright (c) 1991, 1993
5fb937a59Sjtc * The Regents of the University of California. All rights reserved.
6dab5e017Scgd *
7dab5e017Scgd * Redistribution and use in source and binary forms, with or without
8dab5e017Scgd * modification, are permitted provided that the following conditions
9dab5e017Scgd * are met:
10dab5e017Scgd * 1. Redistributions of source code must retain the above copyright
11dab5e017Scgd * notice, this list of conditions and the following disclaimer.
12dab5e017Scgd * 2. Redistributions in binary form must reproduce the above copyright
13dab5e017Scgd * notice, this list of conditions and the following disclaimer in the
14dab5e017Scgd * documentation and/or other materials provided with the distribution.
1589aaa1bbSagc * 3. Neither the name of the University nor the names of its contributors
16dab5e017Scgd * may be used to endorse or promote products derived from this software
17dab5e017Scgd * without specific prior written permission.
18dab5e017Scgd *
19dab5e017Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20dab5e017Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21dab5e017Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22dab5e017Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23dab5e017Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24dab5e017Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25dab5e017Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26dab5e017Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27dab5e017Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28dab5e017Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29dab5e017Scgd * SUCH DAMAGE.
30dab5e017Scgd */
31dab5e017Scgd
322aa5d6b7Slukem #include <sys/cdefs.h>
33*9b4eccc9Smlelstv __RCSID("$NetBSD: set.c,v 1.18 2015/06/21 08:23:22 mlelstv Exp $");
34dab5e017Scgd
35eae295f6Sroy #include <err.h>
362aa5d6b7Slukem #include <stdio.h>
3798eb8895Sroy #include <term.h>
38dab5e017Scgd #include <termios.h>
39dab5e017Scgd #include <unistd.h>
40dab5e017Scgd #include "extern.h"
41dab5e017Scgd
42dab5e017Scgd #define CHK(val, dft) (val <= 0 ? dft : val)
43dab5e017Scgd
44be0c033dSjoerg static int set_tabs(void);
45dab5e017Scgd
46dab5e017Scgd /*
47dab5e017Scgd * Reset the terminal mode bits to a sensible state. Very useful after
48dab5e017Scgd * a child program dies in raw mode.
49dab5e017Scgd */
50dab5e017Scgd void
reset_mode(void)51be0c033dSjoerg reset_mode(void)
52dab5e017Scgd {
53dab5e017Scgd tcgetattr(STDERR_FILENO, &mode);
54dab5e017Scgd
55dab5e017Scgd #if defined(VDISCARD) && defined(CDISCARD)
56dab5e017Scgd mode.c_cc[VDISCARD] = CHK(mode.c_cc[VDISCARD], CDISCARD);
57dab5e017Scgd #endif
58dab5e017Scgd mode.c_cc[VEOF] = CHK(mode.c_cc[VEOF], CEOF);
59dab5e017Scgd mode.c_cc[VERASE] = CHK(mode.c_cc[VERASE], CERASE);
60dab5e017Scgd #if defined(VFLUSH) && defined(CFLUSH)
61dab5e017Scgd mode.c_cc[VFLUSH] = CHK(mode.c_cc[VFLUSH], CFLUSH);
62dab5e017Scgd #endif
63dab5e017Scgd mode.c_cc[VINTR] = CHK(mode.c_cc[VINTR], CINTR);
64dab5e017Scgd mode.c_cc[VKILL] = CHK(mode.c_cc[VKILL], CKILL);
65dab5e017Scgd #if defined(VLNEXT) && defined(CLNEXT)
66dab5e017Scgd mode.c_cc[VLNEXT] = CHK(mode.c_cc[VLNEXT], CLNEXT);
67dab5e017Scgd #endif
68dab5e017Scgd mode.c_cc[VQUIT] = CHK(mode.c_cc[VQUIT], CQUIT);
69dab5e017Scgd #if defined(VREPRINT) && defined(CRPRNT)
70dab5e017Scgd mode.c_cc[VREPRINT] = CHK(mode.c_cc[VREPRINT], CRPRNT);
71dab5e017Scgd #endif
72dab5e017Scgd mode.c_cc[VSTART] = CHK(mode.c_cc[VSTART], CSTART);
73dab5e017Scgd mode.c_cc[VSTOP] = CHK(mode.c_cc[VSTOP], CSTOP);
74dab5e017Scgd mode.c_cc[VSUSP] = CHK(mode.c_cc[VSUSP], CSUSP);
75dab5e017Scgd #if defined(VWERASE) && defined(CWERASE)
76dab5e017Scgd mode.c_cc[VWERASE] = CHK(mode.c_cc[VWERASE], CWERASE);
77dab5e017Scgd #endif
78dab5e017Scgd
79dab5e017Scgd mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | ISTRIP | INLCR | IGNCR
80dab5e017Scgd #ifdef IUCLC
81dab5e017Scgd | IUCLC
82dab5e017Scgd #endif
83dab5e017Scgd #ifdef IXANY
84dab5e017Scgd | IXANY
85dab5e017Scgd #endif
86dab5e017Scgd | IXOFF);
87dab5e017Scgd
88dab5e017Scgd mode.c_iflag |= (BRKINT | IGNPAR | ICRNL | IXON
89dab5e017Scgd #ifdef IMAXBEL
90dab5e017Scgd | IMAXBEL
91dab5e017Scgd #endif
92dab5e017Scgd );
93dab5e017Scgd
94dab5e017Scgd mode.c_oflag &= ~(0
95dab5e017Scgd #ifdef OLCUC
96dab5e017Scgd | OLCUC
97dab5e017Scgd #endif
98dab5e017Scgd #ifdef OCRNL
99dab5e017Scgd | OCRNL
100dab5e017Scgd #endif
101dab5e017Scgd #ifdef ONOCR
102dab5e017Scgd | ONOCR
103dab5e017Scgd #endif
104dab5e017Scgd #ifdef ONLRET
105dab5e017Scgd | ONLRET
106dab5e017Scgd #endif
107dab5e017Scgd #ifdef OFILL
108dab5e017Scgd | OFILL
109dab5e017Scgd #endif
110dab5e017Scgd #ifdef OFDEL
111dab5e017Scgd | OFDEL
112dab5e017Scgd #endif
113dab5e017Scgd #ifdef NLDLY
114dab5e017Scgd | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY
115dab5e017Scgd #endif
116dab5e017Scgd );
117dab5e017Scgd
118dab5e017Scgd mode.c_oflag |= (OPOST
119dab5e017Scgd #ifdef ONLCR
120dab5e017Scgd | ONLCR
121dab5e017Scgd #endif
122dab5e017Scgd );
123dab5e017Scgd
124ff01ffc7Scgd mode.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
125dab5e017Scgd mode.c_cflag |= (CS8 | CREAD);
126dab5e017Scgd mode.c_lflag &= ~(ECHONL | NOFLSH | TOSTOP
127dab5e017Scgd #ifdef ECHOPTR
128dab5e017Scgd | ECHOPRT
129dab5e017Scgd #endif
130dab5e017Scgd #ifdef XCASE
131dab5e017Scgd | XCASE
132dab5e017Scgd #endif
133dab5e017Scgd );
134dab5e017Scgd
135dab5e017Scgd mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOE | ECHOK
136dab5e017Scgd #ifdef ECHOCTL
137dab5e017Scgd | ECHOCTL
138dab5e017Scgd #endif
139dab5e017Scgd #ifdef ECHOKE
140dab5e017Scgd | ECHOKE
141dab5e017Scgd #endif
142dab5e017Scgd );
143dab5e017Scgd
144dab5e017Scgd tcsetattr(STDERR_FILENO, TCSADRAIN, &mode);
145dab5e017Scgd }
146dab5e017Scgd
147dab5e017Scgd /*
148258cf0abSroy * Determine the erase, interrupt, and kill characters from the terminfo
149dab5e017Scgd * entry and command line and update their values in 'mode'.
150dab5e017Scgd */
151dab5e017Scgd void
set_control_chars(int erasechar,int intrchar,int killchar)152dc8f6bbdSchs set_control_chars(int erasechar, int intrchar, int killchar)
153dab5e017Scgd {
154*9b4eccc9Smlelstv int bs_char;
155dab5e017Scgd
156*9b4eccc9Smlelstv if (key_backspace != NULL && key_backspace[1] == '\0')
157*9b4eccc9Smlelstv bs_char = key_backspace[0];
158dab5e017Scgd else
159*9b4eccc9Smlelstv bs_char = 0;
160*9b4eccc9Smlelstv
161*9b4eccc9Smlelstv if (erasechar == 0 && bs_char != 0 && !over_strike)
162*9b4eccc9Smlelstv erasechar = -1;
163*9b4eccc9Smlelstv if (erasechar < 0)
164*9b4eccc9Smlelstv erasechar = (bs_char != 0) ? bs_char : CTRL('h');
165*9b4eccc9Smlelstv
166*9b4eccc9Smlelstv if (mode.c_cc[VERASE] == 0 || erasechar != 0)
167*9b4eccc9Smlelstv mode.c_cc[VERASE] = erasechar ? erasechar : CERASE;
168dab5e017Scgd
169dab5e017Scgd if (mode.c_cc[VINTR] == 0 || intrchar != 0)
170dab5e017Scgd mode.c_cc[VINTR] = intrchar ? intrchar : CINTR;
171dab5e017Scgd
172dab5e017Scgd if (mode.c_cc[VKILL] == 0 || killchar != 0)
173dab5e017Scgd mode.c_cc[VKILL] = killchar ? killchar : CKILL;
174dab5e017Scgd }
175dab5e017Scgd
176dab5e017Scgd /*
177dab5e017Scgd * Set up various conversions in 'mode', including parity, tabs, returns,
178258cf0abSroy * echo, and case, according to the terminfo entry. If the program we're
179dab5e017Scgd * running was named with a leading upper-case character, map external
180dab5e017Scgd * uppercase to internal lowercase.
181dab5e017Scgd */
182dab5e017Scgd void
set_conversions(int usingupper)183dc8f6bbdSchs set_conversions(int usingupper)
184dab5e017Scgd {
185dab5e017Scgd
186dab5e017Scgd #ifdef ONLCR
187dab5e017Scgd mode.c_oflag |= ONLCR;
188dab5e017Scgd #endif
189dab5e017Scgd mode.c_iflag |= ICRNL;
190dab5e017Scgd mode.c_lflag |= ECHO;
191dab5e017Scgd mode.c_oflag |= OXTABS;
19298eb8895Sroy if (newline != NULL && newline[0] == '\n' && !newline[1]) { /* Newline, not linefeed. */
193dab5e017Scgd #ifdef ONLCR
194dab5e017Scgd mode.c_oflag &= ~ONLCR;
195dab5e017Scgd #endif
196dab5e017Scgd mode.c_iflag &= ~ICRNL;
197dab5e017Scgd }
19898eb8895Sroy if (tab) /* Print tabs. */
199dab5e017Scgd mode.c_oflag &= ~OXTABS;
200dab5e017Scgd mode.c_lflag |= (ECHOE | ECHOK);
201dab5e017Scgd }
202dab5e017Scgd
203dab5e017Scgd /* Output startup string. */
204dab5e017Scgd void
set_init(void)205be0c033dSjoerg set_init(void)
206dab5e017Scgd {
20798eb8895Sroy const char *bp;
208dab5e017Scgd int settle;
209dab5e017Scgd
210dab5e017Scgd #ifdef TAB3
211dab5e017Scgd if (oldmode.c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
212dab5e017Scgd oldmode.c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
213dab5e017Scgd tcsetattr(STDERR_FILENO, TCSADRAIN, &oldmode);
214dab5e017Scgd }
215dab5e017Scgd #endif
216dab5e017Scgd settle = set_tabs();
217dab5e017Scgd
218dab5e017Scgd if (isreset) {
21998eb8895Sroy if (reset_1string) {
22098eb8895Sroy tputs(reset_1string, 0, outc);
221dab5e017Scgd settle = 1;
222dab5e017Scgd }
22398eb8895Sroy if (reset_2string) {
22498eb8895Sroy tputs(reset_2string, 0, outc);
22598eb8895Sroy settle = 1;
22698eb8895Sroy }
22798eb8895Sroy if ((bp = reset_file) || (bp = init_file)) {
228eae295f6Sroy tset_cat(bp);
229dab5e017Scgd settle = 1;
230dab5e017Scgd }
231dab5e017Scgd }
232dab5e017Scgd
233dab5e017Scgd if (settle) {
234dab5e017Scgd (void)putc('\r', stderr);
235dab5e017Scgd (void)fflush(stderr);
236dab5e017Scgd (void)sleep(1); /* Settle the terminal. */
237dab5e017Scgd }
238dab5e017Scgd }
239dab5e017Scgd
240dab5e017Scgd /*
241dab5e017Scgd * Set the hardware tabs on the terminal, using the ct (clear all tabs),
242dab5e017Scgd * st (set one tab) and ch (horizontal cursor addressing) capabilities.
243dab5e017Scgd * This is done before if and is, so they can patch in case we blow this.
244dab5e017Scgd * Return nonzero if we set any tab stops, zero if not.
245dab5e017Scgd */
246be0c033dSjoerg static int
set_tabs(void)247be0c033dSjoerg set_tabs(void)
248dab5e017Scgd {
249dab5e017Scgd int c;
25098eb8895Sroy char *out;
251dab5e017Scgd
252dab5e017Scgd if (set_tab) {
25398eb8895Sroy if (clear_all_tabs) {
25498eb8895Sroy (void)putc('\r', stderr); /* Force to left margin. */
25598eb8895Sroy tputs(clear_all_tabs, 0, outc);
25698eb8895Sroy }
25798eb8895Sroy
25898eb8895Sroy for (c = 8; c < ncolumns; c += 8) {
25998eb8895Sroy if (column_address)
2604060cbcdSroy out = tiparm(column_address, c);
26198eb8895Sroy else
26298eb8895Sroy out = NULL;
26398eb8895Sroy if (out)
26498eb8895Sroy tputs(out, 1, outc);
265dab5e017Scgd else
266dab5e017Scgd (void)fprintf(stderr, "%s", " ");
267dab5e017Scgd /* Set the tab. */
268dab5e017Scgd tputs(set_tab, 0, outc);
269dab5e017Scgd }
270dab5e017Scgd putc('\r', stderr);
271dab5e017Scgd return (1);
272dab5e017Scgd }
273dab5e017Scgd return (0);
274dab5e017Scgd }
275