1: /*
2: * Copyright (c) 2011-2012 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: #include <sys/types.h>
20: #include <stdio.h>
21: #ifdef STDC_HEADERS
22: # include <stdlib.h>
23: # include <stddef.h>
24: #else
25: # ifdef HAVE_STDLIB_H
26: # include <stdlib.h>
27: # endif
28: #endif /* STDC_HEADERS */
29: #ifdef HAVE_STRING_H
30: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
31: # include <memory.h>
32: # endif
33: # include <string.h>
34: #endif /* HAVE_STRING_H */
35: #ifdef HAVE_STRINGS_H
36: # include <strings.h>
37: #endif /* HAVE_STRINGS_H */
38: #include <termios.h>
39:
40: #include "missing.h"
41: #include "sudo_debug.h"
42:
43: #ifndef TCSASOFT
44: # define TCSASOFT 0
45: #endif
46: #ifndef ECHONL
47: # define ECHONL 0
48: #endif
49: #ifndef IEXTEN
50: # define IEXTEN 0
51: #endif
52: #ifndef IUCLC
53: # define IUCLC 0
54: #endif
55:
56: #ifndef _POSIX_VDISABLE
57: # ifdef VDISABLE
58: # define _POSIX_VDISABLE VDISABLE
59: # else
60: # define _POSIX_VDISABLE 0
61: # endif
62: #endif
63:
64: static struct termios term, oterm;
65: static int changed;
66: int term_erase;
67: int term_kill;
68:
69: int
70: term_restore(int fd, int flush)
71: {
72: debug_decl(term_restore, SUDO_DEBUG_UTIL)
73:
74: if (changed) {
75: int flags = TCSASOFT;
76: flags |= flush ? TCSAFLUSH : TCSADRAIN;
77: if (tcsetattr(fd, flags, &oterm) != 0)
78: debug_return_int(0);
79: changed = 0;
80: }
81: debug_return_int(1);
82: }
83:
84: int
85: term_noecho(int fd)
86: {
87: debug_decl(term_noecho, SUDO_DEBUG_UTIL)
88:
89: if (!changed && tcgetattr(fd, &oterm) != 0)
90: debug_return_int(0);
91: (void) memcpy(&term, &oterm, sizeof(term));
92: CLR(term.c_lflag, ECHO|ECHONL);
93: #ifdef VSTATUS
94: term.c_cc[VSTATUS] = _POSIX_VDISABLE;
95: #endif
96: if (tcsetattr(fd, TCSADRAIN|TCSASOFT, &term) == 0) {
97: changed = 1;
98: debug_return_int(1);
99: }
100: debug_return_int(0);
101: }
102:
103: int
104: term_raw(int fd, int isig)
105: {
106: struct termios term;
107: debug_decl(term_raw, SUDO_DEBUG_UTIL)
108:
109: if (!changed && tcgetattr(fd, &oterm) != 0)
110: return 0;
111: (void) memcpy(&term, &oterm, sizeof(term));
112: /* Set terminal to raw mode */
113: term.c_cc[VMIN] = 1;
114: term.c_cc[VTIME] = 0;
115: CLR(term.c_iflag, ICRNL | IGNCR | INLCR | IUCLC | IXON);
116: CLR(term.c_oflag, OPOST);
117: CLR(term.c_lflag, ECHO | ICANON | ISIG | IEXTEN);
118: if (isig)
119: SET(term.c_lflag, ISIG);
120: if (tcsetattr(fd, TCSADRAIN|TCSASOFT, &term) == 0) {
121: changed = 1;
122: debug_return_int(1);
123: }
124: debug_return_int(0);
125: }
126:
127: int
128: term_cbreak(int fd)
129: {
130: debug_decl(term_cbreak, SUDO_DEBUG_UTIL)
131:
132: if (!changed && tcgetattr(fd, &oterm) != 0)
133: return 0;
134: (void) memcpy(&term, &oterm, sizeof(term));
135: /* Set terminal to half-cooked mode */
136: term.c_cc[VMIN] = 1;
137: term.c_cc[VTIME] = 0;
138: CLR(term.c_lflag, ECHO | ECHONL | ICANON | IEXTEN);
139: SET(term.c_lflag, ISIG);
140: #ifdef VSTATUS
141: term.c_cc[VSTATUS] = _POSIX_VDISABLE;
142: #endif
143: if (tcsetattr(fd, TCSADRAIN|TCSASOFT, &term) == 0) {
144: term_erase = term.c_cc[VERASE];
145: term_kill = term.c_cc[VKILL];
146: changed = 1;
147: debug_return_int(1);
148: }
149: debug_return_int(0);
150: }
151:
152: int
153: term_copy(int src, int dst)
154: {
155: struct termios tt;
156: debug_decl(term_copy, SUDO_DEBUG_UTIL)
157:
158: if (tcgetattr(src, &tt) != 0)
159: debug_return_int(0);
160: if (tcsetattr(dst, TCSANOW|TCSASOFT, &tt) != 0)
161: debug_return_int(0);
162: debug_return_int(1);
163: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>