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.

208 lignes
4.4 KiB

  1. #include <stdarg.h>
  2. #include "btcli.h"
  3. #include "utils.h"
  4. const char *btpd_dir;
  5. struct ipc *ipc;
  6. void
  7. diemsg(const char *fmt, ...)
  8. {
  9. va_list ap;
  10. va_start(ap, fmt);
  11. vfprintf(stderr, fmt, ap);
  12. va_end(ap);
  13. exit(1);
  14. }
  15. void
  16. btpd_connect(void)
  17. {
  18. if ((errno = ipc_open(btpd_dir, &ipc)) != 0)
  19. diemsg("cannot open connection to btpd in %s (%s).\n", btpd_dir,
  20. strerror(errno));
  21. }
  22. enum ipc_err
  23. handle_ipc_res(enum ipc_err code, const char *cmd, const char *target)
  24. {
  25. switch (code) {
  26. case IPC_OK:
  27. break;
  28. case IPC_COMMERR:
  29. diemsg("error in communication with btpd.\n");
  30. default:
  31. fprintf(stderr, "btcli %s '%s': %s.\n", cmd, target,
  32. ipc_strerror(code));
  33. }
  34. return code;
  35. }
  36. void
  37. print_percent(long long part, long long whole)
  38. {
  39. printf("%5.1f%% ", floor(1000.0 * part / whole) / 10);
  40. }
  41. void
  42. print_rate(long long rate)
  43. {
  44. if (rate >= 999.995 * (1 << 10))
  45. printf("%6.2fMB/s ", (double)rate / (1 << 20));
  46. else
  47. printf("%6.2fkB/s ", (double)rate / (1 << 10));
  48. }
  49. void
  50. print_size(long long size)
  51. {
  52. if (size >= 999.995 * (1 << 20))
  53. printf("%6.2fG ", (double)size / (1 << 30));
  54. else
  55. printf("%6.2fM ", (double)size / (1 << 20));
  56. }
  57. void
  58. print_ratio(long long part, long long whole)
  59. {
  60. printf("%7.2f ", (double)part / whole);
  61. }
  62. char
  63. tstate_char(enum ipc_tstate ts)
  64. {
  65. switch (ts) {
  66. case IPC_TSTATE_INACTIVE:
  67. return 'I';
  68. case IPC_TSTATE_START:
  69. return '+';
  70. case IPC_TSTATE_STOP:
  71. return '-';
  72. case IPC_TSTATE_LEECH:
  73. return 'L';
  74. case IPC_TSTATE_SEED:
  75. return 'S';
  76. }
  77. diemsg("unrecognized torrent state.\n");
  78. }
  79. int
  80. torrent_spec(char *arg, struct ipc_torrent *tp)
  81. {
  82. char *p;
  83. tp->u.num = strtoul(arg, &p, 10);
  84. if (*p == '\0') {
  85. tp->by_hash = 0;
  86. return 1;
  87. }
  88. if ((p = mi_load(arg, NULL)) == NULL) {
  89. fprintf(stderr, "btcli: bad torrent '%s' (%s).\n", arg,
  90. strerror(errno));
  91. return 0;
  92. }
  93. tp->by_hash = 1;
  94. mi_info_hash(p, tp->u.hash);
  95. free(p);
  96. return 1;
  97. }
  98. static struct {
  99. const char *name;
  100. void (*fun)(int, char **);
  101. void (*help)(void);
  102. } cmd_table[] = {
  103. { "add", cmd_add, usage_add },
  104. { "del", cmd_del, usage_del },
  105. { "kill", cmd_kill, usage_kill },
  106. { "list", cmd_list, usage_list },
  107. { "rate", cmd_rate, usage_rate },
  108. { "start", cmd_start, usage_start },
  109. { "stop", cmd_stop, usage_stop },
  110. { "stat", cmd_stat, usage_stat }
  111. };
  112. static void
  113. usage(void)
  114. {
  115. printf(
  116. "btcli is the btpd command line interface.\n"
  117. "\n"
  118. "Usage: btcli [main options] command [command options]\n"
  119. "\n"
  120. "Main options:\n"
  121. "-d dir\n"
  122. "\tThe btpd directory.\n"
  123. "\n"
  124. "--help [command]\n"
  125. "\tShow this text or help for the specified command.\n"
  126. "\n"
  127. "Commands:\n"
  128. "add\t- Add torrents to btpd.\n"
  129. "del\t- Remove torrents from btpd.\n"
  130. "kill\t- Shut down btpd.\n"
  131. "list\t- List torrents.\n"
  132. "rate\t- Set up/download rate limits.\n"
  133. "start\t- Activate torrents.\n"
  134. "stat\t- Display stats for active torrents.\n"
  135. "stop\t- Deactivate torrents.\n"
  136. "\n"
  137. "Note:\n"
  138. "Torrents can be specified either with its number or its file.\n"
  139. "\n"
  140. );
  141. exit(1);
  142. }
  143. static struct option base_opts [] = {
  144. { "help", no_argument, NULL, 'H' },
  145. {NULL, 0, NULL, 0}
  146. };
  147. int
  148. main(int argc, char **argv)
  149. {
  150. int ch, help = 0;
  151. if (argc < 2)
  152. usage();
  153. while ((ch = getopt_long(argc, argv, "+d:", base_opts, NULL)) != -1) {
  154. switch (ch) {
  155. case 'd':
  156. btpd_dir = optarg;
  157. break;
  158. case 'H':
  159. help = 1;
  160. break;
  161. default:
  162. usage();
  163. }
  164. }
  165. argc -= optind;
  166. argv += optind;
  167. if (argc == 0)
  168. usage();
  169. if (btpd_dir == NULL)
  170. if ((btpd_dir = find_btpd_dir()) == NULL)
  171. diemsg("cannot find the btpd directory.\n");
  172. optind = 0;
  173. int found = 0;
  174. for (int i = 0; !found && i < ARRAY_COUNT(cmd_table); i++) {
  175. if (strcmp(argv[0], cmd_table[i].name) == 0) {
  176. found = 1;
  177. if (help)
  178. cmd_table[i].help();
  179. else
  180. cmd_table[i].fun(argc, argv);
  181. }
  182. }
  183. if (!found)
  184. usage();
  185. return 0;
  186. }