summaryrefslogtreecommitdiffhomepage
path: root/cli-chansession.c
diff options
context:
space:
mode:
Diffstat (limited to 'cli-chansession.c')
-rw-r--r--cli-chansession.c63
1 files changed, 61 insertions, 2 deletions
diff --git a/cli-chansession.c b/cli-chansession.c
index 126c32f..65d1f4f 100644
--- a/cli-chansession.c
+++ b/cli-chansession.c
@@ -38,9 +38,10 @@
static void cli_closechansess(struct Channel *channel);
static int cli_initchansess(struct Channel *channel);
static void cli_chansessreq(struct Channel *channel);
-
static void send_chansess_pty_req(struct Channel *channel);
static void send_chansess_shell_req(struct Channel *channel);
+static void cli_escape_handler(struct Channel *channel, unsigned char* buf, int *len);
+
static void cli_tty_setup();
@@ -374,7 +375,9 @@ static int cli_initchansess(struct Channel *channel) {
if (cli_opts.wantpty) {
cli_tty_setup();
- }
+ channel->read_mangler = cli_escape_handler;
+ cli_ses.last_char = '\r';
+ }
return 0; /* Success */
}
@@ -429,3 +432,59 @@ void cli_send_chansess_request() {
TRACE(("leave cli_send_chansess_request"))
}
+
+// returns 1 if the character should be consumed, 0 to pass through
+static int
+do_escape(unsigned char c) {
+ switch (c) {
+ case '.':
+ dropbear_exit("Terminated");
+ return 1;
+ break;
+ case 0x1a:
+ // ctrl-z
+ cli_tty_cleanup();
+ kill(getpid(), SIGTSTP);
+ // after continuation
+ cli_tty_setup();
+ cli_ses.winchange = 1;
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+static
+void cli_escape_handler(struct Channel *channel, unsigned char* buf, int *len) {
+ char c;
+ int skip_char = 0;
+
+ // only handle escape characters if they are read one at a time. simplifies
+ // the code and avoids nasty people putting ~. at the start of a line to paste
+ if (*len != 1) {
+ cli_ses.last_char = 0x0;
+ return;
+ }
+
+ c = buf[0];
+
+ if (cli_ses.last_char == DROPBEAR_ESCAPE_CHAR) {
+ skip_char = do_escape(c);
+ cli_ses.last_char = 0x0;
+ } else {
+ if (c == DROPBEAR_ESCAPE_CHAR) {
+ if (cli_ses.last_char == '\r') {
+ cli_ses.last_char = DROPBEAR_ESCAPE_CHAR;
+ skip_char = 1;
+ } else {
+ cli_ses.last_char = 0x0;
+ }
+ } else {
+ cli_ses.last_char = c;
+ }
+ }
+
+ if (skip_char) {
+ *len = 0;
+ }
+}