summaryrefslogtreecommitdiffhomepage
path: root/cli-chansession.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2013-03-23 23:16:06 +0800
committerMatt Johnston <matt@ucc.asn.au>2013-03-23 23:16:06 +0800
commit5996c3824c52425c2d4f3d7cb69f0c9fa81a33b8 (patch)
treee3b73be4387ad1f8b8e23b6b4d0d6a81081a36c6 /cli-chansession.c
parentc172fb3b326ec796a1e81656548653f188a8d62c (diff)
Add ~. and ~^Z handling to exit/suspend dbclient
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;
+ }
+}