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.

222 lignes
4.3 KiB

  1. #include <ctype.h>
  2. #include <err.h>
  3. #include <errno.h>
  4. #include <inttypes.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include "benc.h"
  10. #include "iobuf.h"
  11. #include "btpd_if.h"
  12. int
  13. ipc_open(const char *key, struct ipc **out)
  14. {
  15. size_t plen;
  16. size_t keylen;
  17. struct ipc *res;
  18. if (key == NULL)
  19. key = "default";
  20. keylen = strlen(key);
  21. for (int i = 0; i < keylen; i++)
  22. if (!isalnum(key[i]))
  23. return EINVAL;
  24. res = malloc(sizeof(*res));
  25. if (res == NULL)
  26. return ENOMEM;
  27. plen = sizeof(res->addr.sun_path);
  28. if (snprintf(res->addr.sun_path, plen,
  29. "/tmp/btpd_%u_%s", geteuid(), key) >= plen) {
  30. free(res);
  31. return ENAMETOOLONG;
  32. }
  33. res->addr.sun_family = AF_UNIX;
  34. *out = res;
  35. return 0;
  36. }
  37. int
  38. ipc_close(struct ipc *ipc)
  39. {
  40. free(ipc);
  41. return 0;
  42. }
  43. static int
  44. ipc_connect(struct ipc *ipc, FILE **out)
  45. {
  46. FILE *fp;
  47. int sd;
  48. int error;
  49. if ((sd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
  50. return errno;
  51. if (connect(sd, (struct sockaddr *)&ipc->addr, sizeof(ipc->addr)) == -1)
  52. goto error;
  53. if ((fp = fdopen(sd, "r+")) == NULL)
  54. goto error;
  55. *out = fp;
  56. return 0;
  57. error:
  58. error = errno;
  59. close(sd);
  60. return error;
  61. }
  62. static int
  63. ipc_response(FILE *fp, char **out, uint32_t *len)
  64. {
  65. uint32_t size;
  66. char *buf;
  67. if (fread(&size, sizeof(size), 1, fp) != 1) {
  68. if (ferror(fp))
  69. return errno;
  70. else
  71. return ECONNRESET;
  72. }
  73. if (size == 0)
  74. return EINVAL;
  75. if ((buf = malloc(size)) == NULL)
  76. return ENOMEM;
  77. if (fread(buf, 1, size, fp) != size) {
  78. if (ferror(fp))
  79. return errno;
  80. else
  81. return ECONNRESET;
  82. }
  83. *out = buf;
  84. *len = size;
  85. return 0;
  86. }
  87. static int
  88. ipc_req_res(struct ipc *ipc,
  89. const char *req, uint32_t qlen,
  90. char **res, uint32_t *rlen)
  91. {
  92. FILE *fp;
  93. int error;
  94. if ((error = ipc_connect(ipc, &fp)) != 0)
  95. return error;
  96. if (fwrite(&qlen, sizeof(qlen), 1, fp) != 1)
  97. goto error;
  98. if (fwrite(req, 1, qlen, fp) != qlen)
  99. goto error;
  100. if (fflush(fp) != 0)
  101. goto error;
  102. if ((errno = ipc_response(fp, res, rlen)) != 0)
  103. goto error;
  104. if ((errno = benc_validate(*res, *rlen)) != 0)
  105. goto error;
  106. fclose(fp);
  107. return 0;
  108. error:
  109. error = errno;
  110. fclose(fp);
  111. return error;
  112. }
  113. int
  114. btpd_die(struct ipc *ipc)
  115. {
  116. int error;
  117. char *response = NULL;
  118. const char shutdown[] = "l3:diee";
  119. uint32_t size = sizeof(shutdown) - 1;
  120. uint32_t rsiz;
  121. if ((error = ipc_req_res(ipc, shutdown, size, &response, &rsiz)) != 0)
  122. return error;
  123. error = benc_validate(response, rsiz);
  124. if (error == 0) {
  125. int64_t tmp;
  126. benc_dget_int64(response, "code", &tmp);
  127. error = tmp;
  128. }
  129. free(response);
  130. return error;
  131. }
  132. int
  133. btpd_add(struct ipc *ipc, char **paths, unsigned npaths, char **out)
  134. {
  135. int error;
  136. struct io_buffer iob;
  137. char *res = NULL;
  138. uint32_t reslen;
  139. buf_init(&iob, 1024);
  140. buf_print(&iob, "l3:add");
  141. for (unsigned i = 0; i < npaths; i++) {
  142. int plen = strlen(paths[i]);
  143. buf_print(&iob, "%d:", plen);
  144. buf_write(&iob, paths[i], plen);
  145. }
  146. buf_print(&iob, "e");
  147. error = ipc_req_res(ipc, iob.buf, iob.buf_off, &res, &reslen);
  148. free(iob.buf);
  149. if (error == 0)
  150. *out = res;
  151. return error;
  152. }
  153. int
  154. btpd_stat(struct ipc *ipc, char **out)
  155. {
  156. const char cmd[] = "l4:state";
  157. uint32_t cmdlen = sizeof(cmd) - 1;
  158. char *res;
  159. uint32_t reslen;
  160. if ((errno = ipc_req_res(ipc, cmd, cmdlen, &res, &reslen)) != 0)
  161. return errno;
  162. *out = res;
  163. return 0;
  164. }
  165. int
  166. btpd_del(struct ipc *ipc, uint8_t (*hash)[20], unsigned nhashes, char **out)
  167. {
  168. int error;
  169. struct io_buffer iob;
  170. char *res = NULL;
  171. uint32_t reslen;
  172. buf_init(&iob, 1024);
  173. buf_write(&iob, "l3:del", 6);
  174. for (unsigned i = 0; i < nhashes; i++) {
  175. buf_write(&iob, "20:", 3);
  176. buf_write(&iob, hash[i], 20);
  177. }
  178. buf_write(&iob, "e", 1);
  179. error = ipc_req_res(ipc, iob.buf, iob.buf_off, &res, &reslen);
  180. free(iob.buf);
  181. if (error != 0)
  182. return error;
  183. *out = res;
  184. return 0;
  185. }