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.

214 lignes
4.6 KiB

  1. #include <sys/types.h>
  2. #include <sys/mman.h>
  3. #include <sys/stat.h>
  4. #include <assert.h>
  5. #include <errno.h>
  6. #include <fcntl.h>
  7. #include <math.h>
  8. #include <limits.h>
  9. #include <stdarg.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <openssl/sha.h>
  15. #include "btpd.h"
  16. #include "tracker_req.h"
  17. #include "stream.h"
  18. static unsigned m_ntorrents;
  19. static struct torrent_tq m_torrents = BTPDQ_HEAD_INITIALIZER(m_torrents);
  20. const struct torrent_tq *
  21. torrent_get_all(void)
  22. {
  23. return &m_torrents;
  24. }
  25. unsigned
  26. torrent_count(void)
  27. {
  28. return m_ntorrents;
  29. }
  30. struct torrent *
  31. torrent_get(const uint8_t *hash)
  32. {
  33. struct torrent *tp = BTPDQ_FIRST(&m_torrents);
  34. while (tp != NULL && bcmp(hash, tp->meta.info_hash, 20) != 0)
  35. tp = BTPDQ_NEXT(tp, entry);
  36. return tp;
  37. }
  38. const char *
  39. torrent_name(struct torrent *tp)
  40. {
  41. return tp->meta.name;
  42. }
  43. off_t
  44. torrent_piece_size(struct torrent *tp, uint32_t index)
  45. {
  46. if (index < tp->meta.npieces - 1)
  47. return tp->meta.piece_length;
  48. else {
  49. off_t allbutlast = tp->meta.piece_length * (tp->meta.npieces - 1);
  50. return tp->meta.total_length - allbutlast;
  51. }
  52. }
  53. uint32_t
  54. torrent_piece_blocks(struct torrent *tp, uint32_t piece)
  55. {
  56. return ceil(torrent_piece_size(tp, piece) / (double)PIECE_BLOCKLEN);
  57. }
  58. uint32_t
  59. torrent_block_size(struct torrent *tp, uint32_t piece, uint32_t nblocks,
  60. uint32_t block)
  61. {
  62. if (block < nblocks - 1)
  63. return PIECE_BLOCKLEN;
  64. else {
  65. uint32_t allbutlast = PIECE_BLOCKLEN * (nblocks - 1);
  66. return torrent_piece_size(tp, piece) - allbutlast;
  67. }
  68. }
  69. static void
  70. torrent_relpath(const uint8_t *hash, char *buf)
  71. {
  72. for (int i = 0; i < 20; i++)
  73. snprintf(buf + i * 2, 3, "%.2x", hash[i]);
  74. }
  75. int
  76. torrent_set_links(const uint8_t *hash, const char *torrent,
  77. const char *content)
  78. {
  79. char relpath[RELPATH_SIZE];
  80. char file[PATH_MAX];
  81. torrent_relpath(hash, relpath);
  82. snprintf(file, PATH_MAX, "torrents/%s", relpath);
  83. if (mkdir(file, 0777) == -1 && errno != EEXIST)
  84. return errno;
  85. snprintf(file, PATH_MAX, "torrents/%s/torrent", relpath);
  86. if (unlink(file) == -1 && errno != ENOENT)
  87. return errno;
  88. if (symlink(torrent, file) == -1)
  89. return errno;
  90. snprintf(file, PATH_MAX, "torrents/%s/content", relpath);
  91. if (unlink(file) == -1 && errno != ENOENT)
  92. return errno;
  93. if (symlink(content, file) == -1)
  94. return errno;
  95. return 0;
  96. }
  97. int
  98. torrent_start(const uint8_t *hash)
  99. {
  100. struct torrent *tp;
  101. struct metainfo *mi;
  102. int error;
  103. char relpath[RELPATH_SIZE];
  104. char file[PATH_MAX];
  105. torrent_relpath(hash, relpath);
  106. snprintf(file, PATH_MAX, "torrents/%s/torrent", relpath);
  107. if ((error = load_metainfo(file, -1, 0, &mi)) != 0) {
  108. btpd_log(BTPD_L_ERROR, "Couldn't load torrent file %s: %s.\n",
  109. file, strerror(error));
  110. return error;
  111. }
  112. tp = btpd_calloc(1, sizeof(*tp));
  113. bcopy(relpath, tp->relpath, RELPATH_SIZE);
  114. tp->meta = *mi;
  115. free(mi);
  116. btpd_log(BTPD_L_BTPD, "Starting torrent '%s'.\n", torrent_name(tp));
  117. if ((error = tr_create(tp)) == 0) {
  118. net_create(tp);
  119. cm_create(tp);
  120. BTPDQ_INSERT_TAIL(&m_torrents, tp, entry);
  121. m_ntorrents++;
  122. cm_start(tp);
  123. } else {
  124. clear_metainfo(&tp->meta);
  125. free(tp);
  126. }
  127. return error;
  128. }
  129. static void
  130. torrent_kill(struct torrent *tp)
  131. {
  132. btpd_log(BTPD_L_BTPD, "Removed torrent '%s'.\n", torrent_name(tp));
  133. assert(m_ntorrents > 0);
  134. assert(!(tr_active(tp) || net_active(tp) || cm_active(tp)));
  135. m_ntorrents--;
  136. BTPDQ_REMOVE(&m_torrents, tp, entry);
  137. clear_metainfo(&tp->meta);
  138. tr_kill(tp);
  139. net_kill(tp);
  140. cm_kill(tp);
  141. free(tp);
  142. if (m_ntorrents == 0)
  143. btpd_on_no_torrents();
  144. }
  145. void
  146. torrent_stop(struct torrent *tp)
  147. {
  148. int tra, cma;
  149. switch (tp->state) {
  150. case T_STARTING:
  151. case T_ACTIVE:
  152. tp->state = T_STOPPING;
  153. if (net_active(tp))
  154. net_stop(tp);
  155. tra = tr_active(tp);
  156. cma = cm_active(tp);
  157. if (tra)
  158. tr_stop(tp);
  159. if (cma)
  160. cm_stop(tp);
  161. if (!(tra || cma))
  162. torrent_kill(tp);
  163. break;
  164. case T_STOPPING:
  165. if (tr_active(tp))
  166. tr_stop(tp);
  167. break;
  168. }
  169. }
  170. void
  171. torrent_on_cm_started(struct torrent *tp)
  172. {
  173. tp->state = T_ACTIVE;
  174. net_start(tp);
  175. tr_start(tp);
  176. }
  177. void
  178. torrent_on_cm_stopped(struct torrent *tp)
  179. {
  180. assert(tp->state == T_STOPPING);
  181. if (!tr_active(tp))
  182. torrent_kill(tp);
  183. }
  184. void
  185. torrent_on_tr_stopped(struct torrent *tp)
  186. {
  187. assert(tp->state == T_STOPPING);
  188. if (!cm_active(tp))
  189. torrent_kill(tp);
  190. }