diff options
author | Matt Johnston <matt@ucc.asn.au> | 2013-03-23 23:16:06 +0800 |
---|---|---|
committer | Matt Johnston <matt@ucc.asn.au> | 2013-03-23 23:16:06 +0800 |
commit | 5996c3824c52425c2d4f3d7cb69f0c9fa81a33b8 (patch) | |
tree | e3b73be4387ad1f8b8e23b6b4d0d6a81081a36c6 /cli-chansession.c | |
parent | c172fb3b326ec796a1e81656548653f188a8d62c (diff) |
Add ~. and ~^Z handling to exit/suspend dbclient
Diffstat (limited to 'cli-chansession.c')
-rw-r--r-- | cli-chansession.c | 63 |
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; + } +} |