update init.d to clean new state location /var/lib/sudo, prepare to upload
[debian/sudo] / term.c
1 /*
2  * Copyright (c) 2009 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 <sys/param.h>
21 #include <stdio.h>
22 #ifdef STDC_HEADERS
23 # include <stdlib.h>
24 # include <stddef.h>
25 #else
26 # ifdef HAVE_STDLIB_H
27 #  include <stdlib.h>
28 # endif
29 #endif /* STDC_HEADERS */
30 #ifdef HAVE_STRING_H
31 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
32 #  include <memory.h>
33 # endif
34 # include <string.h>
35 #else
36 # ifdef HAVE_STRINGS_H
37 #  include <strings.h>
38 # endif
39 #endif /* HAVE_STRING_H */
40 #ifdef HAVE_TERMIOS_H
41 # include <termios.h>
42 #else
43 # ifdef HAVE_TERMIO_H
44 #  include <termio.h>
45 # else
46 #  include <sgtty.h>
47 #  include <sys/ioctl.h>
48 # endif /* HAVE_TERMIO_H */
49 #endif /* HAVE_TERMIOS_H */
50
51 #include "sudo.h"
52
53 #ifndef TCSASOFT
54 # define TCSASOFT       0
55 #endif
56 #ifndef ECHONL
57 # define ECHONL         0
58 #endif
59 #ifndef IEXTEN
60 # define IEXTEN         0
61 #endif
62
63 #ifndef _POSIX_VDISABLE
64 # ifdef VDISABLE
65 #  define _POSIX_VDISABLE       VDISABLE
66 # else
67 #  define _POSIX_VDISABLE       0
68 # endif
69 #endif
70
71 /*
72  * Compat macros for non-termios systems.
73  */
74 #ifndef HAVE_TERMIOS_H
75 # ifdef HAVE_TERMIO_H
76 #  undef termios
77 #  define termios               termio
78 #  define tcgetattr(f, t)       ioctl(f, TCGETA, t)
79 #  define tcsetattr(f, a, t)    ioctl(f, a, t)
80 #  undef TCSAFLUSH
81 #  define TCSAFLUSH             TCSETAF
82 # else /* SGTTY */
83 #  undef termios
84 #  define termios               sgttyb
85 #  define c_lflag               sg_flags
86 #  define tcgetattr(f, t)       ioctl(f, TIOCGETP, t)
87 #  define tcsetattr(f, a, t)    ioctl(f, a, t)
88 #  undef TCSAFLUSH
89 #  define TCSAFLUSH             TIOCSETP
90 # endif /* HAVE_TERMIO_H */
91 #endif /* HAVE_TERMIOS_H */
92
93 typedef struct termios sudo_term_t;
94
95 static sudo_term_t term, oterm;
96 static int changed;
97 int term_erase;
98 int term_kill;
99
100 int
101 term_restore(fd)
102     int fd;
103 {
104     if (changed) {
105         if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &oterm) != 0)
106             return(0);
107         changed = 0;
108     }
109     return(1);
110 }
111
112 int
113 term_noecho(fd)
114     int fd;
115 {
116     if (!changed && tcgetattr(fd, &oterm) != 0)
117         return(0);
118     (void) memcpy(&term, &oterm, sizeof(term));
119     CLR(term.c_lflag, ECHO|ECHONL);
120 #ifdef VSTATUS
121     term.c_cc[VSTATUS] = _POSIX_VDISABLE;
122 #endif
123     if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &term) == 0) {
124         changed = 1;
125         return(1);
126     }
127     return(0);
128 }
129
130 #if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
131 int
132 term_raw(fd)
133     int fd;
134 {
135     if (!changed && tcgetattr(fd, &oterm) != 0)
136         return(0);
137     (void) memcpy(&term, &oterm, sizeof(term));
138     /* Set terminal to half-cooked mode */
139     term.c_cc[VMIN] = 1;
140     term.c_cc[VTIME] = 0;
141     CLR(term.c_lflag, ECHO | ECHONL | ICANON | IEXTEN);
142     SET(term.c_lflag, ISIG);
143 #ifdef VSTATUS
144     term.c_cc[VSTATUS] = _POSIX_VDISABLE;
145 #endif
146     if (tcsetattr(fd, TCSAFLUSH|TCSASOFT, &term) == 0) {
147         term_erase = term.c_cc[VERASE];
148         term_kill = term.c_cc[VKILL];
149         changed = 1;
150         return(1);
151     }
152     return(0);
153 }
154
155 #else /* SGTTY */
156
157 int
158 term_raw(fd)
159     int fd;
160 {
161     if (!changed && ioctl(fd, TIOCGETP, &oterm) != 0)
162         return(0);
163     (void) memcpy(&term, &oterm, sizeof(term));
164     /* Set terminal to half-cooked mode */
165     CLR(term.c_lflag, ECHO);
166     SET(term.sg_flags, CBREAK);
167     if (ioctl(fd, TIOCSETP, &term) == 0) {
168         term_erase = term.sg_erase;
169         term_kill = term.sg_kill;
170         changed = 1;
171         return(1);
172     }
173     return(0);
174 }
175
176 #endif