瀏覽代碼

Make chck_buffer out/in to pi9_stream, update pi9_string with chck's

implementation.
master
Jari Vetoniemi 10 年之前
父節點
當前提交
e1b56125e8
共有 5 個文件被更改,包括 375 次插入283 次删除
  1. +29
    -29
      bin/server.c
  2. +236
    -234
      src/pi9.c
  3. +5
    -5
      src/pi9.h
  4. +42
    -10
      src/pi9_string.c
  5. +63
    -5
      src/pi9_string.h

+ 29
- 29
bin/server.c 查看文件

@ -230,7 +230,7 @@ cb_read_qtdir(struct pi9 *pi9, struct node *node, uint64_t offset, uint32_t coun
pi9_string_set_cstr_with_length(&stats[1].name, "..", 2, false);
for (uint32_t i = 0; i < 2; ++i) {
if (!pi9_write_stat(&stats[i], pi9->out))
if (!pi9_write_stat(&stats[i], pi9->stream))
return false;
}
@ -243,7 +243,7 @@ cb_read_qtdir(struct pi9 *pi9, struct node *node, uint64_t offset, uint32_t coun
if (c->procs.size)
c->stat.length = c->procs.size(pi9, c);
if (!pi9_write_stat(&c->stat, pi9->out))
if (!pi9_write_stat(&c->stat, pi9->stream))
return false;
}
@ -260,7 +260,7 @@ cb_read_hello(struct pi9 *pi9, struct node *node, uint64_t offset, uint32_t coun
// The bytes are returned with the read reply message.
// XXX: Just example here, we ignore offset and count
return (pi9_write("Hello World!", 1, sizeof("Hello World!"), pi9->out) == sizeof("Hello World!"));
return (pi9_write("Hello World!", 1, sizeof("Hello World!"), pi9->stream) == sizeof("Hello World!"));
}
static bool
@ -401,16 +401,16 @@ cb_attach(struct pi9 *pi9, uint16_t tag, uint32_t fid, uint32_t afid, const stru
return true;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_oom:
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->out);
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
err_no_auth:
pi9_write_error(tag, PI9_ERR_NO_AUTH, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_AUTH, pi9->stream);
return false;
}
@ -507,16 +507,16 @@ cb_walk(struct pi9 *pi9, uint16_t tag, uint32_t fid, uint32_t newfid, uint16_t n
return true;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_fid_in_use:
pi9_write_error(tag, PI9_ERR_FID_IN_USE, pi9->out);
pi9_write_error(tag, PI9_ERR_FID_IN_USE, pi9->stream);
return false;
err_not_directory:
pi9_write_error(tag, PI9_ERR_NOT_DIRECTORY, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_DIRECTORY, pi9->stream);
return false;
err_oom:
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->out);
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->stream);
return false;
}
@ -555,10 +555,10 @@ cb_open(struct pi9 *pi9, uint16_t tag, uint32_t fid, uint8_t mode, struct pi9_qi
return true;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
}
@ -604,14 +604,14 @@ cb_create(struct pi9 *pi9, uint16_t tag, uint32_t fid, const struct pi9_string *
// (out_iounit is by default 0)
// FIXME: creation code here
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
}
@ -633,13 +633,13 @@ cb_read(struct pi9 *pi9, uint16_t tag, uint32_t fid, uint64_t offset, uint32_t c
return true;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, pi9->out);
pi9_write_error(tag, PI9_ERR_WRITE, pi9->stream);
return false;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
}
@ -666,13 +666,13 @@ cb_write(struct pi9 *pi9, uint16_t tag, uint32_t fid, uint64_t offset, uint32_t
return true;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, pi9->out);
pi9_write_error(tag, PI9_ERR_WRITE, pi9->stream);
return false;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
}
@ -692,7 +692,7 @@ cb_clunk(struct pi9 *pi9, uint16_t tag, uint32_t fid)
return true;
err_oom:
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->out);
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->stream);
return false;
}
@ -723,13 +723,13 @@ cb_remove(struct pi9 *pi9, uint16_t tag, uint32_t fid)
return true;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_oom:
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->out);
pi9_write_error(tag, PI9_ERR_OUT_OF_MEMORY, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
}
@ -752,7 +752,7 @@ cb_stat(struct pi9 *pi9, uint16_t tag, uint32_t fid, struct pi9_stat **out_stat)
return true;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
}
@ -842,10 +842,10 @@ cb_twstat(struct pi9 *pi9, uint16_t tag, uint32_t fid, const struct pi9_stat *st
return true;
err_nofid:
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->out);
pi9_write_error(tag, PI9_ERR_NO_FID, pi9->stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, pi9->stream);
return false;
}

+ 236
- 234
src/pi9.c 查看文件

