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.

278 lignes
5.3 KiB

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <sys/un.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <sys/stat.h>
  7. #include <sys/time.h>
  8. #include <sys/wait.h>
  9. #include <ctype.h>
  10. #include <dirent.h>
  11. #include <err.h>
  12. #include <errno.h>
  13. #include <fcntl.h>
  14. #include <getopt.h>
  15. #include <math.h>
  16. #include <locale.h>
  17. #include <pthread.h>
  18. #include <pwd.h>
  19. #include <signal.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <time.h>
  24. #include <unistd.h>
  25. #include "btpd.h"
  26. #include "http.h"
  27. static uint8_t m_peer_id[20];
  28. static struct event m_sigint;
  29. static struct event m_sigterm;
  30. static unsigned m_ntorrents;
  31. static struct torrent_tq m_torrents = BTPDQ_HEAD_INITIALIZER(m_torrents);
  32. static unsigned m_nactive;
  33. static int m_shutdown;
  34. void
  35. btpd_exit(int code)
  36. {
  37. btpd_log(BTPD_L_BTPD, "Exiting.\n");
  38. exit(code);
  39. }
  40. void
  41. btpd_tp_activated(struct torrent *tp)
  42. {
  43. m_nactive++;
  44. }
  45. void
  46. btpd_tp_deactivated(struct torrent *tp)
  47. {
  48. m_nactive--;
  49. if (m_nactive == 0 && m_shutdown)
  50. btpd_exit(0);
  51. }
  52. static void
  53. grace_cb(int fd, short type, void *arg)
  54. {
  55. struct torrent *tp;
  56. BTPDQ_FOREACH(tp, &m_torrents, entry)
  57. torrent_deactivate(tp);
  58. }
  59. void
  60. btpd_shutdown(struct timeval *grace_tv)
  61. {
  62. if (m_nactive == 0)
  63. btpd_exit(0);
  64. else {
  65. struct torrent *tp;
  66. m_shutdown = 1;
  67. BTPDQ_FOREACH(tp, &m_torrents, entry)
  68. torrent_deactivate(tp);
  69. if (grace_tv != NULL)
  70. event_once(-1, EV_TIMEOUT, grace_cb, NULL, grace_tv);
  71. }
  72. }
  73. static void
  74. signal_cb(int signal, short type, void *arg)
  75. {
  76. btpd_log(BTPD_L_BTPD, "Got signal %d.\n", signal);
  77. btpd_shutdown((& (struct timeval) { 30, 0 }));
  78. }
  79. void
  80. btpd_add_torrent(struct torrent *tp)
  81. {
  82. BTPDQ_INSERT_TAIL(&m_torrents, tp, entry);
  83. m_ntorrents++;
  84. }
  85. void
  86. btpd_del_torrent(struct torrent *tp)
  87. {
  88. BTPDQ_REMOVE(&m_torrents, tp, entry);
  89. m_ntorrents--;
  90. }
  91. const struct torrent_tq *
  92. btpd_get_torrents(void)
  93. {
  94. return &m_torrents;
  95. }
  96. unsigned
  97. btpd_get_ntorrents(void)
  98. {
  99. return m_ntorrents;
  100. }
  101. struct torrent *
  102. btpd_get_torrent(const uint8_t *hash)
  103. {
  104. struct torrent *tp = BTPDQ_FIRST(&m_torrents);
  105. while (tp != NULL && bcmp(hash, tp->meta.info_hash, 20) != 0)
  106. tp = BTPDQ_NEXT(tp, entry);
  107. return tp;
  108. }
  109. struct torrent *
  110. btpd_get_torrent_num(unsigned num)
  111. {
  112. struct torrent *tp = BTPDQ_FIRST(&m_torrents);
  113. while (tp != NULL && tp->num != num)
  114. tp = BTPDQ_NEXT(tp, entry);
  115. return tp;
  116. }
  117. const uint8_t *
  118. btpd_get_peer_id(void)
  119. {
  120. return m_peer_id;
  121. }
  122. static int
  123. nodot(struct dirent *dp)
  124. {
  125. return !(strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0);
  126. }
  127. static void
  128. load_library(void)
  129. {
  130. int ne;
  131. struct dirent **entries;
  132. if ((ne = scandir("library", &entries, nodot, NULL)) < 0)
  133. btpd_err("Couldn't open the library.\n");
  134. for (int i = 0; i < ne; i++) {
  135. struct torrent *tp;
  136. struct dirent *e = entries[i];
  137. if (torrent_load(&tp, e->d_name) == 0)
  138. btpd_add_torrent(tp);
  139. free(e);
  140. }
  141. free(entries);
  142. }
  143. struct td_cb {
  144. void (*cb)(void *);
  145. void *arg;
  146. BTPDQ_ENTRY(td_cb) entry;
  147. };
  148. BTPDQ_HEAD(td_cb_tq, td_cb);
  149. static int m_td_rd, m_td_wr;
  150. static struct event m_td_ev;
  151. static struct td_cb_tq m_td_cbs = BTPDQ_HEAD_INITIALIZER(m_td_cbs);
  152. static pthread_mutex_t m_td_lock;
  153. void
  154. td_acquire_lock(void)
  155. {
  156. pthread_mutex_lock(&m_td_lock);
  157. }
  158. void
  159. td_release_lock(void)
  160. {
  161. pthread_mutex_unlock(&m_td_lock);
  162. }
  163. void
  164. td_post(void (*fun)(void *), void *arg)
  165. {
  166. struct td_cb *cb = btpd_calloc(1, sizeof(*cb));
  167. cb->cb = fun;
  168. cb->arg = arg;
  169. BTPDQ_INSERT_TAIL(&m_td_cbs, cb, entry);
  170. }
  171. void
  172. td_post_end(void)
  173. {
  174. char c = '1';
  175. td_release_lock();
  176. write(m_td_wr, &c, sizeof(c));
  177. }
  178. static void
  179. td_cb(int fd, short type, void *arg)
  180. {
  181. char buf[1024];
  182. struct td_cb_tq tmpq = BTPDQ_HEAD_INITIALIZER(tmpq);
  183. struct td_cb *cb, *next;
  184. read(fd, buf, sizeof(buf));
  185. td_acquire_lock();
  186. BTPDQ_FOREACH_MUTABLE(cb, &m_td_cbs, entry, next)
  187. BTPDQ_INSERT_TAIL(&tmpq, cb, entry);
  188. BTPDQ_INIT(&m_td_cbs);
  189. td_release_lock();
  190. BTPDQ_FOREACH_MUTABLE(cb, &tmpq, entry, next) {
  191. cb->cb(cb->arg);
  192. free(cb);
  193. }
  194. }
  195. static void
  196. td_init(void)
  197. {
  198. int err;
  199. int fds[2];
  200. if (pipe(fds) == -1) {
  201. btpd_err("Couldn't create thread callback pipe (%s).\n",
  202. strerror(errno));
  203. }
  204. m_td_rd = fds[0];
  205. m_td_wr = fds[1];
  206. if ((err = pthread_mutex_init(&m_td_lock, NULL)) != 0)
  207. btpd_err("Couldn't create mutex (%s).\n", strerror(err));
  208. event_set(&m_td_ev, m_td_rd, EV_READ|EV_PERSIST, td_cb, NULL);
  209. event_add(&m_td_ev, NULL);
  210. }
  211. void ipc_init(void);
  212. void
  213. btpd_init(void)
  214. {
  215. bcopy(BTPD_VERSION, m_peer_id, sizeof(BTPD_VERSION) - 1);
  216. m_peer_id[sizeof(BTPD_VERSION) - 1] = '|';
  217. srandom(time(NULL));
  218. for (int i = sizeof(BTPD_VERSION); i < 20; i++)
  219. m_peer_id[i] = rand_between(0, 255);
  220. td_init();
  221. http_init();
  222. net_init();
  223. ipc_init();
  224. ul_init();
  225. cm_init();
  226. load_library();
  227. #if 0
  228. struct torrent *tp;
  229. BTPDQ_FOREACH(tp, &m_torrents, entry)
  230. torrent_activate(tp);
  231. #endif
  232. signal(SIGPIPE, SIG_IGN);
  233. signal_set(&m_sigint, SIGINT, signal_cb, NULL);
  234. signal_add(&m_sigint, NULL);
  235. signal_set(&m_sigterm, SIGTERM, signal_cb, NULL);
  236. signal_add(&m_sigterm, NULL);
  237. }