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.

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