xref: /dflybsd-src/contrib/ncurses/progs/reset_cmd.c (revision 0cadad7e49c6219b0de0675ef6a6f44683d177d4)
1*32bb5217SDaniel Fojt /****************************************************************************
2*32bb5217SDaniel Fojt  * Copyright 2019,2020 Thomas E. Dickey                                     *
3*32bb5217SDaniel Fojt  * Copyright 2016,2017 Free Software Foundation, Inc.                       *
4*32bb5217SDaniel Fojt  *                                                                          *
5*32bb5217SDaniel Fojt  * Permission is hereby granted, free of charge, to any person obtaining a  *
6*32bb5217SDaniel Fojt  * copy of this software and associated documentation files (the            *
7*32bb5217SDaniel Fojt  * "Software"), to deal in the Software without restriction, including      *
8*32bb5217SDaniel Fojt  * without limitation the rights to use, copy, modify, merge, publish,      *
9*32bb5217SDaniel Fojt  * distribute, distribute with modifications, sublicense, and/or sell       *
10*32bb5217SDaniel Fojt  * copies of the Software, and to permit persons to whom the Software is    *
11*32bb5217SDaniel Fojt  * furnished to do so, subject to the following conditions:                 *
12*32bb5217SDaniel Fojt  *                                                                          *
13*32bb5217SDaniel Fojt  * The above copyright notice and this permission notice shall be included  *
14*32bb5217SDaniel Fojt  * in all copies or substantial portions of the Software.                   *
15*32bb5217SDaniel Fojt  *                                                                          *
16*32bb5217SDaniel Fojt  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17*32bb5217SDaniel Fojt  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18*32bb5217SDaniel Fojt  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19*32bb5217SDaniel Fojt  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20*32bb5217SDaniel Fojt  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21*32bb5217SDaniel Fojt  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22*32bb5217SDaniel Fojt  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23*32bb5217SDaniel Fojt  *                                                                          *
24*32bb5217SDaniel Fojt  * Except as contained in this notice, the name(s) of the above copyright   *
25*32bb5217SDaniel Fojt  * holders shall not be used in advertising or otherwise to promote the     *
26*32bb5217SDaniel Fojt  * sale, use or other dealings in this Software without prior written       *
27*32bb5217SDaniel Fojt  * authorization.                                                           *
28*32bb5217SDaniel Fojt  ****************************************************************************/
29*32bb5217SDaniel Fojt 
30*32bb5217SDaniel Fojt /****************************************************************************
31*32bb5217SDaniel Fojt  *  Author: Thomas E. Dickey                                                *
32*32bb5217SDaniel Fojt  ****************************************************************************/
33*32bb5217SDaniel Fojt 
34*32bb5217SDaniel Fojt #include <reset_cmd.h>
35*32bb5217SDaniel Fojt #include <tty_settings.h>
36*32bb5217SDaniel Fojt 
37*32bb5217SDaniel Fojt #include <errno.h>
38*32bb5217SDaniel Fojt #include <stdio.h>
39*32bb5217SDaniel Fojt #include <fcntl.h>
40*32bb5217SDaniel Fojt 
41*32bb5217SDaniel Fojt #if HAVE_SIZECHANGE
42*32bb5217SDaniel Fojt # if !defined(sun) || !TERMIOS
43*32bb5217SDaniel Fojt #  if HAVE_SYS_IOCTL_H
44*32bb5217SDaniel Fojt #   include <sys/ioctl.h>
45*32bb5217SDaniel Fojt #  endif
46*32bb5217SDaniel Fojt # endif
47*32bb5217SDaniel Fojt #endif
48*32bb5217SDaniel Fojt 
49*32bb5217SDaniel Fojt #if NEED_PTEM_H
50*32bb5217SDaniel Fojt /* they neglected to define struct winsize in termios.h -- it's only
51*32bb5217SDaniel Fojt    in termio.h	*/
52*32bb5217SDaniel Fojt #include <sys/stream.h>
53*32bb5217SDaniel Fojt #include <sys/ptem.h>
54*32bb5217SDaniel Fojt #endif
55*32bb5217SDaniel Fojt 
56*32bb5217SDaniel Fojt MODULE_ID("$Id: reset_cmd.c,v 1.19 2020/02/02 23:34:34 tom Exp $")
57*32bb5217SDaniel Fojt 
58*32bb5217SDaniel Fojt /*
59*32bb5217SDaniel Fojt  * SCO defines TIOCGSIZE and the corresponding struct.  Other systems (SunOS,
60*32bb5217SDaniel Fojt  * Solaris, IRIX) define TIOCGWINSZ and struct winsize.
61*32bb5217SDaniel Fojt  */
62*32bb5217SDaniel Fojt #ifdef TIOCGSIZE
63*32bb5217SDaniel Fojt # define IOCTL_GET_WINSIZE TIOCGSIZE
64*32bb5217SDaniel Fojt # define IOCTL_SET_WINSIZE TIOCSSIZE
65*32bb5217SDaniel Fojt # define STRUCT_WINSIZE struct ttysize
66*32bb5217SDaniel Fojt # define WINSIZE_ROWS(n) n.ts_lines
67*32bb5217SDaniel Fojt # define WINSIZE_COLS(n) n.ts_cols
68*32bb5217SDaniel Fojt #else
69*32bb5217SDaniel Fojt # ifdef TIOCGWINSZ
70*32bb5217SDaniel Fojt #  define IOCTL_GET_WINSIZE TIOCGWINSZ
71*32bb5217SDaniel Fojt #  define IOCTL_SET_WINSIZE TIOCSWINSZ
72*32bb5217SDaniel Fojt #  define STRUCT_WINSIZE struct winsize
73*32bb5217SDaniel Fojt #  define WINSIZE_ROWS(n) n.ws_row
74*32bb5217SDaniel Fojt #  define WINSIZE_COLS(n) n.ws_col
75*32bb5217SDaniel Fojt # endif
76*32bb5217SDaniel Fojt #endif
77*32bb5217SDaniel Fojt 
78*32bb5217SDaniel Fojt static FILE *my_file;
79*32bb5217SDaniel Fojt 
80*32bb5217SDaniel Fojt static bool use_reset = FALSE;	/* invoked as reset */
81*32bb5217SDaniel Fojt static bool use_init = FALSE;	/* invoked as init */
82*32bb5217SDaniel Fojt 
83*32bb5217SDaniel Fojt static void
failed(const char * msg)84*32bb5217SDaniel Fojt failed(const char *msg)
85*32bb5217SDaniel Fojt {
86*32bb5217SDaniel Fojt     int code = errno;
87*32bb5217SDaniel Fojt 
88*32bb5217SDaniel Fojt     (void) fprintf(stderr, "%s: %s: %s\n", _nc_progname, msg, strerror(code));
89*32bb5217SDaniel Fojt     restore_tty_settings();
90*32bb5217SDaniel Fojt     (void) fprintf(my_file, "\n");
91*32bb5217SDaniel Fojt     fflush(my_file);
92*32bb5217SDaniel Fojt     ExitProgram(ErrSystem(code));
93*32bb5217SDaniel Fojt     /* NOTREACHED */
94*32bb5217SDaniel Fojt }
95*32bb5217SDaniel Fojt 
96*32bb5217SDaniel Fojt static bool
cat_file(char * file)97*32bb5217SDaniel Fojt cat_file(char *file)
98*32bb5217SDaniel Fojt {
99*32bb5217SDaniel Fojt     FILE *fp;
100*32bb5217SDaniel Fojt     size_t nr;
101*32bb5217SDaniel Fojt     char buf[BUFSIZ];
102*32bb5217SDaniel Fojt     bool sent = FALSE;
103*32bb5217SDaniel Fojt 
104*32bb5217SDaniel Fojt     if (file != 0) {
105*32bb5217SDaniel Fojt 	if ((fp = fopen(file, "r")) == 0)
106*32bb5217SDaniel Fojt 	    failed(file);
107*32bb5217SDaniel Fojt 
108*32bb5217SDaniel Fojt 	while ((nr = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) {
109*32bb5217SDaniel Fojt 	    if (fwrite(buf, sizeof(char), nr, my_file) != nr) {
110*32bb5217SDaniel Fojt 		failed(file);
111*32bb5217SDaniel Fojt 	    }
112*32bb5217SDaniel Fojt 	    sent = TRUE;
113*32bb5217SDaniel Fojt 	}
114*32bb5217SDaniel Fojt 	fclose(fp);
115*32bb5217SDaniel Fojt     }
116*32bb5217SDaniel Fojt     return sent;
117*32bb5217SDaniel Fojt }
118*32bb5217SDaniel Fojt 
119*32bb5217SDaniel Fojt static int
out_char(int c)120*32bb5217SDaniel Fojt out_char(int c)
121*32bb5217SDaniel Fojt {
122*32bb5217SDaniel Fojt     return putc(c, my_file);
123*32bb5217SDaniel Fojt }
124*32bb5217SDaniel Fojt 
125*32bb5217SDaniel Fojt /**************************************************************************
126*32bb5217SDaniel Fojt  * Mode-setting logic
127*32bb5217SDaniel Fojt  **************************************************************************/
128*32bb5217SDaniel Fojt 
129*32bb5217SDaniel Fojt /* some BSD systems have these built in, some systems are missing
130*32bb5217SDaniel Fojt  * one or more definitions. The safest solution is to override unless the
131*32bb5217SDaniel Fojt  * commonly-altered ones are defined.
132*32bb5217SDaniel Fojt  */
133*32bb5217SDaniel Fojt #if !(defined(CERASE) && defined(CINTR) && defined(CKILL) && defined(CQUIT))
134*32bb5217SDaniel Fojt #undef CEOF
135*32bb5217SDaniel Fojt #undef CERASE
136*32bb5217SDaniel Fojt #undef CINTR
137*32bb5217SDaniel Fojt #undef CKILL
138*32bb5217SDaniel Fojt #undef CLNEXT
139*32bb5217SDaniel Fojt #undef CRPRNT
140*32bb5217SDaniel Fojt #undef CQUIT
141*32bb5217SDaniel Fojt #undef CSTART
142*32bb5217SDaniel Fojt #undef CSTOP
143*32bb5217SDaniel Fojt #undef CSUSP
144*32bb5217SDaniel Fojt #endif
145*32bb5217SDaniel Fojt 
146*32bb5217SDaniel Fojt /* control-character defaults */
147*32bb5217SDaniel Fojt #ifndef CEOF
148*32bb5217SDaniel Fojt #define CEOF	CTRL('D')
149*32bb5217SDaniel Fojt #endif
150*32bb5217SDaniel Fojt #ifndef CERASE
151*32bb5217SDaniel Fojt #define CERASE	CTRL('H')
152*32bb5217SDaniel Fojt #endif
153*32bb5217SDaniel Fojt #ifndef CINTR
154*32bb5217SDaniel Fojt #define CINTR	127		/* ^? */
155*32bb5217SDaniel Fojt #endif
156*32bb5217SDaniel Fojt #ifndef CKILL
157*32bb5217SDaniel Fojt #define CKILL	CTRL('U')
158*32bb5217SDaniel Fojt #endif
159*32bb5217SDaniel Fojt #ifndef CLNEXT
160*32bb5217SDaniel Fojt #define CLNEXT  CTRL('v')
161*32bb5217SDaniel Fojt #endif
162*32bb5217SDaniel Fojt #ifndef CRPRNT
163*32bb5217SDaniel Fojt #define CRPRNT  CTRL('r')
164*32bb5217SDaniel Fojt #endif
165*32bb5217SDaniel Fojt #ifndef CQUIT
166*32bb5217SDaniel Fojt #define CQUIT	CTRL('\\')
167*32bb5217SDaniel Fojt #endif
168*32bb5217SDaniel Fojt #ifndef CSTART
169*32bb5217SDaniel Fojt #define CSTART	CTRL('Q')
170*32bb5217SDaniel Fojt #endif
171*32bb5217SDaniel Fojt #ifndef CSTOP
172*32bb5217SDaniel Fojt #define CSTOP	CTRL('S')
173*32bb5217SDaniel Fojt #endif
174*32bb5217SDaniel Fojt #ifndef CSUSP
175*32bb5217SDaniel Fojt #define CSUSP	CTRL('Z')
176*32bb5217SDaniel Fojt #endif
177*32bb5217SDaniel Fojt 
178*32bb5217SDaniel Fojt #if defined(_POSIX_VDISABLE)
179*32bb5217SDaniel Fojt #define DISABLED(val)   (((_POSIX_VDISABLE != -1) \
180*32bb5217SDaniel Fojt 		       && ((val) == _POSIX_VDISABLE)) \
181*32bb5217SDaniel Fojt 		      || ((val) <= 0))
182*32bb5217SDaniel Fojt #else
183*32bb5217SDaniel Fojt #define DISABLED(val)   ((int)(val) <= 0)
184*32bb5217SDaniel Fojt #endif
185*32bb5217SDaniel Fojt 
186*32bb5217SDaniel Fojt #define CHK(val, dft)   (unsigned char) (DISABLED(val) ? dft : val)
187*32bb5217SDaniel Fojt 
188*32bb5217SDaniel Fojt #define reset_char(item, value) \
189*32bb5217SDaniel Fojt     tty_settings->c_cc[item] = CHK(tty_settings->c_cc[item], value)
190*32bb5217SDaniel Fojt 
191*32bb5217SDaniel Fojt /*
192*32bb5217SDaniel Fojt  * Reset the terminal mode bits to a sensible state.  Very useful after
193*32bb5217SDaniel Fojt  * a child program dies in raw mode.
194*32bb5217SDaniel Fojt  */
195*32bb5217SDaniel Fojt void
reset_tty_settings(int fd,TTY * tty_settings)196*32bb5217SDaniel Fojt reset_tty_settings(int fd, TTY * tty_settings)
197*32bb5217SDaniel Fojt {
198*32bb5217SDaniel Fojt     GET_TTY(fd, tty_settings);
199*32bb5217SDaniel Fojt 
200*32bb5217SDaniel Fojt #ifdef TERMIOS
201*32bb5217SDaniel Fojt #if defined(VDISCARD) && defined(CDISCARD)
202*32bb5217SDaniel Fojt     reset_char(VDISCARD, CDISCARD);
203*32bb5217SDaniel Fojt #endif
204*32bb5217SDaniel Fojt     reset_char(VEOF, CEOF);
205*32bb5217SDaniel Fojt     reset_char(VERASE, CERASE);
206*32bb5217SDaniel Fojt #if defined(VFLUSH) && defined(CFLUSH)
207*32bb5217SDaniel Fojt     reset_char(VFLUSH, CFLUSH);
208*32bb5217SDaniel Fojt #endif
209*32bb5217SDaniel Fojt     reset_char(VINTR, CINTR);
210*32bb5217SDaniel Fojt     reset_char(VKILL, CKILL);
211*32bb5217SDaniel Fojt #if defined(VLNEXT) && defined(CLNEXT)
212*32bb5217SDaniel Fojt     reset_char(VLNEXT, CLNEXT);
213*32bb5217SDaniel Fojt #endif
214*32bb5217SDaniel Fojt     reset_char(VQUIT, CQUIT);
215*32bb5217SDaniel Fojt #if defined(VREPRINT) && defined(CRPRNT)
216*32bb5217SDaniel Fojt     reset_char(VREPRINT, CRPRNT);
217*32bb5217SDaniel Fojt #endif
218*32bb5217SDaniel Fojt #if defined(VSTART) && defined(CSTART)
219*32bb5217SDaniel Fojt     reset_char(VSTART, CSTART);
220*32bb5217SDaniel Fojt #endif
221*32bb5217SDaniel Fojt #if defined(VSTOP) && defined(CSTOP)
222*32bb5217SDaniel Fojt     reset_char(VSTOP, CSTOP);
223*32bb5217SDaniel Fojt #endif
224*32bb5217SDaniel Fojt #if defined(VSUSP) && defined(CSUSP)
225*32bb5217SDaniel Fojt     reset_char(VSUSP, CSUSP);
226*32bb5217SDaniel Fojt #endif
227*32bb5217SDaniel Fojt #if defined(VWERASE) && defined(CWERASE)
228*32bb5217SDaniel Fojt     reset_char(VWERASE, CWERASE);
229*32bb5217SDaniel Fojt #endif
230*32bb5217SDaniel Fojt 
231*32bb5217SDaniel Fojt     tty_settings->c_iflag &= ~((unsigned) (IGNBRK
232*32bb5217SDaniel Fojt 					   | PARMRK
233*32bb5217SDaniel Fojt 					   | INPCK
234*32bb5217SDaniel Fojt 					   | ISTRIP
235*32bb5217SDaniel Fojt 					   | INLCR
236*32bb5217SDaniel Fojt 					   | IGNCR
237*32bb5217SDaniel Fojt #ifdef IUCLC
238*32bb5217SDaniel Fojt 					   | IUCLC
239*32bb5217SDaniel Fojt #endif
240*32bb5217SDaniel Fojt #ifdef IXANY
241*32bb5217SDaniel Fojt 					   | IXANY
242*32bb5217SDaniel Fojt #endif
243*32bb5217SDaniel Fojt 					   | IXOFF));
244*32bb5217SDaniel Fojt 
245*32bb5217SDaniel Fojt     tty_settings->c_iflag |= (BRKINT
246*32bb5217SDaniel Fojt 			      | IGNPAR
247*32bb5217SDaniel Fojt 			      | ICRNL
248*32bb5217SDaniel Fojt 			      | IXON
249*32bb5217SDaniel Fojt #ifdef IMAXBEL
250*32bb5217SDaniel Fojt 			      | IMAXBEL
251*32bb5217SDaniel Fojt #endif
252*32bb5217SDaniel Fojt 	);
253*32bb5217SDaniel Fojt 
254*32bb5217SDaniel Fojt     tty_settings->c_oflag &= ~((unsigned) (0
255*32bb5217SDaniel Fojt #ifdef OLCUC
256*32bb5217SDaniel Fojt 					   | OLCUC
257*32bb5217SDaniel Fojt #endif
258*32bb5217SDaniel Fojt #ifdef OCRNL
259*32bb5217SDaniel Fojt 					   | OCRNL
260*32bb5217SDaniel Fojt #endif
261*32bb5217SDaniel Fojt #ifdef ONOCR
262*32bb5217SDaniel Fojt 					   | ONOCR
263*32bb5217SDaniel Fojt #endif
264*32bb5217SDaniel Fojt #ifdef ONLRET
265*32bb5217SDaniel Fojt 					   | ONLRET
266*32bb5217SDaniel Fojt #endif
267*32bb5217SDaniel Fojt #ifdef OFILL
268*32bb5217SDaniel Fojt 					   | OFILL
269*32bb5217SDaniel Fojt #endif
270*32bb5217SDaniel Fojt #ifdef OFDEL
271*32bb5217SDaniel Fojt 					   | OFDEL
272*32bb5217SDaniel Fojt #endif
273*32bb5217SDaniel Fojt #ifdef NLDLY
274*32bb5217SDaniel Fojt 					   | NLDLY
275*32bb5217SDaniel Fojt #endif
276*32bb5217SDaniel Fojt #ifdef CRDLY
277*32bb5217SDaniel Fojt 					   | CRDLY
278*32bb5217SDaniel Fojt #endif
279*32bb5217SDaniel Fojt #ifdef TABDLY
280*32bb5217SDaniel Fojt 					   | TABDLY
281*32bb5217SDaniel Fojt #endif
282*32bb5217SDaniel Fojt #ifdef BSDLY
283*32bb5217SDaniel Fojt 					   | BSDLY
284*32bb5217SDaniel Fojt #endif
285*32bb5217SDaniel Fojt #ifdef VTDLY
286*32bb5217SDaniel Fojt 					   | VTDLY
287*32bb5217SDaniel Fojt #endif
288*32bb5217SDaniel Fojt #ifdef FFDLY
289*32bb5217SDaniel Fojt 					   | FFDLY
290*32bb5217SDaniel Fojt #endif
291*32bb5217SDaniel Fojt 			       ));
292*32bb5217SDaniel Fojt 
293*32bb5217SDaniel Fojt     tty_settings->c_oflag |= (OPOST
294*32bb5217SDaniel Fojt #ifdef ONLCR
295*32bb5217SDaniel Fojt 			      | ONLCR
296*32bb5217SDaniel Fojt #endif
297*32bb5217SDaniel Fojt 	);
298*32bb5217SDaniel Fojt 
299*32bb5217SDaniel Fojt     tty_settings->c_cflag &= ~((unsigned) (CSIZE
300*32bb5217SDaniel Fojt 					   | CSTOPB
301*32bb5217SDaniel Fojt 					   | PARENB
302*32bb5217SDaniel Fojt 					   | PARODD
303*32bb5217SDaniel Fojt 					   | CLOCAL));
304*32bb5217SDaniel Fojt     tty_settings->c_cflag |= (CS8 | CREAD);
305*32bb5217SDaniel Fojt     tty_settings->c_lflag &= ~((unsigned) (ECHONL
306*32bb5217SDaniel Fojt 					   | NOFLSH
307*32bb5217SDaniel Fojt #ifdef TOSTOP
308*32bb5217SDaniel Fojt 					   | TOSTOP
309*32bb5217SDaniel Fojt #endif
310*32bb5217SDaniel Fojt #ifdef ECHOPTR
311*32bb5217SDaniel Fojt 					   | ECHOPRT
312*32bb5217SDaniel Fojt #endif
313*32bb5217SDaniel Fojt #ifdef XCASE
314*32bb5217SDaniel Fojt 					   | XCASE
315*32bb5217SDaniel Fojt #endif
316*32bb5217SDaniel Fojt 			       ));
317*32bb5217SDaniel Fojt 
318*32bb5217SDaniel Fojt     tty_settings->c_lflag |= (ISIG
319*32bb5217SDaniel Fojt 			      | ICANON
320*32bb5217SDaniel Fojt 			      | ECHO
321*32bb5217SDaniel Fojt 			      | ECHOE
322*32bb5217SDaniel Fojt 			      | ECHOK
323*32bb5217SDaniel Fojt #ifdef ECHOCTL
324*32bb5217SDaniel Fojt 			      | ECHOCTL
325*32bb5217SDaniel Fojt #endif
326*32bb5217SDaniel Fojt #ifdef ECHOKE
327*32bb5217SDaniel Fojt 			      | ECHOKE
328*32bb5217SDaniel Fojt #endif
329*32bb5217SDaniel Fojt 	);
330*32bb5217SDaniel Fojt #endif
331*32bb5217SDaniel Fojt 
332*32bb5217SDaniel Fojt     SET_TTY(fd, tty_settings);
333*32bb5217SDaniel Fojt }
334*32bb5217SDaniel Fojt 
335*32bb5217SDaniel Fojt /*
336*32bb5217SDaniel Fojt  * Returns a "good" value for the erase character.  This is loosely based on
337*32bb5217SDaniel Fojt  * the BSD4.4 logic.
338*32bb5217SDaniel Fojt  */
339*32bb5217SDaniel Fojt static int
default_erase(void)340*32bb5217SDaniel Fojt default_erase(void)
341*32bb5217SDaniel Fojt {
342*32bb5217SDaniel Fojt     int result;
343*32bb5217SDaniel Fojt 
344*32bb5217SDaniel Fojt     if (over_strike
345*32bb5217SDaniel Fojt 	&& VALID_STRING(key_backspace)
346*32bb5217SDaniel Fojt 	&& strlen(key_backspace) == 1) {
347*32bb5217SDaniel Fojt 	result = key_backspace[0];
348*32bb5217SDaniel Fojt     } else {
349*32bb5217SDaniel Fojt 	result = CERASE;
350*32bb5217SDaniel Fojt     }
351*32bb5217SDaniel Fojt 
352*32bb5217SDaniel Fojt     return result;
353*32bb5217SDaniel Fojt }
354*32bb5217SDaniel Fojt 
355*32bb5217SDaniel Fojt /*
356*32bb5217SDaniel Fojt  * Update the values of the erase, interrupt, and kill characters in the TTY
357*32bb5217SDaniel Fojt  * parameter.
358*32bb5217SDaniel Fojt  *
359*32bb5217SDaniel Fojt  * SVr4 tset (e.g., Solaris 2.5) only modifies the intr, quit or erase
360*32bb5217SDaniel Fojt  * characters if they're unset, or if we specify them as options.  This differs
361*32bb5217SDaniel Fojt  * from BSD 4.4 tset, which always sets erase.
362*32bb5217SDaniel Fojt  */
363*32bb5217SDaniel Fojt void
set_control_chars(TTY * tty_settings,int my_erase,int my_intr,int my_kill)364*32bb5217SDaniel Fojt set_control_chars(TTY * tty_settings, int my_erase, int my_intr, int my_kill)
365*32bb5217SDaniel Fojt {
366*32bb5217SDaniel Fojt     if (DISABLED(tty_settings->c_cc[VERASE]) || my_erase >= 0) {
367*32bb5217SDaniel Fojt 	tty_settings->c_cc[VERASE] = UChar((my_erase >= 0)
368*32bb5217SDaniel Fojt 					   ? my_erase
369*32bb5217SDaniel Fojt 					   : default_erase());
370*32bb5217SDaniel Fojt     }
371*32bb5217SDaniel Fojt 
372*32bb5217SDaniel Fojt     if (DISABLED(tty_settings->c_cc[VINTR]) || my_intr >= 0) {
373*32bb5217SDaniel Fojt 	tty_settings->c_cc[VINTR] = UChar((my_intr >= 0)
374*32bb5217SDaniel Fojt 					  ? my_intr
375*32bb5217SDaniel Fojt 					  : CINTR);
376*32bb5217SDaniel Fojt     }
377*32bb5217SDaniel Fojt 
378*32bb5217SDaniel Fojt     if (DISABLED(tty_settings->c_cc[VKILL]) || my_kill >= 0) {
379*32bb5217SDaniel Fojt 	tty_settings->c_cc[VKILL] = UChar((my_kill >= 0)
380*32bb5217SDaniel Fojt 					  ? my_kill
381*32bb5217SDaniel Fojt 					  : CKILL);
382*32bb5217SDaniel Fojt     }
383*32bb5217SDaniel Fojt }
384*32bb5217SDaniel Fojt 
385*32bb5217SDaniel Fojt /*
386*32bb5217SDaniel Fojt  * Set up various conversions in the TTY parameter, including parity, tabs,
387*32bb5217SDaniel Fojt  * returns, echo, and case, according to the termcap entry.
388*32bb5217SDaniel Fojt  */
389*32bb5217SDaniel Fojt void
set_conversions(TTY * tty_settings)390*32bb5217SDaniel Fojt set_conversions(TTY * tty_settings)
391*32bb5217SDaniel Fojt {
392*32bb5217SDaniel Fojt #ifdef ONLCR
393*32bb5217SDaniel Fojt     tty_settings->c_oflag |= ONLCR;
394*32bb5217SDaniel Fojt #endif
395*32bb5217SDaniel Fojt     tty_settings->c_iflag |= ICRNL;
396*32bb5217SDaniel Fojt     tty_settings->c_lflag |= ECHO;
397*32bb5217SDaniel Fojt #ifdef OXTABS
398*32bb5217SDaniel Fojt     tty_settings->c_oflag |= OXTABS;
399*32bb5217SDaniel Fojt #endif /* OXTABS */
400*32bb5217SDaniel Fojt 
401*32bb5217SDaniel Fojt     /* test used to be tgetflag("NL") */
402*32bb5217SDaniel Fojt     if (VALID_STRING(newline) && newline[0] == '\n' && !newline[1]) {
403*32bb5217SDaniel Fojt 	/* Newline, not linefeed. */
404*32bb5217SDaniel Fojt #ifdef ONLCR
405*32bb5217SDaniel Fojt 	tty_settings->c_oflag &= ~((unsigned) ONLCR);
406*32bb5217SDaniel Fojt #endif
407*32bb5217SDaniel Fojt 	tty_settings->c_iflag &= ~((unsigned) ICRNL);
408*32bb5217SDaniel Fojt     }
409*32bb5217SDaniel Fojt #ifdef OXTABS
410*32bb5217SDaniel Fojt     /* test used to be tgetflag("pt") */
411*32bb5217SDaniel Fojt     if (VALID_STRING(set_tab) && VALID_STRING(clear_all_tabs))
412*32bb5217SDaniel Fojt 	tty_settings->c_oflag &= ~OXTABS;
413*32bb5217SDaniel Fojt #endif /* OXTABS */
414*32bb5217SDaniel Fojt     tty_settings->c_lflag |= (ECHOE | ECHOK);
415*32bb5217SDaniel Fojt }
416*32bb5217SDaniel Fojt 
417*32bb5217SDaniel Fojt static bool
sent_string(const char * s)418*32bb5217SDaniel Fojt sent_string(const char *s)
419*32bb5217SDaniel Fojt {
420*32bb5217SDaniel Fojt     bool sent = FALSE;
421*32bb5217SDaniel Fojt     if (VALID_STRING(s)) {
422*32bb5217SDaniel Fojt 	tputs(s, 0, out_char);
423*32bb5217SDaniel Fojt 	sent = TRUE;
424*32bb5217SDaniel Fojt     }
425*32bb5217SDaniel Fojt     return sent;
426*32bb5217SDaniel Fojt }
427*32bb5217SDaniel Fojt 
428*32bb5217SDaniel Fojt static bool
to_left_margin(void)429*32bb5217SDaniel Fojt to_left_margin(void)
430*32bb5217SDaniel Fojt {
431*32bb5217SDaniel Fojt     if (VALID_STRING(carriage_return)) {
432*32bb5217SDaniel Fojt 	sent_string(carriage_return);
433*32bb5217SDaniel Fojt     } else {
434*32bb5217SDaniel Fojt 	out_char('\r');
435*32bb5217SDaniel Fojt     }
436*32bb5217SDaniel Fojt     return TRUE;
437*32bb5217SDaniel Fojt }
438*32bb5217SDaniel Fojt 
439*32bb5217SDaniel Fojt /*
440*32bb5217SDaniel Fojt  * Set the hardware tabs on the terminal, using the 'ct' (clear all tabs),
441*32bb5217SDaniel Fojt  * 'st' (set one tab) and 'ch' (horizontal cursor addressing) capabilities.
442*32bb5217SDaniel Fojt  * This is done before 'if' and 'is', so they can recover in case of error.
443*32bb5217SDaniel Fojt  *
444*32bb5217SDaniel Fojt  * Return TRUE if we set any tab stops, FALSE if not.
445*32bb5217SDaniel Fojt  */
446*32bb5217SDaniel Fojt static bool
reset_tabstops(int wide)447*32bb5217SDaniel Fojt reset_tabstops(int wide)
448*32bb5217SDaniel Fojt {
449*32bb5217SDaniel Fojt     if ((init_tabs != 8)
450*32bb5217SDaniel Fojt 	&& VALID_NUMERIC(init_tabs)
451*32bb5217SDaniel Fojt 	&& VALID_STRING(set_tab)
452*32bb5217SDaniel Fojt 	&& VALID_STRING(clear_all_tabs)) {
453*32bb5217SDaniel Fojt 	int c;
454*32bb5217SDaniel Fojt 
455*32bb5217SDaniel Fojt 	to_left_margin();
456*32bb5217SDaniel Fojt 	tputs(clear_all_tabs, 0, out_char);
457*32bb5217SDaniel Fojt 	if (init_tabs > 1) {
458*32bb5217SDaniel Fojt 	    if (init_tabs > wide)
459*32bb5217SDaniel Fojt 		init_tabs = (short) wide;
460*32bb5217SDaniel Fojt 	    for (c = init_tabs; c < wide; c += init_tabs) {
461*32bb5217SDaniel Fojt 		fprintf(my_file, "%*s", init_tabs, " ");
462*32bb5217SDaniel Fojt 		tputs(set_tab, 0, out_char);
463*32bb5217SDaniel Fojt 	    }
464*32bb5217SDaniel Fojt 	    to_left_margin();
465*32bb5217SDaniel Fojt 	}
466*32bb5217SDaniel Fojt 	return (TRUE);
467*32bb5217SDaniel Fojt     }
468*32bb5217SDaniel Fojt     return (FALSE);
469*32bb5217SDaniel Fojt }
470*32bb5217SDaniel Fojt 
471*32bb5217SDaniel Fojt /* Output startup string. */
472*32bb5217SDaniel Fojt bool
send_init_strings(int fd GCC_UNUSED,TTY * old_settings)473*32bb5217SDaniel Fojt send_init_strings(int fd GCC_UNUSED, TTY * old_settings)
474*32bb5217SDaniel Fojt {
475*32bb5217SDaniel Fojt     int i;
476*32bb5217SDaniel Fojt     bool need_flush = FALSE;
477*32bb5217SDaniel Fojt 
478*32bb5217SDaniel Fojt     (void) old_settings;
479*32bb5217SDaniel Fojt #ifdef TAB3
480*32bb5217SDaniel Fojt     if (old_settings != 0 &&
481*32bb5217SDaniel Fojt 	old_settings->c_oflag & (TAB3 | ONLCR | OCRNL | ONLRET)) {
482*32bb5217SDaniel Fojt 	old_settings->c_oflag &= (TAB3 | ONLCR | OCRNL | ONLRET);
483*32bb5217SDaniel Fojt 	SET_TTY(fd, old_settings);
484*32bb5217SDaniel Fojt     }
485*32bb5217SDaniel Fojt #endif
486*32bb5217SDaniel Fojt     if (use_reset || use_init) {
487*32bb5217SDaniel Fojt 	if (VALID_STRING(init_prog)) {
488*32bb5217SDaniel Fojt 	    IGNORE_RC(system(init_prog));
489*32bb5217SDaniel Fojt 	}
490*32bb5217SDaniel Fojt 
491*32bb5217SDaniel Fojt 	need_flush |= sent_string((use_reset && (reset_1string != 0))
492*32bb5217SDaniel Fojt 				  ? reset_1string
493*32bb5217SDaniel Fojt 				  : init_1string);
494*32bb5217SDaniel Fojt 
495*32bb5217SDaniel Fojt 	need_flush |= sent_string((use_reset && (reset_2string != 0))
496*32bb5217SDaniel Fojt 				  ? reset_2string
497*32bb5217SDaniel Fojt 				  : init_2string);
498*32bb5217SDaniel Fojt 
499*32bb5217SDaniel Fojt 	if (VALID_STRING(clear_margins)) {
500*32bb5217SDaniel Fojt 	    need_flush |= sent_string(clear_margins);
501*32bb5217SDaniel Fojt 	} else
502*32bb5217SDaniel Fojt #if defined(set_lr_margin)
503*32bb5217SDaniel Fojt 	if (VALID_STRING(set_lr_margin)) {
504*32bb5217SDaniel Fojt 	    need_flush |= sent_string(TPARM_2(set_lr_margin, 0,
505*32bb5217SDaniel Fojt 					      columns - 1));
506*32bb5217SDaniel Fojt 	} else
507*32bb5217SDaniel Fojt #endif
508*32bb5217SDaniel Fojt #if defined(set_left_margin_parm) && defined(set_right_margin_parm)
509*32bb5217SDaniel Fojt 	    if (VALID_STRING(set_left_margin_parm)
510*32bb5217SDaniel Fojt 		&& VALID_STRING(set_right_margin_parm)) {
511*32bb5217SDaniel Fojt 	    need_flush |= sent_string(TPARM_1(set_left_margin_parm, 0));
512*32bb5217SDaniel Fojt 	    need_flush |= sent_string(TPARM_1(set_right_margin_parm,
513*32bb5217SDaniel Fojt 					      columns - 1));
514*32bb5217SDaniel Fojt 	} else
515*32bb5217SDaniel Fojt #endif
516*32bb5217SDaniel Fojt 	    if (VALID_STRING(set_left_margin)
517*32bb5217SDaniel Fojt 		&& VALID_STRING(set_right_margin)) {
518*32bb5217SDaniel Fojt 	    need_flush |= to_left_margin();
519*32bb5217SDaniel Fojt 	    need_flush |= sent_string(set_left_margin);
520*32bb5217SDaniel Fojt 	    if (VALID_STRING(parm_right_cursor)) {
521*32bb5217SDaniel Fojt 		need_flush |= sent_string(TPARM_1(parm_right_cursor,
522*32bb5217SDaniel Fojt 						  columns - 1));
523*32bb5217SDaniel Fojt 	    } else {
524*32bb5217SDaniel Fojt 		for (i = 0; i < columns - 1; i++) {
525*32bb5217SDaniel Fojt 		    out_char(' ');
526*32bb5217SDaniel Fojt 		    need_flush = TRUE;
527*32bb5217SDaniel Fojt 		}
528*32bb5217SDaniel Fojt 	    }
529*32bb5217SDaniel Fojt 	    need_flush |= sent_string(set_right_margin);
530*32bb5217SDaniel Fojt 	    need_flush |= to_left_margin();
531*32bb5217SDaniel Fojt 	}
532*32bb5217SDaniel Fojt 
533*32bb5217SDaniel Fojt 	need_flush |= reset_tabstops(columns);
534*32bb5217SDaniel Fojt 
535*32bb5217SDaniel Fojt 	need_flush |= cat_file((use_reset && reset_file) ? reset_file : init_file);
536*32bb5217SDaniel Fojt 
537*32bb5217SDaniel Fojt 	need_flush |= sent_string((use_reset && (reset_3string != 0))
538*32bb5217SDaniel Fojt 				  ? reset_3string
539*32bb5217SDaniel Fojt 				  : init_3string);
540*32bb5217SDaniel Fojt     }
541*32bb5217SDaniel Fojt 
542*32bb5217SDaniel Fojt     return need_flush;
543*32bb5217SDaniel Fojt }
544*32bb5217SDaniel Fojt 
545*32bb5217SDaniel Fojt /*
546*32bb5217SDaniel Fojt  * Tell the user if a control key has been changed from the default value.
547*32bb5217SDaniel Fojt  */
548*32bb5217SDaniel Fojt static void
show_tty_change(TTY * old_settings,TTY * new_settings,const char * name,int which,unsigned def)549*32bb5217SDaniel Fojt show_tty_change(TTY * old_settings,
550*32bb5217SDaniel Fojt 		TTY * new_settings,
551*32bb5217SDaniel Fojt 		const char *name,
552*32bb5217SDaniel Fojt 		int which,
553*32bb5217SDaniel Fojt 		unsigned def)
554*32bb5217SDaniel Fojt {
555*32bb5217SDaniel Fojt     unsigned older, newer;
556*32bb5217SDaniel Fojt     char *p;
557*32bb5217SDaniel Fojt 
558*32bb5217SDaniel Fojt     newer = new_settings->c_cc[which];
559*32bb5217SDaniel Fojt     older = old_settings->c_cc[which];
560*32bb5217SDaniel Fojt 
561*32bb5217SDaniel Fojt     if (older == newer && older == def)
562*32bb5217SDaniel Fojt 	return;
563*32bb5217SDaniel Fojt 
564*32bb5217SDaniel Fojt     (void) fprintf(stderr, "%s %s ", name, older == newer ? "is" : "set to");
565*32bb5217SDaniel Fojt 
566*32bb5217SDaniel Fojt     if (DISABLED(newer)) {
567*32bb5217SDaniel Fojt 	(void) fprintf(stderr, "undef.\n");
568*32bb5217SDaniel Fojt 	/*
569*32bb5217SDaniel Fojt 	 * Check 'delete' before 'backspace', since the key_backspace value
570*32bb5217SDaniel Fojt 	 * is ambiguous.
571*32bb5217SDaniel Fojt 	 */
572*32bb5217SDaniel Fojt     } else if (newer == 0177) {
573*32bb5217SDaniel Fojt 	(void) fprintf(stderr, "delete.\n");
574*32bb5217SDaniel Fojt     } else if ((p = key_backspace) != 0
575*32bb5217SDaniel Fojt 	       && newer == (unsigned char) p[0]
576*32bb5217SDaniel Fojt 	       && p[1] == '\0') {
577*32bb5217SDaniel Fojt 	(void) fprintf(stderr, "backspace.\n");
578*32bb5217SDaniel Fojt     } else if (newer < 040) {
579*32bb5217SDaniel Fojt 	newer ^= 0100;
580*32bb5217SDaniel Fojt 	(void) fprintf(stderr, "control-%c (^%c).\n", UChar(newer), UChar(newer));
581*32bb5217SDaniel Fojt     } else
582*32bb5217SDaniel Fojt 	(void) fprintf(stderr, "%c.\n", UChar(newer));
583*32bb5217SDaniel Fojt }
584*32bb5217SDaniel Fojt 
585*32bb5217SDaniel Fojt /**************************************************************************
586*32bb5217SDaniel Fojt  * Miscellaneous.
587*32bb5217SDaniel Fojt  **************************************************************************/
588*32bb5217SDaniel Fojt 
589*32bb5217SDaniel Fojt void
reset_start(FILE * fp,bool is_reset,bool is_init)590*32bb5217SDaniel Fojt reset_start(FILE *fp, bool is_reset, bool is_init)
591*32bb5217SDaniel Fojt {
592*32bb5217SDaniel Fojt     my_file = fp;
593*32bb5217SDaniel Fojt     use_reset = is_reset;
594*32bb5217SDaniel Fojt     use_init = is_init;
595*32bb5217SDaniel Fojt }
596*32bb5217SDaniel Fojt 
597*32bb5217SDaniel Fojt void
reset_flush(void)598*32bb5217SDaniel Fojt reset_flush(void)
599*32bb5217SDaniel Fojt {
600*32bb5217SDaniel Fojt     if (my_file != 0)
601*32bb5217SDaniel Fojt 	fflush(my_file);
602*32bb5217SDaniel Fojt }
603*32bb5217SDaniel Fojt 
604*32bb5217SDaniel Fojt void
print_tty_chars(TTY * old_settings,TTY * new_settings)605*32bb5217SDaniel Fojt print_tty_chars(TTY * old_settings, TTY * new_settings)
606*32bb5217SDaniel Fojt {
607*32bb5217SDaniel Fojt     show_tty_change(old_settings, new_settings, "Erase", VERASE, CERASE);
608*32bb5217SDaniel Fojt     show_tty_change(old_settings, new_settings, "Kill", VKILL, CKILL);
609*32bb5217SDaniel Fojt     show_tty_change(old_settings, new_settings, "Interrupt", VINTR, CINTR);
610*32bb5217SDaniel Fojt }
611*32bb5217SDaniel Fojt 
612*32bb5217SDaniel Fojt #if HAVE_SIZECHANGE
613*32bb5217SDaniel Fojt /*
614*32bb5217SDaniel Fojt  * Set window size if not set already, but update our copy of the values if the
615*32bb5217SDaniel Fojt  * size was set.
616*32bb5217SDaniel Fojt  */
617*32bb5217SDaniel Fojt void
set_window_size(int fd,short * high,short * wide)618*32bb5217SDaniel Fojt set_window_size(int fd, short *high, short *wide)
619*32bb5217SDaniel Fojt {
620*32bb5217SDaniel Fojt     STRUCT_WINSIZE win;
621*32bb5217SDaniel Fojt     (void) ioctl(fd, IOCTL_GET_WINSIZE, &win);
622*32bb5217SDaniel Fojt     if (WINSIZE_ROWS(win) == 0 &&
623*32bb5217SDaniel Fojt 	WINSIZE_COLS(win) == 0) {
624*32bb5217SDaniel Fojt 	if (*high > 0 && *wide > 0) {
625*32bb5217SDaniel Fojt 	    WINSIZE_ROWS(win) = (unsigned short) *high;
626*32bb5217SDaniel Fojt 	    WINSIZE_COLS(win) = (unsigned short) *wide;
627*32bb5217SDaniel Fojt 	    (void) ioctl(fd, IOCTL_SET_WINSIZE, &win);
628*32bb5217SDaniel Fojt 	}
629*32bb5217SDaniel Fojt     } else if (WINSIZE_ROWS(win) > 0 &&
630*32bb5217SDaniel Fojt 	       WINSIZE_COLS(win) > 0) {
631*32bb5217SDaniel Fojt 	*high = (short) WINSIZE_ROWS(win);
632*32bb5217SDaniel Fojt 	*wide = (short) WINSIZE_COLS(win);
633*32bb5217SDaniel Fojt     }
634*32bb5217SDaniel Fojt }
635*32bb5217SDaniel Fojt #endif
636