A clone of btpd with my configuration changes.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
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. }