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.

225 lignes
5.6 KiB

  1. #include <math.h>
  2. #include "btcli.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] [file ...]\n"
  10. "\n"
  11. "Arguments:\n"
  12. "file ...\n"
  13. "\tOnly display stats for the given torrent(s).\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_errors;
  31. long long content_got, content_size, downloaded, uploaded, rate_up,
  32. rate_down;
  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_TRERR,
  45. IPC_TVAL_PCCOUNT,
  46. IPC_TVAL_PCSEEN,
  47. IPC_TVAL_SESSUP,
  48. IPC_TVAL_SESSDWN,
  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_percent(long long part, long long whole)
  57. {
  58. printf("%5.1f%% ", floor(1000.0 * part / whole) / 10);
  59. }
  60. static void
  61. print_rate(long long rate)
  62. {
  63. if (rate >= 999.995 * (1 << 10))
  64. printf("%6.2fMB/s ", (double)rate / (1 << 20));
  65. else
  66. printf("%6.2fkB/s ", (double)rate / (1 << 10));
  67. }
  68. static void
  69. print_size(long long size)
  70. {
  71. if (size >= 999.995 * (1 << 20))
  72. printf("%6.2fG ", (double)size / (1 << 30));
  73. else
  74. printf("%6.2fM ", (double)size / (1 << 20));
  75. }
  76. static void
  77. print_stat(struct btstat *st)
  78. {
  79. print_percent(st->content_got, st->content_size);
  80. print_size(st->downloaded);
  81. print_rate(st->rate_down);
  82. print_size(st->uploaded);
  83. print_rate(st->rate_up);
  84. printf("%5u ", st->peers);
  85. print_percent(st->pieces_seen, st->torrent_pieces);
  86. if (st->tr_errors > 0)
  87. printf("E%u", st->tr_errors);
  88. printf("\n");
  89. }
  90. static void
  91. stat_cb(int obji, enum ipc_err objerr, struct ipc_get_res *res, void *arg)
  92. {
  93. struct cbarg *cba = arg;
  94. struct btstat st, *tot = &cba->tot;
  95. if (objerr != IPC_OK || res[IPC_TVAL_STATE].v.num == IPC_TSTATE_INACTIVE)
  96. return;
  97. bzero(&st, sizeof(st));
  98. st.state = res[IPC_TVAL_STATE].v.num;
  99. st.num = res[IPC_TVAL_NUM].v.num;
  100. tot->torrent_pieces += (st.torrent_pieces = res[IPC_TVAL_PCCOUNT].v.num);
  101. tot->pieces_seen += (st.pieces_seen = res[IPC_TVAL_PCSEEN].v.num);
  102. tot->content_got += (st.content_got = res[IPC_TVAL_CGOT].v.num);
  103. tot->content_size += (st.content_size = res[IPC_TVAL_CSIZE].v.num);
  104. tot->downloaded += (st.downloaded = res[IPC_TVAL_SESSDWN].v.num);
  105. tot->uploaded += (st.uploaded = res[IPC_TVAL_SESSUP].v.num);
  106. tot->rate_down += (st.rate_down = res[IPC_TVAL_RATEDWN].v.num);
  107. tot->rate_up += (st.rate_up = res[IPC_TVAL_RATEUP].v.num);
  108. tot->peers += (st.peers = res[IPC_TVAL_PCOUNT].v.num);
  109. if ((st.tr_errors = res[IPC_TVAL_TRERR].v.num) > 0)
  110. tot->tr_errors++;
  111. if (cba->individual) {
  112. if (cba->names)
  113. printf("%.*s\n", (int)res[IPC_TVAL_NAME].v.str.l,
  114. res[IPC_TVAL_NAME].v.str.p);
  115. int n = printf("%u:", st.num);
  116. while (n < 7) {
  117. putchar(' ');
  118. n++;
  119. }
  120. printf("%c. ", tstate_char(st.state));
  121. print_stat(&st);
  122. }
  123. }
  124. static void
  125. do_stat(int individual, int names, int seconds, struct ipc_torrent *tps,
  126. int ntps)
  127. {
  128. enum ipc_err err;
  129. struct cbarg cba;
  130. int header = 1;
  131. if (names)
  132. individual = 1;
  133. cba.individual = individual;
  134. cba.names = names;
  135. again:
  136. header--;
  137. if (header == 0) {
  138. if (individual) {
  139. header = 1;
  140. printf("NUM ST ");
  141. } else
  142. header = 20;
  143. printf(" HAVE DLOAD RTDWN ULOAD RTUP PEERS AVAIL\n");
  144. }
  145. bzero(&cba.tot, sizeof(cba.tot));
  146. cba.tot.state = IPC_TSTATE_INACTIVE;
  147. if (tps == NULL)
  148. err = btpd_tget_wc(ipc, IPC_TWC_ACTIVE, stkeys, nstkeys,
  149. stat_cb, &cba);
  150. else
  151. err = btpd_tget(ipc, tps, ntps, stkeys, nstkeys, stat_cb, &cba);
  152. if (err != IPC_OK)
  153. errx(1, ipc_strerror(err));
  154. if (names)
  155. printf("-----\n");
  156. if (individual)
  157. printf("Total: ");
  158. print_stat(&cba.tot);
  159. if (seconds > 0) {
  160. sleep(seconds);
  161. goto again;
  162. }
  163. }
  164. static struct option stat_opts [] = {
  165. { "help", no_argument, NULL, 'H' },
  166. {NULL, 0, NULL, 0}
  167. };
  168. void
  169. cmd_stat(int argc, char **argv)
  170. {
  171. int ch;
  172. int wflag = 0, iflag = 0, nflag = 0, seconds = 0;
  173. struct ipc_torrent *tps = NULL;
  174. int ntps = 0;
  175. char *endptr;
  176. while ((ch = getopt_long(argc, argv, "inw:", stat_opts, NULL)) != -1) {
  177. switch (ch) {
  178. case 'i':
  179. iflag = 1;
  180. break;
  181. case 'n':
  182. nflag = 1;
  183. break;
  184. case 'w':
  185. wflag = 1;
  186. seconds = strtol(optarg, &endptr, 10);
  187. if (*endptr != '\0' || seconds < 1)
  188. usage_stat();
  189. break;
  190. default:
  191. usage_stat();
  192. }
  193. }
  194. argc -= optind;
  195. argv += optind;
  196. if (argc > 0) {
  197. tps = malloc(argc * sizeof(*tps));
  198. for (int i = 0; i < argc; i++) {
  199. if (torrent_spec(argv[i], &tps[ntps]))
  200. ntps++;
  201. else
  202. exit(1);
  203. }
  204. }
  205. btpd_connect();
  206. do_stat(iflag, nflag, seconds, tps, ntps);
  207. }