@@ -11,7 +11,7 @@ struct cli { | |||||
static struct event m_cli_incoming; | static struct event m_cli_incoming; | ||||
static int | static int | ||||
write_buffer(struct cli *cli, struct io_buffer *iob) | |||||
write_buffer(struct cli *cli, struct iobuf *iob) | |||||
{ | { | ||||
int err = 0; | int err = 0; | ||||
if (!iob->error) { | if (!iob->error) { | ||||
@@ -20,107 +20,107 @@ write_buffer(struct cli *cli, struct io_buffer *iob) | |||||
err = write_fully(cli->sd, iob->buf, iob->off); | err = write_fully(cli->sd, iob->buf, iob->off); | ||||
} else | } else | ||||
btpd_err("Out of memory.\n"); | btpd_err("Out of memory.\n"); | ||||
buf_free(iob); | |||||
iobuf_free(iob); | |||||
return err; | return err; | ||||
} | } | ||||
static int | static int | ||||
write_code_buffer(struct cli *cli, enum ipc_err code) | write_code_buffer(struct cli *cli, enum ipc_err code) | ||||
{ | { | ||||
struct io_buffer iob = buf_init(16); | |||||
buf_print(&iob, "d4:codei%uee", code); | |||||
struct iobuf iob = iobuf_init(16); | |||||
iobuf_print(&iob, "d4:codei%uee", code); | |||||
return write_buffer(cli, &iob); | return write_buffer(cli, &iob); | ||||
} | } | ||||
static int | static int | ||||
write_add_buffer(struct cli *cli, unsigned num) | write_add_buffer(struct cli *cli, unsigned num) | ||||
{ | { | ||||
struct io_buffer iob = buf_init(32); | |||||
buf_print(&iob, "d4:codei%ue3:numi%uee", IPC_OK, num); | |||||
struct iobuf iob = iobuf_init(32); | |||||
iobuf_print(&iob, "d4:codei%ue3:numi%uee", IPC_OK, num); | |||||
return write_buffer(cli, &iob); | return write_buffer(cli, &iob); | ||||
} | } | ||||
static void | static void | ||||
write_ans(struct io_buffer *iob, struct tlib *tl, enum ipc_tval val) | |||||
write_ans(struct iobuf *iob, struct tlib *tl, enum ipc_tval val) | |||||
{ | { | ||||
enum ipc_tstate ts = IPC_TSTATE_INACTIVE; | enum ipc_tstate ts = IPC_TSTATE_INACTIVE; | ||||
switch (val) { | switch (val) { | ||||
case IPC_TVAL_CGOT: | case IPC_TVAL_CGOT: | ||||
buf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? tl->content_have : (long long)cm_content(tl->tp)); | tl->tp == NULL ? tl->content_have : (long long)cm_content(tl->tp)); | ||||
return; | return; | ||||
case IPC_TVAL_CSIZE: | case IPC_TVAL_CSIZE: | ||||
buf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
(long long)tl->content_size); | (long long)tl->content_size); | ||||
return; | return; | ||||
case IPC_TVAL_PCCOUNT: | case IPC_TVAL_PCCOUNT: | ||||
if (tl->tp == NULL) | if (tl->tp == NULL) | ||||
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_ETINACTIVE); | |||||
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_ETINACTIVE); | |||||
else | else | ||||
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
(unsigned long)tl->tp->npieces); | (unsigned long)tl->tp->npieces); | ||||
return; | return; | ||||
case IPC_TVAL_PCGOT: | case IPC_TVAL_PCGOT: | ||||
if (tl->tp == NULL) | if (tl->tp == NULL) | ||||
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_ETINACTIVE); | |||||
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_ETINACTIVE); | |||||
else | else | ||||
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
(unsigned long)cm_pieces(tl->tp)); | (unsigned long)cm_pieces(tl->tp)); | ||||
return; | return; | ||||
case IPC_TVAL_PCSEEN: | case IPC_TVAL_PCSEEN: | ||||
if (tl->tp == NULL) | if (tl->tp == NULL) | ||||
buf_print(iob, "i%dei%de", IPC_TYPE_NUM, 0); | |||||
iobuf_print(iob, "i%dei%de", IPC_TYPE_NUM, 0); | |||||
else { | else { | ||||
unsigned long pcseen = 0; | unsigned long pcseen = 0; | ||||
for (unsigned long i = 0; i < tl->tp->npieces; i++) | for (unsigned long i = 0; i < tl->tp->npieces; i++) | ||||
if (tl->tp->net->piece_count[i] > 0) | if (tl->tp->net->piece_count[i] > 0) | ||||
pcseen++; | pcseen++; | ||||
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM, pcseen); | |||||
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM, pcseen); | |||||
} | } | ||||
return; | return; | ||||
case IPC_TVAL_RATEDWN: | case IPC_TVAL_RATEDWN: | ||||
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? 0UL : tl->tp->net->rate_dwn / RATEHISTORY); | tl->tp == NULL ? 0UL : tl->tp->net->rate_dwn / RATEHISTORY); | ||||
return; | return; | ||||
case IPC_TVAL_RATEUP: | case IPC_TVAL_RATEUP: | ||||
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? 0UL : tl->tp->net->rate_up / RATEHISTORY); | tl->tp == NULL ? 0UL : tl->tp->net->rate_up / RATEHISTORY); | ||||
return; | return; | ||||
case IPC_TVAL_SESSDWN: | case IPC_TVAL_SESSDWN: | ||||
buf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? 0LL : tl->tp->net->downloaded); | tl->tp == NULL ? 0LL : tl->tp->net->downloaded); | ||||
return; | return; | ||||
case IPC_TVAL_SESSUP: | case IPC_TVAL_SESSUP: | ||||
buf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%llde", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? 0LL : tl->tp->net->uploaded); | tl->tp == NULL ? 0LL : tl->tp->net->uploaded); | ||||
return; | return; | ||||
case IPC_TVAL_DIR: | case IPC_TVAL_DIR: | ||||
if (tl->dir != NULL) | if (tl->dir != NULL) | ||||
buf_print(iob, "i%de%d:%s", IPC_TYPE_STR, (int)strlen(tl->dir), | |||||
iobuf_print(iob, "i%de%d:%s", IPC_TYPE_STR, (int)strlen(tl->dir), | |||||
tl->dir); | tl->dir); | ||||
else | else | ||||
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT); | |||||
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT); | |||||
return; | return; | ||||
case IPC_TVAL_NAME: | case IPC_TVAL_NAME: | ||||
if (tl->name != NULL) | if (tl->name != NULL) | ||||
buf_print(iob, "i%de%d:%s", IPC_TYPE_STR, (int)strlen(tl->name), | |||||
iobuf_print(iob, "i%de%d:%s", IPC_TYPE_STR, (int)strlen(tl->name), | |||||
tl->name); | tl->name); | ||||
else | else | ||||
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT); | |||||
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT); | |||||
return; | return; | ||||
case IPC_TVAL_IHASH: | case IPC_TVAL_IHASH: | ||||
buf_print(iob, "i%de20:", IPC_TYPE_BIN); | |||||
buf_write(iob, tl->hash, 20); | |||||
iobuf_print(iob, "i%de20:", IPC_TYPE_BIN); | |||||
iobuf_write(iob, tl->hash, 20); | |||||
return; | return; | ||||
case IPC_TVAL_NUM: | case IPC_TVAL_NUM: | ||||
buf_print(iob, "i%dei%ue", IPC_TYPE_NUM, tl->num); | |||||
iobuf_print(iob, "i%dei%ue", IPC_TYPE_NUM, tl->num); | |||||
return; | return; | ||||
case IPC_TVAL_PCOUNT: | case IPC_TVAL_PCOUNT: | ||||
buf_print(iob, "i%dei%ue", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%ue", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? 0 : tl->tp->net->npeers); | tl->tp == NULL ? 0 : tl->tp->net->npeers); | ||||
return; | return; | ||||
case IPC_TVAL_STATE: | case IPC_TVAL_STATE: | ||||
buf_print(iob, "i%de", IPC_TYPE_NUM); | |||||
iobuf_print(iob, "i%de", IPC_TYPE_NUM); | |||||
if (tl->tp != NULL) { | if (tl->tp != NULL) { | ||||
switch (tl->tp->state) { | switch (tl->tp->state) { | ||||
case T_STARTING: | case T_STARTING: | ||||
@@ -137,24 +137,24 @@ write_ans(struct io_buffer *iob, struct tlib *tl, enum ipc_tval val) | |||||
break; | break; | ||||
} | } | ||||
} | } | ||||
buf_print(iob, "i%de", ts); | |||||
iobuf_print(iob, "i%de", ts); | |||||
return; | return; | ||||
case IPC_TVAL_TOTDWN: | case IPC_TVAL_TOTDWN: | ||||
buf_print(iob, "i%dei%llde", IPC_TYPE_NUM, tl->tot_down + | |||||
iobuf_print(iob, "i%dei%llde", IPC_TYPE_NUM, tl->tot_down + | |||||
(tl->tp == NULL ? 0 : tl->tp->net->downloaded)); | (tl->tp == NULL ? 0 : tl->tp->net->downloaded)); | ||||
return; | return; | ||||
case IPC_TVAL_TOTUP: | case IPC_TVAL_TOTUP: | ||||
buf_print(iob, "i%dei%llde", IPC_TYPE_NUM, tl->tot_up + | |||||
iobuf_print(iob, "i%dei%llde", IPC_TYPE_NUM, tl->tot_up + | |||||
(tl->tp == NULL ? 0 : tl->tp->net->uploaded)); | (tl->tp == NULL ? 0 : tl->tp->net->uploaded)); | ||||
return; | return; | ||||
case IPC_TVAL_TRERR: | case IPC_TVAL_TRERR: | ||||
buf_print(iob, "i%dei%ue", IPC_TYPE_NUM, | |||||
iobuf_print(iob, "i%dei%ue", IPC_TYPE_NUM, | |||||
tl->tp == NULL ? 0 : tr_errors(tl->tp)); | tl->tp == NULL ? 0 : tr_errors(tl->tp)); | ||||
return; | return; | ||||
case IPC_TVALCOUNT: | case IPC_TVALCOUNT: | ||||
break; | break; | ||||
} | } | ||||
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_ENOKEY); | |||||
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_ENOKEY); | |||||
} | } | ||||
static int | static int | ||||
@@ -166,7 +166,7 @@ cmd_tget(struct cli *cli, int argc, const char *args) | |||||
size_t nkeys; | size_t nkeys; | ||||
const char *keys, *p; | const char *keys, *p; | ||||
enum ipc_tval *opts; | enum ipc_tval *opts; | ||||
struct io_buffer iob; | |||||
struct iobuf iob; | |||||
if ((keys = benc_dget_lst(args, "keys")) == NULL) | if ((keys = benc_dget_lst(args, "keys")) == NULL) | ||||
return IPC_COMMERR; | return IPC_COMMERR; | ||||
@@ -178,8 +178,8 @@ cmd_tget(struct cli *cli, int argc, const char *args) | |||||
for (int i = 0; i < nkeys; i++) | for (int i = 0; i < nkeys; i++) | ||||
opts[i] = benc_int(p, &p); | opts[i] = benc_int(p, &p); | ||||
iob = buf_init(1 << 15); | |||||
buf_swrite(&iob, "d4:codei0e6:resultl"); | |||||
iob = iobuf_init(1 << 15); | |||||
iobuf_swrite(&iob, "d4:codei0e6:resultl"); | |||||
p = benc_dget_any(args, "from"); | p = benc_dget_any(args, "from"); | ||||
if (benc_isint(p)) { | if (benc_isint(p)) { | ||||
enum ipc_twc from = benc_int(p, NULL); | enum ipc_twc from = benc_int(p, NULL); | ||||
@@ -189,10 +189,10 @@ cmd_tget(struct cli *cli, int argc, const char *args) | |||||
if ((from == IPC_TWC_ALL || | if ((from == IPC_TWC_ALL || | ||||
(tlv[i]->tp == NULL && from == IPC_TWC_INACTIVE) || | (tlv[i]->tp == NULL && from == IPC_TWC_INACTIVE) || | ||||
(tlv[i]->tp != NULL && from == IPC_TWC_ACTIVE))) { | (tlv[i]->tp != NULL && from == IPC_TWC_ACTIVE))) { | ||||
buf_swrite(&iob, "l"); | |||||
iobuf_swrite(&iob, "l"); | |||||
for (int k = 0; k < nkeys; k++) | for (int k = 0; k < nkeys; k++) | ||||
write_ans(&iob, tlv[i], opts[k]); | write_ans(&iob, tlv[i], opts[k]); | ||||
buf_swrite(&iob, "e"); | |||||
iobuf_swrite(&iob, "e"); | |||||
} | } | ||||
} | } | ||||
} else if (benc_islst(p)) { | } else if (benc_islst(p)) { | ||||
@@ -203,20 +203,20 @@ cmd_tget(struct cli *cli, int argc, const char *args) | |||||
else if (benc_isstr(p) && benc_strlen(p) == 20) | else if (benc_isstr(p) && benc_strlen(p) == 20) | ||||
tl = tlib_by_hash(benc_mem(p, NULL, NULL)); | tl = tlib_by_hash(benc_mem(p, NULL, NULL)); | ||||
else { | else { | ||||
buf_free(&iob); | |||||
iobuf_free(&iob); | |||||
free(opts); | free(opts); | ||||
return IPC_COMMERR; | return IPC_COMMERR; | ||||
} | } | ||||
if (tl != NULL) { | if (tl != NULL) { | ||||
buf_swrite(&iob, "l"); | |||||
iobuf_swrite(&iob, "l"); | |||||
for (int i = 0; i < nkeys; i++) | for (int i = 0; i < nkeys; i++) | ||||
write_ans(&iob, tl, opts[i]); | write_ans(&iob, tl, opts[i]); | ||||
buf_swrite(&iob, "e"); | |||||
iobuf_swrite(&iob, "e"); | |||||
} else | } else | ||||
buf_print(&iob, "i%de", IPC_ENOTENT); | |||||
iobuf_print(&iob, "i%de", IPC_ENOTENT); | |||||
} | } | ||||
} | } | ||||
buf_swrite(&iob, "ee"); | |||||
iobuf_swrite(&iob, "ee"); | |||||
free(opts); | free(opts); | ||||
return write_buffer(cli, &iob); | return write_buffer(cli, &iob); | ||||
} | } | ||||
@@ -156,9 +156,9 @@ save_info(struct tlib *tl) | |||||
{ | { | ||||
FILE *fp; | FILE *fp; | ||||
char relpath[SHAHEXSIZE], path[PATH_MAX], wpath[PATH_MAX]; | char relpath[SHAHEXSIZE], path[PATH_MAX], wpath[PATH_MAX]; | ||||
struct io_buffer iob = buf_init(1 << 10); | |||||
struct iobuf iob = iobuf_init(1 << 10); | |||||
buf_print(&iob, | |||||
iobuf_print(&iob, | |||||
"d4:infod" | "d4:infod" | ||||
"12:content havei%llde12:content sizei%llde" | "12:content havei%llde12:content sizei%llde" | ||||
"3:dir%d:%s4:name%d:%s" | "3:dir%d:%s4:name%d:%s" | ||||
@@ -177,7 +177,7 @@ save_info(struct tlib *tl) | |||||
if ((fp = fopen(wpath, "w")) == NULL) | if ((fp = fopen(wpath, "w")) == NULL) | ||||
btpd_err("failed to open '%s' (%s).\n", wpath, strerror(errno)); | btpd_err("failed to open '%s' (%s).\n", wpath, strerror(errno)); | ||||
dct_subst_save(fp, "de", iob.buf); | dct_subst_save(fp, "de", iob.buf); | ||||
buf_free(&iob); | |||||
iobuf_free(&iob); | |||||
if ((fflush(fp) == EOF || fsync(fileno(fp)) != 0 | if ((fflush(fp) == EOF || fsync(fileno(fp)) != 0 | ||||
|| ferror(fp) || fclose(fp) != 0)) | || ferror(fp) || fclose(fp) != 0)) | ||||
btpd_err("failed to write '%s'.\n", wpath); | btpd_err("failed to write '%s'.\n", wpath); | ||||
@@ -74,21 +74,21 @@ cmd_add(int argc, char **argv) | |||||
size_t mi_size; | size_t mi_size; | ||||
enum ipc_err code; | enum ipc_err code; | ||||
char dpath[PATH_MAX]; | char dpath[PATH_MAX]; | ||||
struct io_buffer iob; | |||||
struct iobuf iob; | |||||
if ((mi = mi_load(argv[0], &mi_size)) == NULL) | if ((mi = mi_load(argv[0], &mi_size)) == NULL) | ||||
err(1, "error loading '%s'", argv[0]); | err(1, "error loading '%s'", argv[0]); | ||||
iob = buf_init(PATH_MAX); | |||||
buf_write(&iob, dir, dirlen); | |||||
iob = iobuf_init(PATH_MAX); | |||||
iobuf_write(&iob, dir, dirlen); | |||||
if (topdir && !mi_simple(mi)) { | if (topdir && !mi_simple(mi)) { | ||||
size_t tdlen; | size_t tdlen; | ||||
const char *td = | const char *td = | ||||
benc_dget_mem(benc_dget_dct(mi, "info"), "name", &tdlen); | benc_dget_mem(benc_dget_dct(mi, "info"), "name", &tdlen); | ||||
buf_swrite(&iob, "/"); | |||||
buf_write(&iob, td, tdlen); | |||||
iobuf_swrite(&iob, "/"); | |||||
iobuf_write(&iob, td, tdlen); | |||||
} | } | ||||
buf_swrite(&iob, "\0"); | |||||
iobuf_swrite(&iob, "\0"); | |||||
if ((errno = make_abs_path(iob.buf, dpath)) != 0) | if ((errno = make_abs_path(iob.buf, dpath)) != 0) | ||||
err(1, "make_abs_path '%s'", dpath); | err(1, "make_abs_path '%s'", dpath); | ||||
code = btpd_add(ipc, mi, mi_size, dpath, name); | code = btpd_add(ipc, mi, mi_size, dpath, name); | ||||
@@ -129,7 +129,7 @@ ipc_req_res(struct ipc *ipc, const char *req, uint32_t qlen, char **res, | |||||
} | } | ||||
static enum ipc_err | static enum ipc_err | ||||
ipc_buf_req_res(struct ipc *ipc, struct io_buffer *iob, char **res, | |||||
ipc_buf_req_res(struct ipc *ipc, struct iobuf *iob, char **res, | |||||
uint32_t *rlen) | uint32_t *rlen) | ||||
{ | { | ||||
enum ipc_err err; | enum ipc_err err; | ||||
@@ -137,12 +137,12 @@ ipc_buf_req_res(struct ipc *ipc, struct io_buffer *iob, char **res, | |||||
err = IPC_COMMERR; | err = IPC_COMMERR; | ||||
else | else | ||||
err = ipc_req_res(ipc, iob->buf, iob->off, res, rlen); | err = ipc_req_res(ipc, iob->buf, iob->off, res, rlen); | ||||
buf_free(iob); | |||||
iobuf_free(iob); | |||||
return err; | return err; | ||||
} | } | ||||
static enum ipc_err | static enum ipc_err | ||||
ipc_buf_req_code(struct ipc *ipc, struct io_buffer *iob) | |||||
ipc_buf_req_code(struct ipc *ipc, struct iobuf *iob) | |||||
{ | { | ||||
enum ipc_err err; | enum ipc_err err; | ||||
char *res; | char *res; | ||||
@@ -158,11 +158,11 @@ ipc_buf_req_code(struct ipc *ipc, struct io_buffer *iob) | |||||
enum ipc_err | enum ipc_err | ||||
btpd_die(struct ipc *ipc, int seconds) | btpd_die(struct ipc *ipc, int seconds) | ||||
{ | { | ||||
struct io_buffer iob = buf_init(16); | |||||
struct iobuf iob = iobuf_init(16); | |||||
if (seconds >= 0) | if (seconds >= 0) | ||||
buf_print(&iob, "l3:diei%dee", seconds); | |||||
iobuf_print(&iob, "l3:diei%dee", seconds); | |||||
else | else | ||||
buf_swrite(&iob, "l3:diee"); | |||||
iobuf_swrite(&iob, "l3:diee"); | |||||
return ipc_buf_req_code(ipc, &iob); | return ipc_buf_req_code(ipc, &iob); | ||||
} | } | ||||
@@ -219,24 +219,24 @@ btpd_tget(struct ipc *ipc, struct ipc_torrent *tps, size_t ntps, | |||||
char *res; | char *res; | ||||
uint32_t rlen; | uint32_t rlen; | ||||
enum ipc_err err; | enum ipc_err err; | ||||
struct io_buffer iob; | |||||
struct iobuf iob; | |||||
if (nkeys == 0 || ntps == 0) | if (nkeys == 0 || ntps == 0) | ||||
return IPC_COMMERR; | return IPC_COMMERR; | ||||
iob = buf_init(1 << 14); | |||||
buf_swrite(&iob, "l4:tgetd4:froml"); | |||||
iob = iobuf_init(1 << 14); | |||||
iobuf_swrite(&iob, "l4:tgetd4:froml"); | |||||
for (int i = 0; i < ntps; i++) { | for (int i = 0; i < ntps; i++) { | ||||
if (tps[i].by_hash) { | if (tps[i].by_hash) { | ||||
buf_swrite(&iob, "20:"); | |||||
buf_write(&iob, tps[i].u.hash, 20); | |||||
iobuf_swrite(&iob, "20:"); | |||||
iobuf_write(&iob, tps[i].u.hash, 20); | |||||
} else | } else | ||||
buf_print(&iob, "i%ue", tps[i].u.num); | |||||
iobuf_print(&iob, "i%ue", tps[i].u.num); | |||||
} | } | ||||
buf_swrite(&iob, "e4:keysl"); | |||||
iobuf_swrite(&iob, "e4:keysl"); | |||||
for (int k = 0; k < nkeys; k++) | for (int k = 0; k < nkeys; k++) | ||||
buf_print(&iob, "i%de", keys[k]); | |||||
buf_swrite(&iob, "eee"); | |||||
iobuf_print(&iob, "i%de", keys[k]); | |||||
iobuf_swrite(&iob, "eee"); | |||||
if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0) | if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0) | ||||
err = tget_common(res, keys, nkeys, cb, arg); | err = tget_common(res, keys, nkeys, cb, arg); | ||||
@@ -249,17 +249,17 @@ btpd_tget_wc(struct ipc *ipc, enum ipc_twc twc, enum ipc_tval *keys, | |||||
{ | { | ||||
char *res; | char *res; | ||||
uint32_t rlen; | uint32_t rlen; | ||||
struct io_buffer iob; | |||||
struct iobuf iob; | |||||
enum ipc_err err; | enum ipc_err err; | ||||
if (nkeys == 0) | if (nkeys == 0) | ||||
return IPC_COMMERR; | return IPC_COMMERR; | ||||
iob = buf_init(1 << 14); | |||||
buf_print(&iob, "l4:tgetd4:fromi%de4:keysl", twc); | |||||
iob = iobuf_init(1 << 14); | |||||
iobuf_print(&iob, "l4:tgetd4:fromi%de4:keysl", twc); | |||||
for (int i = 0; i < nkeys; i++) | for (int i = 0; i < nkeys; i++) | ||||
buf_print(&iob, "i%de", keys[i]); | |||||
buf_swrite(&iob, "eee"); | |||||
iobuf_print(&iob, "i%de", keys[i]); | |||||
iobuf_swrite(&iob, "eee"); | |||||
if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0) | if ((err = ipc_buf_req_res(ipc, &iob, &res, &rlen)) == 0) | ||||
err = tget_common(res, keys, nkeys, cb, arg); | err = tget_common(res, keys, nkeys, cb, arg); | ||||
@@ -270,27 +270,27 @@ enum ipc_err | |||||
btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, const char *content, | btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, const char *content, | ||||
const char *name) | const char *name) | ||||
{ | { | ||||
struct io_buffer iob = buf_init(1 << 10); | |||||
buf_print(&iob, "l3:addd7:content%d:%s", (int)strlen(content), | |||||
struct iobuf iob = iobuf_init(1 << 10); | |||||
iobuf_print(&iob, "l3:addd7:content%d:%s", (int)strlen(content), | |||||
content); | content); | ||||
if (name != NULL) | 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"); | |||||
iobuf_print(&iob, "4:name%d:%s", (int)strlen(name), name); | |||||
iobuf_print(&iob, "7:torrent%lu:", (unsigned long)mi_size); | |||||
iobuf_write(&iob, mi, mi_size); | |||||
iobuf_swrite(&iob, "ee"); | |||||
return ipc_buf_req_code(ipc, &iob); | return ipc_buf_req_code(ipc, &iob); | ||||
} | } | ||||
static enum ipc_err | static enum ipc_err | ||||
simple_treq(struct ipc *ipc, char *cmd, struct ipc_torrent *tp) | simple_treq(struct ipc *ipc, char *cmd, struct ipc_torrent *tp) | ||||
{ | { | ||||
struct io_buffer iob = buf_init(32); | |||||
struct iobuf iob = iobuf_init(32); | |||||
if (tp->by_hash) { | 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"); | |||||
iobuf_print(&iob, "l%d:%s20:", (int)strlen(cmd), cmd); | |||||
iobuf_write(&iob, tp->u.hash, 20); | |||||
iobuf_swrite(&iob, "e"); | |||||
} else | } else | ||||
buf_print(&iob, "l%d:%si%uee", (int)strlen(cmd), cmd, tp->u.num); | |||||
iobuf_print(&iob, "l%d:%si%uee", (int)strlen(cmd), cmd, tp->u.num); | |||||
return ipc_buf_req_code(ipc, &iob); | return ipc_buf_req_code(ipc, &iob); | ||||
} | } | ||||
@@ -315,7 +315,7 @@ btpd_stop(struct ipc *ipc, struct ipc_torrent *tp) | |||||
enum ipc_err | enum ipc_err | ||||
btpd_stop_all(struct ipc *ipc) | btpd_stop_all(struct ipc *ipc) | ||||
{ | { | ||||
struct io_buffer iob = buf_init(16); | |||||
buf_swrite(&iob, "l8:stop-alle"); | |||||
struct iobuf iob = iobuf_init(16); | |||||
iobuf_swrite(&iob, "l8:stop-alle"); | |||||
return ipc_buf_req_code(ipc, &iob); | return ipc_buf_req_code(ipc, &iob); | ||||
} | } |
@@ -1,3 +1,4 @@ | |||||
#include <assert.h> | |||||
#include <inttypes.h> | #include <inttypes.h> | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
@@ -5,44 +6,66 @@ | |||||
#include <string.h> | #include <string.h> | ||||
#include "iobuf.h" | #include "iobuf.h" | ||||
#include "subr.h" | |||||
#define GROWLEN (1 << 14) | |||||
struct io_buffer | |||||
buf_init(size_t size) | |||||
struct iobuf | |||||
iobuf_init(size_t size) | |||||
{ | { | ||||
struct io_buffer iob; | |||||
struct iobuf iob; | |||||
iob.size = size; | |||||
iob.off = 0; | iob.off = 0; | ||||
iob.len = size; | |||||
iob.skip = 0; | |||||
iob.error = (iob.buf = malloc(size)) == NULL ? 1 : 0; | iob.error = (iob.buf = malloc(size)) == NULL ? 1 : 0; | ||||
return iob; | return iob; | ||||
} | } | ||||
void | void | ||||
buf_free(struct io_buffer *iob) | |||||
iobuf_free(struct iobuf *iob) | |||||
{ | { | ||||
if (iob->buf != NULL) | if (iob->buf != NULL) | ||||
free(iob->buf); | |||||
free(iob->buf - iob->skip); | |||||
iob->buf = NULL; | |||||
iob->error = 1; | |||||
} | |||||
void | |||||
iobuf_consumed(struct iobuf *iob, size_t count) | |||||
{ | |||||
if (iob->error) | |||||
return; | |||||
assert(count <= iob->off); | |||||
iob->skip += count; | |||||
iob->buf += count; | |||||
iob->off -= count; | |||||
} | } | ||||
int | int | ||||
buf_grow(struct io_buffer *iob, size_t addlen) | |||||
iobuf_accommodate(struct iobuf *iob, size_t count) | |||||
{ | { | ||||
if (iob->error) | if (iob->error) | ||||
return iob->error; | |||||
char *nbuf = realloc(iob->buf, iob->len + addlen); | |||||
if (nbuf == NULL) { | |||||
iob->error = 1; | |||||
return 0; | return 0; | ||||
size_t esize = iob->size - (iob->skip + iob->off); | |||||
if (esize >= count) | |||||
return 1; | |||||
else if (esize + iob->skip >= count) { | |||||
bcopy(iob->buf, iob->buf - iob->skip, iob->off); | |||||
iob->buf -= iob->skip; | |||||
iob->skip = 0; | |||||
return 1; | |||||
} else { | } else { | ||||
iob->buf = nbuf; | |||||
iob->len += addlen; | |||||
uint8_t *nbuf = realloc(iob->buf - iob->skip, iob->size + count); | |||||
if (nbuf == NULL) { | |||||
iob->error = 1; | |||||
return 0; | |||||
} | |||||
iob->buf = nbuf + iob->skip; | |||||
iob->size += count; | |||||
return 1; | return 1; | ||||
} | } | ||||
} | } | ||||
int | int | ||||
buf_print(struct io_buffer *iob, const char *fmt, ...) | |||||
iobuf_print(struct iobuf *iob, const char *fmt, ...) | |||||
{ | { | ||||
if (iob->error) | if (iob->error) | ||||
return 0; | return 0; | ||||
@@ -51,9 +74,8 @@ buf_print(struct io_buffer *iob, const char *fmt, ...) | |||||
va_start(ap, fmt); | va_start(ap, fmt); | ||||
np = vsnprintf(NULL, 0, fmt, ap); | np = vsnprintf(NULL, 0, fmt, ap); | ||||
va_end(ap); | va_end(ap); | ||||
if (np + 1 > iob->len - iob->off) | |||||
if (!buf_grow(iob, (1 + (np + 1) / GROWLEN) * GROWLEN)) | |||||
return 0; | |||||
if (!iobuf_accommodate(iob, np + 1)) | |||||
return 0; | |||||
va_start(ap, fmt); | va_start(ap, fmt); | ||||
vsnprintf(iob->buf + iob->off, np + 1, fmt, ap); | vsnprintf(iob->buf + iob->off, np + 1, fmt, ap); | ||||
va_end(ap); | va_end(ap); | ||||
@@ -62,14 +84,19 @@ buf_print(struct io_buffer *iob, const char *fmt, ...) | |||||
} | } | ||||
int | int | ||||
buf_write(struct io_buffer *iob, const void *buf, size_t len) | |||||
iobuf_write(struct iobuf *iob, const void *buf, size_t count) | |||||
{ | { | ||||
if (iob->error) | if (iob->error) | ||||
return 0; | return 0; | ||||
if (len > iob->len - iob->off) | |||||
if (!buf_grow(iob, (1 + len / GROWLEN) * GROWLEN)) | |||||
return 0; | |||||
bcopy(buf, iob->buf + iob->off, len); | |||||
iob->off += len; | |||||
if (!iobuf_accommodate(iob, count)) | |||||
return 0; | |||||
bcopy(buf, iob->buf + iob->off, count); | |||||
iob->off += count; | |||||
return 1; | return 1; | ||||
} | } | ||||
void * | |||||
iobuf_find(struct iobuf *iob, const void *p, size_t plen) | |||||
{ | |||||
return iob->error ? NULL : memfind(p, plen, iob->buf, iob->off); | |||||
} |
@@ -1,20 +1,23 @@ | |||||
#ifndef BTPD_IOBUF_H | #ifndef BTPD_IOBUF_H | ||||
#define BTPD_IOBUF_H | #define BTPD_IOBUF_H | ||||
struct io_buffer { | |||||
struct iobuf { | |||||
uint8_t *buf; | |||||
size_t size; | |||||
size_t off; | size_t off; | ||||
size_t len; | |||||
char *buf; | |||||
size_t skip; | |||||
int error; | int error; | ||||
}; | }; | ||||
struct io_buffer buf_init(size_t size); | |||||
void buf_free(struct io_buffer *iob); | |||||
int buf_grow(struct io_buffer *iob, size_t size); | |||||
int buf_write(struct io_buffer *iob, const void *data, size_t size); | |||||
struct iobuf iobuf_init(size_t size); | |||||
void iobuf_free(struct iobuf *iob); | |||||
int iobuf_accommodate(struct iobuf *iob, size_t size); | |||||
int iobuf_write(struct iobuf *iob, const void *data, size_t size); | |||||
__attribute__((format (printf, 2, 3))) | __attribute__((format (printf, 2, 3))) | ||||
int buf_print(struct io_buffer *iob, const char *fmt, ...); | |||||
int iobuf_print(struct iobuf *iob, const char *fmt, ...); | |||||
void *iobuf_find(struct iobuf *iob, const void *p, size_t plen); | |||||
void iobuf_consumed(struct iobuf *iob, size_t count); | |||||
#define buf_swrite(iob, s) buf_write(iob, s, sizeof(s) - 1) | |||||
#define iobuf_swrite(iob, s) iobuf_write(iob, s, sizeof(s) - 1) | |||||
#endif | #endif |