… | |
… | |
70 | get_pty_streams (int *fd_tty, char **ttydev) |
70 | get_pty_streams (int *fd_tty, char **ttydev) |
71 | { |
71 | { |
72 | #ifdef NO_SETOWNER_TTYDEV |
72 | #ifdef NO_SETOWNER_TTYDEV |
73 | int pfd; |
73 | int pfd; |
74 | |
74 | |
75 | # ifdef PTYS_ARE_GETPT |
75 | # if defined(PTYS_ARE_GETPT) |
76 | pfd = getpt(); |
76 | pfd = getpt(); |
77 | # else |
|
|
78 | # ifdef PTYS_ARE_POSIX |
77 | # elif defined(PTYS_ARE_POSIX) |
79 | pfd = posix_openpt (O_RDWR); |
78 | pfd = posix_openpt (O_RDWR); |
80 | # else |
79 | # else |
81 | pfd = open ("/dev/ptmx", O_RDWR | O_NOCTTY, 0); |
80 | pfd = open ("/dev/ptmx", O_RDWR | O_NOCTTY, 0); |
82 | # endif |
|
|
83 | # endif |
81 | # endif |
84 | if (pfd >= 0) |
82 | if (pfd >= 0) |
85 | { |
83 | { |
86 | if (grantpt (pfd) == 0 /* change slave permissions */ |
84 | if (grantpt (pfd) == 0 /* change slave permissions */ |
87 | && unlockpt (pfd) == 0) |
85 | && unlockpt (pfd) == 0) |
88 | { /* slave now unlocked */ |
86 | { /* slave now unlocked */ |
89 | *ttydev = strdup (ptsname (pfd)); /* get slave's name */ |
87 | *ttydev = strdup (ptsname (pfd)); /* get slave's name */ |
90 | return pfd; |
88 | return pfd; |
91 | } |
89 | } |
|
|
90 | |
92 | close (pfd); |
91 | close (pfd); |
93 | } |
92 | } |
94 | #endif |
93 | #endif |
|
|
94 | |
95 | return -1; |
95 | return -1; |
96 | } |
96 | } |
97 | |
97 | |
98 | static inline int |
98 | static inline int |
99 | get_pty_openpty (int *fd_tty, char **ttydev) |
99 | get_pty_openpty (int *fd_tty, char **ttydev) |
… | |
… | |
108 | { |
108 | { |
109 | *ttydev = strdup (tty_name); |
109 | *ttydev = strdup (tty_name); |
110 | return pfd; |
110 | return pfd; |
111 | } |
111 | } |
112 | #endif |
112 | #endif |
|
|
113 | |
113 | return -1; |
114 | return -1; |
114 | } |
115 | } |
115 | |
116 | |
116 | static inline int |
117 | static inline int |
117 | get_pty__getpty (int *fd_tty, char **ttydev) |
118 | get_pty__getpty (int *fd_tty, char **ttydev) |
… | |
… | |
121 | |
122 | |
122 | *ttydev = _getpty (&pfd, O_RDWR | O_NONBLOCK | O_NOCTTY, 0622, 0); |
123 | *ttydev = _getpty (&pfd, O_RDWR | O_NONBLOCK | O_NOCTTY, 0622, 0); |
123 | if (*ttydev != NULL) |
124 | if (*ttydev != NULL) |
124 | return pfd; |
125 | return pfd; |
125 | #endif |
126 | #endif |
|
|
127 | |
126 | return -1; |
128 | return -1; |
127 | } |
129 | } |
128 | |
130 | |
129 | static inline int |
131 | static inline int |
130 | get_pty_ptc (int *fd_tty, char **ttydev) |
132 | get_pty_ptc (int *fd_tty, char **ttydev) |
… | |
… | |
136 | { |
138 | { |
137 | *ttydev = strdup (ttyname (pfd)); |
139 | *ttydev = strdup (ttyname (pfd)); |
138 | return pfd; |
140 | return pfd; |
139 | } |
141 | } |
140 | #endif |
142 | #endif |
|
|
143 | |
141 | return -1; |
144 | return -1; |
142 | } |
145 | } |
143 | |
146 | |
144 | static inline int |
147 | static inline int |
145 | get_pty_clone (int *fd_tty, char **ttydev) |
148 | get_pty_clone (int *fd_tty, char **ttydev) |
… | |
… | |
151 | { |
154 | { |
152 | *ttydev = strdup (ptsname (pfd)); |
155 | *ttydev = strdup (ptsname (pfd)); |
153 | return pfd; |
156 | return pfd; |
154 | } |
157 | } |
155 | #endif |
158 | #endif |
|
|
159 | |
156 | return -1; |
160 | return -1; |
157 | } |
161 | } |
158 | |
162 | |
159 | static inline int |
163 | static inline int |
160 | get_pty_numeric (int *fd_tty, char **ttydev) |
164 | get_pty_numeric (int *fd_tty, char **ttydev) |
161 | { |
165 | { |
162 | #ifdef PTYS_ARE_NUMERIC |
166 | #ifdef PTYS_ARE_NUMERIC |
163 | int pfd; |
167 | int pfd; |
164 | int idx; |
168 | int idx; |
165 | char *c1, *c2; |
169 | char *c1, *c2; |
166 | char pty_name[] = "/dev/ptyp???"; |
170 | char pty_name[] = "/dev/ptyp???"; |
167 | char tty_name[] = "/dev/ttyp???"; |
171 | char tty_name[] = "/dev/ttyp???"; |
168 | |
172 | |
169 | c1 = &(pty_name[sizeof (pty_name) - 4]); |
173 | c1 = &(pty_name[sizeof (pty_name) - 4]); |
170 | c2 = &(tty_name[sizeof (tty_name) - 4]); |
174 | c2 = &(tty_name[sizeof (tty_name) - 4]); |
|
|
175 | |
171 | for (idx = 0; idx < 256; idx++) |
176 | for (idx = 0; idx < 256; idx++) |
172 | { |
177 | { |
173 | sprintf (c1, "%d", idx); |
178 | sprintf (c1, "%d", idx); |
174 | sprintf (c2, "%d", idx); |
179 | sprintf (c2, "%d", idx); |
|
|
180 | |
175 | if (access (tty_name, F_OK) < 0) |
181 | if (access (tty_name, F_OK) < 0) |
176 | { |
182 | { |
177 | idx = 256; |
183 | idx = 256; |
178 | break; |
184 | break; |
179 | } |
185 | } |
180 | |
186 | |
181 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
187 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
182 | { |
188 | { |
183 | if (access (tty_name, R_OK | W_OK) == 0) |
189 | if (access (tty_name, R_OK | W_OK) == 0) |
184 | { |
190 | { |
185 | *ttydev = strdup (tty_name); |
191 | *ttydev = strdup (tty_name); |
186 | return pfd; |
192 | return pfd; |
187 | } |
193 | } |
188 | |
194 | |
189 | close (pfd); |
195 | close (pfd); |
190 | } |
196 | } |
191 | } |
197 | } |
192 | #endif |
198 | #endif |
|
|
199 | |
193 | return -1; |
200 | return -1; |
194 | } |
201 | } |
195 | |
202 | |
196 | static inline int |
203 | static inline int |
197 | get_pty_searched (int *fd_tty, char **ttydev) |
204 | get_pty_searched (int *fd_tty, char **ttydev) |
198 | { |
205 | { |
… | |
… | |
201 | # define PTYCHAR1 "pqrstuvwxyz" |
208 | # define PTYCHAR1 "pqrstuvwxyz" |
202 | # endif |
209 | # endif |
203 | # ifndef PTYCHAR2 |
210 | # ifndef PTYCHAR2 |
204 | # define PTYCHAR2 "0123456789abcdef" |
211 | # define PTYCHAR2 "0123456789abcdef" |
205 | # endif |
212 | # endif |
206 | int pfd; |
213 | int pfd; |
207 | const char *c1, *c2; |
214 | const char *c1, *c2; |
208 | char pty_name[] = "/dev/pty??"; |
215 | char pty_name[] = "/dev/pty??"; |
209 | char tty_name[] = "/dev/tty??"; |
216 | char tty_name[] = "/dev/tty??"; |
210 | |
217 | |
211 | for (c1 = PTYCHAR1; *c1; c1++) |
218 | for (c1 = PTYCHAR1; *c1; c1++) |
212 | { |
219 | { |
213 | pty_name[ (sizeof (pty_name) - 3)] = |
220 | pty_name[ (sizeof (pty_name) - 3)] = |
214 | tty_name[ (sizeof (pty_name) - 3)] = *c1; |
221 | tty_name[ (sizeof (pty_name) - 3)] = *c1; |
|
|
222 | |
215 | for (c2 = PTYCHAR2; *c2; c2++) |
223 | for (c2 = PTYCHAR2; *c2; c2++) |
216 | { |
224 | { |
217 | pty_name[ (sizeof (pty_name) - 2)] = |
225 | pty_name[ (sizeof (pty_name) - 2)] = |
218 | tty_name[ (sizeof (pty_name) - 2)] = *c2; |
226 | tty_name[ (sizeof (pty_name) - 2)] = *c2; |
|
|
227 | |
219 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
228 | if ((pfd = open (pty_name, O_RDWR | O_NOCTTY, 0)) >= 0) |
220 | { |
229 | { |
221 | if (access (tty_name, R_OK | W_OK) == 0) |
230 | if (access (tty_name, R_OK | W_OK) == 0) |
222 | { |
231 | { |
223 | *ttydev = strdup (tty_name); |
232 | *ttydev = strdup (tty_name); |
224 | return pfd; |
233 | return pfd; |
225 | } |
234 | } |
226 | |
235 | |
227 | close (pfd); |
236 | close (pfd); |
228 | } |
237 | } |
229 | } |
238 | } |
230 | } |
239 | } |
231 | #endif |
240 | #endif |
|
|
241 | |
232 | return -1; |
242 | return -1; |
233 | } |
243 | } |
234 | |
244 | |
235 | static int |
245 | static int |
236 | get_pty (int *fd_tty, char **ttydev) |
246 | get_pty (int *fd_tty, char **ttydev) |
237 | { |
247 | { |
… | |
… | |
243 | || (pfd = get_pty_ptc (fd_tty, ttydev)) != -1 |
253 | || (pfd = get_pty_ptc (fd_tty, ttydev)) != -1 |
244 | || (pfd = get_pty_clone (fd_tty, ttydev)) != -1 |
254 | || (pfd = get_pty_clone (fd_tty, ttydev)) != -1 |
245 | || (pfd = get_pty_numeric (fd_tty, ttydev)) != -1 |
255 | || (pfd = get_pty_numeric (fd_tty, ttydev)) != -1 |
246 | || (pfd = get_pty_searched (fd_tty, ttydev)) != -1) |
256 | || (pfd = get_pty_searched (fd_tty, ttydev)) != -1) |
247 | return pfd; |
257 | return pfd; |
|
|
258 | |
248 | return -1; |
259 | return -1; |
249 | } |
260 | } |
250 | |
261 | |
251 | /*----------------------------------------------------------------------*/ |
262 | /*----------------------------------------------------------------------*/ |
252 | /* |
263 | /* |
… | |
… | |
263 | * Make our tty a controlling tty so that /dev/tty points to us |
274 | * Make our tty a controlling tty so that /dev/tty points to us |
264 | */ |
275 | */ |
265 | static int |
276 | static int |
266 | control_tty (int fd_tty) |
277 | control_tty (int fd_tty) |
267 | { |
278 | { |
268 | int fd; |
|
|
269 | |
|
|
270 | /* ---------------------------------------- */ |
|
|
271 | setsid (); |
279 | setsid (); |
272 | |
280 | |
273 | /* ---------------------------------------- */ |
|
|
274 | # if defined(PTYS_ARE_PTMX) && defined(I_PUSH) |
281 | #if defined(PTYS_ARE_PTMX) && defined(I_PUSH) |
275 | /* |
282 | /* |
276 | * Push STREAMS modules: |
283 | * Push STREAMS modules: |
277 | * ptem: pseudo-terminal hardware emulation module. |
284 | * ptem: pseudo-terminal hardware emulation module. |
278 | * ldterm: standard terminal line discipline. |
285 | * ldterm: standard terminal line discipline. |
279 | * ttcompat: V7, 4BSD and XENIX STREAMS compatibility module. |
286 | * ttcompat: V7, 4BSD and XENIX STREAMS compatibility module. |
… | |
… | |
287 | * documentation is really unclear about whether it is any close () on |
294 | * documentation is really unclear about whether it is any close () on |
288 | * the master side or the last close () - i.e. a proper STREAMS dismantling |
295 | * the master side or the last close () - i.e. a proper STREAMS dismantling |
289 | * close () - on the master side which causes a hang up to be sent |
296 | * close () - on the master side which causes a hang up to be sent |
290 | * through - Geoff Wing |
297 | * through - Geoff Wing |
291 | */ |
298 | */ |
292 | # ifdef HAVE_ISASTREAM |
299 | # ifdef HAVE_ISASTREAM |
293 | if (isastream (fd_tty) == 1) |
300 | if (isastream (fd_tty) == 1) |
294 | # endif |
301 | # endif |
295 | { |
302 | { |
296 | ioctl (fd_tty, I_PUSH, "ptem"); |
303 | ioctl (fd_tty, I_PUSH, "ptem"); |
297 | ioctl (fd_tty, I_PUSH, "ldterm"); |
304 | ioctl (fd_tty, I_PUSH, "ldterm"); |
298 | ioctl (fd_tty, I_PUSH, "ttcompat"); |
305 | ioctl (fd_tty, I_PUSH, "ttcompat"); |
299 | } |
306 | } |
300 | # endif |
307 | #endif |
301 | /* ---------------------------------------- */ |
308 | |
302 | fd = ioctl (fd_tty, TIOCSCTTY, NULL); |
309 | ioctl (fd_tty, TIOCSCTTY, NULL); |
303 | /* ---------------------------------------- */ |
310 | |
304 | fd = open ("/dev/tty", O_WRONLY); |
311 | int fd = open ("/dev/tty", O_WRONLY); |
305 | if (fd < 0) |
312 | if (fd < 0) |
306 | return -1; /* fatal */ |
313 | return -1; /* fatal */ |
|
|
314 | |
307 | close (fd); |
315 | close (fd); |
308 | /* ---------------------------------------- */ |
|
|
309 | |
316 | |
310 | return 0; |
317 | return 0; |
311 | } |
318 | } |
312 | |
319 | |
313 | void |
320 | void |
… | |
… | |
372 | } |
379 | } |
373 | else |
380 | else |
374 | #endif /* TTY_GID_SUPPORT */ |
381 | #endif /* TTY_GID_SUPPORT */ |
375 | { |
382 | { |
376 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
383 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
377 | gid = getgid (); |
384 | gid = 0; |
378 | } |
385 | } |
379 | } |
386 | } |
380 | } ttyconf; |
387 | } ttyconf; |
381 | |
388 | |
382 | ///////////////////////////////////////////////////////////////////////////// |
389 | ///////////////////////////////////////////////////////////////////////////// |
… | |
… | |
387 | if (!name || !*name) |
394 | if (!name || !*name) |
388 | return; |
395 | return; |
389 | |
396 | |
390 | if (action == SAVE) |
397 | if (action == SAVE) |
391 | { |
398 | { |
392 | # ifndef RESET_TTY_TO_COMMON_DEFAULTS |
399 | chown (name, getuid (), ttyconf.gid); /* fail silently */ |
393 | /* store original tty status for restoration rxvt_clean_exit () -- rgg 04/12/95 */ |
400 | chmod (name, ttyconf.mode); |
394 | if (lstat (name, &savestat) < 0) /* you lose out */ |
401 | # ifdef HAVE_REVOKE |
395 | ; |
402 | revoke (name); |
396 | else |
|
|
397 | # endif |
403 | # endif |
398 | { |
|
|
399 | saved = true; |
|
|
400 | chown (name, getuid (), ttyconf.gid); /* fail silently */ |
|
|
401 | chmod (name, ttyconf.mode); |
|
|
402 | # ifdef HAVE_REVOKE |
|
|
403 | revoke (name); |
|
|
404 | # endif |
|
|
405 | } |
|
|
406 | } |
404 | } |
407 | else |
405 | else |
408 | { /* action == RESTORE */ |
406 | { /* action == RESTORE */ |
409 | # ifndef RESET_TTY_TO_COMMON_DEFAULTS |
407 | chmod (name, RESTORE_TTY_MODE); |
410 | if (saved) |
|
|
411 | { |
|
|
412 | chmod (name, savestat.st_mode); |
|
|
413 | chown (name, savestat.st_uid, savestat.st_gid); |
|
|
414 | } |
|
|
415 | # else |
|
|
416 | chmod (name, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)); |
|
|
417 | chown (name, 0, 0); |
408 | chown (name, 0, ttyconf.gid); |
418 | # endif |
|
|
419 | |
|
|
420 | } |
409 | } |
421 | } |
410 | } |
422 | #endif |
411 | #endif |
423 | |
412 | |
424 | rxvt_ptytty_unix::rxvt_ptytty_unix () |
413 | rxvt_ptytty_unix::rxvt_ptytty_unix () |
425 | { |
414 | { |
426 | pty = tty = -1; |
415 | pty = tty = -1; |
427 | name = 0; |
416 | name = 0; |
428 | #ifndef NO_SETOWNER_TTYDEV |
|
|
429 | saved = false; |
|
|
430 | #endif |
|
|
431 | #if UTMP_SUPPORT |
417 | #if UTMP_SUPPORT |
432 | cmd_pid = 0; |
418 | cmd_pid = 0; |
433 | #endif |
419 | #endif |
434 | } |
420 | } |
435 | |
421 | |
… | |
… | |
630 | close (sv[1]); |
616 | close (sv[1]); |
631 | fcntl (sock_fd, F_SETFD, FD_CLOEXEC); |
617 | fcntl (sock_fd, F_SETFD, FD_CLOEXEC); |
632 | } |
618 | } |
633 | else |
619 | else |
634 | { |
620 | { |
635 | setgid (getegid ()); |
|
|
636 | setuid (geteuid ()); |
|
|
637 | |
|
|
638 | // server, pty-helper |
621 | // server, pty-helper |
639 | sock_fd = sv[1]; |
622 | sock_fd = sv[1]; |
640 | |
623 | |
641 | for (int fd = 0; fd < 1023; fd++) |
624 | for (int fd = 0; fd < 1023; fd++) |
642 | if (fd != sock_fd && fd != 1) |
625 | if (fd != sock_fd) |
643 | close (fd); |
626 | close (fd); |
644 | |
627 | |
645 | serve (); |
628 | serve (); |
646 | _exit (EXIT_SUCCESS); |
629 | _exit (EXIT_SUCCESS); |
647 | } |
630 | } |