ii

My fork of https://tools.suckless.org/ii/
git clone https://git.inz.fi/ii
Log | Files | Refs | README | LICENSE

commit 1e24934687420d59e055dc0425e5749362cac54a
parent 06b86af2291718112455397036f68c12dc58af0b
Author: Santtu Lakkala <inz@inz.fi>
Date:   Wed,  9 Mar 2022 15:47:26 +0200

Always terminate server output

In some cases, the server message buffer might get truncated, always
terminate the string sent with CR+LF so the connection stays in a
reasonable state.

Diffstat:
Mii.c | 38++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/ii.c b/ii.c @@ -431,6 +431,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf) { char *p = NULL; size_t buflen; + int w = 0; if (buf[0] == '\0') return; @@ -454,9 +455,9 @@ proc_channels_input(int ircfd, Channel *c, char *buf) { /* password protected channel */ if (p) - snprintf(msg, sizeof(msg), "JOIN %s %s\r\n", &buf[3], p + 1); + w = snprintf(msg, sizeof(msg), "JOIN %s %s\r\n", &buf[3], p + 1); else - snprintf(msg, sizeof(msg), "JOIN %s\r\n", &buf[3]); + w = snprintf(msg, sizeof(msg), "JOIN %s\r\n", &buf[3]); channel_join(&buf[3]); } else if (p) { if ((c = channel_join(&buf[3]))) @@ -466,7 +467,7 @@ proc_channels_input(int ircfd, Channel *c, char *buf) break; case 't': /* topic */ if (buf[3]) - snprintf(msg, sizeof(msg), "TOPIC %s :%s\r\n", c->name, &buf[3]); + w = snprintf(msg, sizeof(msg), "TOPIC %s :%s\r\n", c->name, &buf[3]); break; case 'a': /* away */ if (buf[3]) { @@ -474,48 +475,57 @@ proc_channels_input(int ircfd, Channel *c, char *buf) channel_print(c, msg); } if (buf[3]) - snprintf(msg, sizeof(msg), "AWAY :%s\r\n", &buf[3]); + w = snprintf(msg, sizeof(msg), "AWAY :%s\r\n", &buf[3]); else - snprintf(msg, sizeof(msg), "AWAY\r\n"); + w = snprintf(msg, sizeof(msg), "AWAY\r\n"); break; case 'n': /* change nick */ if (buf[3]) { strlcpy(_nick, &buf[3], sizeof(_nick)); - snprintf(msg, sizeof(msg), "NICK %s\r\n", &buf[3]); + w = snprintf(msg, sizeof(msg), "NICK %s\r\n", &buf[3]); } break; case 'l': /* leave */ if (c == channelmaster) return; if (buf[3]) - snprintf(msg, sizeof(msg), "PART %s :%s\r\n", c->name, &buf[3]); + w = snprintf(msg, sizeof(msg), "PART %s :%s\r\n", c->name, &buf[3]); else - snprintf(msg, sizeof(msg), + w = snprintf(msg, sizeof(msg), "PART %s :leaving\r\n", c->name); + if (w >= sizeof(msg) - 1) { + msg[sizeof(msg) - 3] = '\r'; + msg[sizeof(msg) - 2] = '\n'; + } ewritestr(ircfd, msg); channel_leave(c); return; break; case 'q': /* quit */ if (buf[3]) - snprintf(msg, sizeof(msg), "QUIT :%s\r\n", &buf[3]); + w = snprintf(msg, sizeof(msg), "QUIT :%s\r\n", &buf[3]); else - snprintf(msg, sizeof(msg), + w = snprintf(msg, sizeof(msg), "QUIT %s\r\n", "bye"); ewritestr(ircfd, msg); isrunning = 0; return; break; default: /* raw IRC command */ - snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]); + w = snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]); break; } } else { /* raw IRC command */ - snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]); + w = snprintf(msg, sizeof(msg), "%s\r\n", &buf[1]); + } + if (msg[0] == '\0') + return; + if (w >= sizeof(msg) - 1) { + msg[sizeof(msg) - 3] = '\r'; + msg[sizeof(msg) - 2] = '\n'; } - if (msg[0] != '\0') - ewritestr(ircfd, msg); + ewritestr(ircfd, msg); } static void