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.

subr.c 2.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. vopen(int *res, int flags, const char *fmt, ...)
  67. {
  68. int fd, didmkdirs;
  69. char path[PATH_MAX + 1];
  70. va_list ap;
  71. va_start(ap, fmt);
  72. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX) {
  73. va_end(ap);
  74. return ENAMETOOLONG;
  75. }
  76. va_end(ap);
  77. didmkdirs = 0;
  78. again:
  79. fd = open(path, flags, 0666);
  80. if (fd < 0 && errno == ENOENT && (flags & O_CREAT) != 0 && !didmkdirs) {
  81. if (mkdirs(path) == 0) {
  82. didmkdirs = 1;
  83. goto again;
  84. } else
  85. return errno;
  86. }
  87. if (fd >= 0) {
  88. *res = fd;
  89. return 0;
  90. } else
  91. return errno;
  92. }
  93. int
  94. canon_path(const char *path, char **res)
  95. {
  96. char rp[PATH_MAX];
  97. if (realpath(path, rp) == NULL)
  98. return errno;
  99. #if 0
  100. // This could be necessary on solaris.
  101. if (rp[0] != '/') {
  102. char wd[MAXPATHLEN];
  103. if (getcwd(wd, MAXPATHLEN) == NULL)
  104. return errno;
  105. if (strlcat(wd, "/", MAXPATHLEN) >= MAXPATHLEN)
  106. return ENAMETOOLONG;
  107. if (strlcat(wd, rp, MAXPATHLEN) >= MAXPATHLEN)
  108. return ENAMETOOLONG;
  109. strcpy(rp, wd);
  110. }
  111. #endif
  112. if ((*res = strdup(rp)) == NULL)
  113. return ENOMEM;
  114. return 0;
  115. }
  116. long
  117. rand_between(long min, long max)
  118. {
  119. return min + (long)rint((double)random() * (max - min) / RAND_MAX);
  120. }