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.

272 lignes
6.0 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 int
  19. ro_fd_cb(const char *path, int *fd, void *arg)
  20. {
  21. struct torrent *tp = arg;
  22. return vopen(fd, O_RDONLY, "%s/content/%s", tp->relpath, path);
  23. }
  24. static int
  25. wo_fd_cb(const char *path, int *fd, void *arg)
  26. {
  27. struct torrent *tp = arg;
  28. return vopen(fd, O_WRONLY|O_CREAT, "%s/content/%s", tp->relpath, path);
  29. }
  30. static int
  31. torrent_load3(const char *file, struct metainfo *mi, char *mem, size_t memsiz)
  32. {
  33. struct torrent *tp = btpd_calloc(1, sizeof(*tp));
  34. tp->relpath = strdup(file);
  35. if (tp->relpath == NULL)
  36. btpd_err("Out of memory.\n");
  37. tp->piece_count = btpd_calloc(mi->npieces, sizeof(tp->piece_count[0]));
  38. tp->busy_field = btpd_calloc(ceil(mi->npieces / 8.0), 1);
  39. BTPDQ_INIT(&tp->peers);
  40. BTPDQ_INIT(&tp->getlst);
  41. tp->imem = mem;
  42. tp->isiz = memsiz;
  43. tp->piece_field = tp->imem;
  44. tp->block_field =
  45. (uint8_t *)tp->imem + (size_t)ceil(mi->npieces / 8.0);
  46. for (uint32_t i = 0; i < mi->npieces; i++)
  47. if (has_bit(tp->piece_field, i))
  48. tp->have_npieces++;
  49. tp->meta = *mi;
  50. free(mi);
  51. btpd_add_torrent(tp);
  52. tracker_req(tp, TR_STARTED);
  53. return 0;
  54. }
  55. static int
  56. torrent_load2(const char *name, struct metainfo *mi)
  57. {
  58. int error, ifd;
  59. struct stat sb;
  60. char *mem;
  61. size_t memsiz;
  62. const char *file = name;
  63. if ((error = vopen(&ifd, O_RDWR, "%s/resume", file)) != 0) {
  64. btpd_log(BTPD_L_ERROR, "Error opening %s.i: %s.\n",
  65. file, strerror(error));
  66. return error;
  67. }
  68. if (fstat(ifd, &sb) == -1) {
  69. error = errno;
  70. btpd_log(BTPD_L_ERROR, "Error stating %s.i: %s.\n",
  71. file, strerror(error));
  72. close(ifd);
  73. return error;
  74. }
  75. memsiz =
  76. ceil(mi->npieces / 8.0) +
  77. mi->npieces * ceil(mi->piece_length / (double)(1 << 17));
  78. if (sb.st_size != memsiz) {
  79. btpd_log(BTPD_L_ERROR, "File has wrong size: %s.i.\n", file);
  80. close(ifd);
  81. return EINVAL;
  82. }
  83. mem = mmap(NULL, memsiz, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
  84. if (mem == MAP_FAILED)
  85. btpd_err("Error mmap'ing %s.i: %s.\n", file, strerror(errno));
  86. close(ifd);
  87. if ((error = torrent_load3(file, mi, mem, memsiz) != 0)) {
  88. munmap(mem, memsiz);
  89. return error;
  90. }
  91. return 0;
  92. }
  93. int
  94. torrent_load(const char *name)
  95. {
  96. struct metainfo *mi;
  97. int error;
  98. char file[PATH_MAX];
  99. snprintf(file, PATH_MAX, "%s/torrent", name);
  100. if ((error = load_metainfo(file, -1, 0, &mi)) != 0) {
  101. btpd_log(BTPD_L_ERROR, "Couldn't load metainfo file %s: %s.\n",
  102. file, strerror(error));
  103. return error;
  104. }
  105. if (btpd_get_torrent(mi->info_hash) != NULL) {
  106. btpd_log(BTPD_L_BTPD, "%s has same hash as an already loaded torrent.\n", file);
  107. error = EEXIST;
  108. }
  109. if (error == 0)
  110. error = torrent_load2(name, mi);
  111. if (error != 0) {
  112. clear_metainfo(mi);
  113. free(mi);
  114. }
  115. return error;
  116. }
  117. void
  118. torrent_unload(struct torrent *tp)
  119. {
  120. struct peer *peer;
  121. struct piece *piece;
  122. btpd_log(BTPD_L_BTPD, "Unloading %s.\n", tp->relpath);
  123. tracker_req(tp, TR_STOPPED);
  124. peer = BTPDQ_FIRST(&tp->peers);
  125. while (peer != NULL) {
  126. struct peer *next = BTPDQ_NEXT(peer, p_entry);
  127. BTPDQ_REMOVE(&tp->peers, peer, p_entry);
  128. BTPDQ_INSERT_TAIL(&net_unattached, peer, p_entry);
  129. peer->flags &= ~PF_ATTACHED;
  130. peer = next;
  131. }
  132. peer = BTPDQ_FIRST(&net_unattached);
  133. while (peer != NULL) {
  134. struct peer *next = BTPDQ_NEXT(peer, p_entry);
  135. if (peer->tp == tp)
  136. peer_kill(peer);
  137. peer = next;
  138. }
  139. while ((piece = BTPDQ_FIRST(&tp->getlst)) != NULL)
  140. piece_free(piece);
  141. free(tp->piece_count);
  142. free(tp->busy_field);
  143. free((void *)tp->relpath);
  144. clear_metainfo(&tp->meta);
  145. munmap(tp->imem, tp->isiz);
  146. btpd_del_torrent(tp);
  147. free(tp);
  148. }
  149. off_t
  150. torrent_bytes_left(struct torrent *tp)
  151. {
  152. if (tp->have_npieces == 0)
  153. return tp->meta.total_length;
  154. else if (has_bit(tp->piece_field, tp->meta.npieces - 1)) {
  155. return tp->meta.total_length -
  156. ((tp->have_npieces - 1) * tp->meta.piece_length +
  157. tp->meta.total_length % tp->meta.piece_length);
  158. } else
  159. return tp->meta.total_length -
  160. tp->have_npieces * tp->meta.piece_length;
  161. }
  162. char *
  163. torrent_get_bytes(struct torrent *tp, off_t start, size_t len)
  164. {
  165. char *buf = btpd_malloc(len);
  166. struct bt_stream_ro *bts;
  167. if ((bts = bts_open_ro(&tp->meta, start, ro_fd_cb, tp)) == NULL)
  168. btpd_err("Out of memory.\n");
  169. if (bts_read_ro(bts, buf, len) != 0)
  170. btpd_err("Io error.\n");
  171. bts_close_ro(bts);
  172. return buf;
  173. }
  174. void
  175. torrent_put_bytes(struct torrent *tp, const char *buf, off_t start, size_t len)
  176. {
  177. int err;
  178. struct bt_stream_wo *bts;
  179. if ((bts = bts_open_wo(&tp->meta, start, wo_fd_cb, tp)) == NULL)
  180. btpd_err("Out of memory.\n");
  181. if ((err = bts_write_wo(bts, buf, len)) != 0)
  182. btpd_err("Io error1: %s\n", strerror(err));
  183. if ((err = bts_close_wo(bts)) != 0)
  184. btpd_err("Io error2: %s\n", strerror(err));
  185. }
  186. int
  187. torrent_has_peer(struct torrent *tp, const uint8_t *id)
  188. {
  189. int has = 0;
  190. struct peer *p = BTPDQ_FIRST(&tp->peers);
  191. while (p != NULL) {
  192. if (bcmp(p->id, id, 20) == 0) {
  193. has = 1;
  194. break;
  195. }
  196. p = BTPDQ_NEXT(p, p_entry);
  197. }
  198. return has;
  199. }
  200. off_t
  201. torrent_piece_size(struct torrent *tp, uint32_t index)
  202. {
  203. if (index < tp->meta.npieces - 1)
  204. return tp->meta.piece_length;
  205. else {
  206. off_t allbutlast = tp->meta.piece_length * (tp->meta.npieces - 1);
  207. return tp->meta.total_length - allbutlast;
  208. }
  209. }
  210. uint32_t
  211. torrent_block_size(struct piece *pc, uint32_t index)
  212. {
  213. if (index < pc->nblocks - 1)
  214. return PIECE_BLOCKLEN;
  215. else {
  216. uint32_t allbutlast = PIECE_BLOCKLEN * (pc->nblocks - 1);
  217. return torrent_piece_size(pc->tp, pc->index) - allbutlast;
  218. }
  219. }
  220. int
  221. torrent_has_all(struct torrent *tp)
  222. {
  223. return tp->have_npieces == tp->meta.npieces;
  224. }