A clone of btpd with my configuration changes.
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

pirms 18 gadiem
pirms 18 gadiem
pirms 18 gadiem
pirms 18 gadiem
pirms 18 gadiem
pirms 18 gadiem
pirms 18 gadiem
pirms 18 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <sys/un.h>
  4. #include <assert.h>
  5. #include <ctype.h>
  6. #include <err.h>
  7. #include <errno.h>
  8. #include <inttypes.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include "benc.h"
  14. #include "btpd_if.h"
  15. #include "iobuf.h"
  16. #include "subr.h"
  17. struct ipc {
  18. int sd;
  19. };
  20. static const char *errmsgs[] = {
  21. #define ERRDEF(name, msg) msg,
  22. #include "ipcdefs.h"
  23. #undef ERRDEF
  24. NULL
  25. };
  26. static const char *tval_names[] = {
  27. #define TVDEF(val, type, name) name,
  28. #include "ipcdefs.h"
  29. #undef TVDEF
  30. NULL
  31. };
  32. const char *
  33. ipc_strerror(enum ipc_err err)
  34. {
  35. if (err < 0 || err >= IPC_ERRCOUNT)
  36. return "unknown error";
  37. return errmsgs[err];
  38. }
  39. const char *
  40. tval_name(enum ipc_tval key)
  41. {
  42. if (key < 0 || key >= IPC_TVALCOUNT)
  43. return "unknown key";
  44. return tval_names[key];
  45. }
  46. int
  47. ipc_open(const char *dir, struct ipc **out)
  48. {
  49. int sd = -1, err = 0;
  50. size_t plen;
  51. struct ipc *res;
  52. struct sockaddr_un addr;
  53. plen = sizeof(addr.sun_path);
  54. if (snprintf(addr.sun_path, plen, "%s/sock", dir) >= plen)
  55. return ENAMETOOLONG;
  56. addr.sun_family = AF_UNIX;
  57. if ((sd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
  58. return errno;
  59. if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
  60. err = errno;
  61. close(sd);
  62. return err;
  63. }
  64. if ((res = malloc(sizeof(*res))) == NULL) {
  65. close(sd);
  66. return ENOMEM;
  67. }
  68. res->sd = sd;
  69. *out = res;
  70. return 0;
  71. }
  72. void
  73. ipc_close(struct ipc *ipc)
  74. {
  75. close(ipc->sd);
  76. free(ipc);
  77. }
  78. static enum ipc_err
  79. ipc_response(struct ipc *ipc, char **out, uint32_t *len)
  80. {
  81. uint32_t size;
  82. char *buf;
  83. if (read_fully(ipc->sd, &size, sizeof(size)) != 0)
  84. return IPC_COMMERR;
  85. if (size == 0)
  86. return IPC_COMMERR;
  87. if ((buf = malloc(size)) == NULL)
  88. return IPC_COMMERR;
  89. if (read_fully(ipc->sd, buf, size) != 0) {
  90. free(buf);
  91. return IPC_COMMERR;
  92. }
  93. *out = buf;
  94. *len = size;
  95. return IPC_OK;
  96. }
  97. static enum ipc_err
  98. ipc_req_res(struct ipc *ipc, const char *req, uint32_t qlen, char **res,
  99. uint32_t *rlen)
  100. {
  101. if (write_fully(ipc->sd, &qlen, sizeof(qlen)) != 0)
  102. return IPC_COMMERR;
  103. if (write_fully(ipc->sd, req, qlen) != 0)
  104. return IPC_COMMERR;
  105. if (ipc_response(ipc, res, rlen) != 0)
  106. return IPC_COMMERR;
  107. if (benc_validate(*res, *rlen) != 0)
  108. return IPC_COMMERR;
  109. if (!benc_isdct(*res))
  110. return IPC_COMMERR;
  111. return IPC_OK;
  112. }
  113. static enum ipc_err
  114. ipc_buf_req_res(struct ipc *ipc, struct io_buffer *iob, char **res,
  115. uint32_t *rlen)
  116. {
  117. enum ipc_err err;
  118. if (iob->error)
  119. err = IPC_COMMERR;
  120. else
  121. err = ipc_req_res(ipc, iob->buf, iob->off, res, rlen);
  122. buf_free(iob);
  123. return err;
  124. }
  125. static enum ipc_err
  126. ipc_buf_req_code(struct ipc *ipc, struct io_buffer *iob)
  127. {
  128. enum ipc_err err;
  129. char *res;
  130. uint32_t rlen;
  131. if ((err = ipc_buf_req_res(ipc, iob, &res, &rlen)) == 0) {
  132. err = benc_dget_int(res, "code");
  133. free(res);
  134. }
  135. return err;
  136. }
  137. enum ipc_err
  138. btpd_die(struct ipc *ipc, int seconds)
  139. {
  140. struct io_buffer iob = buf_init(16);
  141. if (seconds >= 0)
  142. buf_print(&iob, "l3:diei%dee", seconds);
  143. else
  144. buf_swrite(&iob, "l3:diee");
  145. return ipc_buf_req_code(ipc, &iob);
  146. }
  147. static enum ipc_err
  148. tget_common(char *ans, enum ipc_tval *keys, size_t nkeys, tget_cb_t cb,
  149. void *arg)
  150. {
  151. int err;
  152. const char *res;
  153. struct ipc_get_res cbres[IPC_TVALCOUNT];
  154. if ((err = benc_dget_int(ans, "code")) != 0)
  155. return err;
  156. res = benc_dget_lst(ans, "result");
  157. int obji = 0;
  158. for (res = benc_first(res); res != NULL; res = benc_next(res)) {
  159. if (benc_isint(res)) {
  160. cb(obji, benc_int(res, NULL), NULL, arg);
  161. obji++;
  162. continue;
  163. }
  164. const char *t = benc_first(res);
  165. const char *v = benc_next(t);
  166. for (int j = 0; j < nkeys; j++) {
  167. cbres[keys[j]].type = benc_int(t, NULL);
  168. switch (cbres[keys[j]].type) {
  169. case IPC_TYPE_ERR:
  170. case IPC_TYPE_NUM:
  171. cbres[keys[j]].v.num = benc_int(v, NULL);
  172. break;
  173. case IPC_TYPE_STR:
  174. case IPC_TYPE_BIN:
  175. cbres[keys[j]].v.str.p= benc_mem(v, &cbres[keys[j]].v.str.l,
  176. NULL);
  177. break;
  178. }
  179. t = benc_next(v);
  180. if (t != NULL)
  181. v = benc_next(t);
  182. }
  183. cb(obji, IPC_OK, cbres, arg);
  184. obji++;
  185. }
  186. free(ans);
  187. return IPC_OK;
  188. }
  189. enum ipc_err
  190. btpd_tget(struct ipc *ipc, struct ipc_torrent *tps, size_t ntps,
  191. enum ipc_tval *keys, size_t nkeys, tget_cb_t cb, void *arg)
  192. {
  193. char *res;
  194. uint32_t rlen;
  195. enum ipc_err err;
  196. struct io_buffer iob;
  197. if (nkeys == 0 || ntps == 0)
  198. return IPC_COMMERR;
  199. iob = buf_init(1 << 14);
  200. buf_swrite(&iob, "l4:tgetd4:froml");
  201. for (int i = 0; i < ntps; i++) {
  202. if (tps[i].by_hash) {
  203. buf_swrite(&iob, "20:");
  204. buf_write(&iob, tps[i].u.hash, 20);
  205. } else
  206. buf_print(&iob, "i%ue", tps[i].u.num);
  207. }
  208. buf_swrite(&iob, "e4:keysl");
  209. for (int k = 0; k < nkeys; k++)
  210. buf_print(&iob, "i%de", keys[k]);
  211. buf_swrite(&iob, "eee");
  212. if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0)
  213. err = tget_common(res, keys, nkeys, cb, arg);
  214. return err;
  215. }
  216. enum ipc_err
  217. btpd_tget_wc(struct ipc *ipc, enum ipc_twc twc, enum ipc_tval *keys,
  218. size_t nkeys, tget_cb_t cb, void *arg)
  219. {
  220. char *res;
  221. uint32_t rlen;
  222. struct io_buffer iob;
  223. enum ipc_err err;
  224. if (nkeys == 0)
  225. return IPC_COMMERR;
  226. iob = buf_init(1 << 14);
  227. buf_print(&iob, "l4:tgetd4:fromi%de4:keysl", twc);
  228. for (int i = 0; i < nkeys; i++)
  229. buf_print(&iob, "i%de", keys[i]);
  230. buf_swrite(&iob, "eee");
  231. if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0)
  232. err = tget_common(res, keys, nkeys, cb, arg);
  233. return err;
  234. }
  235. enum ipc_err
  236. btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, const char *content,
  237. const char *name)
  238. {
  239. struct io_buffer iob = buf_init(1 << 10);
  240. buf_print(&iob, "l3:addd7:content%d:%s", (int)strlen(content),
  241. content);
  242. if (name != NULL)
  243. buf_print(&iob, "4:name%d:%s", (int)strlen(name), name);
  244. buf_print(&iob, "7:torrent%lu:", (unsigned long)mi_size);
  245. buf_write(&iob, mi, mi_size);
  246. buf_swrite(&iob, "ee");
  247. return ipc_buf_req_code(ipc, &iob);
  248. }
  249. static enum ipc_err
  250. simple_treq(struct ipc *ipc, char *cmd, struct ipc_torrent *tp)
  251. {
  252. struct io_buffer iob = buf_init(32);
  253. if (tp->by_hash) {
  254. buf_print(&iob, "l%d:%s20:", (int)strlen(cmd), cmd);
  255. buf_write(&iob, tp->u.hash, 20);
  256. buf_swrite(&iob, "e");
  257. } else
  258. buf_print(&iob, "l%d:%si%uee", (int)strlen(cmd), cmd, tp->u.num);
  259. return ipc_buf_req_code(ipc, &iob);
  260. }
  261. enum ipc_err
  262. btpd_del(struct ipc *ipc, struct ipc_torrent *tp)
  263. {
  264. return simple_treq(ipc, "del", tp);
  265. }
  266. enum ipc_err
  267. btpd_start(struct ipc *ipc, struct ipc_torrent *tp)
  268. {
  269. return simple_treq(ipc, "start", tp);
  270. }
  271. enum ipc_err
  272. btpd_stop(struct ipc *ipc, struct ipc_torrent *tp)
  273. {
  274. return simple_treq(ipc, "stop", tp);
  275. }
  276. enum ipc_err
  277. btpd_stop_all(struct ipc *ipc)
  278. {
  279. struct io_buffer iob = buf_init(16);
  280. buf_swrite(&iob, "l8:stop-alle");
  281. return ipc_buf_req_code(ipc, &iob);
  282. }