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.

303 lignes
8.7 KiB

  1. #include "btpd.h"
  2. #include <getopt.h>
  3. #include <time.h>
  4. int btpd_daemon_phase = 2;
  5. int first_btpd_comm[2];
  6. int pidfd;
  7. void
  8. first_btpd_exit(char code)
  9. {
  10. write(first_btpd_comm[1], &code, 1);
  11. close(first_btpd_comm[0]);
  12. close(first_btpd_comm[1]);
  13. }
  14. static void
  15. writepid(void)
  16. {
  17. int nw;
  18. char pidtxt[100];
  19. nw = snprintf(pidtxt, sizeof(pidtxt), "%ld", (long)getpid());
  20. ftruncate(pidfd, 0);
  21. write(pidfd, pidtxt, nw);
  22. }
  23. static void
  24. setup_daemon(int daemonize, const char *dir)
  25. {
  26. char c;
  27. pid_t pid;
  28. struct timespec ts;
  29. if (snprintf(NULL, 0, "btpd") != 4)
  30. btpd_err("snprintf doesn't work.\n");
  31. if (evtimer_gettime(&ts) != 0)
  32. btpd_err("evtimer_gettime failed (%s).\n", strerror(errno));
  33. if (dir == NULL) {
  34. if ((dir = find_btpd_dir()) == NULL)
  35. btpd_err("Cannot find the btpd directory.\n");
  36. if (dir[0] != '/')
  37. btpd_err("Got non absolute path '%s' from system environment.\n",
  38. dir);
  39. btpd_dir = dir;
  40. }
  41. if (mkdir(dir, 0777) == -1 && errno != EEXIST)
  42. btpd_err("Couldn't create home '%s' (%s).\n", dir, strerror(errno));
  43. if (chdir(dir) != 0)
  44. btpd_err("Couldn't change working directory to '%s' (%s).\n", dir,
  45. strerror(errno));
  46. if (mkdir("torrents", 0777) == -1 && errno != EEXIST)
  47. btpd_err("Couldn't create torrents subdir (%s).\n", strerror(errno));
  48. if (btpd_dir == NULL) {
  49. char wd[PATH_MAX];
  50. if (getcwd(wd, PATH_MAX) == NULL)
  51. btpd_err("Couldn't get working directory (%s).\n",
  52. strerror(errno));
  53. if ((btpd_dir = strdup(wd)) == NULL)
  54. btpd_err("Out of memory.\n");
  55. }
  56. if (daemonize) {
  57. if (pipe(first_btpd_comm) < 0)
  58. btpd_err("Failed to create pipe (%s).\n", strerror(errno));
  59. if ((pid = fork()) < 0)
  60. btpd_err("fork() failed (%s).\n", strerror(errno));
  61. if (pid != 0) {
  62. read(first_btpd_comm[0], &c, 1);
  63. exit(c);
  64. }
  65. btpd_daemon_phase--;
  66. if (setsid() < 0)
  67. btpd_err("setsid() failed (%s).\n", strerror(errno));
  68. if ((pid = fork()) < 0)
  69. btpd_err("fork() failed (%s).\n", strerror(errno));
  70. if (pid != 0)
  71. exit(0);
  72. }
  73. if ((pidfd = open("pid", O_CREAT|O_WRONLY, 0666)) == -1)
  74. btpd_err("Couldn't open 'pid' (%s).\n", strerror(errno));
  75. if (lockf(pidfd, F_TLOCK, 0) == -1)
  76. btpd_err("Another instance of btpd is probably running in %s.\n", dir);
  77. writepid();
  78. }
  79. static void
  80. usage(void)
  81. {
  82. printf(
  83. "btpd is the BitTorrent Protocol Daemon.\n"
  84. "\n"
  85. "Usage: btpd [-d dir] [-p port] [more options...]\n"
  86. "\n"
  87. "Options:\n"
  88. "-4\n"
  89. "\tUse IPv4. If given in conjunction with -6, "
  90. "both versions are used.\n"
  91. "\n"
  92. "-6\n"
  93. "\tUse IPv6. By default IPv4 is used.\n"
  94. "\n"
  95. "--bw-in n\n"
  96. "\tLimit incoming BitTorrent traffic to n kB/s.\n"
  97. "\tDefault is 0 which means unlimited.\n"
  98. "\n"
  99. "--bw-out n\n"
  100. "\tLimit outgoing BitTorrent traffic to n kB/s.\n"
  101. "\tDefault is 0 which means unlimited.\n"
  102. "\n"
  103. "-d dir\n"
  104. "\tThe directory in which to run btpd. Default is '$HOME/.btpd'.\n"
  105. "\n"
  106. "--empty-start\n"
  107. "\tStart btpd without any active torrents.\n"
  108. "\n"
  109. "--help\n"
  110. "\tShow this text.\n"
  111. "\n"
  112. "--ip addr\n"
  113. "\tLet the tracker distribute the given address instead of the one\n"
  114. "\tit sees btpd connect from.\n"
  115. "\n"
  116. "--ipcprot mode\n"
  117. "\tSet the protection mode of the command socket.\n"
  118. "\tThe mode is specified by an octal number. Default is 0600.\n"
  119. "\n"
  120. "--logfile file\n"
  121. "\tWhere to put the logfile. By default it's put in the btpd dir.\n"
  122. "\n"
  123. "--max-peers n\n"
  124. "\tLimit the amount of peers to n.\n"
  125. "\n"
  126. "--max-uploads n\n"
  127. "\tControls the number of simultaneous uploads.\n"
  128. "\tThe possible values are:\n"
  129. "\t\tn < -1 : Choose n >= 2 based on --bw-out (default).\n"
  130. "\t\tn = -1 : Upload to every interested peer.\n"
  131. "\t\tn = 0 : Dont't upload to anyone.\n"
  132. "\t\tn > 0 : Upload to at most n peers simultaneously.\n"
  133. "\n"
  134. "--no-daemon\n"
  135. "\tKeep the btpd process in the foregorund and log to std{out,err}.\n"
  136. "\tThis option is intended for debugging purposes.\n"
  137. "\n"
  138. "-p n, --port n\n"
  139. "\tListen at port n. Default is 6881.\n"
  140. "\n"
  141. "--prealloc n\n"
  142. "\tPreallocate disk space in chunks of n kB. Default is 2048.\n"
  143. "\tNote that n will be rounded up to the closest multiple of the\n"
  144. "\ttorrent piece size. If n is zero no preallocation will be done.\n"
  145. "\n"
  146. "--numwant n\n"
  147. "\tSet the number of peers to fetch on each request. Default is 50.\n"
  148. "\n");
  149. exit(1);
  150. }
  151. static int longval = 0;
  152. static struct option longopts[] = {
  153. { "port", required_argument, NULL, 'p' },
  154. { "bw-in", required_argument, &longval, 1 },
  155. { "bw-out", required_argument, &longval, 2 },
  156. { "prealloc", required_argument, &longval, 3 },
  157. { "max-uploads", required_argument, &longval, 4 },
  158. { "max-peers", required_argument, &longval, 5 },
  159. { "no-daemon", no_argument, &longval, 6 },
  160. { "logfile", required_argument, &longval, 7 },
  161. { "ipcprot", required_argument, &longval, 8 },
  162. { "empty-start", no_argument, &longval, 9 },
  163. { "ip", required_argument, &longval, 10 },
  164. { "logmask", required_argument, &longval, 11 },
  165. { "numwant", required_argument, &longval, 12 },
  166. { "help", no_argument, &longval, 128 },
  167. { NULL, 0, NULL, 0 }
  168. };
  169. int
  170. main(int argc, char **argv)
  171. {
  172. char *dir = NULL, *log = NULL;
  173. int daemonize = 1, opt4 = 0, opt6 = 0;
  174. for (;;) {
  175. switch (getopt_long(argc, argv, "46d:p:", longopts, NULL)) {
  176. case -1:
  177. goto args_done;
  178. case '4':
  179. opt4 = 1;
  180. break;
  181. case '6':
  182. opt6 = 1;
  183. break;
  184. case 'd':
  185. dir = optarg;
  186. break;
  187. case 'p':
  188. net_port = atoi(optarg);
  189. break;
  190. case 0:
  191. switch (longval) {
  192. case 1:
  193. net_bw_limit_in = atoi(optarg) * 1024;
  194. break;
  195. case 2:
  196. net_bw_limit_out = atoi(optarg) * 1024;
  197. break;
  198. case 3:
  199. cm_alloc_size = atoi(optarg) * 1024;
  200. break;
  201. case 4:
  202. net_max_uploads = atoi(optarg);
  203. break;
  204. case 5:
  205. net_max_peers = atoi(optarg);
  206. break;
  207. case 6:
  208. daemonize = 0;
  209. break;
  210. case 7:
  211. log = optarg;
  212. break;
  213. case 8:
  214. ipcprot = strtol(optarg, NULL, 8);
  215. break;
  216. case 9:
  217. empty_start = 1;
  218. break;
  219. case 10:
  220. tr_ip_arg = optarg;
  221. break;
  222. case 11:
  223. btpd_logmask = atoi(optarg);
  224. break;
  225. case 12:
  226. net_numwant = (unsigned)atoi(optarg);
  227. break;
  228. default:
  229. usage();
  230. }
  231. break;
  232. case '?':
  233. default:
  234. usage();
  235. }
  236. }
  237. args_done:
  238. argc -= optind;
  239. argv += optind;
  240. if (opt6) {
  241. net_ipv6 = 1;
  242. if (!opt4)
  243. net_ipv4 = 0;
  244. }
  245. if (argc > 0)
  246. usage();
  247. setup_daemon(daemonize, dir);
  248. if (evloop_init() != 0)
  249. btpd_err("Failed to initialize evloop (%s).\n", strerror(errno));
  250. btpd_init();
  251. if (daemonize) {
  252. if (freopen("/dev/null", "r", stdin) == NULL)
  253. btpd_err("freopen of stdin failed (%s).\n", strerror(errno));
  254. if (freopen(log == NULL ? "log" : log, "a", stderr) == NULL)
  255. btpd_err("Couldn't open '%s' (%s).\n", log, strerror(errno));
  256. if (dup2(fileno(stderr), fileno(stdout)) < 0)
  257. btpd_err("dup2 failed (%s).\n", strerror(errno));
  258. first_btpd_exit(0);
  259. }
  260. setlinebuf(stdout);
  261. setlinebuf(stderr);
  262. btpd_daemon_phase = 0;
  263. if (!empty_start)
  264. active_start();
  265. else
  266. active_clear();
  267. evloop();
  268. btpd_err("Exit from evloop with error (%s).\n", strerror(errno));
  269. return 1;
  270. }