瀏覽代碼

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

master
Richard Nyberg 15 年之前
父節點
當前提交
3af2b0c0ac
共有 6 個文件被更改,包括 149 次插入119 次删除
  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 查看文件

@@ -11,7 +11,7 @@ struct cli {
static struct event m_cli_incoming;

static int
write_buffer(struct cli *cli, struct io_buffer *iob)
write_buffer(struct cli *cli, struct iobuf *iob)
{
int err = 0;
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);
} else
btpd_err("Out of memory.\n");
buf_free(iob);
iobuf_free(iob);
return err;
}

static int
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);
}

static int
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);
}

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;
switch (val) {
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));
return;
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);
return;
case IPC_TVAL_PCCOUNT:
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
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM,
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM,
(unsigned long)tl->tp->npieces);
return;
case IPC_TVAL_PCGOT:
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
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM,
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM,
(unsigned long)cm_pieces(tl->tp));
return;
case IPC_TVAL_PCSEEN:
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 {
unsigned long pcseen = 0;
for (unsigned long i = 0; i < tl->tp->npieces; i++)
if (tl->tp->net->piece_count[i] > 0)
pcseen++;
buf_print(iob, "i%dei%lue", IPC_TYPE_NUM, pcseen);
iobuf_print(iob, "i%dei%lue", IPC_TYPE_NUM, pcseen);
}
return;
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);
return;
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);
return;
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);
return;
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);
return;
case IPC_TVAL_DIR:
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);
else
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT);
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT);
return;
case IPC_TVAL_NAME:
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);
else
buf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT);
iobuf_print(iob, "i%dei%de", IPC_TYPE_ERR, IPC_EBADTENT);
return;
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;
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;
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);
return;
case IPC_TVAL_STATE:
buf_print(iob, "i%de", IPC_TYPE_NUM);
iobuf_print(iob, "i%de", IPC_TYPE_NUM);
if (tl->tp != NULL) {
switch (tl->tp->state) {
case T_STARTING:
@@ -137,24 +137,24 @@ write_ans(struct io_buffer *iob, struct tlib *tl, enum ipc_tval val)
break;
}
}
buf_print(iob, "i%de", ts);
iobuf_print(iob, "i%de", ts);
return;
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));
return;
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));
return;
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));
return;
case IPC_TVALCOUNT:
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
@@ -166,7 +166,7 @@ cmd_tget(struct cli *cli, int argc, const char *args)
size_t nkeys;
const char *keys, *p;
enum ipc_tval *opts;
struct io_buffer iob;
struct iobuf iob;

if ((keys = benc_dget_lst(args, "keys")) == NULL)
return IPC_COMMERR;
@@ -178,8 +178,8 @@ cmd_tget(struct cli *cli, int argc, const char *args)
for (int i = 0; i < nkeys; i++)
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");
if (benc_isint(p)) {
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 ||
(tlv[i]->tp == NULL && from == IPC_TWC_INACTIVE) ||
(tlv[i]->tp != NULL && from == IPC_TWC_ACTIVE))) {
buf_swrite(&iob, "l");
iobuf_swrite(&iob, "l");
for (int k = 0; k < nkeys; k++)
write_ans(&iob, tlv[i], opts[k]);
buf_swrite(&iob, "e");
iobuf_swrite(&iob, "e");
}
}
} 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)
tl = tlib_by_hash(benc_mem(p, NULL, NULL));
else {
buf_free(&iob);
iobuf_free(&iob);
free(opts);
return IPC_COMMERR;
}
if (tl != NULL) {
buf_swrite(&iob, "l");
iobuf_swrite(&iob, "l");
for (int i = 0; i < nkeys; i++)
write_ans(&iob, tl, opts[i]);
buf_swrite(&iob, "e");
iobuf_swrite(&iob, "e");
} 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);
return write_buffer(cli, &iob);
}


+ 3
- 3
btpd/tlib.c 查看文件

