diff options
Diffstat (limited to 'sshpty.c')
-rw-r--r-- | sshpty.c | 194 |
1 files changed, 2 insertions, 192 deletions
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); | 15 | RCSID("$OpenBSD: sshpty.c,v 1.11 2004/01/11 21:55:06 deraadt Exp $"); |
16 | 16 | ||
17 | #ifdef HAVE_UTIL_H | 17 | #ifdef HAVE_UTIL_H |
18 | # include <util.h> | 18 | # include <util.h> |
@@ -22,17 +22,9 @@ RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); | |||
22 | #include "log.h" | 22 | #include "log.h" |
23 | #include "misc.h" | 23 | #include "misc.h" |
24 | 24 | ||
25 | /* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ | ||
26 | #if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) | ||
27 | #undef HAVE_DEV_PTMX | ||
28 | #endif | ||
29 | |||
30 | #ifdef HAVE_PTY_H | 25 | #ifdef HAVE_PTY_H |
31 | # include <pty.h> | 26 | # include <pty.h> |
32 | #endif | 27 | #endif |
33 | #if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H) | ||
34 | # include <sys/stropts.h> | ||
35 | #endif | ||
36 | 28 | ||
37 | #ifndef O_NOCTTY | 29 | #ifndef O_NOCTTY |
38 | #define O_NOCTTY 0 | 30 | #define O_NOCTTY 0 |
@@ -48,7 +40,6 @@ RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $"); | |||
48 | int | 40 | int |
49 | pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) | 41 | pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) |
50 | { | 42 | { |
51 | #if defined(HAVE_OPENPTY) || defined(BSD4_4) | ||
52 | /* openpty(3) exists in OSF/1 and some other os'es */ | 43 | /* openpty(3) exists in OSF/1 and some other os'es */ |
53 | char *name; | 44 | char *name; |
54 | int i; | 45 | int i; |
@@ -64,187 +55,6 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) | |||
64 | 55 | ||
65 | strlcpy(namebuf, name, namebuflen); /* possible truncation */ | 56 | strlcpy(namebuf, name, namebuflen); /* possible truncation */ |
66 | return 1; | 57 | return 1; |
67 | #else /* HAVE_OPENPTY */ | ||
68 | #ifdef HAVE__GETPTY | ||
69 | /* | ||
70 | * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more | ||
71 | * pty's automagically when needed | ||
72 | */ | ||
73 | char *slave; | ||
74 | |||
75 | slave = _getpty(ptyfd, O_RDWR, 0622, 0); | ||
76 | if (slave == NULL) { | ||
77 | error("_getpty: %.100s", strerror(errno)); | ||
78 | return 0; | ||
79 | } | ||
80 | strlcpy(namebuf, slave, namebuflen); | ||
81 | /* Open the slave side. */ | ||
82 | *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); | ||
83 | if (*ttyfd < 0) { | ||
84 | error("%.200s: %.100s", namebuf, strerror(errno)); | ||
85 | close(*ptyfd); | ||
86 | return 0; | ||
87 | } | ||
88 | return 1; | ||
89 | #else /* HAVE__GETPTY */ | ||
90 | #if defined(HAVE_DEV_PTMX) | ||
91 | /* | ||
92 | * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 | ||
93 | * also has bsd-style ptys, but they simply do not work.) | ||
94 | */ | ||
95 | int ptm; | ||
96 | char *pts; | ||
97 | mysig_t old_signal; | ||
98 | |||
99 | ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); | ||
100 | if (ptm < 0) { | ||
101 | error("/dev/ptmx: %.100s", strerror(errno)); | ||
102 | return 0; | ||
103 | } | ||
104 | old_signal = signal(SIGCHLD, SIG_DFL); | ||
105 | if (grantpt(ptm) < 0) { | ||
106 | error("grantpt: %.100s", strerror(errno)); | ||
107 | return 0; | ||
108 | } | ||
109 | signal(SIGCHLD, old_signal); | ||
110 | if (unlockpt(ptm) < 0) { | ||
111 | error("unlockpt: %.100s", strerror(errno)); | ||
112 | return 0; | ||
113 | } | ||
114 | pts = ptsname(ptm); | ||
115 | if (pts == NULL) | ||
116 | error("Slave pty side name could not be obtained."); | ||
117 | strlcpy(namebuf, pts, namebuflen); | ||
118 | *ptyfd = ptm; | ||
119 | |||
120 | /* Open the slave side. */ | ||
121 | *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); | ||
122 | if (*ttyfd < 0) { | ||
123 | error("%.100s: %.100s", namebuf, strerror(errno)); | ||
124 | close(*ptyfd); | ||
125 | return 0; | ||
126 | } | ||
127 | #ifndef HAVE_CYGWIN | ||
128 | /* | ||
129 | * Push the appropriate streams modules, as described in Solaris pts(7). | ||
130 | * HP-UX pts(7) doesn't have ttcompat module. | ||
131 | */ | ||
132 | if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) | ||
133 | error("ioctl I_PUSH ptem: %.100s", strerror(errno)); | ||
134 | if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) | ||
135 | error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); | ||
136 | #ifndef __hpux | ||
137 | if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) | ||
138 | error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); | ||
139 | #endif | ||
140 | #endif | ||
141 | return 1; | ||
142 | #else /* HAVE_DEV_PTMX */ | ||
143 | #ifdef HAVE_DEV_PTS_AND_PTC | ||
144 | /* AIX-style pty code. */ | ||
145 | const char *name; | ||
146 | |||
147 | *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); | ||
148 | if (*ptyfd < 0) { | ||
149 | error("Could not open /dev/ptc: %.100s", strerror(errno)); | ||
150 | return 0; | ||
151 | } | ||
152 | name = ttyname(*ptyfd); | ||
153 | if (!name) | ||
154 | fatal("Open of /dev/ptc returns device for which ttyname fails."); | ||
155 | strlcpy(namebuf, name, namebuflen); | ||
156 | *ttyfd = open(name, O_RDWR | O_NOCTTY); | ||
157 | if (*ttyfd < 0) { | ||
158 | error("Could not open pty slave side %.100s: %.100s", | ||
159 | name, strerror(errno)); | ||
160 | close(*ptyfd); | ||
161 | return 0; | ||
162 | } | ||
163 | return 1; | ||
164 | #else /* HAVE_DEV_PTS_AND_PTC */ | ||
165 | #ifdef _UNICOS | ||
166 | char buf[64]; | ||
167 | int i; | ||
168 | int highpty; | ||
169 | |||
170 | #ifdef _SC_CRAY_NPTY | ||
171 | highpty = sysconf(_SC_CRAY_NPTY); | ||
172 | if (highpty == -1) | ||
173 | highpty = 128; | ||
174 | #else | ||
175 | highpty = 128; | ||
176 | #endif | ||
177 | |||
178 | for (i = 0; i < highpty; i++) { | ||
179 | snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); | ||
180 | *ptyfd = open(buf, O_RDWR|O_NOCTTY); | ||
181 | if (*ptyfd < 0) | ||
182 | continue; | ||
183 | snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); | ||
184 | /* Open the slave side. */ | ||
185 | *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); | ||
186 | if (*ttyfd < 0) { | ||
187 | error("%.100s: %.100s", namebuf, strerror(errno)); | ||
188 | close(*ptyfd); | ||
189 | return 0; | ||
190 | } | ||
191 | return 1; | ||
192 | } | ||
193 | return 0; | ||
194 | #else | ||
195 | /* BSD-style pty code. */ | ||
196 | char buf[64]; | ||
197 | int i; | ||
198 | const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
199 | const char *ptyminors = "0123456789abcdef"; | ||
200 | int num_minors = strlen(ptyminors); | ||
201 | int num_ptys = strlen(ptymajors) * num_minors; | ||
202 | struct termios tio; | ||
203 | |||
204 | for (i = 0; i < num_ptys; i++) { | ||
205 | snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], | ||
206 | ptyminors[i % num_minors]); | ||
207 | snprintf(namebuf, namebuflen, "/dev/tty%c%c", | ||
208 | ptymajors[i / num_minors], ptyminors[i % num_minors]); | ||
209 | |||
210 | *ptyfd = open(buf, O_RDWR | O_NOCTTY); | ||
211 | if (*ptyfd < 0) { | ||
212 | /* Try SCO style naming */ | ||
213 | snprintf(buf, sizeof buf, "/dev/ptyp%d", i); | ||
214 | snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); | ||
215 | *ptyfd = open(buf, O_RDWR | O_NOCTTY); | ||
216 | if (*ptyfd < 0) | ||
217 | continue; | ||
218 | } | ||
219 | |||
220 | /* Open the slave side. */ | ||
221 | *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); | ||
222 | if (*ttyfd < 0) { | ||
223 | error("%.100s: %.100s", namebuf, strerror(errno)); | ||
224 | close(*ptyfd); | ||
225 | return 0; | ||
226 | } | ||
227 | /* set tty modes to a sane state for broken clients */ | ||
228 | if (tcgetattr(*ptyfd, &tio) < 0) | ||
229 | logit("Getting tty modes for pty failed: %.100s", strerror(errno)); | ||
230 | else { | ||
231 | tio.c_lflag |= (ECHO | ISIG | ICANON); | ||
232 | tio.c_oflag |= (OPOST | ONLCR); | ||
233 | tio.c_iflag |= ICRNL; | ||
234 | |||
235 | /* Set the new modes for the terminal. */ | ||
236 | if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) | ||
237 | logit("Setting tty modes for pty failed: %.100s", strerror(errno)); | ||
238 | } | ||
239 | |||
240 | return 1; | ||
241 | } | ||
242 | return 0; | ||
243 | #endif /* CRAY */ | ||
244 | #endif /* HAVE_DEV_PTS_AND_PTC */ | ||
245 | #endif /* HAVE_DEV_PTMX */ | ||
246 | #endif /* HAVE__GETPTY */ | ||
247 | #endif /* HAVE_OPENPTY */ | ||
248 | } | 58 | } |
249 | 59 | ||
250 | /* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ | 60 | /* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ |
@@ -343,7 +153,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname) | |||
343 | if (fd < 0) | 153 | if (fd < 0) |
344 | error("open /dev/tty failed - could not set controlling tty: %.100s", | 154 | error("open /dev/tty failed - could not set controlling tty: %.100s", |
345 | strerror(errno)); | 155 | strerror(errno)); |
346 | else | 156 | else |
347 | close(fd); | 157 | close(fd); |
348 | #endif /* _UNICOS */ | 158 | #endif /* _UNICOS */ |
349 | } | 159 | } |