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.

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