diff --git a/btpd/cli_if.c b/btpd/cli_if.c index 830cdb4..6c421e0 100644 --- a/btpd/cli_if.c +++ b/btpd/cli_if.c @@ -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); diff --git a/btpd/content.c b/btpd/content.c index d60d09e..5265f57 100644 --- a/btpd/content.c +++ b/btpd/content.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -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; } diff --git a/btpd/content.h b/btpd/content.h index 7ac10e0..9c92dfe 100644 --- a/btpd/content.h +++ b/btpd/content.h @@ -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 diff --git a/btpd/download_subr.c b/btpd/download_subr.c index df2aaaf..67d9e85 100644 --- a/btpd/download_subr.c +++ b/btpd/download_subr.c @@ -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) { diff --git a/btpd/net_buf.c b/btpd/net_buf.c index 880d94f..e927a09 100644 --- a/btpd/net_buf.c +++ b/btpd/net_buf.c @@ -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)) { diff --git a/btpd/peer.c b/btpd/peer.c index 109b836..8fbfcfd 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -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 { diff --git a/btpd/tracker_req.c b/btpd/tracker_req.c index 8d6018b..e07ee78 100644 --- a/btpd/tracker_req.c +++ b/btpd/tracker_req.c @@ -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]); } diff --git a/btpd/util.c b/btpd/util.c index 576d55b..6a660d8 100644 --- a/btpd/util.c +++ b/btpd/util.c @@ -1,5 +1,6 @@ #include #include +#include #include "btpd.h" diff --git a/cli/btcli.c b/cli/btcli.c index 95139a0..306df1c 100644 --- a/cli/btcli.c +++ b/cli/btcli.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -46,24 +47,37 @@ handle_ipc_res(enum ipc_code code, const char *target) void print_state_name(struct tpstat *ts) { - char statec[] = ">*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) { diff --git a/cli/btpd_if.c b/cli/btpd_if.c index f33851f..c15ce08 100644 --- a/cli/btpd_if.c +++ b/cli/btpd_if.c @@ -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; diff --git a/cli/btpd_if.h b/cli/btpd_if.h index b7096aa..1cc51d9 100644 --- a/cli/btpd_if.h +++ b/cli/btpd_if.h @@ -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[]; };