On Wed, Mar 13, 2019 at 07:47:08AM -0600, Todd C. Miller wrote: > On Wed, 13 Mar 2019 14:35:06 +0200, Artturi Alm wrote: > > > i don't have issues with tilde when using locally, but i mostly ssh to > > reach cu, and too many times i've forgotten to configure ssh/use -e, > > with this cu(1) becomes safer/easier to use for us with non-english > > keyboard. > > ~tilde is certainly annoying when it's three key presses alone, > > and then you mostly get only one shot at trying.. > > The cu from Taylor UUCP uses -E for this (it uses -e to specify > even parity). If we are going to support this, I think it makes > sense to be as compatible as possible with other systems. > > - todd
Sure, makes sense to me, thanks. On Wed, Mar 13, 2019 at 02:36:03PM +0000, Nicholas Marriott wrote: > Why only % rather than have -e take an argument like ssh? > I'm lazy, and wanted to avoid breaking the "line" in usage().. :] i had also missed escaping the alternative escape character in do_command(), diff with these things fixed below. -Artturi diff --git a/usr.bin/cu/command.c b/usr.bin/cu/command.c index c07fe73aeca..e225fb544be 100644 --- a/usr.bin/cu/command.c +++ b/usr.bin/cu/command.c @@ -30,6 +30,7 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <vis.h> #include "cu.h" @@ -223,6 +224,8 @@ start_record(void) void do_command(char c) { + char esc[4 + 1]; + if (restricted && strchr("CRX$>", c) != NULL) { cu_warnx("~%c command is not allowed in restricted mode", c); return; @@ -266,20 +269,26 @@ do_command(char c) sleep(1); ioctl(line_fd, TIOCCBRK, NULL); break; - case '~': - bufferevent_write(line_ev, "~", 1); + default: + if (c != escape_char) + break; + esc[0] = escape_char; + esc[1] = '\0'; + bufferevent_write(line_ev, esc, 1); break; case '?': + vis(esc, escape_char, VIS_WHITE | VIS_NOSLASH, 0); printf("\r\n" - "~# send break\r\n" - "~$ pipe local command to remote host\r\n" - "~> send file to remote host\r\n" - "~C connect program to remote host\r\n" - "~D de-assert DTR line briefly\r\n" - "~R start recording to file\r\n" - "~S set speed\r\n" - "~X send file with XMODEM\r\n" - "~? get this summary\r\n" + "%s# send break\r\n" + "%s$ pipe local command to remote host\r\n" + "%s> send file to remote host\r\n" + "%sC connect program to remote host\r\n" + "%sD de-assert DTR line briefly\r\n" + "%sR start recording to file\r\n" + "%sS set speed\r\n" + "%sX send file with XMODEM\r\n" + "%s? get this summary\r\n", + esc, esc, esc, esc, esc, esc, esc, esc, esc ); break; } diff --git a/usr.bin/cu/cu.1 b/usr.bin/cu/cu.1 index 104a6ea7893..d52e0b94e5f 100644 --- a/usr.bin/cu/cu.1 +++ b/usr.bin/cu/cu.1 @@ -38,6 +38,7 @@ .Op Fl dr .Op Fl l Ar line .Op Fl s Ar speed | Fl Ar speed +.Op Fl E Ar escape_char .Nm .Op Ar host .Sh DESCRIPTION @@ -92,6 +93,8 @@ and .It Fl s Ar speed | Fl Ar speed Set the speed of the connection. The default is 9600. +.It Fl E Ar escape_char +Specify a escape character to use instead of the default tilde. .El .Pp If diff --git a/usr.bin/cu/cu.c b/usr.bin/cu/cu.c index 03a2df4181f..f269f4a74f3 100644 --- a/usr.bin/cu/cu.c +++ b/usr.bin/cu/cu.c @@ -41,6 +41,7 @@ FILE *record_file; struct termios saved_tio; struct bufferevent *input_ev; struct bufferevent *output_ev; +int escape_char = -1; int is_direct = -1; int restricted = 0; const char *line_path = NULL; @@ -53,7 +54,7 @@ struct event sighup_ev; enum { STATE_NONE, STATE_NEWLINE, - STATE_TILDE + STATE_ESCAPE } last_state = STATE_NEWLINE; __dead void usage(void); @@ -67,8 +68,8 @@ void try_remote(const char *, const char *, const char *); __dead void usage(void) { - fprintf(stderr, "usage: %s [-dr] [-l line] [-s speed | -speed]\n", - __progname); + fprintf(stderr, "usage: %s [-dr] [-l line] [-s speed | -speed]" + " [-E escape_char]\n", __progname); fprintf(stderr, " %s [host]\n", __progname); exit(1); } @@ -101,7 +102,7 @@ main(int argc, char **argv) errx(1, "speed asprintf"); } - while ((opt = getopt(argc, argv, "drl:s:")) != -1) { + while ((opt = getopt(argc, argv, "drl:s:E:")) != -1) { switch (opt) { case 'd': is_direct = 1; @@ -119,6 +120,17 @@ main(int argc, char **argv) if (errstr != NULL) errx(1, "speed is %s: %s", errstr, optarg); break; + case 'E': + if (optarg[0] == '^' && optarg[2] == 0 && + (unsigned char)optarg[1] >= 64 && + (unsigned char)optarg[1] < 128) + escape_char = (unsigned char)optarg[1] & 31; + else if (strlen(optarg) == 1) + escape_char = (unsigned char)optarg[0]; + else + errx(1, "invalid escape character: %s", + optarg); + break; default: usage(); } @@ -155,6 +167,8 @@ main(int argc, char **argv) line_speed = 9600; if (is_direct == -1) is_direct = 0; + if (escape_char == -1) + escape_char = '~'; if (strchr(line_path, '/') == NULL) { if (asprintf(&tmp, "%s%s", _PATH_DEV, line_path) == -1) @@ -308,14 +322,14 @@ stream_read(struct bufferevent *bufev, void *data) last_state = STATE_NEWLINE; break; case STATE_NEWLINE: - if (state_change && *ptr == '~') { - last_state = STATE_TILDE; + if (state_change && *ptr == escape_char) { + last_state = STATE_ESCAPE; continue; } if (*ptr != '\r') last_state = STATE_NONE; break; - case STATE_TILDE: + case STATE_ESCAPE: do_command(*ptr); last_state = STATE_NEWLINE; continue; diff --git a/usr.bin/cu/cu.h b/usr.bin/cu/cu.h index 2a7ca45d414..abcedc6d77a 100644 --- a/usr.bin/cu/cu.h +++ b/usr.bin/cu/cu.h @@ -23,6 +23,7 @@ void do_command(char); /* cu.c */ +extern int escape_char; extern int restricted; extern FILE *record_file; extern struct termios saved_tio;