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 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 19 година
пре 18 година
пре 18 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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