소스 검색

* Pressing Ctrl-C on the client side now drops the connection.

tags/v0.99.beta14
Sam Hocevar sam 19 년 전
부모
커밋
a188ec5c32
1개의 변경된 파일76개의 추가작업 그리고 25개의 파일을 삭제
  1. +76
    -25
      caca/driver_network.c

+ 76
- 25
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;


불러오는 중...
취소
저장