123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- #include "all.h"
- extern uchar buf[];
- Xfid *
- rpc2xfid(Rpccall *cmd, Dir *dp)
- {
- char *argptr = cmd->args;
- Xfile *xp;
- Xfid *xf;
- Session *s;
- char *service;
- Authunix au;
- Qid qid;
- char client[256], *user;
- Unixidmap *m;
- int i;
- uvlong x1, x2;
- chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr);
- if(argptr[0] == 0 && argptr[1] == 0){ /* root */
- chat("root...");
- xp = xfroot(&argptr[2], 0);
- s = xp ? xp->s : 0;
- }else{
- ulong ul;
- chat("noroot %.8lux...", *((ulong*)argptr));
- if((ul=GLONG()) != starttime){
- chat("bad tag %lux %lux...", ul, starttime);
- return 0;
- }
- s = (Session *)GLONG();
- x1 = GLONG();
- x2 = GLONG();
- qid.path = x1 | (x2<<32);
- qid.vers = 0;
- qid.type = GBYTE();
- xp = xfile(&qid, s, 0);
- }
- if(xp == 0){
- chat("no xfile...");
- return 0;
- }
- if(auth2unix(&cmd->cred, &au) != 0){
- chat("auth flavor=%ld, count=%ld\n",
- cmd->cred.flavor, cmd->cred.count);
- for(i=0; i<cmd->cred.count; i++)
- chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
- chat("...");
- return 0;
- }else{
- /* chat("auth: %d %.*s u=%d g=%d",
- * au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
- * for(i=0; i<au.gidlen; i++)
- * chat(", %d", au.gids[i]);
- * chat("...");
- */
- char *p = memchr(au.mach.s, '.', au.mach.n);
- chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s);
- }
- if(au.mach.n >= sizeof client){
- chat("client name too long...");
- return 0;
- }
- memcpy(client, au.mach.s, au.mach.n);
- client[au.mach.n] = 0;
- service = xp->parent->s->service;
- cmd->up = m = pair2idmap(service, cmd->host);
- if(m == 0){
- chat("no map for pair (%s,%s)...", service, client);
- /*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF,
- (cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/
- /*if(getdom(cmd->host, client, sizeof(client))<0)
- return 0;/**/
- return 0;
- }
- /*chat("map=(%s,%s)...", m->server, m->client);/**/
- cmd->user = user = id2name(&m->u.ids, au.uid);
- if(user == 0){
- chat("no user for id %ld...", au.uid);
- return 0;
- }
- chat("user=%s...", user);/**/
- xf = 0;
- if(s == xp->parent->s){
- if(!s->noauth)
- xf = setuser(xp, user);
- if(xf == 0)
- xf = setuser(xp, "none");
- if(xf == 0)
- chat("can't set user none...");
- }else
- xf = xp->users;
- if(xf)
- chat("uid=%s...", xf->uid);
- if(xf && dp && xfstat(xf, dp) < 0){
- chat("can't stat %s...", xp->name);
- return 0;
- }
- return xf;
- }
- Xfid *
- setuser(Xfile *xp, char *user)
- {
- Xfid *xf, *xpf;
- Session *s;
- xf = xfid(user, xp, 1);
- if(xf->urfid)
- return xf;
- if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */
- return xfid(user, xp, -1);
- s = xp->s;
- xf->urfid = newfid(s);
- xf->urfid->owner = &xf->urfid;
- setfid(s, xpf->urfid);
- s->f.newfid = xf->urfid - s->fids;
- s->f.nwname = 1;
- s->f.wname[0] = xp->name;
- if(xmesg(s, Twalk) || s->f.nwqid != 1)
- return xfid(user, xp, -1);
- return xf;
- }
- int
- xfstat(Xfid *xf, Dir *dp)
- {
- Xfile *xp;
- Session *s;
- char buf[128];
- xp = xf->xp;
- s = xp->s;
- if(s != xp->parent->s){
- seprint(buf, buf+sizeof buf, "#%s", xf->uid);
- dp->name = strstore(buf);
- dp->uid = xf->uid;
- dp->gid = xf->uid;
- dp->muid = xf->uid;
- dp->qid.path = (uvlong)xf->uid;
- dp->qid.type = QTFILE;
- dp->qid.vers = 0;
- dp->mode = 0666;
- dp->atime = time(0);
- dp->mtime = dp->atime;
- dp->length = NETCHLEN;
- dp->type = 0;
- dp->type = 0;
- return 0;
- }
- setfid(s, xf->urfid);
- if(xmesg(s, Tstat) == 0){
- convM2D(s->f.stat, s->f.nstat, dp, (char*)s->statbuf);
- if(xp->qid.path == dp->qid.path){
- xp->name = strstore(dp->name);
- return 0;
- }
- /* not reached ? */
- chat("xp->qid.path=0x%.16llux, dp->qid.path=0x%.16llux name=%s...",
- xp->qid.path, dp->qid.path, dp->name);
- }
- if(xp != xp->parent)
- xpclear(xp);
- else
- clog("can't stat root: %s",
- s->f.type == Rerror ? s->f.ename : "??");
- return -1;
- }
- int
- xfwstat(Xfid *xf, Dir *dp)
- {
- Xfile *xp;
- Session *s;
- xp = xf->xp;
- s = xp->s;
- /*
- * xf->urfid can be zero because some DOS NFS clients
- * try to do wstat on the #user authentication files on close.
- */
- if(s == 0 || xf->urfid == 0)
- return -1;
- setfid(s, xf->urfid);
- s->f.stat = s->statbuf;
- convD2M(dp, s->f.stat, Maxstatdata);
- if(xmesg(s, Twstat))
- return -1;
- xp->name = strstore(dp->name);
- return 0;
- }
- int
- xfopen(Xfid *xf, int flag)
- {
- static int modes[] = {
- [Oread] OREAD, [Owrite] OWRITE, [Oread|Owrite] ORDWR,
- };
- Xfile *xp;
- Session *s;
- Fid *opfid;
- int omode;
- if(xf->opfid && (xf->mode & flag & Open) == flag)
- return 0;
- omode = modes[(xf->mode|flag) & Open];
- if(flag & Trunc)
- omode |= OTRUNC;
- xp = xf->xp;
- chat("open(\"%s\", %d)...", xp->name, omode);
- s = xp->s;
- opfid = newfid(s);
- setfid(s, xf->urfid);
- s->f.newfid = opfid - s->fids;
- s->f.nwname = 0;
- if(xmesg(s, Twalk)){
- putfid(s, opfid);
- return -1;
- }
- setfid(s, opfid);
- s->f.mode = omode;
- if(xmesg(s, Topen)){
- clunkfid(s, opfid);
- return -1;
- }
- if(xf->opfid)
- clunkfid(s, xf->opfid);
- xf->mode |= flag & Open;
- xf->opfid = opfid;
- opfid->owner = &xf->opfid;
- xf->offset = 0;
- return 0;
- }
- void
- xfclose(Xfid *xf)
- {
- Xfile *xp;
- if(xf->mode & Open){
- xp = xf->xp;
- chat("close(\"%s\")...", xp->name);
- if(xf->opfid)
- clunkfid(xp->s, xf->opfid);
- xf->mode &= ~Open;
- xf->opfid = 0;
- }
- }
- void
- xfclear(Xfid *xf)
- {
- Xfile *xp = xf->xp;
- if(xf->opfid){
- clunkfid(xp->s, xf->opfid);
- xf->opfid = 0;
- }
- if(xf->urfid){
- clunkfid(xp->s, xf->urfid);
- xf->urfid = 0;
- }
- xfid(xf->uid, xp, -1);
- }
- Xfid *
- xfwalkcr(int type, Xfid *xf, String *elem, long perm)
- {
- Session *s;
- Xfile *xp, *newxp;
- Xfid *newxf;
- Fid *nfid;
- chat("xf%s(\"%s\")...", type==Tcreate ? "create" : "walk", elem->s);
- xp = xf->xp;
- s = xp->s;
- nfid = newfid(s);
- setfid(s, xf->urfid);
- s->f.newfid = nfid - s->fids;
- if(type == Tcreate){
- s->f.nwname = 0;
- if(xmesg(s, Twalk)){
- putfid(s, nfid);
- return 0;
- }
- s->f.fid = nfid - s->fids;
- }
- if(type == Tcreate){
- s->f.name = elem->s;
- s->f.perm = perm;
- s->f.mode = (perm&DMDIR) ? OREAD : ORDWR;
- if(xmesg(s, type)){
- clunkfid(s, nfid);
- return 0;
- }
- }else{ /* Twalk */
- s->f.nwname = 1;
- s->f.wname[0] = elem->s;
- if(xmesg(s, type) || s->f.nwqid!=1){
- putfid(s, nfid);
- return 0;
- }
- s->f.qid = s->f.wqid[0]; /* only one element */
- }
- chat("fid=%d,qid=0x%llux,%ld,%.2ux...", s->f.fid, s->f.qid.path, s->f.qid.vers, s->f.qid.type);
- newxp = xfile(&s->f.qid, s, 1);
- if(newxp->parent == 0){
- chat("new xfile...");
- newxp->parent = xp;
- newxp->sib = xp->child;
- xp->child = newxp;
- }
- newxf = xfid(xf->uid, newxp, 1);
- if(type == Tcreate){
- newxf->mode = (perm&DMDIR) ? Oread : (Oread|Owrite);
- newxf->opfid = nfid;
- nfid->owner = &newxf->opfid;
- nfid = newfid(s);
- setfid(s, xf->urfid);
- s->f.newfid = nfid - s->fids;
- s->f.nwname = 1;
- s->f.wname[0] = elem->s;
- if(xmesg(s, Twalk) || s->f.nwqid!=1){
- putfid(s, nfid);
- xpclear(newxp);
- return 0;
- }
- newxf->urfid = nfid;
- nfid->owner = &newxf->urfid;
- }else if(newxf->urfid){
- chat("old xfid %ld...", newxf->urfid-s->fids);
- clunkfid(s, nfid);
- }else{
- newxf->urfid = nfid;
- nfid->owner = &newxf->urfid;
- }
- newxp->name = strstore(elem->s);
- return newxf;
- }
- void
- xpclear(Xfile *xp)
- {
- Session *s;
- Xfid *xf;
- Xfile *xnp;
- s = xp->s;
- while(xf = xp->users) /* assign = */
- xfclear(xf);
- while(xnp = xp->child){ /* assign = */
- xp->child = xnp->sib;
- xnp->parent = 0;
- xpclear(xnp);
- xfile(&xnp->qid, s, -1);
- }
- if(xnp = xp->parent){ /* assign = */
- if(xnp->child == xp)
- xnp->child = xp->sib;
- else{
- xnp = xnp->child;
- while(xnp->sib != xp)
- xnp = xnp->sib;
- xnp->sib = xp->sib;
- }
- xfile(&xp->qid, s, -1);
- }
- }
- int
- xp2fhandle(Xfile *xp, Fhandle fh)
- {
- uchar *dataptr = fh;
- ulong x;
- int n;
- memset(fh, 0, FHSIZE);
- if(xp == xp->parent){ /* root */
- dataptr[0] = 0;
- dataptr[1] = 0;
- n = strlen(xp->s->service);
- if(n > FHSIZE-3)
- n = FHSIZE-3;
- memmove(&dataptr[2], xp->s->service, n);
- dataptr[2+n] = 0;
- }else{
- PLONG(starttime);
- PLONG((u32int)(uintptr)xp->s);
- x = xp->qid.path;
- PLONG(x);
- x = xp->qid.path>>32;
- PLONG(x);
- PBYTE(xp->qid.type);
- USED(dataptr);
- }
- return FHSIZE;
- }
- int
- dir2fattr(Unixidmap *up, Dir *dp, void *mp)
- {
- uchar *dataptr = mp;
- long length;
- int r;
- r = dp->mode & 0777;
- if (dp->mode & DMDIR)
- length = 1024;
- else
- length = dp->length;
- if((dp->mode & DMDIR) && dp->type == '/' && dp->dev == 0)
- r |= 0555;
- if(dp->mode & DMDIR){
- PLONG(NFDIR); /* type */
- r |= S_IFDIR;
- PLONG(r); /* mode */
- PLONG(3); /* nlink */
- }else{
- PLONG(NFREG); /* type */
- r |= S_IFREG;
- PLONG(r); /* mode */
- PLONG(1); /* nlink */
- }
- r = name2id(&up->u.ids, dp->uid);
- if(r < 0){
- r = name2id(&up->u.ids, "daemon");
- if(r < 0)
- r = 1;
- }
- PLONG(r); /* uid */
- r = name2id(&up->g.ids, dp->gid);
- if(r < 0){
- r = name2id(&up->g.ids, "user");
- if(r < 0)
- r = 1;
- }
- PLONG(r); /* gid */
- PLONG(length); /* size */
- PLONG(2048); /* blocksize */
- PLONG(0); /* rdev */
- r = (length+2047)/2048;
- PLONG(r); /* blocks */
- r = (dp->type<<16) | dp->dev;
- PLONG(r); /* fsid */
- PLONG(dp->qid.path); /* fileid */
- PLONG(dp->atime); /* atime */
- PLONG(0);
- PLONG(dp->mtime); /* mtime */
- PLONG(0);
- PLONG(dp->mtime); /* ctime */
- PLONG(0);
- return dataptr - (uchar *)mp;
- }
- int
- convM2sattr(void *mp, Sattr *sp)
- {
- uchar *argptr = mp;
- sp->mode = GLONG();
- sp->uid = GLONG();
- sp->gid = GLONG();
- sp->size = GLONG();
- sp->atime = GLONG();
- sp->ausec = GLONG();
- sp->mtime = GLONG();
- sp->musec = GLONG();
- return argptr - (uchar *)mp;
- }
|