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.

subr.c 8.3 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  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. enc_be32(void *buf, uint32_t num)
  16. {
  17. uint8_t *p = buf;
  18. *p = (num >> 24) & 0xff;
  19. *(p + 1) = (num >> 16) & 0xff;
  20. *(p + 2) = (num >> 8) & 0xff;
  21. *(p + 3) = num & 0xff;
  22. }
  23. uint32_t
  24. dec_be32(const void *buf)
  25. {
  26. const uint8_t *p = buf;
  27. return (uint32_t)*p << 24 | (uint32_t)*(p + 1) << 16
  28. | (uint16_t)*(p + 2) << 8 | *(p + 3);
  29. }
  30. void
  31. enc_be64(void *buf, uint64_t num)
  32. {
  33. uint8_t *p = buf;
  34. *p = (num >> 56) & 0xff;
  35. *(p + 1) = (num >> 48) & 0xff;
  36. *(p + 2) = (num >> 40) & 0xff;
  37. *(p + 3) = (num >> 32) & 0xff;
  38. *(p + 4) = (num >> 24) & 0xff;
  39. *(p + 5) = (num >> 16) & 0xff;
  40. *(p + 6) = (num >> 8) & 0xff;
  41. *(p + 7) = num & 0xff;
  42. }
  43. uint64_t
  44. dec_be64(const void *buf)
  45. {
  46. const uint8_t *p = buf;
  47. return (uint64_t)*p << 56 | (uint64_t)*(p + 1) << 48
  48. | (uint64_t)*(p + 2) << 40 | (uint64_t)*(p + 3) << 32
  49. | (uint64_t)*(p + 4) << 24 | (uint64_t)*(p + 5) << 16
  50. | (uint64_t)*(p + 6) << 8 | (uint64_t)*(p + 7);
  51. }
  52. void
  53. set_bit(uint8_t *bits, unsigned long index)
  54. {
  55. bits[index / 8] |= (1 << (7 - index % 8));
  56. }
  57. void
  58. clear_bit(uint8_t *bits, unsigned long index)
  59. {
  60. bits[index / 8] &= ~(1 << (7 - index % 8));
  61. }
  62. int
  63. has_bit(const uint8_t *bits, unsigned long index)
  64. {
  65. return bits[index / 8] & (1 << (7 - index % 8));
  66. }
  67. uint8_t
  68. hex2i(char c)
  69. {
  70. if (c >= '0' && c <= '9')
  71. return c - '0';
  72. else if (c >= 'a' && c <= 'f')
  73. return 10 + c - 'a';
  74. else
  75. abort();
  76. }
  77. int
  78. ishex(char *str)
  79. {
  80. while (*str != '\0') {
  81. if (!((*str >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')))
  82. return 0;
  83. str++;
  84. }
  85. return 1;
  86. }
  87. uint8_t *
  88. hex2bin(const char *hex, uint8_t *bin, size_t bsize)
  89. {
  90. for (size_t i = 0; i < bsize; i++)
  91. bin[i] = hex2i(hex[i * 2]) << 4 | hex2i(hex[i * 2 + 1]);
  92. return bin;
  93. }
  94. char *
  95. bin2hex(const uint8_t *bin, char *hex, size_t bsize)
  96. {
  97. size_t i;
  98. const char *hexc = "0123456789abcdef";
  99. for (i = 0; i < bsize; i++) {
  100. hex[i * 2] = hexc[(bin[i] >> 4) & 0xf];
  101. hex[i * 2 + 1] = hexc[bin[i] &0xf];
  102. }
  103. hex[i * 2] = '\0';
  104. return hex;
  105. }
  106. int
  107. set_nonblocking(int fd)
  108. {
  109. int oflags;
  110. if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
  111. return errno;
  112. if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1)
  113. return errno;
  114. return 0;
  115. }
  116. int
  117. set_blocking(int fd)
  118. {
  119. int oflags;
  120. if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
  121. return errno;
  122. if (fcntl(fd, F_SETFL, oflags & ~O_NONBLOCK) == -1)
  123. return errno;
  124. return 0;
  125. }
  126. int
  127. mkdirs(char *path, int mode)
  128. {
  129. int err = 0;
  130. char *spos = strchr(path + 1, '/'); // Skip leading '/'
  131. while (spos != NULL) {
  132. *spos = '\0';
  133. err = mkdir(path, mode);
  134. *spos = '/';
  135. if (err != 0 && errno != EEXIST)
  136. return errno;
  137. spos = strchr(spos + 1, '/');
  138. }
  139. if (mkdir(path, mode) != 0)
  140. return errno;
  141. return 0;
  142. }
  143. int
  144. vaopen(int *res, int flags, const char *fmt, va_list ap)
  145. {
  146. int fd, didmkdirs;
  147. char path[PATH_MAX + 1];
  148. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX)
  149. return ENAMETOOLONG;
  150. didmkdirs = 0;
  151. again:
  152. fd = open(path, flags, 0666);
  153. if (fd < 0 && errno == ENOENT && (flags & O_CREAT) != 0 && !didmkdirs) {
  154. char *rs = rindex(path, '/');
  155. if (rs != NULL) {
  156. *rs = '\0';
  157. if (mkdirs(path, 0777) == 0) {
  158. *rs = '/';
  159. didmkdirs = 1;
  160. goto again;
  161. }
  162. }
  163. return errno;
  164. }
  165. if (fd >= 0) {
  166. *res = fd;
  167. return 0;
  168. } else
  169. return errno;
  170. }
  171. int
  172. vopen(int *res, int flags, const char *fmt, ...)
  173. {
  174. int err;
  175. va_list ap;
  176. va_start(ap, fmt);
  177. err = vaopen(res, flags, fmt, ap);
  178. va_end(ap);
  179. return err;
  180. }
  181. int
  182. vfsync(const char *fmt, ...)
  183. {
  184. int err, fd;
  185. va_list ap;
  186. va_start(ap, fmt);
  187. err = vaopen(&fd, O_RDONLY, fmt, ap);
  188. va_end(ap);
  189. if (err != 0)
  190. return err;
  191. if (fsync(fd) < 0)
  192. err = errno;
  193. close(fd);
  194. return err;
  195. }
  196. int
  197. vfopen(FILE **ret, const char *mode, const char *fmt, ...)
  198. {
  199. int err = 0;
  200. char path[PATH_MAX + 1];
  201. va_list ap;
  202. va_start(ap, fmt);
  203. if (vsnprintf(path, PATH_MAX, fmt, ap) >= PATH_MAX)
  204. err = ENAMETOOLONG;
  205. va_end(ap);
  206. if (err == 0)
  207. if ((*ret = fopen(path, mode)) == NULL)
  208. err = errno;
  209. return err;
  210. }
  211. long
  212. rand_between(long min, long max)
  213. {
  214. return min + (long)rint((double)random() * (max - min) / RAND_MAX);
  215. }
  216. int
  217. write_fully(int fd, const void *buf, size_t len)
  218. {
  219. ssize_t nw;
  220. size_t off = 0;
  221. while (off < len) {
  222. nw = write(fd, buf + off, len - off);
  223. if (nw == -1)
  224. return errno;
  225. off += nw;
  226. }
  227. return 0;
  228. }
  229. int
  230. read_fully(int fd, void *buf, size_t len)
  231. {
  232. ssize_t nread;
  233. size_t off = 0;
  234. while (off < len) {
  235. nread = read(fd, buf + off, len - off);
  236. if (nread == 0)
  237. return EIO;
  238. else if (nread == -1)
  239. return errno;
  240. off += nread;
  241. }
  242. return 0;
  243. }
  244. void *
  245. read_file(const char *path, void *buf, size_t *size)
  246. {
  247. int fd, esave;
  248. void *mem = NULL;
  249. struct stat sb;
  250. if ((fd = open(path, O_RDONLY)) == -1)
  251. return NULL;
  252. if (fstat(fd, &sb) == -1)
  253. goto error;
  254. if (*size != 0 && *size < sb.st_size) {
  255. errno = EFBIG;
  256. goto error;
  257. }
  258. *size = sb.st_size;
  259. if (buf == NULL && (mem = malloc(sb.st_size)) == NULL)
  260. goto error;
  261. if (buf == NULL)
  262. buf = mem;
  263. if ((errno = read_fully(fd, buf, *size)) != 0)
  264. goto error;
  265. close(fd);
  266. return buf;
  267. error:
  268. esave = errno;
  269. if (mem != NULL)
  270. free(mem);
  271. close(fd);
  272. errno = esave;
  273. return NULL;
  274. }
  275. char *
  276. find_btpd_dir(void)
  277. {
  278. char *res = getenv("BTPD_HOME");
  279. if (res != NULL)
  280. return strdup(res);
  281. char *home = getenv("HOME");
  282. if (home == NULL) {
  283. struct passwd *pwent = getpwuid(getuid());
  284. endpwent();
  285. if (pwent != NULL)
  286. home = pwent->pw_dir;
  287. }
  288. if (home != NULL)
  289. asprintf(&res, "%s/.btpd", home);
  290. return res;
  291. }
  292. int
  293. make_abs_path(const char *in, char *out)
  294. {
  295. int ii = 0, oi = 0, lastsep = 0;
  296. switch (in[0]) {
  297. case '\0':
  298. return EINVAL;
  299. case '/':
  300. if (strlen(in) >= PATH_MAX)
  301. return ENAMETOOLONG;
  302. out[0] = '/';
  303. oi++;
  304. ii++;
  305. break;
  306. default:
  307. if (getcwd(out, PATH_MAX) == NULL)
  308. return errno;
  309. oi = strlen(out);
  310. if (oi + strlen(in) + 1 >= PATH_MAX)
  311. return ENAMETOOLONG;
  312. out[oi] = '/';
  313. lastsep = oi;
  314. oi++;
  315. break;
  316. }
  317. after_slash:
  318. while (in[ii] == '/')
  319. ii++;
  320. switch(in[ii]) {
  321. case '\0':
  322. goto end;
  323. case '.':
  324. ii++;
  325. goto one_dot;
  326. default:
  327. goto normal;
  328. }
  329. one_dot:
  330. switch (in[ii]) {
  331. case '\0':
  332. goto end;
  333. case '/':
  334. ii++;
  335. goto after_slash;
  336. case '.':
  337. ii++;
  338. goto two_dot;
  339. default:
  340. out[oi] = '.';
  341. oi++;
  342. goto normal;
  343. }
  344. two_dot:
  345. switch (in[ii]) {
  346. case '\0':
  347. if (lastsep == 0)
  348. oi = 1;
  349. else {
  350. oi = lastsep;
  351. while (out[oi - 1] != '/')
  352. oi--;
  353. lastsep = oi - 1;
  354. }
  355. goto end;
  356. case '/':
  357. if (lastsep == 0)
  358. oi = 1;
  359. else {
  360. oi = lastsep;
  361. while (out[oi - 1] != '/')
  362. oi--;
  363. lastsep = oi - 1;
  364. }
  365. ii++;
  366. goto after_slash;
  367. default:
  368. out[oi] = '.';
  369. out[oi + 1] = '.';
  370. oi += 2;
  371. goto normal;
  372. }
  373. normal:
  374. switch (in[ii]) {
  375. case '\0':
  376. goto end;
  377. case '/':
  378. out[oi] = '/';
  379. lastsep = oi;
  380. oi++;
  381. ii++;
  382. goto after_slash;
  383. default:
  384. out[oi] = in[ii];
  385. oi++;
  386. ii++;
  387. goto normal;
  388. }
  389. end:
  390. if (oi == lastsep + 1 && lastsep != 0)
  391. oi = lastsep;
  392. out[oi] = '\0';
  393. return 0;
  394. }