A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

197 lignes
5.1 KiB

  1. #include "btcli.h"
  2. #include "utils.h"
  3. void
  4. usage_stat(void)
  5. {
  6. printf(
  7. "Display stats for active torrents.\n"
  8. "\n"
  9. "Usage: stat [-i] [-w seconds] [torrent ...]\n"
  10. "\n"
  11. "Arguments:\n"
  12. "torrent ...\n"
  13. "\tOnly display stats for the given torrents.\n"
  14. "\n"
  15. "Options:\n"
  16. "-i\n"
  17. "\tDisplay individual lines for each torrent.\n"
  18. "\n"
  19. "-n\n"
  20. "\tDisplay the name of each torrent. Implies '-i'.\n"
  21. "\n"
  22. "-w n\n"
  23. "\tDisplay stats every n seconds.\n"
  24. "\n");
  25. exit(1);
  26. }
  27. struct btstat {
  28. unsigned num;
  29. enum ipc_tstate state;
  30. unsigned peers, tr_good;
  31. long long content_got, content_size, downloaded, uploaded, rate_up,
  32. rate_down, tot_up;
  33. uint32_t pieces_seen, torrent_pieces;
  34. };
  35. struct cbarg {
  36. int individual, names;
  37. struct btstat tot;
  38. };
  39. static enum ipc_tval stkeys[] = {
  40. IPC_TVAL_STATE,
  41. IPC_TVAL_NUM,
  42. IPC_TVAL_NAME,
  43. IPC_TVAL_PCOUNT,
  44. IPC_TVAL_TRGOOD,
  45. IPC_TVAL_PCCOUNT,
  46. IPC_TVAL_PCSEEN,
  47. IPC_TVAL_SESSUP,
  48. IPC_TVAL_SESSDWN,
  49. IPC_TVAL_TOTUP,
  50. IPC_TVAL_RATEUP,
  51. IPC_TVAL_RATEDWN,
  52. IPC_TVAL_CGOT,
  53. IPC_TVAL_CSIZE
  54. };
  55. #define NSTKEYS ARRAY_COUNT(stkeys)
  56. static void
  57. print_stat(struct btstat *st)
  58. {
  59. print_percent(st->content_got, st->content_size);
  60. print_size(st->downloaded);
  61. print_rate(st->rate_down);
  62. print_size(st->uploaded);
  63. print_rate(st->rate_up);
  64. print_ratio(st->tot_up, st->content_size);
  65. printf("%4u ", st->peers);
  66. print_percent(st->pieces_seen, st->torrent_pieces);
  67. printf("%3u", st->tr_good);
  68. printf("\n");
  69. }
  70. static void
  71. stat_cb(int obji, enum ipc_err objerr, struct ipc_get_res *res, void *arg)
  72. {
  73. struct cbarg *cba = arg;
  74. struct btstat st, *tot = &cba->tot;
  75. if (objerr != IPC_OK || res[IPC_TVAL_STATE].v.num == IPC_TSTATE_INACTIVE)
  76. return;
  77. bzero(&st, sizeof(st));
  78. st.state = res[IPC_TVAL_STATE].v.num;
  79. st.num = res[IPC_TVAL_NUM].v.num;
  80. tot->torrent_pieces += (st.torrent_pieces = res[IPC_TVAL_PCCOUNT].v.num);
  81. tot->pieces_seen += (st.pieces_seen = res[IPC_TVAL_PCSEEN].v.num);
  82. tot->content_got += (st.content_got = res[IPC_TVAL_CGOT].v.num);
  83. tot->content_size += (st.content_size = res[IPC_TVAL_CSIZE].v.num);
  84. tot->downloaded += (st.downloaded = res[IPC_TVAL_SESSDWN].v.num);
  85. tot->uploaded += (st.uploaded = res[IPC_TVAL_SESSUP].v.num);
  86. tot->rate_down += (st.rate_down = res[IPC_TVAL_RATEDWN].v.num);
  87. tot->rate_up += (st.rate_up = res[IPC_TVAL_RATEUP].v.num);
  88. tot->peers += (st.peers = res[IPC_TVAL_PCOUNT].v.num);
  89. tot->tot_up += (st.tot_up = res[IPC_TVAL_TOTUP].v.num);
  90. tot->tr_good += (st.tr_good = res[IPC_TVAL_TRGOOD].v.num);
  91. if (cba->individual) {
  92. if (cba->names)
  93. printf("%.*s\n", (int)res[IPC_TVAL_NAME].v.str.l,
  94. res[IPC_TVAL_NAME].v.str.p);
  95. printf("%4u %c. ", st.num, tstate_char(st.state));
  96. print_stat(&st);
  97. }
  98. }
  99. static void
  100. do_stat(int individual, int names, int seconds, struct ipc_torrent *tps,
  101. int ntps)
  102. {
  103. enum ipc_err err;
  104. struct cbarg cba;
  105. int header = 1;
  106. if (names)
  107. individual = 1;
  108. cba.individual = individual;
  109. cba.names = names;
  110. again:
  111. header--;
  112. if (header == 0) {
  113. if (individual) {
  114. header = 1;
  115. printf(" NUM ST ");
  116. } else
  117. header = 20;
  118. printf(" HAVE DLOAD RTDWN ULOAD RTUP RATIO CONN"
  119. " AVAIL TR\n");
  120. }
  121. bzero(&cba.tot, sizeof(cba.tot));
  122. cba.tot.state = IPC_TSTATE_INACTIVE;
  123. if (tps == NULL)
  124. err = btpd_tget_wc(ipc, IPC_TWC_ACTIVE, stkeys, NSTKEYS,
  125. stat_cb, &cba);
  126. else
  127. err = btpd_tget(ipc, tps, ntps, stkeys, NSTKEYS, stat_cb, &cba);
  128. if (err != IPC_OK)
  129. diemsg("command failed (%s).\n", ipc_strerror(err));
  130. if (names)
  131. printf("-------\n");
  132. if (individual)
  133. printf(" ");
  134. print_stat(&cba.tot);
  135. if (seconds > 0) {
  136. sleep(seconds);
  137. goto again;
  138. }
  139. }
  140. static struct option stat_opts [] = {
  141. { "help", no_argument, NULL, 'H' },
  142. {NULL, 0, NULL, 0}
  143. };
  144. void
  145. cmd_stat(int argc, char **argv)
  146. {
  147. int ch;
  148. int wflag = 0, iflag = 0, nflag = 0, seconds = 0;
  149. struct ipc_torrent *tps = NULL;
  150. int ntps = 0;
  151. char *endptr;
  152. while ((ch = getopt_long(argc, argv, "inw:", stat_opts, NULL)) != -1) {
  153. switch (ch) {
  154. case 'i':
  155. iflag = 1;
  156. break;
  157. case 'n':
  158. nflag = 1;
  159. break;
  160. case 'w':
  161. wflag = 1;
  162. seconds = strtol(optarg, &endptr, 10);
  163. if (*endptr != '\0' || seconds < 1)
  164. usage_stat();
  165. break;
  166. default:
  167. usage_stat();
  168. }
  169. }
  170. argc -= optind;
  171. argv += optind;
  172. if (argc > 0) {
  173. tps = malloc(argc * sizeof(*tps));
  174. for (int i = 0; i < argc; i++) {
  175. if (torrent_spec(argv[i], &tps[ntps]))
  176. ntps++;
  177. else
  178. exit(1);
  179. }
  180. }
  181. btpd_connect();
  182. do_stat(iflag, nflag, seconds, tps, ntps);
  183. }