* Implement a different way to delete a password from the cache.
[alpine.git] / pico / osdep / raw.c
blob96f630f342f460033da6d18b6e91839775a201f1
1 /*
2 * ========================================================================
3 * Copyright 2006 University of Washington
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * ========================================================================
15 * TTY setup routines.
18 #include <system.h>
19 #include <general.h>
21 #include "../estruct.h"
23 #include "raw.h"
26 #if HAS_TERMIOS
28 * These are the TERMIOS-style (POSIX) routines.
31 static struct termios _raw_tty, _original_tty;
33 #elif HAS_TERMIO
35 * These are the TERMIO-style (System V) routines.
38 static struct termio _raw_tty, _original_tty;
40 #else /* RAW_BSD */
42 * These are for the BSD-style routines.
45 static struct sgttyb _raw_tty, _original_tty;
46 static struct ltchars _raw_ltchars, _original_ltchars;
47 static struct tchars _raw_tchars, _original_tchars;
48 static int _raw_lmode, _original_lmode;
50 #endif
53 * current raw state
55 static short _inraw = 0;
58 * Set up the tty driver
60 * Args: state -- which state to put it in. 1 means go into raw (cbreak),
61 * 0 out of raw.
63 * Result: returns 0 if successful and -1 if not.
65 int
66 Raw(int state)
68 /** state is either ON or OFF, as indicated by call **/
69 /* Check return code only on first call. If it fails we're done for and
70 if it goes OK the others will probably go OK too. */
72 if(state == 0 && _inraw){
73 /*----- restore state to original -----*/
75 #if HAS_TERMIOS
77 if(tcsetattr(STDIN_FD, TCSADRAIN, &_original_tty) < 0)
78 return -1;
80 #elif HAS_TERMIO
82 if(ioctl(STDIN_FD, TCSETAW, &_original_tty) < 0)
83 return(-1);
85 #else /* RAW_BSD */
87 if(ioctl(STDIN_FD, TIOCSETP, &_original_tty) < 0)
88 return(-1);
90 (void)ioctl(STDIN_FD, TIOCSLTC, &_original_ltchars);
91 (void)ioctl(STDIN_FD, TIOCSETC, &_original_tchars);
92 (void)ioctl(STDIN_FD, TIOCLSET, &_original_lmode);
94 #endif
96 _inraw = 0;
98 else if(state == 1 && ! _inraw){
99 /*----- Go into raw mode (cbreak actually) ----*/
101 #if HAS_TERMIOS
103 if(tcgetattr(STDIN_FD, &_original_tty) < 0)
104 return -1;
106 tcgetattr(STDIN_FD, &_raw_tty);
107 _raw_tty.c_lflag &= ~(ICANON | ECHO | IEXTEN); /* noecho raw mode */
108 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
109 _raw_tty.c_iflag &= ~ICRNL; /* turn off CR->NL on input */
110 _raw_tty.c_oflag &= ~ONLCR; /* turn off NL->CR on output */
112 _raw_tty.c_cc[VMIN] = '\01'; /* min # of chars to queue */
113 _raw_tty.c_cc[VTIME] = '\0'; /* min time to wait for input*/
114 _raw_tty.c_cc[VINTR] = ctrl('C'); /* make it our special char */
115 _raw_tty.c_cc[VQUIT] = 0;
116 _raw_tty.c_cc[VSUSP] = 0;
117 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
119 #elif HAS_TERMIO
121 if(ioctl(STDIN_FD, TCGETA, &_original_tty) < 0)
122 return(-1);
124 (void)ioctl(STDIN_FD, TCGETA, &_raw_tty); /** again! **/
125 _raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
126 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
127 _raw_tty.c_iflag &= ~ICRNL; /* turn off CR->NL on input */
128 _raw_tty.c_oflag &= ~ONLCR; /* turn off NL->CR on output */
129 _raw_tty.c_cc[VMIN] = 1; /* min # of chars to queue */
130 _raw_tty.c_cc[VTIME] = 0; /* min time to wait for input*/
131 _raw_tty.c_cc[VINTR] = ctrl('C'); /* make it our special char */
132 _raw_tty.c_cc[VQUIT] = 0;
133 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
135 #else /* RAW_BSD */
136 if(ioctl(STDIN_FD, TIOCGETP, &_original_tty) < 0)
137 return(-1);
139 (void)ioctl(STDIN_FD, TIOCGETP, &_raw_tty);
140 (void)ioctl(STDIN_FD, TIOCGETC, &_original_tchars);
141 (void)ioctl(STDIN_FD, TIOCGETC, &_raw_tchars);
142 (void)ioctl(STDIN_FD, TIOCGLTC, &_original_ltchars);
143 (void)ioctl(STDIN_FD, TIOCGLTC, &_raw_ltchars);
144 (void)ioctl(STDIN_FD, TIOCLGET, &_original_lmode);
145 (void)ioctl(STDIN_FD, TIOCLGET, &_raw_lmode);
147 _raw_tty.sg_flags &= ~(ECHO); /* echo off */
148 _raw_tty.sg_flags |= CBREAK; /* raw on */
149 _raw_tty.sg_flags &= ~CRMOD; /* Turn off CR -> LF mapping */
151 _raw_tchars.t_intrc = -1; /* Turn off ^C and ^D */
152 _raw_tchars.t_eofc = -1;
154 _raw_ltchars.t_lnextc = -1; /* Turn off ^V so we can use it */
155 _raw_ltchars.t_dsuspc = -1; /* Turn off ^Y so we can use it */
156 _raw_ltchars.t_suspc = -1; /* Turn off ^Z; we just read 'em */
157 _raw_ltchars.t_werasc = -1; /* Turn off ^w word erase */
158 _raw_ltchars.t_rprntc = -1; /* Turn off ^R reprint line */
159 _raw_ltchars.t_flushc = -1; /* Turn off ^O output flush */
161 (void)ioctl(STDIN_FD, TIOCSETP, &_raw_tty);
162 (void)ioctl(STDIN_FD, TIOCSLTC, &_raw_ltchars);
163 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
164 (void)ioctl(STDIN_FD, TIOCLSET, &_raw_lmode);
165 #endif
166 _inraw = 1;
169 return(0);
174 * Set up the tty driver to use XON/XOFF flow control
176 * Args: state -- True to make sure XON/XOFF turned on, FALSE off.
178 * Result: none.
180 void
181 xonxoff_proc(int state)
183 if(_inraw){
184 if(state){
185 #if HAS_TERMIOS
187 if(!(_raw_tty.c_iflag & IXON)){
188 _raw_tty.c_iflag |= IXON;
189 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
192 #elif HAS_TERMIO
194 if(!(_raw_tty.c_iflag & IXON)){
195 _raw_tty.c_iflag |= IXON; /* turn ON ^S/^Q on input */
196 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
198 #else /* RAW_BSD */
200 if(_raw_tchars.t_startc == -1 || _raw_tchars.t_stopc == -1){
201 _raw_tchars.t_startc = 'Q' - '@'; /* Turn ON ^S/^Q */
202 _raw_tchars.t_stopc = 'S' - '@';
203 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
206 #endif
208 else{
209 #if HAS_TERMIOS
211 if(_raw_tty.c_iflag & IXON){
212 _raw_tty.c_iflag &= ~IXON; /* turn off ^S/^Q on input */
213 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
216 #elif HAS_TERMIO
218 if(_raw_tty.c_iflag & IXON){
219 _raw_tty.c_iflag &= ~IXON; /* turn off ^S/^Q on input */
220 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
223 #else /* RAW_BSD */
224 if(!(_raw_tchars.t_startc == -1 && _raw_tchars.t_stopc == -1)){
225 _raw_tchars.t_startc = -1; /* Turn off ^S/^Q */
226 _raw_tchars.t_stopc = -1;
227 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
229 #endif
236 * Set up the tty driver to do LF->CR translation
238 * Args: state -- True to turn on translation, false to write raw LF's
240 * Result: none.
242 void
243 crlf_proc(int state)
245 if(_inraw){
246 if(state){ /* turn ON NL->CR on output */
247 #if HAS_TERMIOS
249 if(!(_raw_tty.c_oflag & ONLCR)){
250 _raw_tty.c_oflag |= ONLCR;
251 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
254 #elif HAS_TERMIO
256 if(!(_raw_tty.c_oflag & ONLCR)){
257 _raw_tty.c_oflag |= ONLCR;
258 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
261 #else /* RAW_BSD */
262 if(!(_raw_tty.sg_flags & CRMOD)){
263 _raw_tty.sg_flags |= CRMOD;
264 (void)ioctl(STDIN_FD, TIOCSETP, &_raw_tty);
266 #endif
268 else{ /* turn OFF NL-CR on output */
269 #if HAS_TERMIOS
271 if(_raw_tty.c_oflag & ONLCR){
272 _raw_tty.c_oflag &= ~ONLCR;
273 tcsetattr (STDIN_FD, TCSADRAIN, &_raw_tty);
276 #elif HAS_TERMIO
278 if(_raw_tty.c_oflag & ONLCR){
279 _raw_tty.c_oflag &= ~ONLCR;
280 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
283 #else /* RAW_BSD */
285 if(_raw_tty.sg_flags & CRMOD){
286 _raw_tty.sg_flags &= ~CRMOD;
287 (void)ioctl(STDIN_FD, TIOCSETP, &_raw_tty);
290 #endif
297 * Set up the tty driver to handle interrupt char
299 * Args: state -- True to turn on interrupt char, false to not
301 * Result: tty driver that'll send us SIGINT or not
303 void
304 intr_proc(int state)
306 if(_inraw){
307 if(state){
308 #if HAS_TERMIOS
310 _raw_tty.c_lflag |= ISIG; /* enable signals */
311 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
313 #elif HAS_TERMIO
315 _raw_tty.c_lflag |= ISIG; /* enable signals */
316 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
318 #else /* RAW_BSD */
320 _raw_tchars.t_intrc = ctrl('C');
321 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
323 #endif
325 else{
326 #if HAS_TERMIOS
328 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
329 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
331 #elif HAS_TERMIO
333 _raw_tty.c_lflag &= ~ISIG; /* disable signals */
334 (void)ioctl(STDIN_FD, TCSETAW, &_raw_tty);
336 #else /* RAW_BSD */
337 _raw_tchars.t_intrc = -1;
338 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
339 #endif
346 * Discard any pending input characters
348 * Args: none
350 * Result: pending input buffer flushed
352 void
353 flush_input(void)
355 #if HAS_TERMIOS
357 tcflush(STDIN_FD, TCIFLUSH);
359 #elif HAS_TERMIO
361 ioctl(STDIN_FD, TCFLSH, 0);
363 #else /* RAW_BSD */
365 #ifdef TIOCFLUSH
366 #ifdef FREAD
367 int i = FREAD;
368 #else
369 int i = 1;
370 #endif
371 ioctl(STDIN_FD, TIOCFLUSH, &i);
372 #endif /* TIOCFLUSH */
374 #endif
379 * Turn off hi bit stripping
381 void
382 bit_strip_off(void)
384 #if HAS_TERMIOS
386 _raw_tty.c_iflag &= ~ISTRIP;
387 tcsetattr(STDIN_FD, TCSADRAIN, &_raw_tty);
389 #elif HAS_TERMIO
391 /* no op */
393 #else /* RAW_BSD */
395 #ifdef LPASS8
396 _raw_lmode |= LPASS8;
397 #endif
399 #ifdef LPASS8OUT
400 _raw_lmode |= LPASS8OUT;
401 #endif
403 (void)ioctl(STDIN_FD, TIOCLSET, &_raw_lmode);
405 #endif
410 * Turn off quit character (^\) if possible
412 void
413 quit_char_off(void)
415 #if HAS_TERMIOS
417 #elif HAS_TERMIO
419 #else /* RAW_BSD */
420 _raw_tchars.t_quitc = -1;
421 (void)ioctl(STDIN_FD, TIOCSETC, &_raw_tchars);
422 #endif
427 * Returns TRUE if tty is < 4800, 0 otherwise.
430 ttisslow(void)
432 #if HAS_TERMIOS
434 return(cfgetospeed(&_raw_tty) < B4800);
436 #elif HAS_TERMIO
438 return((_raw_tty.c_cflag&CBAUD) < (unsigned int)B4800);
440 #else /* RAW_BSD */
442 return((int)_raw_tty.sg_ispeed < B4800);
444 #endif