diff options
Diffstat (limited to 'mux.c')
-rw-r--r-- | mux.c | 60 |
1 files changed, 48 insertions, 12 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mux.c,v 1.27 2011/05/06 21:34:32 djm Exp $ */ | 1 | /* $OpenBSD: mux.c,v 1.28 2011/05/08 12:52:01 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -153,6 +153,7 @@ struct mux_master_state { | |||
153 | #define MUX_S_ALIVE 0x80000005 | 153 | #define MUX_S_ALIVE 0x80000005 |
154 | #define MUX_S_SESSION_OPENED 0x80000006 | 154 | #define MUX_S_SESSION_OPENED 0x80000006 |
155 | #define MUX_S_REMOTE_PORT 0x80000007 | 155 | #define MUX_S_REMOTE_PORT 0x80000007 |
156 | #define MUX_S_TTY_ALLOC_FAIL 0x80000008 | ||
156 | 157 | ||
157 | /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ | 158 | /* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ |
158 | #define MUX_FWD_LOCAL 1 | 159 | #define MUX_FWD_LOCAL 1 |
@@ -1054,6 +1055,27 @@ mux_exit_message(Channel *c, int exitval) | |||
1054 | buffer_free(&m); | 1055 | buffer_free(&m); |
1055 | } | 1056 | } |
1056 | 1057 | ||
1058 | void | ||
1059 | mux_tty_alloc_failed(Channel *c) | ||
1060 | { | ||
1061 | Buffer m; | ||
1062 | Channel *mux_chan; | ||
1063 | |||
1064 | debug3("%s: channel %d: TTY alloc failed", __func__, c->self); | ||
1065 | |||
1066 | if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL) | ||
1067 | fatal("%s: channel %d missing mux channel %d", | ||
1068 | __func__, c->self, c->ctl_chan); | ||
1069 | |||
1070 | /* Append exit message packet to control socket output queue */ | ||
1071 | buffer_init(&m); | ||
1072 | buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL); | ||
1073 | buffer_put_int(&m, c->self); | ||
1074 | |||
1075 | buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m)); | ||
1076 | buffer_free(&m); | ||
1077 | } | ||
1078 | |||
1057 | /* Prepare a mux master to listen on a Unix domain socket. */ | 1079 | /* Prepare a mux master to listen on a Unix domain socket. */ |
1058 | void | 1080 | void |
1059 | muxserver_listen(void) | 1081 | muxserver_listen(void) |
@@ -1612,7 +1634,7 @@ mux_client_request_session(int fd) | |||
1612 | char *e, *term; | 1634 | char *e, *term; |
1613 | u_int i, rid, sid, esid, exitval, type, exitval_seen; | 1635 | u_int i, rid, sid, esid, exitval, type, exitval_seen; |
1614 | extern char **environ; | 1636 | extern char **environ; |
1615 | int devnull; | 1637 | int devnull, rawmode; |
1616 | 1638 | ||
1617 | debug3("%s: entering", __func__); | 1639 | debug3("%s: entering", __func__); |
1618 | 1640 | ||
@@ -1708,6 +1730,7 @@ mux_client_request_session(int fd) | |||
1708 | signal(SIGTERM, control_client_sighandler); | 1730 | signal(SIGTERM, control_client_sighandler); |
1709 | signal(SIGWINCH, control_client_sigrelay); | 1731 | signal(SIGWINCH, control_client_sigrelay); |
1710 | 1732 | ||
1733 | rawmode = tty_flag; | ||
1711 | if (tty_flag) | 1734 | if (tty_flag) |
1712 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 1735 | enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); |
1713 | 1736 | ||
@@ -1723,22 +1746,35 @@ mux_client_request_session(int fd) | |||
1723 | if (mux_client_read_packet(fd, &m) != 0) | 1746 | if (mux_client_read_packet(fd, &m) != 0) |
1724 | break; | 1747 | break; |
1725 | type = buffer_get_int(&m); | 1748 | type = buffer_get_int(&m); |
1726 | if (type != MUX_S_EXIT_MESSAGE) { | 1749 | switch (type) { |
1750 | case MUX_S_TTY_ALLOC_FAIL: | ||
1751 | if ((esid = buffer_get_int(&m)) != sid) | ||
1752 | fatal("%s: tty alloc fail on unknown session: " | ||
1753 | "my id %u theirs %u", | ||
1754 | __func__, sid, esid); | ||
1755 | leave_raw_mode(options.request_tty == | ||
1756 | REQUEST_TTY_FORCE); | ||
1757 | rawmode = 0; | ||
1758 | continue; | ||
1759 | case MUX_S_EXIT_MESSAGE: | ||
1760 | if ((esid = buffer_get_int(&m)) != sid) | ||
1761 | fatal("%s: exit on unknown session: " | ||
1762 | "my id %u theirs %u", | ||
1763 | __func__, sid, esid); | ||
1764 | if (exitval_seen) | ||
1765 | fatal("%s: exitval sent twice", __func__); | ||
1766 | exitval = buffer_get_int(&m); | ||
1767 | exitval_seen = 1; | ||
1768 | continue; | ||
1769 | default: | ||
1727 | e = buffer_get_string(&m, NULL); | 1770 | e = buffer_get_string(&m, NULL); |
1728 | fatal("%s: master returned error: %s", __func__, e); | 1771 | fatal("%s: master returned error: %s", __func__, e); |
1729 | } | 1772 | } |
1730 | if ((esid = buffer_get_int(&m)) != sid) | ||
1731 | fatal("%s: exit on unknown session: my id %u theirs %u", | ||
1732 | __func__, sid, esid); | ||
1733 | debug("%s: master session id: %u", __func__, sid); | ||
1734 | if (exitval_seen) | ||
1735 | fatal("%s: exitval sent twice", __func__); | ||
1736 | exitval = buffer_get_int(&m); | ||
1737 | exitval_seen = 1; | ||
1738 | } | 1773 | } |
1739 | 1774 | ||
1740 | close(fd); | 1775 | close(fd); |
1741 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | 1776 | if (rawmode) |
1777 | leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); | ||
1742 | 1778 | ||
1743 | if (muxclient_terminate) { | 1779 | if (muxclient_terminate) { |
1744 | debug2("Exiting on signal %d", muxclient_terminate); | 1780 | debug2("Exiting on signal %d", muxclient_terminate); |