diff options
Diffstat (limited to 'src/lib9/convM2D.c')
-rw-r--r-- | src/lib9/convM2D.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/lib9/convM2D.c b/src/lib9/convM2D.c new file mode 100644 index 00000000..6f4b4bd9 --- /dev/null +++ b/src/lib9/convM2D.c @@ -0,0 +1,94 @@ +#include <u.h> +#include <libc.h> +#include <fcall.h> + +int +statcheck(uchar *buf, uint nbuf) +{ + uchar *ebuf; + int i; + + ebuf = buf + nbuf; + + if(nbuf < STATFIXLEN || nbuf != BIT16SZ + GBIT16(buf)) + return -1; + + buf += STATFIXLEN - 4 * BIT16SZ; + + for(i = 0; i < 4; i++){ + if(buf + BIT16SZ > ebuf) + return -1; + buf += BIT16SZ + GBIT16(buf); + } + + if(buf != ebuf) + return -1; + + return 0; +} + +static char nullstring[] = ""; + +uint +convM2D(uchar *buf, uint nbuf, Dir *d, char *strs) +{ + uchar *p, *ebuf; + char *sv[4]; + int i, ns; + + if(nbuf < STATFIXLEN) + return 0; + + p = buf; + ebuf = buf + nbuf; + + p += BIT16SZ; /* ignore size */ + d->type = GBIT16(p); + p += BIT16SZ; + d->dev = GBIT32(p); + p += BIT32SZ; + d->qid.type = GBIT8(p); + p += BIT8SZ; + d->qid.vers = GBIT32(p); + p += BIT32SZ; + d->qid.path = GBIT64(p); + p += BIT64SZ; + d->mode = GBIT32(p); + p += BIT32SZ; + d->atime = GBIT32(p); + p += BIT32SZ; + d->mtime = GBIT32(p); + p += BIT32SZ; + d->length = GBIT64(p); + p += BIT64SZ; + + for(i = 0; i < 4; i++){ + if(p + BIT16SZ > ebuf) + return 0; + ns = GBIT16(p); + p += BIT16SZ; + if(p + ns > ebuf) + return 0; + if(strs){ + sv[i] = strs; + memmove(strs, p, ns); + strs += ns; + *strs++ = '\0'; + } + p += ns; + } + + if(strs){ + d->name = sv[0]; + d->uid = sv[1]; + d->gid = sv[2]; + d->muid = sv[3]; + }else{ + d->name = nullstring; + d->uid = nullstring; + d->gid = nullstring; + d->muid = nullstring; + } + + return p - buf; +} |