A clone of btpd with my configuration changes.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

224 líneas
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. }