A clone of btpd with my configuration changes.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

177 lines
3.3 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 <stdarg.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. void
  14. set_bit(uint8_t *bits, unsigned long index)
  15. {
  16. bits[index / 8] |= (1 << (7 - index % 8));
  17. }
  18. void
  19. clear_bit(uint8_t *bits, unsigned long index)
  20. {
  21. bits[index / 8] &= ~(1 << (7 - index % 8));
  22. }
  23. int
  24. has_bit(const uint8_t *bits, unsigned long index)
  25. {
  26. return bits[index / 8] & (1 << (7 - index % 8));
  27. }
  28. int
  29. set_nonblocking(int fd)
  30. {
  31. int oflags;
  32. if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
  33. return errno;
  34. if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1)
  35. return errno;
  36. return 0;
  37. }
  38. int
  39. set_blocking(int fd)
  40. {
  41. int oflags;
  42. if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
  43. return errno;
  44. if (fcntl(fd, F_SETFL, oflags & ~O_NONBLOCK) == -1)
  45. return errno;
  46. return 0;
  47. }
  48. int
  49. mkdirs(char *path)
  50. {
  51. int err = 0;
  52. char *spos = strchr(path + 1, '/'); // Must ignore the root
  53. while (spos != NULL) {
  54. *spos = '\0';
  55. err = mkdir(path, 0777);
  56. *spos = '/';
  57. if (err != 0 && errno != EEXIST) {
  58. err = errno;
  59. break;
  60. }
  61. spos = strchr(spos + 1, '/');
  62. }
  63. return err;
  64. }
  65. int
  66. vaopen(int *res, int flags, const char *fmt, va_list ap)
  67. {
  68. int fd, didmkdirs;
  69. char path[PATH_MAX + 1];
  70. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX)
  71. return ENAMETOOLONG;
  72. didmkdirs = 0;
  73. again:
  74. fd = open(path, flags, 0666);
  75. if (fd < 0 && errno == ENOENT && (flags & O_CREAT) != 0 && !didmkdirs) {
  76. if (mkdirs(path) == 0) {
  77. didmkdirs = 1;
  78. goto again;
  79. } else
  80. return errno;
  81. }
  82. if (fd >= 0) {
  83. *res = fd;
  84. return 0;
  85. } else
  86. return errno;
  87. }
  88. int
  89. vopen(int *res, int flags, const char *fmt, ...)
  90. {
  91. int err;
  92. va_list ap;
  93. va_start(ap, fmt);
  94. err = vaopen(res, flags, fmt, ap);
  95. va_end(ap);
  96. return err;
  97. }
  98. int
  99. vfsync(const char *fmt, ...)
  100. {
  101. int err, fd;
  102. va_list ap;
  103. va_start(ap, fmt);
  104. err = vaopen(&fd, O_RDONLY, fmt, ap);
  105. va_end(ap);
  106. if (err != 0)
  107. return err;
  108. if (fsync(fd) < 0)
  109. err = errno;
  110. close(fd);
  111. return err;
  112. }
  113. int
  114. vfopen(FILE **ret, const char *mode, const char *fmt, ...)
  115. {
  116. int err = 0;
  117. char path[PATH_MAX + 1];
  118. va_list ap;
  119. va_start(ap, fmt);
  120. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX)
  121. err = ENAMETOOLONG;
  122. va_end(ap);
  123. if (err == 0)
  124. if ((*ret = fopen(path, mode)) == NULL)
  125. err = errno;
  126. return err;
  127. }
  128. int
  129. canon_path(const char *path, char **res)
  130. {
  131. char rp[PATH_MAX];
  132. if (realpath(path, rp) == NULL)
  133. return errno;
  134. #if 0
  135. // This could be necessary on solaris.
  136. if (rp[0] != '/') {
  137. char wd[MAXPATHLEN];
  138. if (getcwd(wd, MAXPATHLEN) == NULL)
  139. return errno;
  140. if (strlcat(wd, "/", MAXPATHLEN) >= MAXPATHLEN)
  141. return ENAMETOOLONG;
  142. if (strlcat(wd, rp, MAXPATHLEN) >= MAXPATHLEN)
  143. return ENAMETOOLONG;
  144. strcpy(rp, wd);
  145. }
  146. #endif
  147. if ((*res = strdup(rp)) == NULL)
  148. return ENOMEM;
  149. return 0;
  150. }
  151. long
  152. rand_between(long min, long max)
  153. {
  154. return min + (long)rint((double)random() * (max - min) / RAND_MAX);
  155. }