summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2023-06-09 00:22:53 +0200
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2023-06-09 00:22:53 +0200
commit5a3bc9d127fdf83f951d638d78fa00c882416609 (patch)
tree30debd0a7b9bee566bf4b698cd40aec77beec046
parent49f8e442832c72a1bf6efde8dd55049a14176899 (diff)
parent48f4fd57802b5748235e18dc1ba367e675cd1109 (diff)
downloadmicrocom-5a3bc9d127fdf83f951d638d78fa00c882416609.tar.gz
microcom-5a3bc9d127fdf83f951d638d78fa00c882416609.tar.xz
Merge branch 'quote-IAC-on-send' of https://github.com/ukleinek/microcom
-rw-r--r--telnet.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/telnet.c b/telnet.c
index 347f8ac..0d8c2a3 100644
--- a/telnet.c
+++ b/telnet.c
@@ -391,7 +391,33 @@ static int handle_command(struct ios_ops *ios, unsigned char *buf, int len)
static ssize_t telnet_write(struct ios_ops *ios, const void *buf, size_t count)
{
- return write(ios->fd, buf, count);
+ size_t handled = 0;
+ ssize_t ret;
+ void *iac;
+
+ /*
+ * To send an IAC character in the data stream, two IACs must be sent.
+ * So find the first IAC in the data to be send (if any), send the data
+ * before that IAC unquoted, then send the double IAC. Repeat until
+ * all IACs are handled.
+ */
+ while ((iac = memchr(buf + handled, IAC, count - handled)) != NULL) {
+ if (iac - (buf + handled)) {
+ ret = write(ios->fd, buf + handled, iac - (buf + handled));
+ if (ret < 0)
+ return ret;
+ handled += ret;
+ } else {
+ dprintf(ios->fd, "%c%c", IAC, IAC);
+ handled += 1;
+ }
+ }
+
+ /* Send the remaining data that needs no quoting. */
+ ret = write(ios->fd, buf + handled, count - handled);
+ if (ret < 0)
+ return ret;
+ return ret + handled;
}
static ssize_t telnet_read(struct ios_ops *ios, void *buf, size_t count)