A clone of btpd with my configuration changes.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

222 行
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. }