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.

224 lignes
5.2 KiB

  1. #include "btpd.h"
  2. #include <openssl/sha.h>
  3. #define SAVE_INTERVAL 300
  4. static unsigned m_ntorrents;
  5. static struct torrent_tq m_torrents = BTPDQ_HEAD_INITIALIZER(m_torrents);
  6. static unsigned m_tsave;
  7. static struct torrent *m_savetp;
  8. const struct torrent_tq *
  9. torrent_get_all(void)
  10. {
  11. return &m_torrents;
  12. }
  13. unsigned
  14. torrent_count(void)
  15. {
  16. return m_ntorrents;
  17. }
  18. struct torrent *
  19. torrent_by_num(unsigned num)
  20. {
  21. struct tlib *tl = tlib_by_num(num);
  22. return tl != NULL ? tl->tp : NULL;
  23. }
  24. struct torrent *
  25. torrent_by_hash(const uint8_t *hash)
  26. {
  27. struct tlib *tl = tlib_by_hash(hash);
  28. return tl != NULL ? tl->tp : NULL;
  29. }
  30. const char *
  31. torrent_name(struct torrent *tp)
  32. {
  33. return tp->tl->name;
  34. }
  35. off_t
  36. torrent_piece_size(struct torrent *tp, uint32_t index)
  37. {
  38. if (index < tp->npieces - 1)
  39. return tp->piece_length;
  40. else {
  41. off_t allbutlast = tp->piece_length * (tp->npieces - 1);
  42. return tp->total_length - allbutlast;
  43. }
  44. }
  45. uint32_t
  46. torrent_piece_blocks(struct torrent *tp, uint32_t piece)
  47. {
  48. return ceil(torrent_piece_size(tp, piece) / (double)PIECE_BLOCKLEN);
  49. }
  50. uint32_t
  51. torrent_block_size(struct torrent *tp, uint32_t piece, uint32_t nblocks,
  52. uint32_t block)
  53. {
  54. if (block < nblocks - 1)
  55. return PIECE_BLOCKLEN;
  56. else {
  57. uint32_t allbutlast = PIECE_BLOCKLEN * (nblocks - 1);
  58. return torrent_piece_size(tp, piece) - allbutlast;
  59. }
  60. }
  61. enum ipc_err
  62. torrent_start(struct tlib *tl)
  63. {
  64. struct torrent *tp;
  65. char *mi;
  66. if (tl->dir == NULL)
  67. return IPC_EBADTENT;
  68. if (tlib_load_mi(tl, &mi) != 0)
  69. return IPC_EBADTENT;
  70. tp = btpd_calloc(1, sizeof(*tp));
  71. tp->tl = tl;
  72. tp->files = mi_files(mi);
  73. tp->nfiles = mi_nfiles(mi);
  74. if (tp->files == NULL)
  75. btpd_err("out of memory.\n");
  76. tp->total_length = mi_total_length(mi);
  77. tp->piece_length = mi_piece_length(mi);
  78. tp->npieces = mi_npieces(mi);
  79. tp->pieces_off =
  80. benc_dget_mem(benc_dget_dct(mi, "info"), "pieces", NULL) - mi;
  81. btpd_log(BTPD_L_BTPD, "Starting torrent '%s'.\n", torrent_name(tp));
  82. if (tr_create(tp, mi) == 0) {
  83. tl->tp = tp;
  84. net_create(tp);
  85. cm_create(tp, mi);
  86. BTPDQ_INSERT_TAIL(&m_torrents, tp, entry);
  87. m_ntorrents++;
  88. cm_start(tp, 0);
  89. free(mi);
  90. if (m_ntorrents == 1) {
  91. m_tsave = btpd_seconds + SAVE_INTERVAL;
  92. m_savetp = tp;
  93. }
  94. return IPC_OK;
  95. } else {
  96. mi_free_files(tp->nfiles, tp->files);
  97. free(tp);
  98. free(mi);
  99. return IPC_EBADTRACKER;
  100. }
  101. }
  102. static void
  103. torrent_kill(struct torrent *tp)
  104. {
  105. btpd_log(BTPD_L_BTPD, "Stopped torrent '%s'.\n", torrent_name(tp));
  106. assert(m_ntorrents > 0);
  107. assert(!(tr_active(tp) || net_active(tp) || cm_active(tp)));
  108. m_ntorrents--;
  109. BTPDQ_REMOVE(&m_torrents, tp, entry);
  110. tp->tl->tp = NULL;
  111. if (tp->delete)
  112. tlib_del(tp->tl);
  113. tr_kill(tp);
  114. net_kill(tp);
  115. cm_kill(tp);
  116. mi_free_files(tp->nfiles, tp->files);
  117. if (m_savetp == tp)
  118. if ((m_savetp = BTPDQ_NEXT(tp, entry)) == NULL)
  119. m_savetp = BTPDQ_FIRST(&m_torrents);
  120. free(tp);
  121. }
  122. void
  123. torrent_stop(struct torrent *tp, int delete)
  124. {
  125. if (delete)
  126. tp->delete = 1;
  127. switch (tp->state) {
  128. case T_LEECH:
  129. case T_SEED:
  130. case T_STARTING:
  131. tp->state = T_STOPPING;
  132. if (net_active(tp))
  133. net_stop(tp);
  134. if (tr_active(tp))
  135. tr_stop(tp);
  136. if (cm_active(tp))
  137. cm_stop(tp);
  138. if (!delete)
  139. tlib_update_info(tp->tl, 0);
  140. break;
  141. case T_STOPPING:
  142. if (tr_active(tp))
  143. tr_stop(tp);
  144. break;
  145. }
  146. }
  147. void
  148. torrent_on_tick(struct torrent *tp)
  149. {
  150. if (tp->state != T_STOPPING && cm_error(tp))
  151. torrent_stop(tp, 0);
  152. switch (tp->state) {
  153. case T_STARTING:
  154. if (cm_started(tp)) {
  155. if (cm_full(tp))
  156. tp->state = T_SEED;
  157. else
  158. tp->state = T_LEECH;
  159. net_start(tp);
  160. tr_start(tp);
  161. }
  162. break;
  163. case T_LEECH:
  164. if (cm_full(tp)) {
  165. struct peer *p, *next;
  166. tp->state = T_SEED;
  167. btpd_log(BTPD_L_BTPD, "Finished downloading '%s'.\n",
  168. torrent_name(tp));
  169. tr_complete(tp);
  170. BTPDQ_FOREACH_MUTABLE(p, &tp->net->peers, p_entry, next) {
  171. assert(p->nwant == 0);
  172. if (peer_full(p))
  173. peer_kill(p);
  174. }
  175. }
  176. break;
  177. case T_STOPPING:
  178. if (!(cm_active(tp) || tr_active(tp)))
  179. torrent_kill(tp);
  180. break;
  181. default:
  182. break;
  183. }
  184. }
  185. void
  186. torrent_on_tick_all(void)
  187. {
  188. struct torrent *tp, *next;
  189. BTPDQ_FOREACH_MUTABLE(tp, &m_torrents, entry, next)
  190. torrent_on_tick(tp);
  191. if (m_savetp != NULL && m_tsave <= btpd_seconds) {
  192. if (m_savetp->state == T_LEECH || m_savetp->state == T_SEED) {
  193. tlib_update_info(m_savetp->tl, 1);
  194. if ((m_savetp = BTPDQ_NEXT(m_savetp, entry)) == NULL)
  195. m_savetp = BTPDQ_FIRST(&m_torrents);
  196. if (m_ntorrents > 0)
  197. m_tsave = btpd_seconds +
  198. max(m_ntorrents, SAVE_INTERVAL) / m_ntorrents;
  199. }
  200. }
  201. }