hirc

IRC client
Log | Files | Refs

commit 5fc053455f7402fa975b1b50dc3903258bbab188
parent 66b3d1bfa7dcc42bc6bd047eacf83863d8bc8cd4
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 19 Dec 2021 22:07:40 +0000

s/main.c s/serv.c s/handle.c s/struct.h s/hirc.h: buffered reading

Diffstat:
Msrc/handle.c | 20+-------------------
Msrc/hirc.h | 2+-
Msrc/main.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/serv.c | 1+
Msrc/struct.h | 3+++
5 files changed, 66 insertions(+), 50 deletions(-)

diff --git a/src/handle.c b/src/handle.c @@ -588,31 +588,13 @@ handle_logonly(char *msg, char **params, struct Server *server, time_t timestamp } void -handle(struct Server *server) { +handle(struct Server *server, char *msg) { time_t timestamp; char **params; char *cmd; char *schmsg; - char *msg; - char buf[511]; - /* using a buffer size of 511: - * - RFC1459 defines the maximum size of a message to be 512 - * - read_line() doesn't copy the \r\n so this is reduced to 510 - * - a \0 is needed at the end, so 510 + 1 = 511 */ int i; - memset(buf, '\0', sizeof(buf)); - if (!ircgets(server, buf, sizeof(buf))) { - if (buf[0] == EOF || buf[0] == 3 || buf[0] == 4) { - serv_disconnect(server, 1, "EOF"); - hist_format(server->history, Activity_error, HIST_SHOW, - "SELF_CONNECTLOST %s %s %s :EOF received", - server->name, server->host, server->port); - } - return; - } - msg = buf; - if (*msg == '!' && strchr(msg, ' ') && *(strchr(msg, ' ')+1) && *(msg+1) != ' ') { msg++; timestamp = (time_t)strtoll(msg, NULL, 10); diff --git a/src/hirc.h b/src/hirc.h @@ -111,7 +111,7 @@ char * schedule_pull(struct Server *server, char *tmsg); int serv_ischannel(struct Server *server, char *str); /* handle.c */ -void handle(struct Server *server); +void handle(struct Server *server, char *msg); void handle_expect(struct Server *server, enum Expect cmd, char *about); char * handle_expect_get(struct Server *server, enum Expect cmd); diff --git a/src/main.c b/src/main.c @@ -124,35 +124,6 @@ param_create(char *msg) { } int -ircgets(struct Server *server, char *buf, size_t buf_len) { - size_t i = 0; - char c = 0; - - do { -#ifdef TLS - if (server->tls) { - switch (tls_read(server->tls_ctx, &c, sizeof(char))) { - case -1: - return 0; - case TLS_WANT_POLLIN: - case TLS_WANT_POLLOUT: - continue; - } - } else { -#endif /* TLS */ - if (read(server->rfd, &c, sizeof(char)) != sizeof(char)) - return 0; -#ifdef TLS - } -#endif /* TLS */ - if (c != '\r') - buf[i++] = c; - } while (c != '\n' && i < buf_len); - buf[i - 1] = '\0'; - return 1; -} - -int read_line(int fd, char *buf, size_t buf_len) { size_t i = 0; char c = 0; @@ -167,6 +138,65 @@ read_line(int fd, char *buf, size_t buf_len) { return 1; } +void +ircread(struct Server *sp) { + char *line, *end; + int ret; + + if (!sp) + return; + +#ifdef TLS + if (sp->tls) { + switch (ret = tls_read(sp->tls_ctx, &sp->inputbuf[sp->inputlen], SERVER_INPUT_SIZE - sp->inputlen - 1)) { + case 0: + serv_disconnect(sp, 1, "EOF"); + hist_format(sp->history, Activity_error, HIST_SHOW, + "SELF_CONNECTLOST %s %s %s :connection closed", + sp->name, sp->host, sp->port); + return; + case -1: + ui_tls_error(sp->tls_ctx, "tls_read()"); + return; + case TLS_WANT_POLLIN: + case TLS_WANT_POLLOUT: + return; + default: + sp->inputlen += ret; + break; + } + } else { +#endif /* TLS */ + switch (ret = read(sp->rfd, &sp->inputbuf[sp->inputlen], SERVER_INPUT_SIZE - sp->inputlen - 1)) { + case 0: + serv_disconnect(sp, 1, "EOF"); + hist_format(sp->history, Activity_error, HIST_SHOW, + "SELF_CONNECTLOST %s %s %s :connection closed", + sp->name, sp->host, sp->port); + return; + case -1: + ui_perror("read()"); + return; + default: + sp->inputlen += ret; + break; + } +#ifdef TLS + } +#endif /* TLS */ + + sp->inputbuf[SERVER_INPUT_SIZE - 1] = '\0'; + line = sp->inputbuf; + while (end = strstr(line, "\r\n")) { + *end = '\0'; + handle(sp, line); + line = end + 2; + } + + sp->inputlen -= line - sp->inputbuf; + memmove(sp->inputbuf, line, sp->inputlen); +} + int ircprintf(struct Server *server, char *format, ...) { char msg[512]; @@ -330,7 +360,7 @@ main(int argc, char *argv[]) { sp->pingsent = 0; sp->lastrecv = time(NULL); sp->rpollfd->revents = 0; - handle(sp); + ircread(sp); } else if (!sp->pingsent && sp->lastrecv && (time(NULL) - sp->lastrecv) >= pinginact) { /* haven't heard from server in pinginact seconds, sending a ping */ ircprintf(sp, "PING :ground control to Major Tom\r\n"); diff --git a/src/serv.c b/src/serv.c @@ -76,6 +76,7 @@ serv_create(char *name, char *host, char *port, char *nick, server = emalloc(sizeof(struct Server)); server->prev = server->next = NULL; server->wfd = server->rfd = server->logfd = -1; + server->inputlen = 0; server->rpollfd = emalloc(sizeof(struct pollfd)); server->rpollfd->fd = -1; server->rpollfd->events = POLLIN; diff --git a/src/struct.h b/src/struct.h @@ -125,10 +125,13 @@ struct Schedule { struct Schedule *next; }; +#define SERVER_INPUT_SIZE 1024 struct Server { struct Server *prev; int wfd; int rfd; + char inputbuf[SERVER_INPUT_SIZE]; + int inputlen; struct pollfd *rpollfd; int logfd; enum ConnStatus status;