diff --git a/caca/driver_network.c b/caca/driver_network.c index 585bd6c..958286d 100644 --- a/caca/driver_network.c +++ b/caca/driver_network.c @@ -40,8 +40,9 @@ #include "cucul.h" #include "cucul_internals.h" -#define BACKLOG 1337 /* Number of pending connections */ -#define BACKBUFFER 300000 /* Size of per-client buffer */ +#define BACKLOG 1337 /* Number of pending connections */ +#define INBUFFER 32 /* Size of per-client input buffer */ +#define OUTBUFFER 300000 /* Size of per-client output buffer */ /* Following vars are static */ #define INIT_PREFIX \ @@ -68,7 +69,9 @@ struct client { int fd; int ready; - char buffer[BACKBUFFER]; + uint8_t inbuf[INBUFFER]; + int inbytes; + uint8_t outbuf[OUTBUFFER]; int start, stop; }; @@ -93,7 +96,7 @@ struct driver_private static void manage_connections(caca_t *kk); static int send_data(caca_t *kk, struct client *c); -ssize_t nonblock_write(int fd, char *buf, size_t len); +ssize_t nonblock_write(int fd, void *buf, size_t len); static int network_init_graphics(caca_t *kk) { @@ -172,6 +175,9 @@ static int network_init_graphics(caca_t *kk) /* Ignore SIGPIPE */ kk->drv.p->sigpipe_handler = signal(SIGPIPE, SIG_IGN); + fprintf(stderr, "initialised network, listening on port %i\n", + kk->drv.p->port); + return 0; } @@ -224,7 +230,12 @@ static void network_display(caca_t *kk) continue; if(send_data(kk, &kk->drv.p->clients[i])) + { + fprintf(stderr, "client %i dropped connection\n", + kk->drv.p->clients[i].fd); + close(kk->drv.p->clients[i].fd); kk->drv.p->clients[i].fd = -1; + } } manage_connections(kk); @@ -259,6 +270,9 @@ static void manage_connections(caca_t *kk) if(fd == -1) return; + fprintf(stderr, "client %i connected from %s\n", + fd, inet_ntoa(remote_addr.sin_addr)); + /* Non blocking socket */ flags = fcntl(fd, F_SETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); @@ -277,11 +291,18 @@ static void manage_connections(caca_t *kk) kk->drv.p->clients[kk->drv.p->client_count].fd = fd; kk->drv.p->clients[kk->drv.p->client_count].ready = 0; + kk->drv.p->clients[kk->drv.p->client_count].inbytes = 0; kk->drv.p->clients[kk->drv.p->client_count].start = 0; kk->drv.p->clients[kk->drv.p->client_count].stop = 0; /* If we already have data to send, send it to the new client */ - send_data(kk, &kk->drv.p->clients[kk->drv.p->client_count]); + if(send_data(kk, &kk->drv.p->clients[kk->drv.p->client_count])) + { + fprintf(stderr, "client %i dropped connection\n", fd); + close(fd); + kk->drv.p->clients[kk->drv.p->client_count].fd = -1; + return; + } kk->drv.p->client_count++; } @@ -294,15 +315,45 @@ static int send_data(caca_t *kk, struct client *c) if(c->fd < 0) return -1; - /* Debug: show incoming data */ + /* Listen to incoming data */ for(;;) { - unsigned char in; - ret = read(c->fd, &in, 1); + ret = read(c->fd, c->inbuf + c->inbytes, 1); if(ret <= 0) break; - fprintf(stderr, "client %i said \\x%.02x\n", c->fd, in); + c->inbytes++; + + /* Check for telnet sequences */ + if(c->inbuf[0] == 0xff) + { + if(c->inbytes == 1) + { + ; + } + else if(c->inbuf[1] == 0xfd || c->inbuf[1] == 0xfc) + { + if(c->inbytes == 3) + { + fprintf(stderr, "client %i said: %.02x %.02x %.02x\n", + c->fd, c->inbuf[0], c->inbuf[1], c->inbuf[2]); + /* Just ignore, lol */ + c->inbytes = 0; + } + } + else + c->inbytes = 0; + } + else if(c->inbytes == 1) + { + if(c->inbuf[0] == 0x03) + { + fprintf(stderr, "client %i pressed C-c\n", c->fd); + return -1; /* User requested to quit */ + } + + c->inbytes = 0; + } } /* Send the telnet initialisation commands */ @@ -325,7 +376,7 @@ static int send_data(caca_t *kk, struct client *c) /* If we have backlog, send the backlog */ if(c->stop) { - ret = nonblock_write(c->fd, c->buffer + c->start, c->stop - c->start); + ret = nonblock_write(c->fd, c->outbuf + c->start, c->stop - c->start); if(ret == -1) { @@ -345,26 +396,26 @@ static int send_data(caca_t *kk, struct client *c) c->start += ret; if(c->stop - c->start + strlen(ANSI_PREFIX) + kk->drv.p->size - > BACKBUFFER) + > OUTBUFFER) { /* Overflow! Empty buffer and start again */ - memcpy(c->buffer, ANSI_RESET, strlen(ANSI_RESET)); + memcpy(c->outbuf, ANSI_RESET, strlen(ANSI_RESET)); c->start = 0; c->stop = strlen(ANSI_RESET); return 0; } /* Need to move? */ - if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->size > BACKBUFFER) + if(c->stop + strlen(ANSI_PREFIX) + kk->drv.p->size > OUTBUFFER) { - memmove(c->buffer, c->buffer + c->start, c->stop - c->start); + memmove(c->outbuf, c->outbuf + c->start, c->stop - c->start); c->stop -= c->start; c->start = 0; } - memcpy(c->buffer + c->stop, ANSI_PREFIX, strlen(ANSI_PREFIX)); + memcpy(c->outbuf + c->stop, ANSI_PREFIX, strlen(ANSI_PREFIX)); c->stop += strlen(ANSI_PREFIX); - memcpy(c->buffer + c->stop, kk->drv.p->buffer, kk->drv.p->size); + memcpy(c->outbuf + c->stop, kk->drv.p->buffer, kk->drv.p->size); c->stop += kk->drv.p->size; return 0; @@ -385,18 +436,18 @@ static int send_data(caca_t *kk, struct client *c) if(ret < (ssize_t)strlen(ANSI_PREFIX)) { - if(strlen(ANSI_PREFIX) + kk->drv.p->size > BACKBUFFER) + if(strlen(ANSI_PREFIX) + kk->drv.p->size > OUTBUFFER) { /* Overflow! Empty buffer and start again */ - memcpy(c->buffer, ANSI_RESET, strlen(ANSI_RESET)); + memcpy(c->outbuf, ANSI_RESET, strlen(ANSI_RESET)); c->start = 0; c->stop = strlen(ANSI_RESET); return 0; } - memcpy(c->buffer, ANSI_PREFIX, strlen(ANSI_PREFIX) - ret); + memcpy(c->outbuf, ANSI_PREFIX, strlen(ANSI_PREFIX) - ret); c->stop = strlen(ANSI_PREFIX) - ret; - memcpy(c->buffer + c->stop, kk->drv.p->buffer, kk->drv.p->size); + memcpy(c->outbuf + c->stop, kk->drv.p->buffer, kk->drv.p->size); c->stop += kk->drv.p->size; return 0; @@ -414,16 +465,16 @@ static int send_data(caca_t *kk, struct client *c) if(ret < kk->drv.p->size) { - if(kk->drv.p->size > BACKBUFFER) + if(kk->drv.p->size > OUTBUFFER) { /* Overflow! Empty buffer and start again */ - memcpy(c->buffer, ANSI_RESET, strlen(ANSI_RESET)); + memcpy(c->outbuf, ANSI_RESET, strlen(ANSI_RESET)); c->start = 0; c->stop = strlen(ANSI_RESET); return 0; } - memcpy(c->buffer, kk->drv.p->buffer, kk->drv.p->size - ret); + memcpy(c->outbuf, kk->drv.p->buffer, kk->drv.p->size - ret); c->stop = kk->drv.p->size - ret; return 0; @@ -432,7 +483,7 @@ static int send_data(caca_t *kk, struct client *c) return 0; } -ssize_t nonblock_write(int fd, char *buf, size_t len) +ssize_t nonblock_write(int fd, void *buf, size_t len) { size_t total = 0; ssize_t ret; @@ -451,7 +502,7 @@ ssize_t nonblock_write(int fd, char *buf, size_t len) return total; total += len; - buf += len; + buf = (void *)((uintptr_t)buf + len); } return total;