A clone of btpd with my configuration changes.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <errno.h>
  4. #include <fcntl.h>
  5. #include <inttypes.h>
  6. #include <limits.h>
  7. #include <math.h>
  8. #include <pwd.h>
  9. #include <stdarg.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. void
  15. set_bit(uint8_t *bits, unsigned long index)
  16. {
  17. bits[index / 8] |= (1 << (7 - index % 8));
  18. }
  19. void
  20. clear_bit(uint8_t *bits, unsigned long index)
  21. {
  22. bits[index / 8] &= ~(1 << (7 - index % 8));
  23. }
  24. int
  25. has_bit(const uint8_t *bits, unsigned long index)
  26. {
  27. return bits[index / 8] & (1 << (7 - index % 8));
  28. }
  29. int
  30. set_nonblocking(int fd)
  31. {
  32. int oflags;
  33. if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
  34. return errno;
  35. if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1)
  36. return errno;
  37. return 0;
  38. }
  39. int
  40. set_blocking(int fd)
  41. {
  42. int oflags;
  43. if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
  44. return errno;
  45. if (fcntl(fd, F_SETFL, oflags & ~O_NONBLOCK) == -1)
  46. return errno;
  47. return 0;
  48. }
  49. int
  50. mkdirs(char *path)
  51. {
  52. int err = 0;
  53. char *spos = strchr(path + 1, '/'); // Must ignore the root
  54. while (spos != NULL) {
  55. *spos = '\0';
  56. err = mkdir(path, 0777);
  57. *spos = '/';
  58. if (err != 0 && errno != EEXIST) {
  59. err = errno;
  60. break;
  61. }
  62. spos = strchr(spos + 1, '/');
  63. }
  64. return err;
  65. }
  66. int
  67. vaopen(int *res, int flags, const char *fmt, va_list ap)
  68. {
  69. int fd, didmkdirs;
  70. char path[PATH_MAX + 1];
  71. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX)
  72. return ENAMETOOLONG;
  73. didmkdirs = 0;
  74. again:
  75. fd = open(path, flags, 0666);
  76. if (fd < 0 && errno == ENOENT && (flags & O_CREAT) != 0 && !didmkdirs) {
  77. if (mkdirs(path) == 0) {
  78. didmkdirs = 1;
  79. goto again;
  80. } else
  81. return errno;
  82. }
  83. if (fd >= 0) {
  84. *res = fd;
  85. return 0;
  86. } else
  87. return errno;
  88. }
  89. int
  90. vopen(int *res, int flags, const char *fmt, ...)
  91. {
  92. int err;
  93. va_list ap;
  94. va_start(ap, fmt);
  95. err = vaopen(res, flags, fmt, ap);
  96. va_end(ap);
  97. return err;
  98. }
  99. int
  100. vfsync(const char *fmt, ...)
  101. {
  102. int err, fd;
  103. va_list ap;
  104. va_start(ap, fmt);
  105. err = vaopen(&fd, O_RDONLY, fmt, ap);
  106. va_end(ap);
  107. if (err != 0)
  108. return err;
  109. if (fsync(fd) < 0)
  110. err = errno;
  111. close(fd);
  112. return err;
  113. }
  114. int
  115. vfopen(FILE **ret, const char *mode, const char *fmt, ...)
  116. {
  117. int err = 0;
  118. char path[PATH_MAX + 1];
  119. va_list ap;
  120. va_start(ap, fmt);
  121. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX)
  122. err = ENAMETOOLONG;
  123. va_end(ap);
  124. if (err == 0)
  125. if ((*ret = fopen(path, mode)) == NULL)
  126. err = errno;
  127. return err;
  128. }
  129. long
  130. rand_between(long min, long max)
  131. {
  132. return min + (long)rint((double)random() * (max - min) / RAND_MAX);
  133. }
  134. int
  135. write_fully(int fd, const void *buf, size_t len)
  136. {
  137. ssize_t nw;
  138. size_t off = 0;
  139. while (off < len) {
  140. nw = write(fd, buf + off, len - off);
  141. if (nw == -1)
  142. return errno;
  143. off += nw;
  144. }
  145. return 0;
  146. }
  147. int
  148. read_fully(int fd, void *buf, size_t len)
  149. {
  150. ssize_t nread;
  151. size_t off = 0;
  152. while (off < len) {
  153. nread = read(fd, buf + off, len - off);
  154. if (nread == 0)
  155. return ECONNRESET;
  156. else if (nread == -1)
  157. return errno;
  158. off += nread;
  159. }
  160. return 0;
  161. }
  162. char *
  163. find_btpd_dir(void)
  164. {
  165. char *res = getenv("BTPD_HOME");
  166. if (res != NULL)
  167. return strdup(res);
  168. char *home = getenv("HOME");
  169. if (home == NULL) {
  170. struct passwd *pwent = getpwuid(getuid());
  171. endpwent();
  172. if (pwent != NULL)
  173. home = pwent->pw_dir;
  174. }
  175. if (home != NULL)
  176. asprintf(&res, "%s/.btpd", home);
  177. return res;
  178. }