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.

200 lines
3.8 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 int m_shutdown;
  31. void
  32. btpd_exit(int code)
  33. {
  34. btpd_log(BTPD_L_BTPD, "Exiting.\n");
  35. exit(code);
  36. }
  37. static void
  38. grace_cb(int fd, short type, void *arg)
  39. {
  40. struct torrent *tp;
  41. BTPDQ_FOREACH(tp, torrent_get_all(), entry)
  42. torrent_stop(tp);
  43. }
  44. void
  45. btpd_shutdown(int grace_seconds)
  46. {
  47. if (torrent_count() == 0)
  48. btpd_exit(0);
  49. else {
  50. struct torrent *tp;
  51. m_shutdown = 1;
  52. BTPDQ_FOREACH(tp, torrent_get_all(), entry)
  53. if (tp->state != T_STOPPING)
  54. torrent_stop(tp);
  55. if (grace_seconds >= 0) {
  56. event_once(-1, EV_TIMEOUT, grace_cb, NULL,
  57. (& (struct timeval) { grace_seconds, 0 }));
  58. }
  59. }
  60. }
  61. int btpd_is_stopping(void)
  62. {
  63. return m_shutdown;
  64. }
  65. const uint8_t *
  66. btpd_get_peer_id(void)
  67. {
  68. return m_peer_id;
  69. }
  70. void
  71. btpd_on_no_torrents(void)
  72. {
  73. if (m_shutdown)
  74. btpd_exit(0);
  75. }
  76. static void
  77. signal_cb(int signal, short type, void *arg)
  78. {
  79. btpd_log(BTPD_L_BTPD, "Got signal %d.\n", signal);
  80. btpd_shutdown(30);
  81. }
  82. struct td_cb {
  83. void (*cb)(void *);
  84. void *arg;
  85. BTPDQ_ENTRY(td_cb) entry;
  86. };
  87. BTPDQ_HEAD(td_cb_tq, td_cb);
  88. static int m_td_rd, m_td_wr;
  89. static struct event m_td_ev;
  90. static struct td_cb_tq m_td_cbs = BTPDQ_HEAD_INITIALIZER(m_td_cbs);
  91. static pthread_mutex_t m_td_lock;
  92. void
  93. td_acquire_lock(void)
  94. {
  95. pthread_mutex_lock(&m_td_lock);
  96. }
  97. void
  98. td_release_lock(void)
  99. {
  100. pthread_mutex_unlock(&m_td_lock);
  101. }
  102. void
  103. td_post(void (*fun)(void *), void *arg)
  104. {
  105. struct td_cb *cb = btpd_calloc(1, sizeof(*cb));
  106. cb->cb = fun;
  107. cb->arg = arg;
  108. BTPDQ_INSERT_TAIL(&m_td_cbs, cb, entry);
  109. }
  110. void
  111. td_post_end(void)
  112. {
  113. char c = '1';
  114. td_release_lock();
  115. write(m_td_wr, &c, sizeof(c));
  116. }
  117. static void
  118. td_cb(int fd, short type, void *arg)
  119. {
  120. char buf[1024];
  121. struct td_cb_tq tmpq = BTPDQ_HEAD_INITIALIZER(tmpq);
  122. struct td_cb *cb, *next;
  123. read(fd, buf, sizeof(buf));
  124. td_acquire_lock();
  125. BTPDQ_FOREACH_MUTABLE(cb, &m_td_cbs, entry, next)
  126. BTPDQ_INSERT_TAIL(&tmpq, cb, entry);
  127. BTPDQ_INIT(&m_td_cbs);
  128. td_release_lock();
  129. BTPDQ_FOREACH_MUTABLE(cb, &tmpq, entry, next) {
  130. cb->cb(cb->arg);
  131. free(cb);
  132. }
  133. }
  134. static void
  135. td_init(void)
  136. {
  137. int err;
  138. int fds[2];
  139. if (pipe(fds) == -1) {
  140. btpd_err("Couldn't create thread callback pipe (%s).\n",
  141. strerror(errno));
  142. }
  143. m_td_rd = fds[0];
  144. m_td_wr = fds[1];
  145. if ((err = pthread_mutex_init(&m_td_lock, NULL)) != 0)
  146. btpd_err("Couldn't create mutex (%s).\n", strerror(err));
  147. event_set(&m_td_ev, m_td_rd, EV_READ|EV_PERSIST, td_cb, NULL);
  148. event_add(&m_td_ev, NULL);
  149. }
  150. void ipc_init(void);
  151. void
  152. btpd_init(void)
  153. {
  154. bcopy(BTPD_VERSION, m_peer_id, sizeof(BTPD_VERSION) - 1);
  155. m_peer_id[sizeof(BTPD_VERSION) - 1] = '|';
  156. srandom(time(NULL));
  157. for (int i = sizeof(BTPD_VERSION); i < 20; i++)
  158. m_peer_id[i] = rand_between(0, 255);
  159. td_init();
  160. http_init();
  161. net_init();
  162. ipc_init();
  163. ul_init();
  164. cm_init();
  165. signal(SIGPIPE, SIG_IGN);
  166. signal_set(&m_sigint, SIGINT, signal_cb, NULL);
  167. signal_add(&m_sigint, NULL);
  168. signal_set(&m_sigterm, SIGTERM, signal_cb, NULL);
  169. signal_add(&m_sigterm, NULL);
  170. }