diff --git a/connection.c b/connection.c index c6d2f53..7b96901 100644 --- a/connection.c +++ b/connection.c @@ -17,7 +17,6 @@ struct client_con { struct list_head list; struct sockaddr_in addr; - struct event_timeout *trigger; struct event_fd *event; struct linebuffer *lbuf; @@ -36,18 +35,10 @@ static void free_client(struct client_con *con) { close(event_get_fd(con->event)); event_remove_fd(con->event); - event_remove_timeout(con->trigger); free(con->lbuf); free(con); } -static int trigger_status(void *privdata) -{ - struct client_con *con = (struct client_con *)privdata; - write(event_get_fd(con->event), "SENDSTATUS\n", 11); - return 0; -} - static int data_cb(int fd, void *privdata) { struct client_con *con = (struct client_con *)privdata; @@ -92,6 +83,15 @@ static int data_cb(int fd, void *privdata) return 0; } +int ctcs_trigger_status(void *privdata) +{ + struct client_con *con; + list_for_each_entry(con, &client_list, list) + write(event_get_fd(con->event), "SENDSTATUS\n", 11); + + return 0; +} + int ctcs_accept_handler(int fd, void *privdata) { struct client_con *con = malloc(sizeof(struct client_con)); @@ -118,9 +118,6 @@ int ctcs_accept_handler(int fd, void *privdata) return 0; } - struct timeval tv = { .tv_sec = 10, .tv_usec = 0 }; - con->trigger = event_add_timeout(&tv, trigger_status, con); - con->event = event_add_readfd(NULL, sockfd, data_cb, con); list_add(&con->list, &client_list); @@ -129,27 +126,27 @@ int ctcs_accept_handler(int fd, void *privdata) int ctcs_httpd_handler(struct httpd_con *con, void *privdata) { - int size = 4096, len = 0; - char *text = malloc(size); - if (text == NULL) { + struct linebuffer *lbuf = create_linebuffer(4096); + if (lbuf == NULL) { httpd_send_error(con, "500 ERROR", "Out of Memory"); return -1; } - len += snprintf(text + len, size - len, "

ctorrent stats

\n\n"); - len += snprintf(text + len, size - len, "\n"); + linebuffer_printf(lbuf, "

ctorrent stats

\n
Client IP:PortChunks (have/total/avail)Download total(current)Upload total(current)
\n"); + linebuffer_printf(lbuf, "\n"); struct client_con *tmp; list_for_each_entry(tmp, &client_list, list) { - len += snprintf(text + len, size - len, "\n", + linebuffer_printf(lbuf, "\n", get_sockaddr_buf(&tmp->addr), (double)tmp->chunk_have / (double)tmp->chunk_total * 100.0, tmp->chunk_have, tmp->chunk_total, tmp->chunk_avail, tmp->total_dn, tmp->bw_dn, tmp->total_up, tmp->bw_up); } - len += snprintf(text + len, size - len, "
Client IP:PortChunks (have/total/avail)Download total(current)Upload total(current)
%s%3.2lf%% (%d/%d/%d)%llu (%d)%llu (%d)
%s%3.2lf%% (%d/%d/%d)%llu (%d)%llu (%d)
\n\n"); + linebuffer_printf(lbuf, "\n\n"); httpd_send_header(con, "200 OK", "text/html"); - write(con->fd, text, len); + linebuffer_writefd(lbuf, con->fd); + linebuffer_free(lbuf); return 0; } diff --git a/connection.h b/connection.h index 8ab26cc..b114c29 100644 --- a/connection.h +++ b/connection.h @@ -3,6 +3,7 @@ #include "httpd.h" +int ctcs_trigger_status(void *privdata); int ctcs_accept_handler(int fd, void *privdata); int ctcs_httpd_handler(struct httpd_con *con, void *privdata); diff --git a/linebuffer.c b/linebuffer.c index b0a3eb7..de9ba6b 100644 --- a/linebuffer.c +++ b/linebuffer.c @@ -49,7 +49,7 @@ int linebuffer_readfd(struct linebuffer *buf, int fd) { int len = read(fd, buf->data + buf->pos, buf->size - buf->pos); if (len <= 0) - return len; + return -1; buf->pos += len; return len; @@ -79,6 +79,17 @@ int linebuffer_parsefd(struct linebuffer *buf, int fd) return 0; } +int linebuffer_writefd(struct linebuffer *buf, int fd) +{ + int len = write(fd, buf->data, buf->pos); + if (len <= 0) + return -1; + + /* TODO: now assuming everything is written */ + buf->pos = 0; + return len; +} + int linebuffer_printf(struct linebuffer *buf, const char *fmt, ...) { va_list az; diff --git a/linebuffer.h b/linebuffer.h index de5a1b0..c021ad3 100644 --- a/linebuffer.h +++ b/linebuffer.h @@ -14,9 +14,11 @@ void linebuffer_free(struct linebuffer *buf); int linebuffer_clear(struct linebuffer *buf); -int linebuffer_put(struct linebuffer *buf, const char *src, unsigned int size); int linebuffer_readfd(struct linebuffer *buf, int fd); int linebuffer_parsefd(struct linebuffer *buf, int fd); +int linebuffer_writefd(struct linebuffer *buf, int fd); + +int linebuffer_put(struct linebuffer *buf, const char *src, unsigned int size); int linebuffer_printf(struct linebuffer *buf, const char *fmt, ...); char * linebuffer_getline(struct linebuffer *buf, int *len); diff --git a/torrent-stats.c b/torrent-stats.c index 9703a51..9262b5a 100644 --- a/torrent-stats.c +++ b/torrent-stats.c @@ -41,6 +41,9 @@ int main(int argc, char *argv[]) httpd_add_cb("/", 1, ctcs_httpd_handler, NULL); + struct timeval tv = { .tv_sec = 10, .tv_usec = 0 }; + event_add_timeout(&tv, ctcs_trigger_status, NULL); + event_loop(); return 0; }