u32int logfsflattenentry(LogfsIdentityStore *is, uchar *buf, u32int limit, Entry *e) { int unamelen, gnamelen, munamelen, namelen; uint len; uchar *p; int unamebad = 0, gnamebad = 0, munamebad = 0; char *uname, *gname, *muname; id2name(is, e->uid, &uname, &unamebad, &unamelen); id2name(is, e->gid, &gname, &gnamebad, &gnamelen); id2name(is, e->muid, &muname, &munamebad, &munamelen); namelen = strlen(e->name); len = 49 + unamelen + unamebad + gnamelen + gnamebad + munamelen + munamebad + namelen; if(buf == nil) return len; if(len > limit) return 0; p = buf; /* size */ PBIT16(p, len - BIT16SZ); p += BIT16SZ; /* type */ p += BIT16SZ; /* dev */ p += BIT32SZ; /* qid.type */ *p++ = e->qid.type; /* qid.vers */ PBIT32(p, e->qid.vers); p += BIT32SZ; /* qid.path */ PBIT64(p, e->qid.path); p+= 8; /* mode */ PBIT32(p, e->perm); p+= BIT32SZ; /* atime */ PBIT32(p, e->mtime); p+= BIT32SZ; /* mtime */ PBIT32(p, e->mtime); p+= BIT32SZ; /* length */ if(e->qid.type & QTDIR) { PBIT64(p, 0); p += 8; } else { PBIT32(p, e->u.file.length); p += BIT32SZ; PBIT32(p, 0); p += BIT32SZ; } /* name */ PBIT16(p, namelen); p += BIT16SZ; memmove(p, e->name, namelen); p+= namelen; /* uid */ PBIT16(p, unamelen + unamebad); p += BIT16SZ; if(unamebad) *p++ = '('; memmove(p, uname, unamelen + unamebad); p+= unamelen; if(unamebad) *p++ = ')'; /* gid */ PBIT16(p, gnamelen + gnamebad); p += BIT16SZ; if(gnamebad) *p++ = '('; memmove(p, gname, gnamelen); p+= gnamelen; if(gnamebad) *p++ = ')'; /* muid */ PBIT16(p, munamelen + munamebad); p += BIT16SZ; if(munamebad) *p++ = '('; memmove(p, muname, munamelen); p+= munamelen; if(munamebad) *p = ')'; //print("len %ud p - buf %ld\n", len, p - buf); return len; }
static void packoldstat(uchar *buf, Dir *d) { uchar *p; ulong q; /* lay down old stat buffer - grotty code but it's temporary */ p = buf; strncpy((char*)p, d->name, 28); p += 28; strncpy((char*)p, d->uid, 28); p += 28; strncpy((char*)p, d->gid, 28); p += 28; q = d->qid.path & ~DMDIR; /* make sure doesn't accidentally look like directory */ if(d->qid.type & QTDIR) /* this is the real test of a new directory */ q |= DMDIR; PBIT32(p, q); p += BIT32SZ; PBIT32(p, d->qid.vers); p += BIT32SZ; PBIT32(p, d->mode); p += BIT32SZ; PBIT32(p, d->atime); p += BIT32SZ; PBIT32(p, d->mtime); p += BIT32SZ; PBIT64(p, d->length); p += BIT64SZ; PBIT16(p, d->type); p += BIT16SZ; PBIT16(p, d->dev); }
static uchar* pqid(uchar *p, Qid *q) { PBIT8(p, q->type); p += BIT8SZ; PBIT32(p, q->vers); p += BIT32SZ; PBIT64(p, q->path); p += BIT64SZ; return p; }
void rewritehdr(Fcall *f, uchar *pkt) { int i, n; n = GBIT32(pkt); PBIT16(pkt+5, f->tag); switch(f->type){ case Tversion: case Rversion: restring(pkt, n, f->version); break; case Tauth: PBIT32(pkt+7, f->afid); restring(pkt, n, f->uname); restring(pkt, n, f->aname); break; case Tflush: PBIT16(pkt+7, f->oldtag); break; case Tattach: restring(pkt, n, f->uname); restring(pkt, n, f->aname); PBIT32(pkt+7, f->fid); PBIT32(pkt+11, f->afid); break; case Twalk: PBIT32(pkt+7, f->fid); PBIT32(pkt+11, f->newfid); for(i=0; i<f->nwname; i++) restring(pkt, n, f->wname[i]); break; case Tcreate: restring(pkt, n, f->name); /* fall through */ case Topen: case Tclunk: case Tremove: case Tstat: case Twstat: case Twrite: PBIT32(pkt+7, f->fid); break; case Tread: PBIT32(pkt+7, f->fid); PBIT64(pkt+11, f->offset); break; case Rerror: restring(pkt, n, f->ename); break; } }
uint convD2M(Dir *d, uchar *buf, uint nbuf) { uchar *p, *ebuf; char *sv[5]; int i, ns, nsv[5], ss, nstr, fixlen; if(nbuf < BIT16SZ) return 0; p = buf; ebuf = buf + nbuf; sv[0] = d->name; sv[1] = d->uid; sv[2] = d->gid; sv[3] = d->muid; fixlen = STATFIXLEN; nstr = 4; ns = 0; for(i = 0; i < nstr; i++) { if(sv[i]) nsv[i] = strlen(sv[i]); else nsv[i] = 0; ns += nsv[i]; } ss = fixlen + ns; /* set size befor erroring, so user can know how much is needed */ /* note that length excludes count field itself */ PBIT16(p, ss-BIT16SZ); p += BIT16SZ; if(ss > nbuf) return BIT16SZ; PBIT16(p, d->type); p += BIT16SZ; PBIT32(p, d->dev); p += BIT32SZ; PBIT8(p, d->qid.type); p += BIT8SZ; PBIT32(p, d->qid.vers); p += BIT32SZ; PBIT64(p, d->qid.path); p += BIT64SZ; PBIT32(p, d->mode); p += BIT32SZ; PBIT32(p, d->atime); p += BIT32SZ; PBIT32(p, d->mtime); p += BIT32SZ; PBIT64(p, d->length); p += BIT64SZ; for(i = 0; i < nstr; i++) { ns = nsv[i]; if(p + ns + BIT16SZ > ebuf) return 0; PBIT16(p, ns); p += BIT16SZ; if(ns) memmove(p, sv[i], ns); p += ns; } if(ss != p - buf) return 0; return p - buf; }
uint convS2M(Fcall *f, uchar *ap, uint nap) { uchar *p; uint i, size; size = sizeS2M(f); if(size == 0) return 0; if(size > nap) return 0; p = (uchar*)ap; PBIT32(p, size); p += BIT32SZ; PBIT8(p, f->type); p += BIT8SZ; PBIT16(p, f->tag); p += BIT16SZ; switch(f->type) { default: return 0; case Tversion: PBIT32(p, f->msize); p += BIT32SZ; p = pstring(p, f->version); break; case Tflush: PBIT16(p, f->oldtag); p += BIT16SZ; break; case Tauth: PBIT32(p, f->afid); p += BIT32SZ; p = pstring(p, f->uname); p = pstring(p, f->aname); break; case Tattach: PBIT32(p, f->fid); p += BIT32SZ; PBIT32(p, f->afid); p += BIT32SZ; p = pstring(p, f->uname); p = pstring(p, f->aname); break; case Twalk: PBIT32(p, f->fid); p += BIT32SZ; PBIT32(p, f->newfid); p += BIT32SZ; PBIT16(p, f->nwname); p += BIT16SZ; if(f->nwname > MAXWELEM) return 0; for(i=0; i<f->nwname; i++) p = pstring(p, f->wname[i]); break; case Topen: PBIT32(p, f->fid); p += BIT32SZ; PBIT8(p, f->mode); p += BIT8SZ; break; case Tcreate: PBIT32(p, f->fid); p += BIT32SZ; p = pstring(p, f->name); PBIT32(p, f->perm); p += BIT32SZ; PBIT8(p, f->mode); p += BIT8SZ; break; case Tread: PBIT32(p, f->fid); p += BIT32SZ; PBIT64(p, f->offset); p += BIT64SZ; PBIT32(p, f->count); p += BIT32SZ; break; case Twrite: PBIT32(p, f->fid); p += BIT32SZ; PBIT64(p, f->offset); p += BIT64SZ; PBIT32(p, f->count); p += BIT32SZ; memmove(p, f->data, f->count); p += f->count; break; case Tclunk: case Tremove: PBIT32(p, f->fid); p += BIT32SZ; break; case Tstat: PBIT32(p, f->fid); p += BIT32SZ; break; case Twstat: PBIT32(p, f->fid); p += BIT32SZ; PBIT16(p, f->nstat); p += BIT16SZ; memmove(p, f->stat, f->nstat); p += f->nstat; break; /* */ case Rversion: PBIT32(p, f->msize); p += BIT32SZ; p = pstring(p, f->version); break; case Rerror: p = pstring(p, f->ename); break; case Rflush: break; case Rauth: p = pqid(p, &f->aqid); break; case Rattach: p = pqid(p, &f->qid); break; case Rwalk: PBIT16(p, f->nwqid); p += BIT16SZ; if(f->nwqid > MAXWELEM) return 0; for(i=0; i<f->nwqid; i++) p = pqid(p, &f->wqid[i]); break; case Ropen: case Rcreate: p = pqid(p, &f->qid); PBIT32(p, f->iounit); p += BIT32SZ; break; case Rread: PBIT32(p, f->count); p += BIT32SZ; memmove(p, f->data, f->count); p += f->count; break; case Rwrite: PBIT32(p, f->count); p += BIT32SZ; break; case Rclunk: break; case Rremove: break; case Rstat: PBIT16(p, f->nstat); p += BIT16SZ; memmove(p, f->stat, f->nstat); p += f->nstat; break; case Rwstat: break; } if(size != p-ap) return 0; return size; }