Browse Source

Make iobuf more useful for io and use better names in its api.

master
Richard Nyberg 16 years ago
parent
commit
3af2b0c0ac
6 changed files with 149 additions and 119 deletions
  1. +43
    -43
      btpd/cli_if.c
  2. +3
    -3
      btpd/tlib.c
  3. +6
    -6
      cli/add.c
  4. +33
    -33
      misc/btpd_if.c
  5. +52
    -25
      misc/iobuf.c
  6. +12
    -9
      misc/iobuf.h

+ 43
- 43
btpd/cli_if.c View File

@@ -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);
} }


+ 3
- 3
btpd/tlib.c View File

@@ -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);


+ 6
- 6
cli/add.c View File

@@ -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);


+ 33
- 33
misc/btpd_if.c View File

@@ -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);
} }

+ 52
- 25
misc/iobuf.c View File

@@ -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);
}

+ 12
- 9
misc/iobuf.h View File

@@ -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

Loading…
Cancel
Save