1 /*
2 dtach - A simple program that emulates the detach feature of screen.
3 Copyright (C) 2004-2016 Ned T. Crigler
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 #include "dtach.h"
20
21 /* The pty struct - The pty information is stored here. */
22 struct pty
23 {
24 /* File descriptor of the pty */
25 int fd;
26 #ifdef BROKEN_MASTER
27 /* File descriptor of the slave side of the pty. For broken systems. */
28 int slave;
29 #endif
30 /* Process id of the child. */
31 pid_t pid;
32 /* The terminal parameters of the pty. Old and new for comparision
33 ** purposes. */
34 struct termios term;
35 /* The current window size of the pty. */
36 struct winsize ws;
37 };
38
39 /* A connected client */
40 struct client
41 {
42 /* The next client in the linked list. */
43 struct client *next;
44 /* The previous client in the linked list. */
45 struct client **pprev;
46 /* File descriptor of the client. */
47 int fd;
48 /* Whether or not the client is attached. */
49 int attached;
50 };
51
52 /* The list of connected clients. */
53 static struct client *clients;
54 /* The pseudo-terminal created for the child process. */
55 static struct pty the_pty;
56 /* The mode of the socket */
57 static mode_t socket_mode;
58
59 #ifndef HAVE_FORKPTY
60 pid_t forkpty(int *amaster, char *name, struct termios *termp,
61 struct winsize *winp);
62 #endif
63
64 /* Unlink the socket */
65 static void
unlink_socket(void)66 unlink_socket(void)
67 {
68 unlink(sockname);
69 }
70
71 /* Check the actual mode of the socket */
72 static void
check_socket_mode(int has_attached_client)73 check_socket_mode(int has_attached_client)
74 {
75 if (has_attached_client && ((socket_mode & 0100) != 0100)) {
76 socket_mode |= 0100;
77 chmod(sockname, socket_mode);
78 } else if (!has_attached_client && ((socket_mode & 0100) == 0100)) {
79 socket_mode &= ~0100;
80 chmod(sockname, socket_mode);
81 }
82 }
83
84 /* Signal */
85 static RETSIGTYPE
die(int sig)86 die(int sig)
87 {
88 /* Well, the child died. */
89 if (sig == SIGCHLD)
90 {
91 #ifdef BROKEN_MASTER
92 /* Damn you Solaris! */
93 close(the_pty.fd);
94 #endif
95 return;
96 }
97 exit(1);
98 }
99
100 /* Sets a file descriptor to non-blocking mode. */
101 static int
setnonblocking(int fd)102 setnonblocking(int fd)
103 {
104 int flags;
105
106 #if defined(O_NONBLOCK)
107 flags = fcntl(fd, F_GETFL);
108 if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0)
109 return -1;
110 return 0;
111 #elif defined(FIONBIO)
112 flags = 1;
113 if (ioctl(fd, FIONBIO, &flags) < 0)
114 return -1;
115 return 0;
116 #else
117 #warning Do not know how to set non-blocking mode.
118 return 0;
119 #endif
120 }
121
122 /* Initialize the pty structure. */
123 static int
init_pty(char ** argv,int statusfd)124 init_pty(char **argv, int statusfd)
125 {
126 /* Use the original terminal's settings. We don't have to set the
127 ** window size here, because the attacher will send it in a packet. */
128 the_pty.term = orig_term;
129 memset(&the_pty.ws, 0, sizeof(struct winsize));
130
131 /* Create the pty process */
132 if (!dont_have_tty)
133 the_pty.pid = forkpty(&the_pty.fd, NULL, &the_pty.term, NULL);
134 else
135 the_pty.pid = forkpty(&the_pty.fd, NULL, NULL, NULL);
136 if (the_pty.pid < 0)
137 return -1;
138 else if (the_pty.pid == 0)
139 {
140 /* Child.. Execute the program. */
141 execvp(*argv, argv);
142
143 /* Report the error to statusfd if we can, or stdout if we
144 ** can't. */
145 if (statusfd != -1)
146 dup2(statusfd, 1);
147 else
148 printf(EOS "\r\n");
149
150 printf("%s: could not execute %s: %s\r\n", progname,
151 *argv, strerror(errno));
152 fflush(stdout);
153 _exit(127);
154 }
155 /* Parent.. Finish up and return */
156 #ifdef BROKEN_MASTER
157 {
158 char *buf;
159
160 buf = ptsname(the_pty.fd);
161 the_pty.slave = open(buf, O_RDWR|O_NOCTTY);
162 }
163 #endif
164 return 0;
165 }
166
167 /* Send a signal to the slave side of a pseudo-terminal. */
168 static void
killpty(struct pty * pty,int sig)169 killpty(struct pty *pty, int sig)
170 {
171 pid_t pgrp = -1;
172
173 #ifdef TIOCSIGNAL
174 if (ioctl(pty->fd, TIOCSIGNAL, sig) >= 0)
175 return;
176 #endif
177 #ifdef TIOCSIG
178 if (ioctl(pty->fd, TIOCSIG, sig) >= 0)
179 return;
180 #endif
181 #ifdef TIOCGPGRP
182 #ifdef BROKEN_MASTER
183 if (ioctl(pty->slave, TIOCGPGRP, &pgrp) >= 0 && pgrp != -1 &&
184 kill(-pgrp, sig) >= 0)
185 return;
186 #endif
187 if (ioctl(pty->fd, TIOCGPGRP, &pgrp) >= 0 && pgrp != -1 &&
188 kill(-pgrp, sig) >= 0)
189 return;
190 #endif
191
192 /* Fallback using the child's pid. */
193 kill(-pty->pid, sig);
194 }
195
196 /* Creates a new unix domain socket. */
197 static int
create_socket(char * name)198 create_socket(char *name)
199 {
200 int s;
201 struct sockaddr_un sockun;
202
203 if (strlen(name) > sizeof(sockun.sun_path) - 1)
204 {
205 errno = ENAMETOOLONG;
206 return -1;
207 }
208
209 s = socket(PF_UNIX, SOCK_STREAM, 0);
210 if (s < 0)
211 return -1;
212 sockun.sun_family = AF_UNIX;
213 strcpy(sockun.sun_path, name);
214 if (bind(s, (struct sockaddr*)&sockun, sizeof(sockun)) < 0)
215 {
216 close(s);
217 return -1;
218 }
219 if (listen(s, 128) < 0)
220 {
221 close(s);
222 return -1;
223 }
224 if (setnonblocking(s) < 0)
225 {
226 close(s);
227 return -1;
228 }
229 /* chmod it to prevent any suprises */
230 socket_mode = 0600;
231 if (chmod(name, socket_mode) < 0)
232 {
233 close(s);
234 return -1;
235 }
236 return s;
237 }
238
239 /* Update the modes on the socket. */
240 static void
update_socket_modes(int exec)241 update_socket_modes(int exec)
242 {
243 struct stat st;
244 mode_t newmode;
245
246 if (stat(sockname, &st) < 0)
247 return;
248
249 if (exec)
250 newmode = st.st_mode | S_IXUSR;
251 else
252 newmode = st.st_mode & ~S_IXUSR;
253
254 if (st.st_mode != newmode)
255 chmod(sockname, newmode);
256 }
257
258 /* Process activity on the pty - Input and terminal changes are sent out to
259 ** the attached clients. If the pty goes away, we die. */
260 static void
pty_activity(int s)261 pty_activity(int s)
262 {
263 unsigned char buf[BUFSIZE];
264 ssize_t len;
265 struct client *p;
266 fd_set readfds, writefds;
267 int highest_fd, nclients;
268
269 /* Read the pty activity */
270 len = read(the_pty.fd, buf, sizeof(buf));
271
272 /* Error -> die */
273 if (len <= 0)
274 exit(1);
275
276 #ifdef BROKEN_MASTER
277 /* Get the current terminal settings. */
278 if (tcgetattr(the_pty.slave, &the_pty.term) < 0)
279 exit(1);
280 #else
281 /* Get the current terminal settings. */
282 if (tcgetattr(the_pty.fd, &the_pty.term) < 0)
283 exit(1);
284 #endif
285
286 top:
287 /*
288 ** Wait until at least one client is writable. Also wait on the control
289 ** socket in case a new client tries to connect.
290 */
291 FD_ZERO(&readfds);
292 FD_ZERO(&writefds);
293 FD_SET(s, &readfds);
294 highest_fd = s;
295 for (p = clients, nclients = 0; p; p = p->next)
296 {
297 if (!p->attached)
298 continue;
299 FD_SET(p->fd, &writefds);
300 if (p->fd > highest_fd)
301 highest_fd = p->fd;
302 nclients++;
303 }
304 if (nclients == 0)
305 return;
306 if (select(highest_fd + 1, &readfds, &writefds, NULL, NULL) < 0)
307 return;
308
309 /* Send the data out to the clients. */
310 for (p = clients, nclients = 0; p; p = p->next)
311 {
312 ssize_t written;
313
314 if (!FD_ISSET(p->fd, &writefds))
315 continue;
316
317 written = 0;
318 while (written < len)
319 {
320 ssize_t n = write(p->fd, buf + written, len - written);
321
322 if (n > 0)
323 {
324 written += n;
325 continue;
326 }
327 else if (n < 0 && errno == EINTR)
328 continue;
329 else if (n < 0 && errno != EAGAIN)
330 nclients = -1;
331 break;
332 }
333 if (nclients != -1 && written == len)
334 nclients++;
335 }
336
337 /* Try again if nothing happened. */
338 if (!FD_ISSET(s, &readfds) && nclients == 0)
339 goto top;
340 }
341
342 /* Process activity on the control socket */
343 static void
control_activity(int s)344 control_activity(int s)
345 {
346 int fd;
347 struct client *p;
348
349 /* Accept the new client and link it in. */
350 fd = accept(s, NULL, NULL);
351 if (fd < 0)
352 return;
353 else if (setnonblocking(fd) < 0)
354 {
355 close(fd);
356 return;
357 }
358
359 /* Link it in. */
360 p = malloc(sizeof(struct client));
361 p->fd = fd;
362 p->attached = 0;
363 p->pprev = &clients;
364 p->next = *(p->pprev);
365 if (p->next)
366 p->next->pprev = &p->next;
367 *(p->pprev) = p;
368 }
369
370 /* Process activity from a client. */
371 static void
client_activity(struct client * p)372 client_activity(struct client *p)
373 {
374 ssize_t len;
375 struct packet pkt;
376
377 /* Read the activity. */
378 len = read(p->fd, &pkt, sizeof(struct packet));
379 if (len < 0 && (errno == EAGAIN || errno == EINTR))
380 return;
381
382 /* Close the client on an error. */
383 if (len <= 0)
384 {
385 close(p->fd);
386 if (p->next)
387 p->next->pprev = p->pprev;
388 *(p->pprev) = p->next;
389 free(p);
390 return;
391 }
392
393 /* Push out data to the program. */
394 if (pkt.type == MSG_PUSH)
395 {
396 if (pkt.len <= sizeof(pkt.u.buf))
397 write(the_pty.fd, pkt.u.buf, pkt.len);
398 }
399
400 /* Attach or detach from the program. */
401 else if (pkt.type == MSG_ATTACH)
402 p->attached = 1;
403 else if (pkt.type == MSG_DETACH)
404 p->attached = 0;
405
406 /* Window size change request, without a forced redraw. */
407 else if (pkt.type == MSG_WINCH)
408 {
409 the_pty.ws = pkt.u.ws;
410 ioctl(the_pty.fd, TIOCSWINSZ, &the_pty.ws);
411 }
412
413 /* Force a redraw using a particular method. */
414 else if (pkt.type == MSG_REDRAW)
415 {
416 int method = pkt.len;
417
418 /* If the client didn't specify a particular method, use
419 ** whatever we had on startup. */
420 if (method == REDRAW_UNSPEC)
421 method = redraw_method;
422 if (method == REDRAW_NONE)
423 return;
424
425 /* Set the window size. */
426 the_pty.ws = pkt.u.ws;
427 ioctl(the_pty.fd, TIOCSWINSZ, &the_pty.ws);
428
429 /* Send a ^L character if the terminal is in no-echo and
430 ** character-at-a-time mode. */
431 if (method == REDRAW_CTRL_L)
432 {
433 char c = '\f';
434
435 if (((the_pty.term.c_lflag & (ECHO|ICANON)) == 0) &&
436 (the_pty.term.c_cc[VMIN] == 1))
437 {
438 write(the_pty.fd, &c, 1);
439 }
440 }
441 /* Send a WINCH signal to the program. */
442 else if (method == REDRAW_WINCH)
443 {
444 killpty(&the_pty, SIGWINCH);
445 }
446 }
447 }
448
449 /* The master process - It watches over the pty process and the attached */
450 /* clients. */
451 static void
master_process(int s,char ** argv,int waitattach,int statusfd)452 master_process(int s, char **argv, int waitattach, int statusfd)
453 {
454 struct client *p, *next;
455 fd_set readfds;
456 int highest_fd;
457 int nullfd;
458
459 int has_attached_client = 0;
460
461 /* Okay, disassociate ourselves from the original terminal, as we
462 ** don't care what happens to it. */
463 setsid();
464
465 /* Set a trap to unlink the socket when we die. */
466 atexit(unlink_socket);
467
468 /* Create a pty in which the process is running. */
469 signal(SIGCHLD, die);
470 if (init_pty(argv, statusfd) < 0)
471 {
472 if (statusfd != -1)
473 dup2(statusfd, 1);
474 if (errno == ENOENT)
475 printf("%s: Could not find a pty.\n", progname);
476 else
477 printf("%s: init_pty: %s\n", progname, strerror(errno));
478 exit(1);
479 }
480
481 /* Set up some signals. */
482 signal(SIGPIPE, SIG_IGN);
483 signal(SIGXFSZ, SIG_IGN);
484 signal(SIGHUP, SIG_IGN);
485 signal(SIGTTIN, SIG_IGN);
486 signal(SIGTTOU, SIG_IGN);
487 signal(SIGINT, die);
488 signal(SIGTERM, die);
489
490 /* Close statusfd, since we don't need it anymore. */
491 if (statusfd != -1)
492 close(statusfd);
493
494 /* Make sure stdin/stdout/stderr point to /dev/null. We are now a
495 ** daemon. */
496 nullfd = open("/dev/null", O_RDWR);
497 dup2(nullfd, 0);
498 dup2(nullfd, 1);
499 dup2(nullfd, 2);
500 if (nullfd > 2)
501 close(nullfd);
502
503 /* Loop forever. */
504 while (1)
505 {
506 int new_has_attached_client = 0;
507
508 /* Re-initialize the file descriptor set for select. */
509 FD_ZERO(&readfds);
510 FD_SET(s, &readfds);
511 highest_fd = s;
512
513 /*
514 ** When waitattach is set, wait until the client attaches
515 ** before trying to read from the pty.
516 */
517 if (waitattach)
518 {
519 if (clients && clients->attached)
520 waitattach = 0;
521 }
522 else
523 {
524 FD_SET(the_pty.fd, &readfds);
525 if (the_pty.fd > highest_fd)
526 highest_fd = the_pty.fd;
527 }
528
529 for (p = clients; p; p = p->next)
530 {
531 FD_SET(p->fd, &readfds);
532 if (p->fd > highest_fd)
533 highest_fd = p->fd;
534
535 if (p->attached)
536 new_has_attached_client = 1;
537 }
538
539 /* chmod the socket if necessary. */
540 if (has_attached_client != new_has_attached_client)
541 {
542 update_socket_modes(new_has_attached_client);
543 has_attached_client = new_has_attached_client;
544 }
545
546 /* Wait for something to happen. */
547 if (select(highest_fd + 1, &readfds, NULL, NULL, NULL) < 0)
548 {
549 if (errno == EINTR || errno == EAGAIN)
550 continue;
551 exit(1);
552 }
553
554 /* New client? */
555 if (FD_ISSET(s, &readfds))
556 control_activity(s);
557 /* Activity on a client? */
558 for (p = clients; p; p = next)
559 {
560 next = p->next;
561 if (FD_ISSET(p->fd, &readfds))
562 client_activity(p);
563 }
564 /* pty activity? */
565 if (FD_ISSET(the_pty.fd, &readfds))
566 pty_activity(s);
567 }
568 }
569
570 int
master_main(char ** argv,int waitattach,int dontfork)571 master_main(char **argv, int waitattach, int dontfork)
572 {
573 int fd[2] = {-1, -1};
574 int s;
575 pid_t pid;
576
577 /* Use a default redraw method if one hasn't been specified yet. */
578 if (redraw_method == REDRAW_UNSPEC)
579 redraw_method = REDRAW_CTRL_L;
580
581 /* Create the unix domain socket. */
582 s = create_socket(sockname);
583 if (s < 0 && errno == ENAMETOOLONG)
584 {
585 char *slash = strrchr(sockname, '/');
586
587 /* Try to shorten the socket's path name by using chdir. */
588 if (slash)
589 {
590 int dirfd = open(".", O_RDONLY);
591
592 if (dirfd >= 0)
593 {
594 *slash = '\0';
595 if (chdir(sockname) >= 0)
596 {
597 s = create_socket(slash + 1);
598 fchdir(dirfd);
599 }
600 *slash = '/';
601 close(dirfd);
602 }
603 }
604 }
605 if (s < 0)
606 {
607 printf("%s: %s: %s\n", progname, sockname, strerror(errno));
608 return 1;
609 }
610
611 #if defined(F_SETFD) && defined(FD_CLOEXEC)
612 fcntl(s, F_SETFD, FD_CLOEXEC);
613
614 /* If FD_CLOEXEC works, create a pipe and use it to report any errors
615 ** that occur while trying to execute the program. */
616 if (dontfork)
617 {
618 fd[1] = dup(2);
619 if (fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0)
620 {
621 close(fd[1]);
622 fd[1] = -1;
623 }
624 }
625 else if (pipe(fd) >= 0)
626 {
627 if (fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0 ||
628 fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0)
629 {
630 close(fd[0]);
631 close(fd[1]);
632 fd[0] = fd[1] = -1;
633 }
634 }
635 #endif
636
637 if (dontfork)
638 {
639 master_process(s, argv, waitattach, fd[1]);
640 return 0;
641 }
642
643 /* Fork off so we can daemonize and such */
644 pid = fork();
645 if (pid < 0)
646 {
647 printf("%s: fork: %s\n", progname, strerror(errno));
648 unlink_socket();
649 return 1;
650 }
651 else if (pid == 0)
652 {
653 /* Child - this becomes the master */
654 if (fd[0] != -1)
655 close(fd[0]);
656 master_process(s, argv, waitattach, fd[1]);
657 return 0;
658 }
659 /* Parent - just return. */
660
661 #if defined(F_SETFD) && defined(FD_CLOEXEC)
662 /* Check if an error occurred while trying to execute the program. */
663 if (fd[0] != -1)
664 {
665 char buf[1024];
666 ssize_t len;
667
668 close(fd[1]);
669 len = read(fd[0], buf, sizeof(buf));
670 if (len > 0)
671 {
672 write(2, buf, len);
673 kill(pid, SIGTERM);
674 return 1;
675 }
676 close(fd[0]);
677 }
678 #endif
679 close(s);
680 return 0;
681 }
682
683 /* BSDish functions for systems that don't have them. */
684 #ifndef HAVE_OPENPTY
685 #define HAVE_OPENPTY
686 /* openpty: Use /dev/ptmx and Unix98 if we have it. */
687 #if defined(HAVE_PTSNAME) && defined(HAVE_GRANTPT) && defined(HAVE_UNLOCKPT)
688 int
openpty(int * amaster,int * aslave,char * name,struct termios * termp,struct winsize * winp)689 openpty(int *amaster, int *aslave, char *name, struct termios *termp,
690 struct winsize *winp)
691 {
692 int master, slave;
693 char *buf;
694
695 #ifdef _AIX
696 master = open("/dev/ptc", O_RDWR|O_NOCTTY);
697 if (master < 0)
698 return -1;
699 buf = ttyname(master);
700 if (!buf)
701 return -1;
702
703 slave = open(buf, O_RDWR|O_NOCTTY);
704 if (slave < 0)
705 return -1;
706 #else
707 master = open("/dev/ptmx", O_RDWR);
708 if (master < 0)
709 return -1;
710 if (grantpt(master) < 0)
711 return -1;
712 if (unlockpt(master) < 0)
713 return -1;
714 buf = ptsname(master);
715 if (!buf)
716 return -1;
717
718 slave = open(buf, O_RDWR|O_NOCTTY);
719 if (slave < 0)
720 return -1;
721
722 #ifdef I_PUSH
723 if (ioctl(slave, I_PUSH, "ptem") < 0)
724 return -1;
725 if (ioctl(slave, I_PUSH, "ldterm") < 0)
726 return -1;
727 #endif
728 #endif
729
730 *amaster = master;
731 *aslave = slave;
732 if (name)
733 strcpy(name, buf);
734 if (termp)
735 tcsetattr(slave, TCSAFLUSH, termp);
736 if (winp)
737 ioctl(slave, TIOCSWINSZ, winp);
738 return 0;
739 }
740 #else
741 #error Do not know how to define openpty.
742 #endif
743 #endif
744
745 #ifndef HAVE_FORKPTY
746 #if defined(HAVE_OPENPTY)
747 pid_t
forkpty(int * amaster,char * name,struct termios * termp,struct winsize * winp)748 forkpty(int *amaster, char *name, struct termios *termp,
749 struct winsize *winp)
750 {
751 pid_t pid;
752 int master, slave;
753
754 if (openpty(&master, &slave, name, termp, winp) < 0)
755 return -1;
756 *amaster = master;
757
758 /* Fork off... */
759 pid = fork();
760 if (pid < 0)
761 return -1;
762 else if (pid == 0)
763 {
764 char *buf;
765 int fd;
766
767 setsid();
768 #ifdef TIOCSCTTY
769 buf = NULL;
770 if (ioctl(slave, TIOCSCTTY, NULL) < 0)
771 _exit(1);
772 #elif defined(_AIX)
773 fd = open("/dev/tty", O_RDWR|O_NOCTTY);
774 if (fd >= 0)
775 {
776 ioctl(fd, TIOCNOTTY, NULL);
777 close(fd);
778 }
779
780 buf = ttyname(master);
781 fd = open(buf, O_RDWR);
782 close(fd);
783
784 fd = open("/dev/tty", O_WRONLY);
785 if (fd < 0)
786 _exit(1);
787 close(fd);
788
789 if (termp && tcsetattr(slave, TCSAFLUSH, termp) == -1)
790 _exit(1);
791 if (ioctl(slave, TIOCSWINSZ, winp) == -1)
792 _exit(1);
793 #else
794 buf = ptsname(master);
795 fd = open(buf, O_RDWR);
796 close(fd);
797 #endif
798 dup2(slave, 0);
799 dup2(slave, 1);
800 dup2(slave, 2);
801
802 if (slave > 2)
803 close(slave);
804 close(master);
805 return 0;
806 }
807 else
808 {
809 close(slave);
810 return pid;
811 }
812 }
813 #else
814 #error Do not know how to define forkpty.
815 #endif
816 #endif
817