@@ -156,9 +156,9 @@ save_info(struct tlib *tl)
{
FILE *fp;
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"
"12:content havei%llde12:content sizei%llde"
"3:dir%d:%s4:name%d:%s"
@@ -177,7 +177,7 @@ save_info(struct tlib *tl)
if ((fp = fopen(wpath, "w")) == NULL)
btpd_err("failed to open '%s' (%s).\n", wpath, strerror(errno));
dct_subst_save(fp, "de", iob.buf);
buf_free(&iob);
iobuf_free(&iob);
if ((fflush(fp) == EOF || fsync(fileno(fp)) != 0
|| ferror(fp) || fclose(fp) != 0))
btpd_err("failed to write '%s'.\n", wpath);


+ 6
- 6
cli/add.c 查看文件

@@ -74,21 +74,21 @@ cmd_add(int argc, char **argv)
size_t mi_size;
enum ipc_err code;
char dpath[PATH_MAX];
struct io_buffer iob;
struct iobuf iob;

if ((mi = mi_load(argv[0], &mi_size)) == NULL)
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)) {
size_t tdlen;
const char *td =
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)
err(1, "make_abs_path '%s'", dpath);
code = btpd_add(ipc, mi, mi_size, dpath, name);


+ 33
- 33
misc/btpd_if.c 查看文件

@@ -129,7 +129,7 @@ ipc_req_res(struct ipc *ipc, const char *req, uint32_t qlen, char **res,
}

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)
{
enum ipc_err err;
@@ -137,12 +137,12 @@ ipc_buf_req_res(struct ipc *ipc, struct io_buffer *iob, char **res,
err = IPC_COMMERR;
else
err = ipc_req_res(ipc, iob->buf, iob->off, res, rlen);
buf_free(iob);
iobuf_free(iob);
return 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;
char *res;
@@ -158,11 +158,11 @@ ipc_buf_req_code(struct ipc *ipc, struct io_buffer *iob)
enum ipc_err
btpd_die(struct ipc *ipc, int seconds)
{
struct io_buffer iob = buf_init(16);
struct iobuf iob = iobuf_init(16);
if (seconds >= 0)
buf_print(&iob, "l3:diei%dee", seconds);
iobuf_print(&iob, "l3:diei%dee", seconds);
else
buf_swrite(&iob, "l3:diee");
iobuf_swrite(&iob, "l3:diee");
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;
uint32_t rlen;
enum ipc_err err;
struct io_buffer iob;
struct iobuf iob;

if (nkeys == 0 || ntps == 0)
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++) {
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
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++)
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)
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;
uint32_t rlen;
struct io_buffer iob;
struct iobuf iob;
enum ipc_err err;

if (nkeys == 0)
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++)
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)
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,
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);
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);
}

static enum ipc_err
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) {
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
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);
}

@@ -315,7 +315,7 @@ btpd_stop(struct ipc *ipc, struct ipc_torrent *tp)
enum ipc_err
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);
}

+ 52
- 25
misc/iobuf.c 查看文件

@@ -1,3 +1,4 @@
#include <assert.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdio.h>
@@ -5,44 +6,66 @@
#include <string.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.len = size;
iob.skip = 0;
iob.error = (iob.buf = malloc(size)) == NULL ? 1 : 0;
return iob;
}

void
buf_free(struct io_buffer *iob)
iobuf_free(struct iobuf *iob)
{
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
buf_grow(struct io_buffer *iob, size_t addlen)
iobuf_accommodate(struct iobuf *iob, size_t count)
{
if (iob->error)
return iob->error;
char *nbuf = realloc(iob->buf, iob->len + addlen);
if (nbuf == NULL) {
iob->error = 1;
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 {
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;
}
}

int
buf_print(struct io_buffer *iob, const char *fmt, ...)
iobuf_print(struct iobuf *iob, const char *fmt, ...)
{
if (iob->error)
return 0;
@@ -51,9 +74,8 @@ buf_print(struct io_buffer *iob, const char *fmt, ...)
va_start(ap, fmt);
np = vsnprintf(NULL, 0, fmt, 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);
vsnprintf(iob->buf + iob->off, np + 1, fmt, ap);
va_end(ap);
@@ -62,14 +84,19 @@ buf_print(struct io_buffer *iob, const char *fmt, ...)
}

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

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 查看文件

@@ -1,20 +1,23 @@
#ifndef BTPD_IOBUF_H
#define BTPD_IOBUF_H

struct io_buffer {
struct iobuf {
uint8_t *buf;
size_t size;
size_t off;
size_t len;
char *buf;
size_t skip;
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)))
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

Loading…
取消
儲存