A clone of btpd with my configuration changes.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

196 строки
5.1 KiB

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