@ -17,6 +17,10 @@ static const uint32_t HDRSZ = 7; // size of header
static const uint32_t QIDSZ = 13; // size of serialized pi9_qid
static const uint32_t STATHDRSZ = 47; // size of serialized pi9_stat, until the variable length data
struct pi9_stream {
struct chck_buffer out, in;
};
enum op {
OPFIRST,
Tversion = 0x64,
@ -50,7 +54,7 @@ enum op {
OPLAST,
};
#define DECOP(x) static bool op_##x(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
#define DECOP(x) static bool op_##x(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
DECOP(Tversion);
DECOP(Tauth);
DECOP(Tattach);
@ -68,7 +72,7 @@ DECOP(Twstat);
static struct {
size_t msz;
bool (*cb)(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out);
bool (*cb)(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream);
} ops[] = {
[Tversion] = { 6, op_Tversion },
[Tauth] = { 8, op_Tauth },
@ -104,49 +108,49 @@ static const struct {
};
static inline bool
write_qid(struct pi9_qid *qid, struct chck_buffer *out)
write_qid(struct pi9_qid *qid, struct pi9_stream *stream)
{
return (chck_buffer_write_int(&qid->type, sizeof(qid->type), out) &&
chck_buffer_write_int(&qid->vers, sizeof(qid->vers), out) &&
chck_buffer_write_int(&qid->path, sizeof(qid->path), out));
return (chck_buffer_write_int(&qid->type, sizeof(qid->type), o">&stream->out) &&
chck_buffer_write_int(&qid->vers, sizeof(qid->vers), o">&stream->out) &&
chck_buffer_write_int(&qid->path, sizeof(qid->path), o">&stream->out));
}
static inline bool
read_qid(struct pi9_qid *qid, struct chck_buffer *in)
read_qid(struct pi9_qid *qid, struct pi9_stream *stream)
{
return (chck_buffer_read_int(&qid->type, sizeof(qid->type), in) &&
chck_buffer_read_int(&qid->vers, sizeof(qid->vers), in) &&
chck_buffer_read_int(&qid->path, sizeof(qid->path), in));
return (chck_buffer_read_int(&qid->type, sizeof(qid->type), o">&stream->in) &&
chck_buffer_read_int(&qid->vers, sizeof(qid->vers), o">&stream->in) &&
chck_buffer_read_int(&qid->path, sizeof(qid->path), o">&stream->in));
}
static inline bool
read_stat(struct pi9_stat *stat, struct chck_buffer *in)
read_stat(struct pi9_stat *stat, struct pi9_stream *stream)
{
uint16_t size;
if (!chck_buffer_read_int(&size, sizeof(size), in) ||
!chck_buffer_read_int(&stat->type, sizeof(stat->type), in) ||
!chck_buffer_read_int(&stat->dev, sizeof(stat->dev), in) ||
!read_qid(&stat->qid, in) ||
!chck_buffer_read_int(&stat->mode, sizeof(stat->mode), in) ||
!chck_buffer_read_int(&stat->atime, sizeof(stat->atime), in) ||
!chck_buffer_read_int(&stat->mtime, sizeof(stat->mtime), in) ||
!chck_buffer_read_int(&stat->length, sizeof(stat->length), in))
if (!chck_buffer_read_int(&size, sizeof(size), o">&stream->in) ||
!chck_buffer_read_int(&stat->type, sizeof(stat->type), o">&stream->in) ||
!chck_buffer_read_int(&stat->dev, sizeof(stat->dev), o">&stream->in) ||
!read_qid(&stat->qid, stream) ||
!chck_buffer_read_int(&stat->mode, sizeof(stat->mode), o">&stream->in) ||
!chck_buffer_read_int(&stat->atime, sizeof(stat->atime), o">&stream->in) ||
!chck_buffer_read_int(&stat->mtime, sizeof(stat->mtime), o">&stream->in) ||
!chck_buffer_read_int(&stat->length, sizeof(stat->length), o">&stream->in))
return false;
struct pi9_string *fields[4] = { &stat->name, &stat->uid, &stat->gid, &stat->muid };
for (uint32_t i = 0; i < 4; ++i) {
uint16_t len;
if (!chck_buffer_read_int(&len, sizeof(len), in))
if (!chck_buffer_read_int(&len, sizeof(len), o">&stream->in))
return false;
pi9_string_set_cstr_with_length(fields[i], in->curpos, len, false);
pi9_string_set_cstr_with_length(fields[i], stream->in.curpos, len, false);
}
return true;
}
static bool
op_Tversion(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tversion(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
// tag should always be NOTAG in version messages
if (tag != NOTAG)
@ -154,8 +158,8 @@ op_Tversion(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_b
uint32_t msize;
uint16_t vsize;
if (!chck_buffer_read_int(&msize, sizeof(msize), in) ||
!chck_buffer_read_int(&vsize, sizeof(vsize), in))
if (!chck_buffer_read_int(&msize, sizeof(msize), o">&stream->in) ||
!chck_buffer_read_int(&vsize, sizeof(vsize), o">&stream->in))
goto err_read;
#if VERBOSE
@ -163,7 +167,7 @@ op_Tversion(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_b
#endif
struct pi9_string version = {0};
pi9_string_set_cstr_with_length(&version, in->curpos, vsize, false);
pi9_string_set_cstr_with_length(&version, stream->in.curpos, vsize, false);
// A successful version request initializes the connection.
// All outstanding I/O on the connection is aborted; all active fids are freed (`clunked') automatically.
@ -177,41 +181,41 @@ op_Tversion(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_b
// only support 9P2000, maybe 9P2000.L later, .u probably never
if (!pi9_string_eq_cstr(&version, "9P2000")) {
static const char *preferred = "9P2000";
const char *reply = (vsize > 0 && pi9_cstrneq(version.data, "9P", (vsize >= 2 ? 2 : vsize)) ? preferred : "unknown");
const char *reply = (pi9_string_starts_with_cstr(&version, "9P") ? preferred : "unknown");
vsize = strlen(reply);
const uint32_t size = HDRSZ + sizeof(msize) + sizeof(vsize) + vsize;
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rversion}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!chck_buffer_write_int(&msize, sizeof(msize), out) ||
!chck_buffer_write_string_of_type(reply, vsize, sizeof(uint16_t), out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rversion}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!chck_buffer_write_int(&msize, sizeof(msize), o">&stream->out) ||
!chck_buffer_write_string_of_type(reply, vsize, sizeof(uint16_t), o">&stream->out))
goto err_write;
} else {
const size_t size = HDRSZ + sizeof(msize) + sizeof(vsize) + vsize;
if (chck_buffer_write(in->buffer, 1, size, out) != size)
if (chck_buffer_write(stream->in.buffer, 1, size, &stream->out) != size)
goto err_write;
*(uint8_t*)(out->buffer + sizeof(uint32_t)) = Rversion;
*(uint8_t*)(stream->in.buffer + sizeof(uint32_t)) = Rversion;
}
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, stream);
return false;
}
static bool
op_Tauth(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tauth(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t afid;
if (!chck_buffer_read_int(&afid, sizeof(afid), in))
if (!chck_buffer_read_int(&afid, sizeof(afid), o">&stream->in))
goto err_read;
#if VERBOSE
@ -219,19 +223,19 @@ op_Tauth(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buff
#endif
uint16_t usize;
if (!chck_buffer_read_int(&usize, sizeof(usize), in))
if (!chck_buffer_read_int(&usize, sizeof(usize), o">&stream->in))
goto err_read;
struct pi9_string uname = {0};
pi9_string_set_cstr_with_length(&uname, in->curpos, usize, false);
chck_buffer_seek(in, usize, SEEK_CUR);
pi9_string_set_cstr_with_length(&uname, stream->in.curpos, usize, false);
chck_buffer_seek(o">&stream->in, usize, SEEK_CUR);
uint16_t asize;
if (!chck_buffer_read_int(&asize, sizeof(asize), in))
if (!chck_buffer_read_int(&asize, sizeof(asize), o">&stream->in))
goto err_read;
struct pi9_string aname = {0};
pi9_string_set_cstr_with_length(&aname, in->curpos, asize, false);
pi9_string_set_cstr_with_length(&aname, stream->in.curpos, asize, false);
struct pi9_qid *qid = NULL;
if (pi9->procs.auth && !pi9->procs.auth(pi9, tag, afid, &uname, &aname, &qid))
@ -241,31 +245,31 @@ op_Tauth(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buff
goto err_no_auth;
const uint32_t size = HDRSZ + QIDSZ;
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rauth}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!write_qid(qid, out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rauth}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!write_qid(qid, stream))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
err_no_auth:
pi9_write_error(tag, PI9_ERR_NO_AUTH, out);
pi9_write_error(tag, PI9_ERR_NO_AUTH, stream);
return false;
}
static bool
op_Tattach(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tattach(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t fid, afid;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&afid, sizeof(afid), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&afid, sizeof(afid), o">&stream->in))
goto err_read;
#if VERBOSE
@ -273,46 +277,46 @@ op_Tattach(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_bu
#endif
uint16_t usize;
if (!chck_buffer_read_int(&usize, sizeof(usize), in))
if (!chck_buffer_read_int(&usize, sizeof(usize), o">&stream->in))
goto err_read;
struct pi9_string uname = {0};
pi9_string_set_cstr_with_length(&uname, in->curpos, usize, false);
chck_buffer_seek(in, usize, SEEK_CUR);
pi9_string_set_cstr_with_length(&uname, stream->in.curpos, usize, false);
chck_buffer_seek(o">&stream->in, usize, SEEK_CUR);
uint16_t asize;
if (!chck_buffer_read_int(&asize, sizeof(asize), in))
if (!chck_buffer_read_int(&asize, sizeof(asize), o">&stream->in))
goto err_read;
struct pi9_string aname = {0};
pi9_string_set_cstr_with_length(&aname, in->curpos, asize, false);
pi9_string_set_cstr_with_length(&aname, stream->in.curpos, asize, false);
struct pi9_qid *qid = NULL;
if (pi9->procs.attach && !pi9->procs.attach(pi9, tag, fid, afid, &uname, &aname, &qid))
return false;
const uint32_t size = HDRSZ + QIDSZ;
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rattach}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!write_qid(qid, out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rattach}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!write_qid(qid, stream))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Tflush(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tflush(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint16_t oldtag;
if (!chck_buffer_read_int(&oldtag, sizeof(oldtag), in))
if (!chck_buffer_read_int(&oldtag, sizeof(oldtag), o">&stream->in))
goto err_read;
#if VERBOSE
@ -327,29 +331,29 @@ op_Tflush(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buf
// In either case, it should respond with an Rflush echoing the tag (not oldtag) of the Tflush message.
// A Tflush can never be responded to by an Rerror message.
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), out) ||
!chck_buffer_write_int((uint8_t[]){Rflush}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out))
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rflush}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Twalk(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Twalk(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint16_t nwname;
uint32_t fid, newfid;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&newfid, sizeof(newfid), in) ||
!chck_buffer_read_int(&nwname, sizeof(nwname), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&newfid, sizeof(newfid), o">&stream->in) ||
!chck_buffer_read_int(&nwname, sizeof(nwname), o">&stream->in))
goto err_read;
#if VERBOSE
@ -362,10 +366,10 @@ op_Twalk(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buff
struct pi9_string walks[MAXWELEM] = {{0}};
for (uint32_t i = 0; i < MAXWELEM; ++i) {
uint16_t len;
if (!chck_buffer_read_int(&len, sizeof(len), in))
if (!chck_buffer_read_int(&len, sizeof(len), o">&stream->in))
goto err_read;
pi9_string_set_cstr_with_length(&walks[i], in->curpos, len, false);
pi9_string_set_cstr_with_length(&walks[i], stream->in.curpos, len, false);
}
uint16_t nwqid = 0;
@ -377,37 +381,37 @@ op_Twalk(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buff
assert(nwqid <= nwname);
const uint32_t size = HDRSZ + sizeof(nwqid) + nwqid * QIDSZ;
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rwalk}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!chck_buffer_write_int(&nwqid, sizeof(nwqid), out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rwalk}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!chck_buffer_write_int(&nwqid, sizeof(nwqid), o">&stream->out))
goto err_write;
for (uint32_t i = 0; i < nwqid; ++i) {
if (!write_qid(qids[i], out))
if (!write_qid(qids[i], stream))
goto err_write;
}
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, stream);
return false;
}
static bool
op_Topen(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Topen(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint8_t mode;
uint32_t fid;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&mode, sizeof(mode), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&mode, sizeof(mode), o">&stream->in))
goto err_read;
// All other bits in mode should be zero
@ -426,42 +430,42 @@ op_Topen(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buff
goto err_not_allowed;
const uint32_t size = HDRSZ + QIDSZ + sizeof(iounit);
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Ropen}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!write_qid(qid, out) ||
!chck_buffer_write_int(&iounit, sizeof(iounit), out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Ropen}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!write_qid(qid, stream) ||
!chck_buffer_write_int(&iounit, sizeof(iounit), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, stream);
return false;
}
static bool
op_Tcreate(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tcreate(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t fid;
uint16_t nsize;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&nsize, sizeof(nsize), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&nsize, sizeof(nsize), o">&stream->in))
goto err_read;
struct pi9_string name = {0};
pi9_string_set_cstr_with_length(&name, in->curpos, nsize, false);
pi9_string_set_cstr_with_length(&name, stream->in.curpos, nsize, false);
uint8_t mode;
uint32_t perm;
if (!chck_buffer_read_int(&perm, sizeof(perm), in) ||
!chck_buffer_read_int(&mode, sizeof(mode), in))
if (!chck_buffer_read_int(&perm, sizeof(perm), o">&stream->in) ||
!chck_buffer_read_int(&mode, sizeof(mode), o">&stream->in))
goto err_read;
#if VERBOSE
@ -481,104 +485,104 @@ op_Tcreate(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_bu
goto err_not_allowed;
const uint32_t size = HDRSZ + QIDSZ + sizeof(iounit);
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rcreate}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!write_qid(qid, out) ||
!chck_buffer_write_int(&iounit, sizeof(iounit), out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rcreate}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!write_qid(qid, stream) ||
!chck_buffer_write_int(&iounit, sizeof(iounit), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
err_not_allowed:
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, out);
pi9_write_error(tag, PI9_ERR_NOT_ALLOWED, stream);
return false;
}
static bool
op_Tread(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tread(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint64_t offset;
uint32_t fid, count;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&offset, sizeof(offset), in) ||
!chck_buffer_read_int(&count, sizeof(count), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&offset, sizeof(offset), o">&stream->in) ||
!chck_buffer_read_int(&count, sizeof(count), o">&stream->in))
goto err_read;
#if VERBOSE
fprintf(stderr, "Tread %u %u %"PRIu64" %u\n", tag, fid, offset, count);
#endif
chck_buffer_seek(out, HDRSZ + sizeof(uint32_t), SEEK_SET);
void *start = out->curpos;
chck_buffer_seek(o">&stream->out, HDRSZ + sizeof(uint32_t), SEEK_SET);
void *start = stream->out.curpos;
if (pi9->procs.read && !pi9->procs.read(pi9, tag, fid, offset, count))
return false;
const uint32_t sbufsz = (offset != 0 ? 0 : (out->curpos - start));
const uint32_t sbufsz = (offset != 0 ? 0 : (stream->out.curpos - start));
const uint32_t size = HDRSZ + sizeof(sbufsz) + sbufsz;
chck_buffer_seek(out, 0, SEEK_SET);
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rread}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!chck_buffer_write_int(&sbufsz, sizeof(sbufsz), out))
chck_buffer_seek(o">&stream->out, 0, SEEK_SET);
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rread}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!chck_buffer_write_int(&sbufsz, sizeof(sbufsz), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Twrite(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Twrite(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint64_t offset;
uint32_t fid, count;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&offset, sizeof(offset), in) ||
!chck_buffer_read_int(&count, sizeof(count), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&offset, sizeof(offset), o">&stream->in) ||
!chck_buffer_read_int(&count, sizeof(count), o">&stream->in))
goto err_read;
#if VERBOSE
fprintf(stderr, "Twrite %u %"PRIu64" %u\n", fid, offset, count);
#endif
if (pi9->procs.write && !pi9->procs.write(pi9, tag, fid, offset, count, (count > 0 ? in->curpos : NULL)))
if (pi9->procs.write && !pi9->procs.write(pi9, tag, fid, offset, count, (count > 0 ? stream->in.curpos : NULL)))
return false;
const uint32_t size = HDRSZ + sizeof(count);
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rwrite}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!chck_buffer_write_int(&count, sizeof(count), out))
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rwrite}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!chck_buffer_write_int(&count, sizeof(count), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Tclunk(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tclunk(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t fid;
if (!chck_buffer_read_int(&fid, sizeof(fid), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in))
goto err_read;
#if VERBOSE
@ -588,26 +592,26 @@ op_Tclunk(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buf
if (pi9->procs.clunk && !pi9->procs.clunk(pi9, tag, fid))
return false;
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), out) ||
!chck_buffer_write_int((uint8_t[]){Rclunk}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out))
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rclunk}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Tremove(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tremove(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t fid;
if (!chck_buffer_read_int(&fid, sizeof(fid), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in))
goto err_read;
#if VERBOSE
@ -617,72 +621,72 @@ op_Tremove(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_bu
if (pi9->procs.remove && !pi9->procs.remove(pi9, tag, fid))
return false;
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), out) ||
!chck_buffer_write_int((uint8_t[]){Rremove}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out))
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rremove}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Tstat(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Tstat(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t fid;
if (!chck_buffer_read_int(&fid, sizeof(fid), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in))
goto err_read;
#if VERBOSE
fprintf(stderr, "Tstat %u %u\n", tag, fid);
#endif
chck_buffer_seek(out, HDRSZ + sizeof(uint16_t), SEEK_SET);
void *start = out->curpos;
chck_buffer_seek(o">&stream->out, HDRSZ + sizeof(uint16_t), SEEK_SET);
void *start = stream->out.curpos;
struct pi9_stat *stat = NULL;
if (pi9->procs.stat && !pi9->procs.stat(pi9, tag, fid, &stat))
return false;
if (stat && !pi9_write_stat(stat, out))
if (stat && !pi9_write_stat(stat, stream))
goto err_write;
// too big
if (out->curpos - start > 0xFFFF)
if (stream->out.curpos - start > 0xFFFF)
goto err_write;
const uint16_t sbufsz = (out->curpos - start);
const uint16_t sbufsz = (stream->out.curpos - start);
const uint32_t size = HDRSZ + sizeof(sbufsz) + sbufsz;
chck_buffer_seek(out, 0, SEEK_SET);
if (!chck_buffer_write_int(&size, sizeof(size), out) ||
!chck_buffer_write_int((uint8_t[]){Rstat}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out) ||
!chck_buffer_write_int(&sbufsz, sizeof(sbufsz), out))
chck_buffer_seek(o">&stream->out, 0, SEEK_SET);
if (!chck_buffer_write_int(&size, sizeof(size), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rstat}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out) ||
!chck_buffer_write_int(&sbufsz, sizeof(sbufsz), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static bool
op_Twstat(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
op_Twstat(struct pi9 *pi9, uint16_t tag, struct pi9_stream *stream)
{
uint32_t fid;
uint16_t sbufsz;
if (!chck_buffer_read_int(&fid, sizeof(fid), in) ||
!chck_buffer_read_int(&sbufsz, sizeof(sbufsz), in))
if (!chck_buffer_read_int(&fid, sizeof(fid), o">&stream->in) ||
!chck_buffer_read_int(&sbufsz, sizeof(sbufsz), o">&stream->in))
goto err_read;
#if VERBOSE
@ -690,32 +694,32 @@ op_Twstat(struct pi9 *pi9, uint16_t tag, struct chck_buffer *in, struct chck_buf
#endif
struct pi9_stat stat = {0};
if (!read_stat(&stat, in))
if (!read_stat(&stat, stream))
goto err_read;
if (pi9->procs.twstat && !pi9->procs.twstat(pi9, tag, fid, &stat))
return false;
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), out) ||
!chck_buffer_write_int((uint8_t[]){Rwstat}, sizeof(uint8_t), out) ||
!chck_buffer_write_int(&tag, sizeof(tag), out))
if (!chck_buffer_write_int(&HDRSZ, sizeof(HDRSZ), o">&stream->out) ||
!chck_buffer_write_int((uint8_t[]){Rwstat}, sizeof(uint8_t), o">&stream->out) ||
!chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out))
goto err_write;
return true;
err_read:
pi9_write_error(tag, PI9_ERR_READ, out);
pi9_write_error(tag, PI9_ERR_READ, stream);
return false;
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
}
static inline bool
call_op(struct pi9 *pi9, enum op op, uint16_t tag, struct chck_buffer *in, struct chck_buffer *out)
call_op(struct pi9 *pi9, enum op op, uint16_t tag, struct pi9_stream *stream)
{
// check opcode range, and only allow T opcodes (% 2), also check that message meets minimum size
if (op <= OPFIRST || op >= OPLAST || op % 2 != 0 || in->size < ops[op].msz)
if (op <= OPFIRST || op >= OPLAST || op % 2 != 0 || stream->in.size < ops[op].msz)
goto err_unknown_op;
if (op == Terror) {
@ -725,68 +729,68 @@ call_op(struct pi9 *pi9, enum op op, uint16_t tag, struct chck_buffer *in, struc
return true;
}
if (out->size < ops[op].msz && !chck_buffer_resize(out, ops[op].msz))
if (stream->out.size < ops[op].msz && !chck_buffer_resize(&stream->out, ops[op].msz))
goto err_write;
return ops[op].cb(pi9, tag, in, out);
return ops[op].cb(pi9, tag, stream);
err_write:
pi9_write_error(tag, PI9_ERR_WRITE, out);
pi9_write_error(tag, PI9_ERR_WRITE, stream);
return false;
err_unknown_op:
pi9_write_error(tag, PI9_ERR_UNKNOWN_OP, out);
pi9_write_error(tag, PI9_ERR_UNKNOWN_OP, stream);
return false;
}
static bool
read_msg(struct pi9 *pi9, int32_t fd, struct chck_buffer *in, struct chck_buffer *out)
read_msg(struct pi9 *pi9, int32_t fd, struct pi9_stream *stream)
{
assert(pi9 && fd >= 0);
if (chck_buffer_fill_from_fd(fd, 1, pi9->msize, in) < HDRSZ)
if (chck_buffer_fill_from_fd(fd, 1, pi9->msize, o">&stream->in) < HDRSZ)
return false;
uint32_t size;
if (!chck_buffer_read_int(&size, sizeof(size), in) || size < HDRSZ)
if (!chck_buffer_read_int(&size, sizeof(size), o">&stream->in) || size < HDRSZ)
return false;
if (in->size < size) {
const size_t to_read = size - in->size;
chck_buffer_seek(in, 0, SEEK_END);
if (chck_buffer_fill_from_fd(fd, 1, to_read, in) < to_read)
if (stream->in.size < size) {
const size_t to_read = size - stream->in.size;
chck_buffer_seek(o">&stream->in, 0, SEEK_END);
if (chck_buffer_fill_from_fd(fd, 1, to_read, o">&stream->in) < to_read)
return false;
chck_buffer_seek(in, sizeof(size), SEEK_SET);
chck_buffer_seek(o">&stream->in, sizeof(size), SEEK_SET);
}
uint8_t op;
uint16_t tag;
if (!chck_buffer_read_int(&op, sizeof(uint8_t), in) ||
!chck_buffer_read_int(&tag, sizeof(uint16_t), in))
if (!chck_buffer_read_int(&op, sizeof(uint8_t), o">&stream->in) ||
!chck_buffer_read_int(&tag, sizeof(uint16_t), o">&stream->in))
return false;
#if VERBOSE
fprintf(stderr, "Read message of size: %u (%u : %u)\n", size, op, tag);
#endif
for (uint32_t i = 0; i < size; ++i)
putc(*(char*)(in->buffer + i), stderr);
putc(*(char*)(stream->in.buffer + i), stderr);
putc('\n', stderr);
#endif
return call_op(pi9, op, tag, in, out);
return call_op(pi9, op, tag, stream);
}
static inline bool
write_msg(int32_t fd, struct chck_buffer *out)
write_msg(int32_t fd, struct pi9_stream *stream)
{
assert(fd >= 0 && out->buffer);
const uint32_t size = *(uint32_t*)out->buffer;
assert(fd >= 0 && stream->out.buffer);
const uint32_t size = *(uint32_t*)stream->out.buffer;
#if VERBOSE
fprintf(stderr, "Write message of size: %u\n", size);
#endif
return write(fd, out->buffer, size) == size;
return write(fd, stream->out.buffer, size) == size;
}
bool
pi9_write_stat(struct pi9_stat *stat, struct chck_buffer *out)
pi9_write_stat(struct pi9_stat *stat, struct pi9_stream *stream)
{
const size_t size = STATHDRSZ + stat->name.size + stat->uid.size + stat->gid.size + stat->muid.size;
@ -795,24 +799,24 @@ pi9_write_stat(struct pi9_stat *stat, struct chck_buffer *out)
return false;
const uint16_t size16 = size;
return (chck_buffer_write_int(&size16, sizeof(size16), out) &&
chck_buffer_write_int(&stat->type, sizeof(stat->type), out) &&
chck_buffer_write_int(&stat->dev, sizeof(stat->dev), out) &&
write_qid(&stat->qid, out) &&
chck_buffer_write_int(&stat->mode, sizeof(stat->mode), out) &&
chck_buffer_write_int(&stat->atime, sizeof(stat->atime), out) &&
chck_buffer_write_int(&stat->mtime, sizeof(stat->mtime), out) &&
chck_buffer_write_int(&stat->length, sizeof(stat->length), out) &&
chck_buffer_write_string_of_type(stat->name.data, stat->name.size, sizeof(uint16_t), out) &&
chck_buffer_write_string_of_type(stat->uid.data, stat->uid.size, sizeof(uint16_t), out) &&
chck_buffer_write_string_of_type(stat->gid.data, stat->gid.size, sizeof(uint16_t), out) &&
chck_buffer_write_string_of_type(stat->muid.data, stat->muid.size, sizeof(uint16_t), out));
return (chck_buffer_write_int(&size16, sizeof(size16), o">&stream->out) &&
chck_buffer_write_int(&stat->type, sizeof(stat->type), o">&stream->out) &&
chck_buffer_write_int(&stat->dev, sizeof(stat->dev), o">&stream->out) &&
write_qid(&stat->qid, stream) &&
chck_buffer_write_int(&stat->mode, sizeof(stat->mode), o">&stream->out) &&
chck_buffer_write_int(&stat->atime, sizeof(stat->atime), o">&stream->out) &&
chck_buffer_write_int(&stat->mtime, sizeof(stat->mtime), o">&stream->out) &&
chck_buffer_write_int(&stat->length, sizeof(stat->length), o">&stream->out) &&
chck_buffer_write_string_of_type(stat->name.data, stat->name.size, sizeof(uint16_t), o">&stream->out) &&
chck_buffer_write_string_of_type(stat->uid.data, stat->uid.size, sizeof(uint16_t), o">&stream->out) &&
chck_buffer_write_string_of_type(stat->gid.data, stat->gid.size, sizeof(uint16_t), o">&stream->out) &&
chck_buffer_write_string_of_type(stat->muid.data, stat->muid.size, sizeof(uint16_t), o">&stream->out));
}
size_t
pi9_write(const void *src, size_t size, size_t nmemb, struct chck_buffer *out)
pi9_write(const void *src, size_t size, size_t nmemb, struct pi9_stream *stream)
{
return chck_buffer_write(src, size, nmemb, out);
return chck_buffer_write(src, size, nmemb, o">&stream->out);
}
void
@ -829,21 +833,21 @@ pi9_stat_release(struct pi9_stat *stat)
bool
pi9_process(struct pi9 *pi9, int32_t fd)
{
assert(pi9 && fd >= 0 && pi9->in && pi9->out);
assert(pi9 && fd >= 0 && pi9->stream);
chck_buffer_seek(pi9->in, 0, SEEK_SET);
chck_buffer_seek(pi9->out, 0, SEEK_SET);
chck_buffer_seek(o">&pi9->stream->in, 0, SEEK_SET);
chck_buffer_seek(o">&pi9->stream->out, 0, SEEK_SET);
bool ret = true;
if (!read_msg(pi9, fd, pi9->in, pi9->out)) {
if (pi9->out->curpos == pi9->out->buffer)
pi9_write_error(NOTAG, PI9_ERR_READ, pi9->out);
if (!read_msg(pi9, fd, pi9->stream)) {
if (pi9->stream->out.curpos == pi9->stream->out.buffer)
pi9_write_error(NOTAG, PI9_ERR_READ, pi9->stream);
ret = false;
}
if (!write_msg(fd, pi9->out)) {
pi9_write_error(NOTAG, PI9_ERR_WRITE, pi9->out);
write_msg(fd, pi9->out);
if (!write_msg(fd, pi9->stream)) {
pi9_write_error(NOTAG, PI9_ERR_WRITE, pi9->stream);
write_msg(fd, pi9->stream);
ret = false;
}
@ -856,8 +860,9 @@ pi9_release(struct pi9 *pi9)
if (!pi9)
return;
chck_buffer_release(pi9->out);
chck_buffer_release(pi9->in);
chck_buffer_release(&pi9->stream->out);
chck_buffer_release(&pi9->stream->in);
free(pi9->stream);
memset(pi9, 0, sizeof(struct pi9));
}
@ -870,16 +875,13 @@ pi9_init(struct pi9 *pi9, uint32_t msize, struct pi9_procs *procs, void *userdat
pi9->msize = (msize > 0 ? msize : 8192);
pi9->userdata = userdata;
if (!(pi9->in = malloc(sizeof(struct chck_buffer))))
goto fail;
if (!(pi9->out = malloc(sizeof(struct chck_buffer))))
if (!(pi9->stream = calloc(1, sizeof(struct pi9_stream))))
goto fail;
if (!chck_buffer(pi9->in, pi9->msize, CHCK_ENDIANESS_LITTLE))
if (!chck_buffer(&pi9->stream->in, pi9->msize, CHCK_ENDIANESS_LITTLE))
goto fail;
if (!chck_buffer(pi9->out, pi9->msize, CHCK_ENDIANESS_LITTLE))
if (!chck_buffer(o">&pi9->stream->out, pi9->msize, CHCK_ENDIANESS_LITTLE))
goto fail;
return true;
@ -892,14 +894,14 @@ fail:
#undef pi9_write_error
void
pi9_write_error(uint16_t tag, enum pi9_error error, struct chck_buffer *out)
pi9_write_error(uint16_t tag, enum pi9_error error, struct pi9_stream *stream)
{
assert(out);
assert(stream);
const int32_t size = HDRSZ + sizeof(uint16_t) + errors[error].size;
chck_buffer_seek(out, 0, SEEK_SET);
chck_buffer_write_int(&size, sizeof(size), out);
chck_buffer_write_int((uint8_t[]){ Rerror }, sizeof(uint8_t), out);
chck_buffer_write_int(&tag, sizeof(tag), out);
chck_buffer_write_string_of_type(errors[error].msg, errors[error].size, sizeof(uint16_t), out);
chck_buffer_seek(o">&stream->out, 0, SEEK_SET);
chck_buffer_write_int(&size, sizeof(size), o">&stream->out);
chck_buffer_write_int((uint8_t[]){ Rerror }, sizeof(uint8_t), o">&stream->out);
chck_buffer_write_int(&tag, sizeof(tag), o">&stream->out);
chck_buffer_write_string_of_type(errors[error].msg, errors[error].size, sizeof(uint16_t), o">&stream->out);
fprintf(stderr, "%s\n", errors[error].msg);
}

+ 5
- 5
src/pi9.h 查看文件

@ -6,7 +6,7 @@
static const uint32_t PI9_NOFID = (uint32_t)~0;
struct chck_buffer;
struct pi9_stream;
struct pi9_qid {
uint8_t type;
@ -30,7 +30,7 @@ struct pi9_stat {
struct pi9 {
void *userdata;
struct chck_buffer *in, *out;
struct pi9_stream *stream;
uint32_t msize;
@ -105,9 +105,9 @@ enum pi9_error {
PI9_ERR_LAST,
};
bool pi9_write_stat(struct pi9_stat *stat, struct chck_buffer *out);
void pi9_write_error(uint16_t tag, enum pi9_error error, struct chck_buffer *out);
size_t pi9_write(const void *src, size_t size, size_t nmemb, struct chck_buffer *out);
bool pi9_write_stat(struct pi9_stat *stat, struct pi9_stream *stream);
void pi9_write_error(uint16_t tag, enum pi9_error error, struct pi9_stream *stream);
size_t pi9_write(const void *src, size_t size, size_t nmemb, struct pi9_stream *stream);
void pi9_stat_release(struct pi9_stat *stat);
bool pi9_process(struct pi9 *pi9, int32_t fd);
bool pi9_init(struct pi9 *pi9, uint32_t msize, struct pi9_procs *procs, void *userdata);

+ 42
- 10
src/pi9_string.c 查看文件

@ -1,5 +1,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include <assert.h>
#include "pi9_string.h"
@ -7,35 +9,35 @@
static inline char*
ccopy(const char *str, size_t len)
{
char *cpy = calloc(1, len);
char *cpy = calloc(1, len + 1);
return (cpy ? memcpy(cpy, str, len) : NULL);
}
void
pi9_string_release(struct pi9_string *string)
{
assert(string);
if (!string)
return;
if (string->is_heap && string->data)
if (string->is_heap)
free(string->data);
string->data = NULL;
string->size = 0;
memset(string, 0, sizeof(struct pi9_string));
}
bool
pi9_string_set_cstr_with_length(struct pi9_string *string, const char *data, uint16_t length, bool is_heap)
pi9_string_set_cstr_with_length(struct pi9_string *string, const char *data, size_t len, bool is_heap)
{
assert(string);
char *copy = (char*)data;
if (is_heap && data && length > 0 && !(copy = ccopy(data, length)))
if (is_heap && data && len > 0 && !(copy = ccopy(data, len)))
return false;
pi9_string_release(string);
string->is_heap = is_heap;
string->data = (length > 0 ? copy : NULL);
string->size = length;
string->data = (len > 0 ? copy : NULL);
string->size = len;
return true;
}
@ -46,10 +48,40 @@ pi9_string_set_cstr(struct pi9_string *string, const char *data, bool is_heap)
return pi9_string_set_cstr_with_length(string, data, (data ? strlen(data) : 0), is_heap);
}
bool
pi9_string_set_varg(struct pi9_string *string, const char *fmt, va_list args)
{
va_list cpy;
va_copy(cpy, args);
char *str = NULL;
const size_t len = vsnprintf(NULL, 0, fmt, args);
if (len > 0 && !(str = malloc(len + 1)))
return false;
vsnprintf(str, len + 1, fmt, cpy);
pi9_string_release(string);
string->is_heap = true;
string->data = (len > 0 ? str : NULL);
string->size = len;
return true;
}
bool
pi9_string_set_format(struct pi9_string *string, const char *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
const bool ret = pi9_string_set_varg(string, fmt, argp);
va_end(argp);
return ret;
}
bool
pi9_string_set(struct pi9_string *string, const struct pi9_string *other, bool is_heap)
{
if (string->data == other->data) {
if (o">!is_heap && string->data == other->data) {
string->size = other->size;
return true;
}

+ 63
- 5
src/pi9_string.h 查看文件

@ -12,15 +12,23 @@ struct pi9_string {
};
static inline bool
pi9_string_eq(const struct pi9_string *a, const struct pi9_string *b)
pi9_cstr_is_empty(const char *data)
{
return (n">a->data == b->data) || (a->size == b->size && !memcmp(a->data, b->data, a->size));
return (o">!data || *data == 0);
}
static inline bool
pi9_string_eq_cstr(const struct pi9_string *a, const char *cstr)
pi9_cstr_ends_with(const char *a, const char *b)
{
const size_t lena = (a ? strlen(a) : 0), lenb = (b ? strlen(b) : 0);
return (lena >= lenb && !memcmp(a + lena - lenb, b, lenb));
}
static inline bool
pi9_cstr_starts_with(const char *a, const char *b)
{
return (cstr == a->data) || (a->data && cstr && !strcmp(a->data, cstr));
const size_t lena = (a ? strlen(a) : 0), lenb = (b ? strlen(b) : 0);
return (lena >= lenb && !memcmp(a, b, lenb));
}
static inline bool
@ -35,10 +43,60 @@ pi9_cstrneq(const char *a, const char *b, size_t len)
return (a == b) || (a && b && !strncmp(a, b, len));
}
static inline bool
pi9_string_is_empty(const struct pi9_string *string)
{
return pi9_cstr_is_empty(string->data);
}
static inline bool
pi9_string_ends_with_cstr(const struct pi9_string *a, const char *cstr)
{
const size_t len = (cstr ? strlen(cstr) : 0);
return (a->size >= len && !memcmp(a->data + a->size - len, cstr, len));
}
static inline bool
pi9_string_starts_with_cstr(const struct pi9_string *a, const char *cstr)
{
const size_t len = (cstr ? strlen(cstr) : 0);
return (a->size >= len && !memcmp(a->data, cstr, len));
}
static inline bool
pi9_string_ends_with(const struct pi9_string *a, const struct pi9_string *b)
{
return (a->size >= b->size && !memcmp(a->data + a->size - b->size, b->data, b->size));
}
static inline bool
pi9_string_starts_with(const struct pi9_string *a, const struct pi9_string *b)
{
return (a->size >= b->size && !memcmp(a->data, b->data, b->size));
}
static inline bool
pi9_string_eq(const struct pi9_string *a, const struct pi9_string *b)
{
return (a->data == b->data) || (a->size == b->size && !memcmp(a->data, b->data, a->size));
}
static inline bool
pi9_string_eq_cstr(const struct pi9_string *a, const char *cstr)
{
const size_t len = (cstr ? strlen(cstr) : 0);
return (len == a->size) && (cstr == a->data || !memcmp(a->data, cstr, a->size));
}
void pi9_string_release(struct pi9_string *string);
bool pi9_string_set_cstr(struct pi9_string *string, const char *data, bool is_heap);
bool pi9_string_set_cstr_with_length(struct pi9_string *string, const char *data, uint16_t length, bool is_heap);
bool pi9_string_set_cstr_with_length(struct pi9_string *string, const char *data, size_t len, bool is_heap);
bool pi9_string_set(struct pi9_string *string, const struct pi9_string *other, bool is_heap);
#if __GNUC__
__attribute__((format(printf, 2, 3)))
#endif
bool pi9_string_set_format(struct pi9_string *string, const char *fmt, ...);
bool pi9_string_set_varg(struct pi9_string *string, const char *fmt, va_list args);
#endif /* __pi9_string_h__ */

Loading…
取消
儲存