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.

202 lignes
3.7 KiB

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