added httpd
This commit is contained in:
parent
d169f4ab47
commit
503b837763
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
CFLAGS := -O2 -pipe -Wall
|
||||
|
||||
OBJS := configfile.o event.o linebuffer.o logging.o sockaddr.o tcpsocket.o
|
||||
OBJS := configfile.o connection.o event.o httpd.o linebuffer.o logging.o sockaddr.o tcpsocket.o
|
||||
|
||||
all: torrent-stats
|
||||
|
||||
|
155
connection.c
Normal file
155
connection.c
Normal file
@ -0,0 +1,155 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "httpd.h"
|
||||
#include "linebuffer.h"
|
||||
#include "list.h"
|
||||
#include "logging.h"
|
||||
#include "sockaddr.h"
|
||||
#include "tcpsocket.h"
|
||||
|
||||
static LIST_HEAD(client_list);
|
||||
|
||||
struct client_con {
|
||||
struct list_head list;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
struct event_timeout *trigger;
|
||||
struct event_fd *event;
|
||||
struct linebuffer *lbuf;
|
||||
|
||||
int bw_up;
|
||||
int bw_dn;
|
||||
|
||||
unsigned long long total_up;
|
||||
unsigned long long total_dn;
|
||||
|
||||
int chunk_total;
|
||||
int chunk_avail;
|
||||
int chunk_have;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
if (linebuffer_read(con->lbuf, fd) < 0) {
|
||||
log_print(LOG_WARN, "data_cb(): client %s read", get_sockaddr_buf(&con->addr));
|
||||
list_del(&con->list);
|
||||
free_client(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *line;
|
||||
while ((line = linebuffer_get(con->lbuf)) != NULL) {
|
||||
if (strncmp(line, "CTBW ", 5) == 0) {
|
||||
int bwup, bwdn, liup, lidn;
|
||||
if (sscanf(line +5, "%d,%d %d,%d", &bwdn, &bwup, &lidn, &liup) == 4) {
|
||||
con->bw_up = bwup;
|
||||
con->bw_dn = bwdn;
|
||||
}
|
||||
|
||||
} else if (strncmp(line, "CTSTATUS ", 9) == 0) {
|
||||
int seeds1 = 0, seeds2 = 0, leech1 = 0, leech2 = 0, count = 0;
|
||||
int chunk1 = 0, chunk2 = 0, chunk3 = 0, bwdn = 0, bwup = 0;
|
||||
int lidn = 0, liup = 0, cache = 0;
|
||||
unsigned long long totdn = 0, totup = 0;
|
||||
|
||||
if (sscanf(line +9, "%d:%d/%d:%d/%d %d/%d/%d %d,%d %llu,%llu %d,%d %d",
|
||||
&seeds1, &seeds2, &leech1, &leech2, &count,
|
||||
&chunk1, &chunk2, &chunk3,
|
||||
&bwdn, &bwup, &totdn, &totup,
|
||||
&lidn, &liup, &cache) == 15) {
|
||||
|
||||
con->total_up = totup;
|
||||
con->total_dn = totdn;
|
||||
con->chunk_have = chunk1;
|
||||
con->chunk_total = chunk2;
|
||||
con->chunk_avail = chunk3;
|
||||
}
|
||||
}
|
||||
free(line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ctcs_accept_handler(int fd, void *privdata)
|
||||
{
|
||||
struct client_con *con = malloc(sizeof(struct client_con));
|
||||
if (con == NULL) {
|
||||
log_print(LOG_WARN, "accept_cb(): out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(con, 0, sizeof(struct client_con));
|
||||
|
||||
con->lbuf = create_linebuffer(1024);
|
||||
if (con->lbuf == NULL) {
|
||||
log_print(LOG_WARN, "accept_cb(): out of memory");
|
||||
free(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int i = sizeof(con->addr);
|
||||
int sockfd = accept(fd, (struct sockaddr *)&con->addr, &i);
|
||||
if (sockfd < 0) {
|
||||
log_print(LOG_WARN, "accept_cb(): accept()");
|
||||
free(con->lbuf);
|
||||
free(con);
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ctcs_httpd_handler(struct httpd_con *con, void *privdata)
|
||||
{
|
||||
int size = 4096, len = 0;
|
||||
char *text = malloc(size);
|
||||
if (text == NULL) {
|
||||
httpd_send_error(con, "500 ERROR", "Out of Memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
len += snprintf(text + len, size - len, "<html><body><h1>ctorrent stats</h1>\n<table border=\"1\">\n");
|
||||
len += snprintf(text + len, size - len, "<tr><td><b>Client IP:Port</b></td><td><b>Chunks (have/total/avail)</b></td><td><b>Download total(current)</b></td><td><b>Upload total(current)</b></td></tr>\n");
|
||||
|
||||
struct client_con *tmp;
|
||||
list_for_each_entry(tmp, &client_list, list) {
|
||||
len += snprintf(text + len, size - len, "<tr><td align=\"right\">%s</td><td align=\"right\">%3.2lf%% (%d/%d/%d)</td><td align=\"right\">%llu (%d)</td><td align=\"right\">%llu (%d)</td></tr>\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, "</table>\n</body></html>\n");
|
||||
|
||||
httpd_send_header(con, "200 OK", "text/html");
|
||||
write(con->fd, text, len);
|
||||
return 0;
|
||||
}
|
9
connection.h
Normal file
9
connection.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef _CONNECTION_H_
|
||||
#define _CONNECTION_H_
|
||||
|
||||
#include "httpd.h"
|
||||
|
||||
int ctcs_accept_handler(int fd, void *privdata);
|
||||
int ctcs_httpd_handler(struct httpd_con *con, void *privdata);
|
||||
|
||||
#endif /* _CONNECTION_H_ */
|
226
httpd.c
Normal file
226
httpd.c
Normal file
@ -0,0 +1,226 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "httpd.h"
|
||||
#include "list.h"
|
||||
#include "logging.h"
|
||||
#include "sockaddr.h"
|
||||
#include "tcpsocket.h"
|
||||
|
||||
static LIST_HEAD(httpd_cb_list);
|
||||
|
||||
static void destroy_httpd_con(struct httpd_con *con)
|
||||
{
|
||||
close(event_get_fd(con->event));
|
||||
event_remove_fd(con->event);
|
||||
|
||||
if (con->req_data != NULL)
|
||||
free(con->req_data);
|
||||
|
||||
if (con->req_headers != NULL)
|
||||
free(con->req_headers);
|
||||
|
||||
if (con->req_args != NULL)
|
||||
free(con->req_args);
|
||||
|
||||
free(con);
|
||||
}
|
||||
|
||||
int httpd_send_header(struct httpd_con *con, char *code, char *type)
|
||||
{
|
||||
char buf[256];
|
||||
int len = snprintf(buf, sizeof(buf), "HTTP/1.0 %s\r\nContent-Type: %s\r\nConnection: close\r\n\r\n", code, type);
|
||||
write(con->fd, buf, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int httpd_send_error(struct httpd_con *con, char *code, char *msg)
|
||||
{
|
||||
httpd_send_header(con, code, "text/plain");
|
||||
write(con->fd, msg, strlen(msg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_headers(struct httpd_con *con)
|
||||
{
|
||||
char *data = con->req_data;
|
||||
while ((data = strstr(data, "\r\n")) && data < con->req_data + con->req_size) {
|
||||
con->req_header_cnt++;
|
||||
data += 2;
|
||||
}
|
||||
|
||||
con->req_headers = malloc(con->req_header_cnt * sizeof(char *));
|
||||
if (con->req_headers == NULL)
|
||||
return -1;
|
||||
|
||||
int i = 0;
|
||||
data = con->req_data;
|
||||
|
||||
do {
|
||||
con->req_headers[i++] = data;
|
||||
|
||||
data = strstr(data, "\r\n");
|
||||
if (data == NULL)
|
||||
break;
|
||||
|
||||
*data++ = '\0';
|
||||
*data++ = '\0';
|
||||
|
||||
} while (data < con->req_data + con->req_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_args(struct httpd_con *con)
|
||||
{
|
||||
/* seperate GET (in req->data) */
|
||||
char *req = strchr(con->req_data, ' ');
|
||||
*req++ = '\0';
|
||||
|
||||
/* HTTP/1.1 will go to header[0] */
|
||||
char *tmp = strchr(req, ' ');
|
||||
*tmp++ = '\0';
|
||||
con->req_headers[0] = tmp;
|
||||
|
||||
/* count args */
|
||||
tmp = req;
|
||||
while (*tmp != '\0' && tmp < con->req_data + con->req_size) {
|
||||
if (*tmp == '?' || *tmp == '&')
|
||||
con->req_arg_cnt++;
|
||||
|
||||
tmp++;
|
||||
}
|
||||
con->req_arg_cnt++;
|
||||
|
||||
/* alloc args */
|
||||
con->req_args = malloc(con->req_arg_cnt * sizeof(char *));
|
||||
if (con->req_args == NULL)
|
||||
return -1;
|
||||
|
||||
int i = 0;
|
||||
tmp = req;
|
||||
|
||||
con->req_args[i++] = tmp;
|
||||
while (*tmp != '\0' && tmp < con->req_data + con->req_size) {
|
||||
if (*tmp == '?' || *tmp == '&') {
|
||||
*tmp++ = '\0';
|
||||
con->req_args[i++] = tmp;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int httpd_content_handler(int fd, void *privdata)
|
||||
{
|
||||
struct httpd_con *con = (struct httpd_con *)privdata;
|
||||
|
||||
if (ioctl(fd, FIONREAD, &con->req_size) == -1) {
|
||||
log_print(LOG_WARN, "http_content_handler(): ioctl(FIONREAD)");
|
||||
destroy_httpd_con(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
con->req_data = malloc(con->req_size);
|
||||
if (con->req_data == NULL) {
|
||||
log_print(LOG_WARN, "http_content_handler(): out of memory");
|
||||
destroy_httpd_con(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
con->req_size = read(fd, con->req_data, con->req_size);
|
||||
if (con->req_size <= 0) {
|
||||
log_print(LOG_WARN, "http_content_handler(): read()");
|
||||
destroy_httpd_con(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(con->req_data, "GET ", 4) != 0) {
|
||||
httpd_send_error(con, "400 Invalid Request", "Not a GET request\r\n");
|
||||
destroy_httpd_con(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (parse_headers(con) < 0) {
|
||||
httpd_send_error(con, "400 Invalid Request", "Error parsing headers\r\n");
|
||||
destroy_httpd_con(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (parse_args(con) < 0) {
|
||||
httpd_send_error(con, "400 Invalid Request", "Error parsing arguments\r\n");
|
||||
destroy_httpd_con(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct httpd_callback *entry;
|
||||
list_for_each_entry(entry, &httpd_cb_list, list) {
|
||||
|
||||
if ((entry->wildcard == 1 && strncmp(entry->name, con->req_args[0], strlen(entry->name)) == 0) ||
|
||||
(entry->wildcard == 0 && strcmp(entry->name, con->req_args[0]) == 0)) {
|
||||
|
||||
entry->callback(con, entry->privdata);
|
||||
destroy_httpd_con(con);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
httpd_send_error(con, "404 Not Found", "File not found\r\n");
|
||||
destroy_httpd_con(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int httpd_accept_handler(int fd, void *privdata)
|
||||
{
|
||||
struct httpd_con *con = malloc(sizeof(struct httpd_con));
|
||||
if (con == NULL) {
|
||||
log_print(LOG_WARN, "httpd_accept_handler(): out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(con, 0, sizeof(struct httpd_con));
|
||||
|
||||
unsigned int i = sizeof(con->addr);
|
||||
con->fd = accept(fd, (struct sockaddr *)&con->addr, &i);
|
||||
if (con->fd < 0) {
|
||||
free(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
con->event = event_add_readfd(NULL, con->fd, httpd_content_handler, con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct httpd_callback * httpd_add_cb(const char *name,
|
||||
int wildcard,
|
||||
int (* callback)(struct httpd_con *con, void *privdata),
|
||||
void *privdata)
|
||||
{
|
||||
struct httpd_callback *hcb = malloc(sizeof(struct httpd_callback));
|
||||
if (hcb == NULL) {
|
||||
log_print(LOG_WARN, "httpd_create_cb(): out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hcb->name = strdup(name);
|
||||
hcb->wildcard = wildcard;
|
||||
hcb->callback = callback;
|
||||
hcb->privdata = privdata;
|
||||
|
||||
list_add_tail(&hcb->list, &httpd_cb_list);
|
||||
return hcb;
|
||||
}
|
||||
|
||||
int httpd_remove_cb(struct httpd_callback *hcb)
|
||||
{
|
||||
list_del(&hcb->list);
|
||||
free(hcb->name);
|
||||
free(hcb);
|
||||
return 0;
|
||||
}
|
42
httpd.h
Normal file
42
httpd.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef _HTTPD_H_
|
||||
#define _HTTPD_H_
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "list.h"
|
||||
|
||||
struct httpd_con {
|
||||
struct sockaddr_in addr;
|
||||
struct event_fd *event;
|
||||
|
||||
int fd;
|
||||
|
||||
char *req_data;
|
||||
unsigned int req_size;
|
||||
|
||||
char **req_headers;
|
||||
unsigned int req_header_cnt;
|
||||
|
||||
char **req_args;
|
||||
unsigned int req_arg_cnt;
|
||||
};
|
||||
|
||||
struct httpd_callback {
|
||||
struct list_head list;
|
||||
char *name;
|
||||
int wildcard;
|
||||
|
||||
int (* callback)(struct httpd_con *con, void *privdata);
|
||||
void *privdata;
|
||||
};
|
||||
|
||||
int httpd_send_header(struct httpd_con *con, char *code, char *type);
|
||||
int httpd_send_error(struct httpd_con *con, char *code, char *msg);
|
||||
|
||||
struct httpd_callback * httpd_add_cb(const char *name, int flags, int (* cb)(struct httpd_con *con, void *privdata), void *privdata);
|
||||
int httpd_remove_cb(struct httpd_callback *cb);
|
||||
|
||||
int httpd_accept_handler(int fd, void *privdata);
|
||||
|
||||
#endif // _HTTP_H_
|
207
torrent-stats.c
207
torrent-stats.c
@ -1,212 +1,16 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "configfile.h"
|
||||
#include "connection.h"
|
||||
#include "event.h"
|
||||
#include "linebuffer.h"
|
||||
#include "httpd.h"
|
||||
#include "list.h"
|
||||
#include "logging.h"
|
||||
#include "sockaddr.h"
|
||||
#include "tcpsocket.h"
|
||||
|
||||
/*
|
||||
startup:
|
||||
PROTOCOL 0002
|
||||
CTORRENT -CD0300-0xECFCD73A6132281994AF75C3 1179237904 1179239410 debian-40r0-i386-netinst.iso.torrent
|
||||
CTSTATUS 0:174/1:5/0 636/636/636 0,1070 169914368,638976 0,0 32
|
||||
|
||||
periodic:
|
||||
CTBW 0,1070 0,0
|
||||
|
||||
-------------------------
|
||||
|
||||
"SENDDETAIL":
|
||||
CTDETAIL 166621184 262144 1179239468 1179238848
|
||||
CTFILES
|
||||
CTFILE 1 636 636 636 166621184 debian-40r0-i386-netinst.iso
|
||||
CTFDONE
|
||||
|
||||
"CTDETAIL %lld %d %ld %ld",
|
||||
BTCONTENT.GetTotalFilesLength(),
|
||||
(int)(BTCONTENT.GetPieceLength()),
|
||||
(long)now,
|
||||
(long)(BTCONTENT.GetSeedTime()) );
|
||||
|
||||
"CTFILE %d %d %d %d %llu %s",
|
||||
(int)n,
|
||||
(int)(BTCONTENT.getFilePieces(n)),
|
||||
(int)(tmpBitField.Count()),
|
||||
(int)(tmpavail.Count()),
|
||||
(unsigned long long)(file->bf_length),
|
||||
file->bf_filename );
|
||||
|
||||
-------------------------
|
||||
|
||||
"SENDSTATUS":
|
||||
CTSTATUS 0:174/1:5/0 636/636/636 0,959 169914368,655360 0,0 32
|
||||
|
||||
"CTSTATUS %d:%d/%d:%d/%d %d/%d/%d %d,%d %llu,%llu %d,%d %d",
|
||||
(int)(m_ctstatus.seeders),
|
||||
(int)(Tracker.GetSeedsCount() - ((BTCONTENT.pBF->IsFull() && Tracker.GetSeedsCount() > 0) ? 1 : 0)),
|
||||
(int)(m_ctstatus.leechers),
|
||||
(int)(Tracker.GetPeersCount() - Tracker.GetSeedsCount() - ((!BTCONTENT.pBF->IsFull() && Tracker.GetPeersCount() > 0) ? 1 : 0)),
|
||||
(int)(WORLD.GetConnCount()),
|
||||
|
||||
(int)(m_ctstatus.nhave),
|
||||
(int)(m_ctstatus.ntotal),
|
||||
(int)(WORLD.Pieces_I_Can_Get()),
|
||||
|
||||
(int)(m_ctstatus.dlrate),
|
||||
(int)(m_ctstatus.ulrate),
|
||||
|
||||
(unsigned long long)(m_ctstatus.dltotal),
|
||||
(unsigned long long)(m_ctstatus.ultotal),
|
||||
|
||||
(int)(m_ctstatus.dlimit),
|
||||
(int)(m_ctstatus.ulimit),
|
||||
|
||||
(int)(m_ctstatus.cacheused) );
|
||||
|
||||
-------------------------
|
||||
|
||||
"SENDCONF":
|
||||
CTCONFIG 0 72 0.000000 100 1 0 16 0
|
||||
|
||||
"SENDPEERS":
|
||||
CTPEERS
|
||||
CTPEER M3-4-2--bae925c0c070 159.148.184.187 UnUi 0 862 114688 688128 520
|
||||
CTPDONE
|
||||
*/
|
||||
|
||||
static LIST_HEAD(client_list);
|
||||
|
||||
struct client_con {
|
||||
struct list_head list;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
struct event_timeout *trigger;
|
||||
struct event_fd *event;
|
||||
struct linebuffer *lbuf;
|
||||
|
||||
int bw_up;
|
||||
int bw_dn;
|
||||
|
||||
unsigned long long total_up;
|
||||
unsigned long long total_dn;
|
||||
|
||||
int chunk_total;
|
||||
int chunk_avail;
|
||||
int chunk_have;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
if (linebuffer_read(con->lbuf, fd) < 0) {
|
||||
log_print(LOG_WARN, "data_cb(): client %s read", get_sockaddr_buf(&con->addr));
|
||||
list_del(&con->list);
|
||||
free_client(con);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *line;
|
||||
while ((line = linebuffer_get(con->lbuf)) != NULL) {
|
||||
// log_print(LOG_DEBUG, "%s: %s", get_sockaddr_buf(&con->addr), line);
|
||||
|
||||
if (strncmp(line, "CTBW ", 5) == 0) {
|
||||
int bwup, bwdn, liup, lidn;
|
||||
if (sscanf(line +5, "%d,%d %d,%d", &bwdn, &bwup, &lidn, &liup) == 4) {
|
||||
con->bw_up = bwup;
|
||||
con->bw_dn = bwdn;
|
||||
}
|
||||
|
||||
} else if (strncmp(line, "CTSTATUS ", 9) == 0) {
|
||||
int seeds1 = 0, seeds2 = 0, leech1 = 0, leech2 = 0, count = 0;
|
||||
int chunk1 = 0, chunk2 = 0, chunk3 = 0, bwdn = 0, bwup = 0;
|
||||
int lidn = 0, liup = 0, cache = 0;
|
||||
unsigned long long totdn = 0, totup = 0;
|
||||
|
||||
if (sscanf(line +9, "%d:%d/%d:%d/%d %d/%d/%d %d,%d %llu,%llu %d,%d %d",
|
||||
&seeds1, &seeds2, &leech1, &leech2, &count,
|
||||
&chunk1, &chunk2, &chunk3,
|
||||
&bwdn, &bwup, &totdn, &totup,
|
||||
&lidn, &liup, &cache) == 15) {
|
||||
|
||||
con->total_up = totup;
|
||||
con->total_dn = totdn;
|
||||
con->chunk_have = chunk1;
|
||||
con->chunk_total = chunk2;
|
||||
con->chunk_avail = chunk3;
|
||||
}
|
||||
|
||||
log_print(LOG_INFO, "%s: got %3.2lf%% of %3.2lf%% [down: %llu (%d), up: %llu (%d)] ",
|
||||
get_sockaddr_buf(&con->addr),
|
||||
(double)con->chunk_have / (double)con->chunk_total * 100.0,
|
||||
(double)con->chunk_avail / (double)con->chunk_total * 100.0,
|
||||
con->total_dn, con->bw_dn, con->total_up, con->bw_up);
|
||||
}
|
||||
|
||||
free(line);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int accept_cb(int fd, void *privdata)
|
||||
{
|
||||
struct client_con *con = malloc(sizeof(struct client_con));
|
||||
if (con == NULL) {
|
||||
log_print(LOG_WARN, "accept_cb(): out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(con, 0, sizeof(struct client_con));
|
||||
|
||||
con->lbuf = create_linebuffer(1024);
|
||||
if (con->lbuf == NULL) {
|
||||
log_print(LOG_WARN, "accept_cb(): out of memory");
|
||||
free(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int i = sizeof(con->addr);
|
||||
int sockfd = accept(fd, (struct sockaddr *)&con->addr, &i);
|
||||
if (sockfd < 0) {
|
||||
log_print(LOG_WARN, "accept_cb(): accept()");
|
||||
free(con->lbuf);
|
||||
free(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_print(LOG_INFO, "new client %s", get_sockaddr_buf(&con->addr));
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int listen_cb(const char *parameter, void *privdata)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
@ -223,7 +27,7 @@ static int listen_cb(const char *parameter, void *privdata)
|
||||
}
|
||||
|
||||
log_print(LOG_INFO, "listen on %s", get_sockaddr_buf(&addr));
|
||||
event_add_readfd(NULL, sockfd, accept_cb, NULL);
|
||||
event_add_readfd(NULL, sockfd, privdata, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -232,7 +36,10 @@ int main(int argc, char *argv[])
|
||||
if (config_parse("torrent-stats.conf") < 0)
|
||||
return 1;
|
||||
|
||||
config_get_strings("global", "listen", listen_cb, NULL);
|
||||
config_get_strings("global", "listen", listen_cb, ctcs_accept_handler);
|
||||
config_get_strings("global", "listen-http", listen_cb, httpd_accept_handler);
|
||||
|
||||
httpd_add_cb("/", 1, ctcs_httpd_handler, NULL);
|
||||
|
||||
event_loop();
|
||||
return 0;
|
||||
|
@ -1,2 +1,3 @@
|
||||
[global]
|
||||
listen 0.0.0.0:2780
|
||||
listen-http 0.0.0.0:8080
|
||||
|
Loading…
Reference in New Issue
Block a user