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;