From e1b56125e88ae998500f4b18d5ea1e5b4471d3ee Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Fri, 13 Mar 2015 00:05:26 +0200 Subject: [PATCH] Make chck_buffer out/in to pi9_stream, update pi9_string with chck's implementation. --- bin/server.c | 58 +++--- src/pi9.c | 470 ++++++++++++++++++++++++----------------------- src/pi9.h | 10 +- src/pi9_string.c | 52 +++++- src/pi9_string.h | 68 ++++++- 5 files changed, 375 insertions(+), 283 deletions(-) diff --git a/bin/server.c b/bin/server.c index b8cff5c..0b492d6 100644 --- a/bin/server.c +++ b/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; } diff --git a/src/pi9.c b/src/pi9.c index d0d2736..a73a81a 100644 --- a/src/pi9.c +++ b/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), &stream->out) && + chck_buffer_write_int(&qid->vers, sizeof(qid->vers), &stream->out) && + chck_buffer_write_int(&qid->path, sizeof(qid->path), &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), &stream->in) && + chck_buffer_read_int(&qid->vers, sizeof(qid->vers), &stream->in) && + chck_buffer_read_int(&qid->path, sizeof(qid->path), &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), &stream->in) || + !chck_buffer_read_int(&stat->type, sizeof(stat->type), &stream->in) || + !chck_buffer_read_int(&stat->dev, sizeof(stat->dev), &stream->in) || + !read_qid(&stat->qid, stream) || + !chck_buffer_read_int(&stat->mode, sizeof(stat->mode), &stream->in) || + !chck_buffer_read_int(&stat->atime, sizeof(stat->atime), &stream->in) || + !chck_buffer_read_int(&stat->mtime, sizeof(stat->mtime), &stream->in) || + !chck_buffer_read_int(&stat->length, sizeof(stat->length), &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), &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), &stream->in) || + !chck_buffer_read_int(&vsize, sizeof(vsize), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rversion}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !chck_buffer_write_int(&msize, sizeof(msize), &stream->out) || + !chck_buffer_write_string_of_type(reply, vsize, sizeof(uint16_t), &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), &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), &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(&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), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rauth}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &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), &stream->in) || + !chck_buffer_read_int(&afid, sizeof(afid), &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), &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(&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), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rattach}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &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), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rflush}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &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), &stream->in) || + !chck_buffer_read_int(&newfid, sizeof(newfid), &stream->in) || + !chck_buffer_read_int(&nwname, sizeof(nwname), &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), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rwalk}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !chck_buffer_write_int(&nwqid, sizeof(nwqid), &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), &stream->in) || + !chck_buffer_read_int(&mode, sizeof(mode), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Ropen}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !write_qid(qid, stream) || + !chck_buffer_write_int(&iounit, sizeof(iounit), &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), &stream->in) || + !chck_buffer_read_int(&nsize, sizeof(nsize), &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), &stream->in) || + !chck_buffer_read_int(&mode, sizeof(mode), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rcreate}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !write_qid(qid, stream) || + !chck_buffer_write_int(&iounit, sizeof(iounit), &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), &stream->in) || + !chck_buffer_read_int(&offset, sizeof(offset), &stream->in) || + !chck_buffer_read_int(&count, sizeof(count), &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(&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(&stream->out, 0, SEEK_SET); + if (!chck_buffer_write_int(&size, sizeof(size), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rread}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !chck_buffer_write_int(&sbufsz, sizeof(sbufsz), &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), &stream->in) || + !chck_buffer_read_int(&offset, sizeof(offset), &stream->in) || + !chck_buffer_read_int(&count, sizeof(count), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rwrite}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !chck_buffer_write_int(&count, sizeof(count), &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), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rclunk}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &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), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rremove}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &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), &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(&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(&stream->out, 0, SEEK_SET); + if (!chck_buffer_write_int(&size, sizeof(size), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rstat}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &stream->out) || + !chck_buffer_write_int(&sbufsz, sizeof(sbufsz), &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), &stream->in) || + !chck_buffer_read_int(&sbufsz, sizeof(sbufsz), &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), &stream->out) || + !chck_buffer_write_int((uint8_t[]){Rwstat}, sizeof(uint8_t), &stream->out) || + !chck_buffer_write_int(&tag, sizeof(tag), &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, &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), &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(&stream->in, 0, SEEK_END); + if (chck_buffer_fill_from_fd(fd, 1, to_read, &stream->in) < to_read) return false; - chck_buffer_seek(in, sizeof(size), SEEK_SET); + chck_buffer_seek(&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), &stream->in) || + !chck_buffer_read_int(&tag, sizeof(uint16_t), &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), &stream->out) && + chck_buffer_write_int(&stat->type, sizeof(stat->type), &stream->out) && + chck_buffer_write_int(&stat->dev, sizeof(stat->dev), &stream->out) && + write_qid(&stat->qid, stream) && + chck_buffer_write_int(&stat->mode, sizeof(stat->mode), &stream->out) && + chck_buffer_write_int(&stat->atime, sizeof(stat->atime), &stream->out) && + chck_buffer_write_int(&stat->mtime, sizeof(stat->mtime), &stream->out) && + chck_buffer_write_int(&stat->length, sizeof(stat->length), &stream->out) && + chck_buffer_write_string_of_type(stat->name.data, stat->name.size, sizeof(uint16_t), &stream->out) && + chck_buffer_write_string_of_type(stat->uid.data, stat->uid.size, sizeof(uint16_t), &stream->out) && + chck_buffer_write_string_of_type(stat->gid.data, stat->gid.size, sizeof(uint16_t), &stream->out) && + chck_buffer_write_string_of_type(stat->muid.data, stat->muid.size, sizeof(uint16_t), &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, &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(&pi9->stream->in, 0, SEEK_SET); + chck_buffer_seek(&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(&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(&stream->out, 0, SEEK_SET); + chck_buffer_write_int(&size, sizeof(size), &stream->out); + chck_buffer_write_int((uint8_t[]){ Rerror }, sizeof(uint8_t), &stream->out); + chck_buffer_write_int(&tag, sizeof(tag), &stream->out); + chck_buffer_write_string_of_type(errors[error].msg, errors[error].size, sizeof(uint16_t), &stream->out); fprintf(stderr, "%s\n", errors[error].msg); } diff --git a/src/pi9.h b/src/pi9.h index 18eda73..13718b1 100644 --- a/src/pi9.h +++ b/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); diff --git a/src/pi9_string.c b/src/pi9_string.c index e7edaba..ec6446f 100644 --- a/src/pi9_string.c +++ b/src/pi9_string.c @@ -1,5 +1,7 @@ #include +#include #include +#include #include #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 (!is_heap && string->data == other->data) { string->size = other->size; return true; } diff --git a/src/pi9_string.h b/src/pi9_string.h index 5064492..e38075e 100644 --- a/src/pi9_string.h +++ b/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 (a->data == b->data) || (a->size == b->size && !memcmp(a->data, b->data, a->size)); + return (!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__ */