Attr* addcap(Attr *a, char *sysuser, Ticket *t) { Attr *newa; char *c; // c = mkcap(t->cuid, t->suid); c = mkcap(sysuser, t->suid); newa = addattr(a, "cuid=%q suid=%q cap=%s", t->cuid, t->suid, c); free(c); return newa; }
void rpcread(Req *r) { Attr *attr; char *p; int ophase, ret; uint8_t *e; uint count; Fsstate *fss; Proto *proto; if(r->ifcall.count < 64){ respond(r, "rpc read too small"); return; } fss = r->fid->aux; if(!fss->pending){ respond(r, "no rpc pending"); return; } switch(fss->rpc.iverb){ default: case Vunknown: retstring(r, fss, "error unknown verb"); break; case Vstart: if(fss->phase != Notstarted){ flog("%d: implicit close due to second start; old attr '%A'", fss->seqnum, fss->attr); if(fss->proto && fss->ps) (*fss->proto->close)(fss); fss->ps = nil; fss->proto = nil; _freeattr(fss->attr); fss->attr = nil; fss->phase = Notstarted; } attr = _parseattr(fss->rpc.arg); if((p = _strfindattr(attr, "proto")) == nil){ retstring(r, fss, "error did not specify proto"); _freeattr(attr); break; } if((proto = findproto(p)) == nil){ snprint(fss->rpc.buf, Maxrpc, "error unknown protocol %q", p); retstring(r, fss, fss->rpc.buf); _freeattr(attr); break; } fss->attr = attr; fss->proto = proto; fss->seqnum = ++seqnum; ret = (*proto->init)(proto, fss); rpcstartlog(attr, fss, ret); if(ret != RpcOk){ _freeattr(fss->attr); fss->attr = nil; fss->phase = Notstarted; } retrpc(r, ret, fss); break; case Vread: if(fss->rpc.arg && fss->rpc.arg[0]){ retstring(r, fss, "error read needs no parameters"); break; } if(rdwrcheck(r, fss) < 0) break; count = r->ifcall.count - 3; ophase = fss->phase; ret = fss->proto->read(fss, (uint8_t*)r->ofcall.data+3, &count); rpcrdwrlog(fss, "read", count, ophase, ret); if(ret == RpcOk){ memmove(r->ofcall.data, "ok ", 3); if(count == 0) r->ofcall.count = 2; else r->ofcall.count = 3+count; fss->pending = 0; respond(r, nil); }else retrpc(r, ret, fss); break; case Vwrite: if(rdwrcheck(r, fss) < 0) break; ophase = fss->phase; ret = fss->proto->write(fss, fss->rpc.arg, fss->rpc.narg); rpcrdwrlog(fss, "write", fss->rpc.narg, ophase, ret); retrpc(r, ret, fss); break; case Vauthinfo: if(fss->phase != Established){ retstring(r, fss, "error authentication unfinished"); break; } if(!fss->haveai){ retstring(r, fss, "error no authinfo available"); break; } memmove(r->ofcall.data, "ok ", 3); fss->ai.cap = mkcap(r->fid->uid, fss->ai.suid); e = convAI2M(&fss->ai, (uint8_t*)r->ofcall.data+3, r->ifcall.count-3); free(fss->ai.cap); fss->ai.cap = nil; if(e == nil){ retstring(r, fss, "error read too small"); break; } r->ofcall.count = e - (uint8_t*)r->ofcall.data; fss->pending = 0; respond(r, nil); break; case Vattr: snprint(fss->rpc.buf, Maxrpc, "ok %A", fss->attr); retstring(r, fss, fss->rpc.buf); break; } }