From e6ffbd9058f4a7930f3fdd0f1f8cca0df11c9e5e Mon Sep 17 00:00:00 2001 From: pnrhub <55432384+pnrhub@users.noreply.github.com> Date: Sat, 16 Sep 2023 12:17:38 +0200 Subject: [PATCH 01/15] Add xmodem and ymodem file send support (#208) * Add xmodem and ymodem file send support --------- Co-authored-by: pnr --- README.md | 2 + man/tio.1.in | 4 + src/meson.build | 1 + src/misc.h | 3 + src/tty.c | 53 +++++++++++- src/xymodem.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 src/xymodem.c diff --git a/README.md b/README.md index 7f57ab7..dc70429 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,8 @@ ctrl-t ? to list the available key commands. [20:19:12.041] ctrl-t t Toggle line timestamp mode [20:19:12.041] ctrl-t U Toggle conversion to uppercase [20:19:12.041] ctrl-t v Show version +[20:19:12.041] ctrl-t x Send file using the XMODEM protocol +[20:19:12.041] ctrl-t y Send file using the YMODEM protocol [20:19:12.041] ctrl-t ctrl-t Send ctrl-t character ``` diff --git a/man/tio.1.in b/man/tio.1.in index 6b75422..b9cdf1a 100644 --- a/man/tio.1.in +++ b/man/tio.1.in @@ -323,6 +323,10 @@ Toggle line timestamp mode Toggle conversion to uppercase on output .IP "\fBctrl-t v" Show version +.IP "\fBctrl-t x" +Send a file using the XMODEM protocol (prompts for file name) +.IP "\fBctrl-t y" +Send a file using the YMODEM protocol (prompts for file name) .IP "\fBctrl-t ctrl-t" Send ctrl-t character diff --git a/src/meson.build b/src/meson.build index cec9429..73af4c7 100644 --- a/src/meson.build +++ b/src/meson.build @@ -18,6 +18,7 @@ tio_sources = [ 'rs485.c', 'timestamp.c', 'alert.c' + 'xymodem.c' ] tio_dep = [ diff --git a/src/misc.h b/src/misc.h index 6fe5368..d9a8e2b 100644 --- a/src/misc.h +++ b/src/misc.h @@ -29,3 +29,6 @@ long string_to_long(char *string); int ctrl_key_code(unsigned char key); void alert_connect(void); void alert_disconnect(void); + +extern char key_hit; +int xymodem_send(int sio, const char *filename, char mode); diff --git a/src/tty.c b/src/tty.c index d6a38ed..0f57d75 100644 --- a/src/tty.c +++ b/src/tty.c @@ -105,6 +105,8 @@ #define KEY_T 0x74 #define KEY_U 0x55 #define KEY_V 0x76 +#define KEY_X 0x78 +#define KEY_Y 0x79 #define KEY_Z 0x7a enum line_mode_t @@ -133,6 +135,8 @@ bool map_i_nl_cr = false; bool map_i_cr_nl = false; bool map_ign_cr = false; +char key_hit = 0xff; + static struct termios tio, tio_old, stdout_new, stdout_old, stdin_new, stdin_old; static unsigned long rx_total = 0, tx_total = 0; static bool connected = false; @@ -321,6 +325,14 @@ void *tty_stdin_input_thread(void *arg) // Process quit and flush key command for (int i = 0; i 0) { + if (*p == 0x08 || *p == 0x7f) { + if (p > line ) { + write(STDOUT_FILENO, "\b \b", 3); + p--; + } + continue; + } + write(STDOUT_FILENO, p, 1); + if (*p == '\r') break; + p++; + } + } + *p = 0; + return (p - line); +} + void handle_command_sequence(char input_char, char *output_char, bool *forward) { char unused_char; @@ -562,7 +600,9 @@ void handle_command_sequence(char input_char, char *output_char, bool *forward) tio_printf(" ctrl-%c t Toggle line timestamp mode", option.prefix_key); tio_printf(" ctrl-%c U Toggle conversion to uppercase on output", option.prefix_key); tio_printf(" ctrl-%c v Show version", option.prefix_key); - tio_printf(" ctrl-%c ctrl-%c Send ctrl-%c character", option.prefix_key, option.prefix_key, option.prefix_key); + tio_printf(" ctrl-%c x Send file via Xmodem-1K", option.prefix_key); + tio_printf(" ctrl-%c y Send file via Ymodem", option.prefix_key); + tio_printf(" ctrl-%c ctrl-%c Send ctrl-%c character", option.prefix_key, option.prefix_key, option.prefix_key); break; case KEY_SHIFT_L: @@ -721,6 +761,17 @@ void handle_command_sequence(char input_char, char *output_char, bool *forward) tio_printf("tio v%s", VERSION); break; + case KEY_X: + case KEY_Y: + tio_printf("Send file with %cMODEM", toupper(input_char)); + tio_printf_raw("Enter file name: "); + if (tio_readln()) { + tio_printf("Sending file '%s'", line); + tio_printf("Press any key to abort transfer"); + tio_printf("%s", xymodem_send(fd, line, input_char) < 0 ? "Aborted" : "Done"); + } + break; + case KEY_Z: tio_printf_array(random_array); break; diff --git a/src/xymodem.c b/src/xymodem.c new file mode 100644 index 0000000..1dbeddc --- /dev/null +++ b/src/xymodem.c @@ -0,0 +1,223 @@ +/* + * Minimalistic implementation of the xmodem-1k and ymodem sender protocol. + * https://en.wikipedia.org/wiki/XMODEM + * https://en.wikipedia.org/wiki/YMODEM + * + * SPDX-License-Identifier: GPL-2.0-or-later OR MIT-0 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "misc.h" + +#define STX 0x02 +#define ACK 0x06 +#define NAK 0x15 +#define CAN 0x18 +#define EOT "\004" + +#define OK 0 +#define ERR (-1) + +#define min(a, b) ((a) < (b) ? (a) : (b)) + +struct xpacket { + uint8_t type; + uint8_t seq; + uint8_t nseq; + uint8_t data[1024]; + uint8_t crc_hi; + uint8_t crc_lo; +} __attribute__((packed)); + +/* See https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks */ +static uint16_t crc16(const uint8_t *data, uint16_t size) +{ + uint16_t crc, s; + + for (crc = 0; size > 0; size--) { + s = *data++ ^ (crc >> 8); + s ^= (s >> 4); + crc = (crc << 8) ^ s ^ (s << 5) ^ (s << 12); + } + return crc; +} + +static int xmodem(int sio, const void *data, size_t len, int seq) +{ + struct xpacket packet; + const uint8_t *buf = data; + char resp = 0; + int rc, crc; + + /* Drain pending characters from serial line. Insist on the + * last drained character being 'C'. + */ + while(1) { + if (key_hit) + return -1; + if (read(sio, &resp, 1) < 0) { + if (errno == EWOULDBLOCK) { + if (resp == 'C') break; + if (resp == CAN) return ERR; + usleep(50000); + continue; + } + perror("Read sync from serial failed"); + return ERR; + } + } + + /* Always work with 1K packets */ + packet.seq = seq; + packet.type = STX; + + while (len) { + size_t sz, z = 0; + char *from, status; + + /* Build next packet, pad with 0 to full seq */ + z = min(len, sizeof(packet.data)); + memcpy(packet.data, buf, z); + memset(packet.data + z, 0, sizeof(packet.data) - z); + crc = crc16(packet.data, sizeof(packet.data)); + packet.crc_hi = crc >> 8; + packet.crc_lo = crc; + packet.nseq = 0xff - packet.seq; + + /* Send packet */ + from = (char *) &packet; + sz = sizeof(packet); + while (sz) { + if (key_hit) + return ERR; + if ((rc = write(sio, from, sz)) < 0 ) { + if (errno == EWOULDBLOCK) { + usleep(1000); + continue; + } + perror("Write packet to serial failed"); + return ERR; + } + from += rc; + sz -= rc; + } + + /* 'lrzsz' does not ACK ymodem's fin packet */ + if (seq == 0 && packet.data[0] == 0) resp = ACK; + + /* Read receiver response, timeout 1 s */ + for(int n=0; n < 20; n++) { + if (key_hit) + return ERR; + if (read(sio, &resp, 1) < 0) { + if (errno == EWOULDBLOCK) { + usleep(50000); + continue; + } + perror("Read ack/nak from serial failed"); + return ERR; + } + break; + } + + /* Update "progress bar" */ + switch (resp) { + case NAK: status = 'N'; break; + case ACK: status = '.'; break; + case 'C': status = 'C'; break; + case CAN: status = '!'; return ERR; + default: status = '?'; + } + write(STDOUT_FILENO, &status, 1); + + /* Move to next block after ACK */ + if (resp == ACK) { + packet.seq++; + len -= z; + buf += z; + } + } + + /* Send EOT at 1 Hz until ACK or CAN received */ + while (seq) { + if (key_hit) + return ERR; + if (write(sio, EOT, 1) < 0) { + perror("Write EOT to serial failed"); + return ERR; + } + write(STDOUT_FILENO, "|", 1); + usleep(1000000); /* 1 s timeout*/ + if (read(sio, &resp, 1) < 0) { + if (errno == EWOULDBLOCK) continue; + perror("Read from serial failed"); + return ERR; + } + if (resp == ACK || resp == CAN) { + write(STDOUT_FILENO, "\r\n", 2); + return (resp == ACK) ? OK : ERR; + } + } + return 0; /* not reached */ +} + +int xymodem_send(int sio, const char *filename, char mode) +{ + size_t len; + int rc, fd; + struct stat stat; + const uint8_t *buf; + + /* Open file, map into memory */ + fd = open(filename, O_RDONLY); + if (fd < 0) { + perror("Could not open file"); + return ERR; + } + fstat(fd, &stat); + len = stat.st_size; + buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (!buf) { + close(fd); + perror("Could not mmap file"); + return ERR; + } + + /* Do transfer */ + key_hit = 0; + if (mode == 'x') { + rc = xmodem(sio, buf, len, 1); + } + else { + /* Ymodem: hdr + file + fin */ + while(1) { + char hdr[128], *p; + p = stpcpy(hdr, filename) + 1; + p += sprintf(p, "%ld %lo %o", len, stat.st_mtime, stat.st_mode); + + rc = -1; + if (xmodem(sio, hdr, p - hdr, 0) < 0) break; /* hdr with metadata */ + if (xmodem(sio, buf, len, 1) < 0) break; /* xmodem file */ + if (xmodem(sio, "", 1, 0) < 0) break; /* empty hdr = fin */ + rc = 0; break; + } + } + key_hit = 0xff; + + /* Flush serial and release resources */ + tcflush(sio, TCIOFLUSH); + munmap((void *)buf, len); + close(fd); + return rc; +} From c9c5f03c10b90b71c767f19a21305a86d745bfc9 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 12:20:34 +0200 Subject: [PATCH 02/15] Fix meson source listing --- src/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meson.build b/src/meson.build index 73af4c7..2b4a0fe 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,7 +17,7 @@ tio_sources = [ 'setspeed.c', 'rs485.c', 'timestamp.c', - 'alert.c' + 'alert.c', 'xymodem.c' ] From 07864a0e78c53ed466f8a687af0653de276417a9 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 12:25:35 +0200 Subject: [PATCH 03/15] Increase line buffer size Just to make sure we accept very long filenames. --- src/tty.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/tty.c b/src/tty.c index 0f57d75..9a3dccd 100644 --- a/src/tty.c +++ b/src/tty.c @@ -157,6 +157,7 @@ static char *tty_buffer_write_ptr = tty_buffer; static pthread_t thread; static int pipefd[2]; static pthread_mutex_t mutex_input_ready = PTHREAD_MUTEX_INITIALIZER; +static char line[BUFSIZ]; static void optional_local_echo(char c) { @@ -484,18 +485,19 @@ static void toggle_line(const char *line_name, int mask, enum line_mode_t line_m } } -#define MAX_LINE 100 -static char line[MAX_LINE]; - static int tio_readln(void) { char *p = line; - + /* Read line, accept BS and DEL as rubout characters */ - for (p = line ; p < &line[MAX_LINE-1]; ) { - if (read(pipefd[0], p, 1) > 0) { - if (*p == 0x08 || *p == 0x7f) { - if (p > line ) { + for (p = line ; p < &line[BUFSIZ-1]; ) + { + if (read(pipefd[0], p, 1) > 0) + { + if (*p == 0x08 || *p == 0x7f) + { + if (p > line ) + { write(STDOUT_FILENO, "\b \b", 3); p--; } From cf6e8b963b8813607df88822c80774f029a190c1 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 12:27:34 +0200 Subject: [PATCH 04/15] Clean up whitespaces --- src/xymodem.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/xymodem.c b/src/xymodem.c index 1dbeddc..3827776 100644 --- a/src/xymodem.c +++ b/src/xymodem.c @@ -4,7 +4,7 @@ * https://en.wikipedia.org/wiki/YMODEM * * SPDX-License-Identifier: GPL-2.0-or-later OR MIT-0 - * + * */ #include @@ -59,7 +59,7 @@ static int xmodem(int sio, const void *data, size_t len, int seq) const uint8_t *buf = data; char resp = 0; int rc, crc; - + /* Drain pending characters from serial line. Insist on the * last drained character being 'C'. */ @@ -112,7 +112,7 @@ static int xmodem(int sio, const void *data, size_t len, int seq) from += rc; sz -= rc; } - + /* 'lrzsz' does not ACK ymodem's fin packet */ if (seq == 0 && packet.data[0] == 0) resp = ACK; @@ -130,7 +130,7 @@ static int xmodem(int sio, const void *data, size_t len, int seq) } break; } - + /* Update "progress bar" */ switch (resp) { case NAK: status = 'N'; break; @@ -178,7 +178,7 @@ int xymodem_send(int sio, const char *filename, char mode) int rc, fd; struct stat stat; const uint8_t *buf; - + /* Open file, map into memory */ fd = open(filename, O_RDONLY); if (fd < 0) { @@ -214,7 +214,7 @@ int xymodem_send(int sio, const char *filename, char mode) } } key_hit = 0xff; - + /* Flush serial and release resources */ tcflush(sio, TCIOFLUSH); munmap((void *)buf, len); From 63dced047f1ba16109805bd80cec842a6b996ba6 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 12:30:52 +0200 Subject: [PATCH 05/15] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index fe8ecd0..f545ad2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -46,5 +46,6 @@ Bill Hass Peter van Dijk Braden Young HiFiPhile +Paul Ruizendaal Thanks to everyone who has contributed to this project. From ed0386d2c4d2f4eb97ff3828f4a748fdba3ddd2c Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 13:14:52 +0200 Subject: [PATCH 06/15] Re-adjust max line size So it stays within maximum size handled by xmodem. --- src/tty.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tty.c b/src/tty.c index 9a3dccd..12df23e 100644 --- a/src/tty.c +++ b/src/tty.c @@ -82,6 +82,8 @@ #define CMSPAR 010000000000 #endif +#define LINE_SIZE_MAX 1000 + #define KEY_0 0x30 #define KEY_1 0x31 #define KEY_2 0x32 @@ -157,7 +159,7 @@ static char *tty_buffer_write_ptr = tty_buffer; static pthread_t thread; static int pipefd[2]; static pthread_mutex_t mutex_input_ready = PTHREAD_MUTEX_INITIALIZER; -static char line[BUFSIZ]; +static char line[LINE_SIZE_MAX]; static void optional_local_echo(char c) { @@ -490,7 +492,7 @@ static int tio_readln(void) char *p = line; /* Read line, accept BS and DEL as rubout characters */ - for (p = line ; p < &line[BUFSIZ-1]; ) + for (p = line ; p < &line[LINE_SIZE_MAX-1]; ) { if (read(pipefd[0], p, 1) > 0) { From 93e49ab5a23b40bd27e60a1028592ac23e4433f1 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 14:13:25 +0200 Subject: [PATCH 07/15] Make quit hint more explicit To minimize confusion for new users. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index ddf8848..97264cf 100644 --- a/src/main.c +++ b/src/main.c @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) tio_printf("tio v%s", VERSION); if (interactive_mode) { - tio_printf("Press ctrl-%c q to quit", option.prefix_key); + tio_printf("Press then to quit", option.prefix_key); } else { tio_printf("Non-interactive mode enabled"); From a42f3f78d196b26183a979a9241ee5290a78942d Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 14:50:41 +0200 Subject: [PATCH 08/15] Overwrite old stale letters on xmodem filename input When entering a file name, eg. 'test' it whould output the following with 2 stale letters of the former input string: [14:41:58.987] Send file with XMODEM [14:42:08.015] Sending file 'test'st [14:42:08.015] Press any key to abort transfer To avoid this we simply overwrite the 2 stale letters with whitespaces. --- src/tty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tty.c b/src/tty.c index 12df23e..027e795 100644 --- a/src/tty.c +++ b/src/tty.c @@ -770,7 +770,7 @@ void handle_command_sequence(char input_char, char *output_char, bool *forward) tio_printf("Send file with %cMODEM", toupper(input_char)); tio_printf_raw("Enter file name: "); if (tio_readln()) { - tio_printf("Sending file '%s'", line); + tio_printf("Sending file '%s' ", line); tio_printf("Press any key to abort transfer"); tio_printf("%s", xymodem_send(fd, line, input_char) < 0 ? "Aborted" : "Done"); } From 838c1108766aac4d3285844043e0518197b86d6d Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 15:03:38 +0200 Subject: [PATCH 09/15] Increase header size for ymodem --- src/xymodem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/xymodem.c b/src/xymodem.c index 3827776..53ec37d 100644 --- a/src/xymodem.c +++ b/src/xymodem.c @@ -202,11 +202,13 @@ int xymodem_send(int sio, const char *filename, char mode) else { /* Ymodem: hdr + file + fin */ while(1) { - char hdr[128], *p; + char hdr[1024], *p; + + rc = -1; + if (strlen(filename) > 977) break; /* hdr block overrun */ p = stpcpy(hdr, filename) + 1; p += sprintf(p, "%ld %lo %o", len, stat.st_mtime, stat.st_mode); - rc = -1; if (xmodem(sio, hdr, p - hdr, 0) < 0) break; /* hdr with metadata */ if (xmodem(sio, buf, len, 1) < 0) break; /* xmodem file */ if (xmodem(sio, "", 1, 0) < 0) break; /* empty hdr = fin */ From c93922fd36ed1a010c76fa03c7076f082bb3378b Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Sat, 16 Sep 2023 16:10:30 +0200 Subject: [PATCH 10/15] Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dc70429..b0758f7 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ when used in combination with [tmux](https://tmux.github.io). * Sensible defaults (115200 8n1) * Support for non-standard baud rates * Support for RS-485 mode + * X-modem (1K) and Y-modem file upload * Support for mark and space parity * List available serial devices by ID * Show RX/TX statistics From 02b60e9fb32ebc94f335f9adb110c3ce36aea44e Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Tue, 19 Sep 2023 21:21:59 +0200 Subject: [PATCH 11/15] Revert "Make quit hint more explicit" This reverts commit 93e49ab5a23b40bd27e60a1028592ac23e4433f1. --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 97264cf..ddf8848 100644 --- a/src/main.c +++ b/src/main.c @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) tio_printf("tio v%s", VERSION); if (interactive_mode) { - tio_printf("Press then to quit", option.prefix_key); + tio_printf("Press ctrl-%c q to quit", option.prefix_key); } else { tio_printf("Non-interactive mode enabled"); From 3d7d9c85b5bb59b64f44f44bc5a8919a40d8604d Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Tue, 19 Sep 2023 21:37:05 +0200 Subject: [PATCH 12/15] Bump version --- meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 1ed012e..5295d0d 100644 --- a/meson.build +++ b/meson.build @@ -1,12 +1,12 @@ project('tio', 'c', - version : '2.6', + version : '2.7', license : [ 'GPL-2'], meson_version : '>= 0.53.2', default_options : [ 'warning_level=2', 'buildtype=release', 'c_std=gnu99' ] ) # The tag date of the project_version(), update when the version bumps. -version_date = '2022-12-17' +version_date = '2023-09-19' # Test for dynamic baudrate configuration interface compiler = meson.get_compiler('c') From 4307e8176010708876e280d528c6ccc27a5d9c95 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Tue, 19 Sep 2023 21:47:55 +0200 Subject: [PATCH 13/15] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index f545ad2..c9684ea 100644 --- a/AUTHORS +++ b/AUTHORS @@ -45,6 +45,7 @@ Vyacheslav Patkov Bill Hass Peter van Dijk Braden Young +Wes Koerber HiFiPhile Paul Ruizendaal From 1c32555c2a4f26b60f94757656825fc6684d6892 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Tue, 19 Sep 2023 21:48:58 +0200 Subject: [PATCH 14/15] Update NEWS --- NEWS | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7d67de2..28a3d31 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,31 @@ -=== tio v2.6 === +=== tio v2.7 === + + + +Changes since tio v2.6: + +Paul Ruizendaal: + + * Add xmodem and ymodem file send support + +HiFiPhile: + + * tty_stdin_input_thread(): write to pipe only if byte_count > 0. + + * Ignore EINTR error. + + * CYGWIN: Add support for "COM*" naming. + +Wes Koerber: + + * chore: reorder log-strip and log-append + + reorder to maintain consistency with documentation + + * chore: update readme, bash completion, man page + + * fix: support --log-append in cli options From 1777206de73aeba7d14e1f2297a0ca96fc791327 Mon Sep 17 00:00:00 2001 From: Martin Lund Date: Thu, 21 Sep 2023 08:47:34 +0200 Subject: [PATCH 15/15] Update plain text man page --- man/tio.1.txt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/man/tio.1.txt b/man/tio.1.txt index 47318ac..6db7fa4 100644 --- a/man/tio.1.txt +++ b/man/tio.1.txt @@ -1,4 +1,4 @@ -tio(1) User Commands tio(1) +tio(1) User Commands tio(1) NAME tio - a simple serial device I/O tool @@ -241,6 +241,8 @@ KEYS ctrl-t L Show line states (DTR, RTS, CTS, DSR, DCD, RI) + ctrl-t m Toggle MSB to LSB bit order + ctrl-t p Pulse serial port line ctrl-t q Quit @@ -253,6 +255,10 @@ KEYS ctrl-t v Show version + ctrl-t x Send a file using the XMODEM protocol (prompts for file name) + + ctrl-t y Send a file using the YMODEM protocol (prompts for file name) + ctrl-t ctrl-t Send ctrl-t character HEXADECIMAL MODE @@ -279,7 +285,8 @@ CONFIGURATION FILE The following configuration file options are available: - pattern Pattern matching user input. This pattern can be an extended regular expression with a single group. + pattern + Pattern matching user input. This pattern can be an extended regular expression with a single group. device TTY device to open. If it contains a "%s" it is substituted with the first group match. @@ -450,4 +457,4 @@ WEBSITE AUTHOR Created by Martin Lund . -tio 2.6 2022-12-17 tio(1) +tio 2.7 2023-09-19 tio(1)