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, "Client IP:Port | Chunks (have/total/avail) | Download total(current) | Upload total(current) |
\n");
+ linebuffer_printf(lbuf, "ctorrent stats
\n\n");
+ linebuffer_printf(lbuf, "Client IP:Port | Chunks (have/total/avail) | Download total(current) | Upload total(current) |
\n");
struct client_con *tmp;
list_for_each_entry(tmp, &client_list, list) {
- len += snprintf(text + len, size - len, "%s | %3.2lf%% (%d/%d/%d) | %llu (%d) | %llu (%d) |
\n",
+ linebuffer_printf(lbuf, "%s | %3.2lf%% (%d/%d/%d) | %llu (%d) | %llu (%d) |
\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, "
\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;
}