characters displayed by btcli.master
@@ -65,26 +65,30 @@ cmd_stat(struct cli *cli, int argc, const char *args) | |||
buf_print(&iob, "9:ntorrentsi%ue", torrent_count()); | |||
buf_swrite(&iob, "8:torrentsl"); | |||
BTPDQ_FOREACH(tp, torrent_get_all(), entry) { | |||
const char *name = torrent_name(tp); | |||
uint32_t seen_npieces = 0; | |||
for (uint32_t i = 0; i < tp->meta.npieces; i++) | |||
if (tp->net->piece_count[i] > 0) | |||
seen_npieces++; | |||
buf_print(&iob, "d4:downi%llde", tp->net->downloaded); | |||
buf_print(&iob, "6:errorsi%ue", tr_errors(tp)); | |||
buf_swrite(&iob, "4:hash20:"); | |||
buf_swrite(&iob, "d"); | |||
buf_print(&iob, "11:content goti%jde", (intmax_t)cm_content(tp)); | |||
buf_print(&iob, "12:content sizei%jde", | |||
(intmax_t)tp->meta.total_length); | |||
buf_print(&iob, "10:downloadedi%llde", tp->net->downloaded); | |||
buf_swrite(&iob, "9:info hash20:"); | |||
buf_write(&iob, tp->meta.info_hash, 20); | |||
buf_print(&iob, "4:havei%jde", (intmax_t)cm_get_size(tp)); | |||
buf_print(&iob, "6:npeersi%ue", tp->net->npeers); | |||
buf_print(&iob, "7:npiecesi%ue", tp->meta.npieces); | |||
buf_print(&iob, "4:path%d:%s", (int)strlen(tp->meta.name), | |||
tp->meta.name); | |||
buf_print(&iob, "2:rdi%lue", tp->net->rate_dwn); | |||
buf_print(&iob, "2:rui%lue", tp->net->rate_up); | |||
buf_print(&iob, "12:seen npiecesi%ue", seen_npieces); | |||
buf_print(&iob, "4:name%d:%s", (int)strlen(name), name); | |||
buf_print(&iob, "5:peersi%ue", tp->net->npeers); | |||
buf_print(&iob, "10:pieces goti%ue", cm_pieces(tp)); | |||
buf_print(&iob, "11:pieces seeni%ue", seen_npieces); | |||
buf_print(&iob, "9:rate downi%lue", tp->net->rate_dwn); | |||
buf_print(&iob, "7:rate upi%lue", tp->net->rate_up); | |||
buf_print(&iob, "5:statei%ue", tp->state); | |||
buf_print(&iob, "5:totali%jde", (intmax_t)tp->meta.total_length); | |||
buf_print(&iob, "2:upi%lldee", tp->net->uploaded); | |||
buf_print(&iob, "14:torrent piecesi%ue", tp->meta.npieces); | |||
buf_print(&iob, "14:tracker errorsi%ue", tr_errors(tp)); | |||
buf_print(&iob, "8:uploadedi%llde", tp->net->uploaded); | |||
buf_swrite(&iob, "e"); | |||
} | |||
buf_swrite(&iob, "ee"); | |||
return write_buffer(cli, &iob); | |||
@@ -4,6 +4,7 @@ | |||
#include <fcntl.h> | |||
#include <math.h> | |||
#include <pthread.h> | |||
#include <signal.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
@@ -434,13 +435,13 @@ cm_full(struct torrent *tp) | |||
} | |||
off_t | |||
cm_get_size(struct torrent *tp) | |||
cm_content(struct torrent *tp) | |||
{ | |||
return tp->cm->ncontent_bytes; | |||
} | |||
uint32_t | |||
cm_get_npieces(struct torrent *tp) | |||
cm_pieces(struct torrent *tp) | |||
{ | |||
return tp->cm->npieces_got; | |||
} | |||
@@ -12,11 +12,12 @@ void cm_stop(struct torrent * tp); | |||
int cm_active(struct torrent *tp); | |||
int cm_full(struct torrent *tp); | |||
off_t cm_content(struct torrent *tp); | |||
uint32_t cm_pieces(struct torrent *tp); | |||
uint8_t *cm_get_piece_field(struct torrent *tp); | |||
uint8_t *cm_get_block_field(struct torrent *tp, uint32_t piece); | |||
uint32_t cm_get_npieces(struct torrent *tp); | |||
int cm_has_piece(struct torrent *tp, uint32_t piece); | |||
int cm_put_bytes(struct torrent *tp, uint32_t piece, uint32_t begin, | |||
@@ -27,6 +28,4 @@ int cm_get_bytes(struct torrent *tp, uint32_t piece, uint32_t begin, | |||
void cm_prealloc(struct torrent *tp, uint32_t piece); | |||
void cm_test_piece(struct torrent *tp, uint32_t piece); | |||
off_t cm_get_size(struct torrent *tp); | |||
#endif |
@@ -106,7 +106,7 @@ static int | |||
dl_should_enter_endgame(struct net *n) | |||
{ | |||
int should; | |||
if (cm_get_npieces(n->tp) + n->npcs_busy == n->tp->meta.npieces) { | |||
if (cm_pieces(n->tp) + n->npcs_busy == n->tp->meta.npieces) { | |||
should = 1; | |||
struct piece *pc; | |||
BTPDQ_FOREACH(pc, &n->getlst, entry) { | |||
@@ -121,7 +121,7 @@ nb_create_have(uint32_t index) | |||
struct net_buf * | |||
nb_create_multihave(struct torrent *tp) | |||
{ | |||
uint32_t have_npieces = cm_get_npieces(tp); | |||
uint32_t have_npieces = cm_pieces(tp); | |||
struct net_buf *out = nb_create_alloc(NB_MULTIHAVE, 9 * have_npieces); | |||
for (uint32_t i = 0, count = 0; count < have_npieces; i++) { | |||
if (cm_has_piece(tp, i)) { | |||
@@ -343,8 +343,8 @@ peer_on_shake(struct peer *p) | |||
printid[i] = '\0'; | |||
btpd_log(BTPD_L_MSG, "received shake(%s) from %p\n", printid, p); | |||
p->piece_field = btpd_calloc(1, (int)ceil(p->n->tp->meta.npieces / 8.0)); | |||
if (cm_get_npieces(p->n->tp) > 0) { | |||
if ((cm_get_npieces(p->n->tp) * 9 < 5 + | |||
if (cm_pieces(p->n->tp) > 0) { | |||
if ((cm_pieces(p->n->tp) * 9 < 5 + | |||
ceil(p->n->tp->meta.npieces / 8.0))) | |||
peer_send(p, nb_create_multihave(p->n->tp)); | |||
else { | |||
@@ -199,7 +199,7 @@ tr_send(struct torrent *tp, enum tr_event event) | |||
"&downloaded=%ju&left=%ju&compact=1%s%s", | |||
tp->meta.announce, qc, e_hash, e_id, net_port, | |||
(intmax_t)tp->net->uploaded, (intmax_t)tp->net->downloaded, | |||
(intmax_t)tp->meta.total_length - cm_get_size(tp), | |||
(intmax_t)tp->meta.total_length - cm_content(tp), | |||
event == TR_EV_EMPTY ? "" : "&event=", m_events[event]); | |||
} | |||
@@ -1,5 +1,6 @@ | |||
#include <stdarg.h> | |||
#include <stdio.h> | |||
#include <time.h> | |||
#include "btpd.h" | |||
@@ -5,6 +5,7 @@ | |||
#include <errno.h> | |||
#include <fcntl.h> | |||
#include <getopt.h> | |||
#include <inttypes.h> | |||
#include <limits.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
@@ -46,24 +47,37 @@ handle_ipc_res(enum ipc_code code, const char *target) | |||
void | |||
print_state_name(struct tpstat *ts) | |||
{ | |||
char statec[] = ">*<U"; | |||
int state = min(ts->state, 3); | |||
printf("%c. %s", statec[state], ts->name); | |||
char c; | |||
switch (ts->state) { | |||
case T_STARTING: | |||
c = '+'; | |||
break; | |||
case T_ACTIVE: | |||
c = ts->pieces_got == ts->torrent_pieces ? 'S' : 'L'; | |||
break; | |||
case T_STOPPING: | |||
c = '-'; | |||
break; | |||
default: | |||
c = 'U'; | |||
break; | |||
} | |||
printf("%c. %s", c, ts->name); | |||
} | |||
void | |||
print_stat(struct tpstat *cur) | |||
print_stat(struct tpstat *ts) | |||
{ | |||
printf("%5.1f%% %6.1fM %7.2fkB/s %6.1fM %7.2fkB/s %4u %5.1f%%", | |||
100.0 * cur->have / cur->total, | |||
(double)cur->downloaded / (1 << 20), | |||
(double)cur->rate_down / (20 << 10), | |||
(double)cur->uploaded / (1 << 20), | |||
(double)cur->rate_up / (20 << 10), | |||
cur->npeers, | |||
100.0 * cur->nseen / cur->npieces); | |||
if (cur->errors > 0) | |||
printf(" E%u", cur->errors); | |||
100.0 * ts->content_got / ts->content_size, | |||
(double)ts->downloaded / (1 << 20), | |||
(double)ts->rate_down / (20 << 10), | |||
(double)ts->uploaded / (1 << 20), | |||
(double)ts->rate_up / (20 << 10), | |||
ts->peers, | |||
100.0 * ts->pieces_seen / ts->torrent_pieces); | |||
if (ts->tr_errors > 0) | |||
printf(" E%u", ts->tr_errors); | |||
printf("\n"); | |||
} | |||
@@ -156,7 +170,7 @@ cmd_add(int argc, char **argv) | |||
&& strcmp(mi->name, mi->files[0].path) == 0))) | |||
snprintf(dpath, PATH_MAX, "%s/%s", bdir, mi->name); | |||
else if (dir != NULL) | |||
strlcpy(dpath, bdir, PATH_MAX); | |||
strncpy(dpath, bdir, PATH_MAX); | |||
else { | |||
if (content_link(mi->info_hash, dpath) != 0) { | |||
warnx("unknown content dir for %s", argv[i]); | |||
@@ -307,7 +321,6 @@ do_stat(int individual, int seconds, int hash_count, uint8_t (*hashes)[20]) | |||
struct tpstat tot; | |||
again: | |||
bzero(&tot, sizeof(tot)); | |||
tot.state = T_ACTIVE; | |||
if (handle_ipc_res(btpd_stat(ipc, &st), "stat") != IPC_OK) | |||
exit(1); | |||
for (int i = 0; i < st->ntorrents; i++) { | |||
@@ -324,11 +337,11 @@ again: | |||
tot.downloaded += cur->downloaded; | |||
tot.rate_up += cur->rate_up; | |||
tot.rate_down += cur->rate_down; | |||
tot.npeers += cur->npeers; | |||
tot.nseen += cur->nseen; | |||
tot.npieces += cur->npieces; | |||
tot.have += cur->have; | |||
tot.total += cur->total; | |||
tot.peers += cur->peers; | |||
tot.pieces_seen += cur->pieces_seen; | |||
tot.torrent_pieces += cur->torrent_pieces; | |||
tot.content_got += cur->content_got; | |||
tot.content_size += cur->content_size; | |||
if (individual) { | |||
print_state_name(cur); | |||
printf(":\n"); | |||
@@ -355,7 +368,7 @@ cmd_stat(int argc, char **argv) | |||
{ | |||
int ch; | |||
int wflag = 0, iflag = 0, seconds = 0; | |||
uint8_t (*hashes)[20]; | |||
uint8_t (*hashes)[20] = NULL; | |||
char *endptr; | |||
while ((ch = getopt_long(argc, argv, "iw:", stat_opts, NULL)) != -1) { | |||
switch (ch) { | |||
@@ -154,19 +154,20 @@ parse_btstat(const uint8_t *res, struct btstat **out) | |||
int i = 0; | |||
for (const char *tp = benc_first(tlst); tp != NULL; tp = benc_next(tp)) { | |||
struct tpstat *ts = &st->torrents[i]; | |||
ts->hash = benc_dget_mema(tp, "hash", NULL); | |||
ts->name = benc_dget_str(tp, "path", NULL); | |||
ts->hash = benc_dget_mema(tp, "info hash", NULL); | |||
ts->name = benc_dget_str(tp, "name", NULL); | |||
ts->state = benc_dget_int(tp, "state"); | |||
ts->errors = benc_dget_int(tp, "errors"); | |||
ts->npieces = benc_dget_int(tp, "npieces"); | |||
ts->nseen = benc_dget_int(tp, "seen npieces"); | |||
ts->npeers = benc_dget_int(tp, "npeers"); | |||
ts->downloaded = benc_dget_int(tp, "down"); | |||
ts->uploaded = benc_dget_int(tp, "up"); | |||
ts->rate_down = benc_dget_int(tp, "rd"); | |||
ts->rate_up = benc_dget_int(tp, "ru"); | |||
ts->have = benc_dget_int(tp, "have"); | |||
ts->total = benc_dget_int(tp, "total"); | |||
ts->peers = benc_dget_int(tp, "peers"); | |||
ts->tr_errors = benc_dget_int(tp, "tracker errors"); | |||
ts->content_got = benc_dget_int(tp, "content got"); | |||
ts->content_size = benc_dget_int(tp, "content size"); | |||
ts->pieces_got = benc_dget_int(tp, "pieces got"); | |||
ts->pieces_seen = benc_dget_int(tp, "pieces seen"); | |||
ts->torrent_pieces = benc_dget_int(tp, "torrent pieces"); | |||
ts->downloaded = benc_dget_int(tp, "downloaded"); | |||
ts->uploaded = benc_dget_int(tp, "uploaded"); | |||
ts->rate_down = benc_dget_int(tp, "rate down"); | |||
ts->rate_up = benc_dget_int(tp, "rate up"); | |||
i++; | |||
} | |||
*out = st; | |||
@@ -22,12 +22,11 @@ struct btstat { | |||
uint8_t *hash; | |||
char *name; | |||
enum torrent_state state; | |||
unsigned errors; | |||
unsigned npeers; | |||
uint32_t npieces, nseen; | |||
off_t have, total; | |||
long long downloaded, uploaded; | |||
unsigned tr_errors; | |||
unsigned peers; | |||
uint32_t pieces_got, pieces_seen, torrent_pieces; | |||
off_t content_got, content_size; | |||
unsigned long long downloaded, uploaded; | |||
unsigned long rate_up, rate_down; | |||
} torrents[]; | |||
}; | |||