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