diff --git a/cli/btpd_if.c b/cli/btpd_if.c deleted file mode 100644 index 8bd0f21..0000000 --- a/cli/btpd_if.c +++ /dev/null @@ -1,313 +0,0 @@ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "benc.h" -#include "btpd_if.h" -#include "iobuf.h" -#include "subr.h" - -struct ipc { - int sd; -}; - -static const char *errmsgs[] = { -#define ERRDEF(name, msg) msg, -#include "ipcdefs.h" -#undef ERRDEF - NULL -}; - -static const char *tval_names[] = { -#define TVDEF(val, type, name) name, -#include "ipcdefs.h" -#undef TVDEF - NULL -}; - -const char * -ipc_strerror(enum ipc_err err) -{ - if (err < 0 || err >= IPC_ERRCOUNT) - return "unknown error"; - return errmsgs[err]; -} - -const char * -tval_name(enum ipc_tval key) -{ - if (key < 0 || key >= IPC_TVALCOUNT) - return "unknown key"; - return tval_names[key]; -} - -int -ipc_open(const char *dir, struct ipc **out) -{ - int sd = -1, err = 0; - size_t plen; - struct ipc *res; - struct sockaddr_un addr; - - plen = sizeof(addr.sun_path); - if (snprintf(addr.sun_path, plen, "%s/sock", dir) >= plen) - return ENAMETOOLONG; - addr.sun_family = AF_UNIX; - - if ((sd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) - return errno; - - if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - err = errno; - close(sd); - return err; - } - - if ((res = malloc(sizeof(*res))) == NULL) { - close(sd); - return ENOMEM; - } - - res->sd = sd; - *out = res; - return 0; -} - -void -ipc_close(struct ipc *ipc) -{ - close(ipc->sd); - free(ipc); -} - -static enum ipc_err -ipc_response(struct ipc *ipc, char **out, uint32_t *len) -{ - uint32_t size; - char *buf; - - if (read_fully(ipc->sd, &size, sizeof(size)) != 0) - return IPC_COMMERR; - if (size == 0) - return IPC_COMMERR; - if ((buf = malloc(size)) == NULL) - return IPC_COMMERR; - if (read_fully(ipc->sd, buf, size) != 0) { - free(buf); - return IPC_COMMERR; - } - *out = buf; - *len = size; - return IPC_OK; -} - -static enum ipc_err -ipc_req_res(struct ipc *ipc, const char *req, uint32_t qlen, char **res, - uint32_t *rlen) -{ - assert(benc_validate(req, qlen) == 0); - if (write_fully(ipc->sd, &qlen, sizeof(qlen)) != 0) - return IPC_COMMERR; - if (write_fully(ipc->sd, req, qlen) != 0) - return IPC_COMMERR; - if (ipc_response(ipc, res, rlen) != 0) - return IPC_COMMERR; - if (benc_validate(*res, *rlen) != 0) - return IPC_COMMERR; - if (!benc_isdct(*res)) - return IPC_COMMERR; - return IPC_OK; -} - -static enum ipc_err -ipc_buf_req_res(struct ipc *ipc, struct io_buffer *iob, char **res, - uint32_t *rlen) -{ - enum ipc_err err = ipc_req_res(ipc, iob->buf, iob->buf_off, res, rlen); - free(iob->buf); - return err; -} - -static enum ipc_err -ipc_buf_req_code(struct ipc *ipc, struct io_buffer *iob) -{ - enum ipc_err err; - char *res; - uint32_t rlen; - - if ((err = ipc_buf_req_res(ipc, iob, &res, &rlen)) == 0) { - err = benc_dget_int(res, "code"); - free(res); - } - return err; -} - -enum ipc_err -btpd_die(struct ipc *ipc, int seconds) -{ - struct io_buffer iob; - buf_init(&iob, 16); - if (seconds >= 0) - buf_print(&iob, "l3:diei%dee", seconds); - else - buf_swrite(&iob, "l3:diee"); - return ipc_buf_req_code(ipc, &iob); -} - -static enum ipc_err -tget_common(char *ans, enum ipc_tval *keys, size_t nkeys, tget_cb_t cb, - void *arg) -{ - int err; - const char *res; - struct ipc_get_res cbres[IPC_TVALCOUNT]; - - if ((err = benc_dget_int(ans, "code")) != 0) - return err; - - res = benc_dget_lst(ans, "result"); - int obji = 0; - for (res = benc_first(res); res != NULL; res = benc_next(res)) { - if (benc_isint(res)) { - cb(obji, benc_int(res, NULL), NULL, arg); - obji++; - continue; - } - const char *t = benc_first(res); - const char *v = benc_next(t); - for (int j = 0; j < nkeys; j++) { - cbres[keys[j]].type = benc_int(t, NULL); - switch (cbres[keys[j]].type) { - case IPC_TYPE_ERR: - case IPC_TYPE_NUM: - cbres[keys[j]].v.num = benc_int(v, NULL); - break; - case IPC_TYPE_STR: - case IPC_TYPE_BIN: - cbres[keys[j]].v.str.p= benc_mem(v, &cbres[keys[j]].v.str.l, - NULL); - break; - } - t = benc_next(v); - if (t != NULL) - v = benc_next(t); - } - cb(obji, IPC_OK, cbres, arg); - obji++; - } - - free(ans); - return IPC_OK; -} - -enum ipc_err -btpd_tget(struct ipc *ipc, struct ipc_torrent *tps, size_t ntps, - enum ipc_tval *keys, size_t nkeys, tget_cb_t cb, void *arg) -{ - char *res; - uint32_t rlen; - enum ipc_err err; - struct io_buffer iob; - - if (nkeys == 0 || ntps == 0) - return IPC_COMMERR; - - buf_init(&iob, 1 << 14); - buf_swrite(&iob, "l4:tgetd4:froml"); - for (int i = 0; i < ntps; i++) { - if (tps[i].by_hash) { - buf_swrite(&iob, "20:"); - buf_write(&iob, tps[i].u.hash, 20); - } else - buf_print(&iob, "i%ue", tps[i].u.num); - } - buf_swrite(&iob, "e4:keysl"); - for (int k = 0; k < nkeys; k++) - buf_print(&iob, "i%de", keys[k]); - buf_swrite(&iob, "eee"); - - if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0) - err = tget_common(res, keys, nkeys, cb, arg); - return err; -} - -enum ipc_err -btpd_tget_wc(struct ipc *ipc, enum ipc_twc twc, enum ipc_tval *keys, - size_t nkeys, tget_cb_t cb, void *arg) -{ - char *res; - uint32_t rlen; - struct io_buffer iob; - enum ipc_err err; - - if (nkeys == 0) - return IPC_COMMERR; - - buf_init(&iob, 1 << 14); - buf_print(&iob, "l4:tgetd4:fromi%de4:keysl", twc); - for (int i = 0; i < nkeys; i++) - buf_print(&iob, "i%de", keys[i]); - buf_swrite(&iob, "eee"); - - if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0) - err = tget_common(res, keys, nkeys, cb, arg); - return err; -} - -enum ipc_err -btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, const char *content, - const char *name) -{ - struct io_buffer iob; - buf_init(&iob, (1 << 10)); - buf_print(&iob, "l3:addd7:content%d:%s", (int)strlen(content), - content); - if (name != NULL) - buf_print(&iob, "4:name%d:%s", (int)strlen(name), name); - buf_print(&iob, "7:torrent%lu:", (unsigned long)mi_size); - buf_write(&iob, mi, mi_size); - buf_swrite(&iob, "ee"); - return ipc_buf_req_code(ipc, &iob); -} - -static enum ipc_err -simple_treq(struct ipc *ipc, char *cmd, struct ipc_torrent *tp) -{ - struct io_buffer iob; - buf_init(&iob, 32); - if (tp->by_hash) { - buf_print(&iob, "l%d:%s20:", (int)strlen(cmd), cmd); - buf_write(&iob, tp->u.hash, 20); - buf_swrite(&iob, "e"); - } else - buf_print(&iob, "l%d:%si%uee", (int)strlen(cmd), cmd, tp->u.num); - return ipc_buf_req_code(ipc, &iob); -} - -enum ipc_err -btpd_del(struct ipc *ipc, struct ipc_torrent *tp) -{ - return simple_treq(ipc, "del", tp); -} - -enum ipc_err -btpd_start(struct ipc *ipc, struct ipc_torrent *tp) -{ - return simple_treq(ipc, "start", tp); -} - -enum ipc_err -btpd_stop(struct ipc *ipc, struct ipc_torrent *tp) -{ - return simple_treq(ipc, "stop", tp); -} diff --git a/cli/btpd_if.h b/cli/btpd_if.h deleted file mode 100644 index ed0d9ba..0000000 --- a/cli/btpd_if.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef BTPD_IPC_H -#define BTPD_IPC_H - -enum ipc_err { -#define ERRDEF(name, msg) IPC_##name, -#include "ipcdefs.h" -#undef ERRDEF - IPC_ERRCOUNT -}; - -enum ipc_type { - IPC_TYPE_ERR, - IPC_TYPE_BIN, - IPC_TYPE_NUM, - IPC_TYPE_STR -}; - -enum ipc_tval { -#define TVDEF(val, type, name) IPC_TVAL_##val, -#include "ipcdefs.h" -#undef TVDEF - IPC_TVALCOUNT -}; - -enum ipc_dval { - IPC_DVAL_MIN, - IPC_DVAL_MAX -}; - -enum ipc_twc { - IPC_TWC_ALL, - IPC_TWC_ACTIVE, - IPC_TWC_INACTIVE -}; - -enum ipc_tstate { - IPC_TSTATE_INACTIVE, - IPC_TSTATE_START, - IPC_TSTATE_STOP, - IPC_TSTATE_LEECH, - IPC_TSTATE_SEED -}; - -#ifndef DAEMON - -struct ipc; - -struct ipc_get_res { - enum ipc_type type; - union { - struct { - const char *p; - size_t l; - } str; - long long num; - } v; -}; - -struct ipc_torrent { - int by_hash; - union { - unsigned num; - uint8_t hash[20]; - } u; -}; - -typedef void (*tget_cb_t)(int obji, enum ipc_err objerr, - struct ipc_get_res *res, void *arg); - -//typedef void (*dget_cb_t)(struct ipc_get_res *res, size_t nres, void *arg); - -int ipc_open(const char *dir, struct ipc **out); -void ipc_close(struct ipc *ipc); - -const char *ipc_strerror(enum ipc_err err); - -enum ipc_err btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, - const char *content, const char *name); -enum ipc_err btpd_del(struct ipc *ipc, struct ipc_torrent *tp); -enum ipc_err btpd_start(struct ipc *ipc, struct ipc_torrent *tp); -enum ipc_err btpd_stop(struct ipc *ipc, struct ipc_torrent *tp); -enum ipc_err btpd_die(struct ipc *ipc, int seconds); -enum ipc_err btpd_get(struct ipc *ipc, enum ipc_dval *keys, size_t nkeys, - tget_cb_t cb, void *arg); -enum ipc_err btpd_tget(struct ipc *ipc, struct ipc_torrent *tps, size_t ntps, - enum ipc_tval *keys, size_t nkeys, tget_cb_t cb, void *arg); -enum ipc_err btpd_tget_wc(struct ipc *ipc, enum ipc_twc, enum ipc_tval *keys, - size_t nkeys, tget_cb_t cb, void *arg); - -#endif - -#endif