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.

205 line
5.4 KiB

  1. #include <sys/types.h>
  2. #include <sys/file.h>
  3. #include <sys/stat.h>
  4. #include <assert.h>
  5. #include <err.h>
  6. #include <errno.h>
  7. #include <fcntl.h>
  8. #include <getopt.h>
  9. #include <locale.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include "btpd.h"
  15. static void
  16. writepid(int pidfd)
  17. {
  18. FILE *fp = fdopen(dup(pidfd), "w");
  19. fprintf(fp, "%d", getpid());
  20. fclose(fp);
  21. }
  22. static void
  23. setup_daemon(int daemonize, const char *dir, const char *log)
  24. {
  25. int pidfd;
  26. if (log == NULL)
  27. log = "log";
  28. if (dir == NULL)
  29. if ((dir = find_btpd_dir()) == NULL)
  30. errx(1, "Cannot find the btpd directory");
  31. btpd_dir = dir;
  32. if (mkdir(dir, 0777) == -1 && errno != EEXIST)
  33. err(1, "Couldn't create home '%s'", dir);
  34. if (chdir(dir) != 0)
  35. err(1, "Couldn't change working directory to '%s'", dir);
  36. if (mkdir("torrents", 0777) == -1 && errno != EEXIST)
  37. err(1, "Couldn't create torrents subdir");
  38. if ((pidfd = open("pid", O_CREAT|O_WRONLY, 0666)) == -1)
  39. err(1, "Couldn't open 'pid'");
  40. if (flock(pidfd, LOCK_NB|LOCK_EX) == -1)
  41. errx(1, "Another instance of btpd is probably running in %s.", dir);
  42. if (daemonize) {
  43. if (daemon(1, 1) != 0)
  44. err(1, "Failed to daemonize");
  45. freopen("/dev/null", "r", stdin);
  46. if (freopen(log, "a", stdout) == NULL)
  47. err(1, "Couldn't open '%s'", log);
  48. dup2(fileno(stdout), fileno(stderr));
  49. setlinebuf(stdout);
  50. setlinebuf(stderr);
  51. }
  52. writepid(pidfd);
  53. }
  54. static void
  55. usage(void)
  56. {
  57. printf(
  58. "btpd is the BitTorrent Protocol Daemon.\n"
  59. "\n"
  60. "Usage: btpd [-d dir] [-p port] [more options...]\n"
  61. "\n"
  62. "Options:\n"
  63. "--bw-in n\n"
  64. "\tLimit incoming BitTorrent traffic to n kB/s.\n"
  65. "\tDefault is 0 which means unlimited.\n"
  66. "\n"
  67. "--bw-out n\n"
  68. "\tLimit outgoing BitTorrent traffic to n kB/s.\n"
  69. "\tDefault is 0 which means unlimited.\n"
  70. "\n"
  71. "-d dir\n"
  72. "\tThe directory in which to run btpd. Default is '$HOME/.btpd'.\n"
  73. "\n"
  74. "--help\n"
  75. "\tShow this text.\n"
  76. "\n"
  77. "--logfile file\n"
  78. "\tWhere to put the logfile. By default it's put in the btpd dir.\n"
  79. "\n"
  80. "--max-peers n\n"
  81. "\tLimit the amount of peers to n.\n"
  82. "\n"
  83. "--max-uploads n\n"
  84. "\tControls the number of simultaneous uploads.\n"
  85. "\tThe possible values are:\n"
  86. "\t\tn < -1 : Choose n >= 2 based on --bw-out (default).\n"
  87. "\t\tn = -1 : Upload to every interested peer.\n"
  88. "\t\tn = 0 : Dont't upload to anyone.\n"
  89. "\t\tn > 0 : Upload to at most n peers simultaneously.\n"
  90. "\n"
  91. "--no-daemon\n"
  92. "\tKeep the btpd process in the foregorund and log to std{out,err}.\n"
  93. "\tThis option is intended for debugging purposes.\n"
  94. "\n"
  95. "-p n, --port n\n"
  96. "\tListen at port n. Default is 6881.\n"
  97. "\n"
  98. "--prealloc n\n"
  99. "\tPreallocate disk space in chunks of n kB. Default is 2048.\n"
  100. "\tNote that n will be rounded up to the closest multiple of the\n"
  101. "\ttorrent piece size. If n is zero no preallocation will be done.\n"
  102. "\n");
  103. exit(1);
  104. }
  105. static int longval = 0;
  106. static struct option longopts[] = {
  107. { "port", required_argument, NULL, 'p' },
  108. { "bw-in", required_argument, &longval, 1 },
  109. { "bw-out", required_argument, &longval, 2 },
  110. { "prealloc", required_argument, &longval, 3 },
  111. { "max-uploads", required_argument, &longval, 4 },
  112. { "max-peers", required_argument, &longval, 5 },
  113. { "no-daemon", no_argument, &longval, 6 },
  114. { "logfile", required_argument, &longval, 7 },
  115. { "help", no_argument, &longval, 128 },
  116. { NULL, 0, NULL, 0 }
  117. };
  118. int
  119. main(int argc, char **argv)
  120. {
  121. char *dir = NULL, *log = NULL;
  122. int daemonize = 1;
  123. setlocale(LC_ALL, "");
  124. for (;;) {
  125. switch (getopt_long(argc, argv, "d:p:", longopts, NULL)) {
  126. case -1:
  127. goto args_done;
  128. case 'd':
  129. dir = optarg;
  130. break;
  131. case 'p':
  132. net_port = atoi(optarg);
  133. break;
  134. case 0:
  135. switch (longval) {
  136. case 1:
  137. net_bw_limit_in = atoi(optarg) * 1024;
  138. break;
  139. case 2:
  140. net_bw_limit_out = atoi(optarg) * 1024;
  141. break;
  142. case 3:
  143. cm_alloc_size = atoi(optarg) * 1024;
  144. break;
  145. case 4:
  146. net_max_uploads = atoi(optarg);
  147. break;
  148. case 5:
  149. net_max_peers = atoi(optarg);
  150. break;
  151. case 6:
  152. daemonize = 0;
  153. break;
  154. case 7:
  155. log = optarg;
  156. break;
  157. default:
  158. usage();
  159. }
  160. break;
  161. case '?':
  162. default:
  163. usage();
  164. }
  165. }
  166. args_done:
  167. argc -= optind;
  168. argv += optind;
  169. if (argc > 0)
  170. usage();
  171. setup_daemon(daemonize, dir, log);
  172. event_init();
  173. btpd_init();
  174. event_dispatch();
  175. btpd_err("Unexpected exit from libevent.\n");
  176. return 1;
  177. }