6 rpc2xfid(Rpccall *cmd, Dir *dp)
8 char *argptr = cmd->args;
15 char client[256], *user;
20 chat("rpc2xfid %.8lux %.8lux %p %p\n", *((ulong*)argptr), *((ulong*)argptr+1), buf, argptr);
21 if(argptr[0] == 0 && argptr[1] == 0){ /* root */
23 xp = xfroot(&argptr[2], 0);
27 chat("noroot %.8lux...", *((ulong*)argptr));
28 if((ul=GLONG()) != starttime){
29 chat("bad tag %lux %lux...", ul, starttime);
32 s = (Session *)GLONG();
35 qid.path = x1 | (x2<<32);
38 xp = xfile(&qid, s, 0);
44 if(auth2unix(&cmd->cred, &au) != 0){
45 chat("auth flavor=%ld, count=%ld\n",
46 cmd->cred.flavor, cmd->cred.count);
47 for(i=0; i<cmd->cred.count; i++)
48 chat(" %.2ux", ((uchar *)cmd->cred.data)[i]);
52 /* chat("auth: %d %.*s u=%d g=%d",
53 * au.stamp, utfnlen(au.mach.s, au.mach.n), au.mach.s, au.uid, au.gid);
54 * for(i=0; i<au.gidlen; i++)
55 * chat(", %d", au.gids[i]);
58 char *p = memchr(au.mach.s, '.', au.mach.n);
59 chat("%ld@%.*s...", au.uid, utfnlen(au.mach.s, (p ? p-au.mach.s : au.mach.n)), au.mach.s);
61 if(au.mach.n >= sizeof client){
62 chat("client name too long...");
65 memcpy(client, au.mach.s, au.mach.n);
66 client[au.mach.n] = 0;
67 service = xp->parent->s->service;
68 cmd->up = m = pair2idmap(service, cmd->host);
70 chat("no map for pair (%s,%s)...", service, client);
71 /*chat("getdom %d.%d.%d.%d", cmd->host&0xFF, (cmd->host>>8)&0xFF,
72 (cmd->host>>16)&0xFF, (cmd->host>>24)&0xFF);/**/
73 /*if(getdom(cmd->host, client, sizeof(client))<0)
77 /*chat("map=(%s,%s)...", m->server, m->client);/**/
78 cmd->user = user = id2name(&m->u.ids, au.uid);
80 chat("no user for id %ld...", au.uid);
83 chat("user=%s...", user);/**/
85 if(s == xp->parent->s){
87 xf = setuser(xp, user);
89 xf = setuser(xp, "none");
91 chat("can't set user none...");
95 chat("uid=%s...", xf->uid);
96 if(xf && dp && xfstat(xf, dp) < 0){
97 chat("can't stat %s...", xp->name);
104 setuser(Xfile *xp, char *user)
109 xf = xfid(user, xp, 1);
112 if(xp->parent==xp || !(xpf = setuser(xp->parent, user))) /* assign = */
113 return xfid(user, xp, -1);
115 xf->urfid = newfid(s);
116 xf->urfid->owner = &xf->urfid;
117 setfid(s, xpf->urfid);
118 s->f.newfid = xf->urfid - s->fids;
120 s->f.wname[0] = xp->name;
121 if(xmesg(s, Twalk) || s->f.nwqid != 1)
122 return xfid(user, xp, -1);
127 xfstat(Xfid *xf, Dir *dp)
135 if(s != xp->parent->s){
136 seprint(buf, buf+sizeof buf, "#%s", xf->uid);
137 dp->name = strstore(buf);
141 dp->qid.path = (uvlong)xf->uid;
142 dp->qid.type = QTFILE;
146 dp->mtime = dp->atime;
147 dp->length = NETCHLEN;
152 setfid(s, xf->urfid);
153 if(xmesg(s, Tstat) == 0){
154 convM2D(s->f.stat, s->f.nstat, dp, (char*)s->statbuf);
155 if(xp->qid.path == dp->qid.path){
156 xp->name = strstore(dp->name);
160 chat("xp->qid.path=0x%.16llux, dp->qid.path=0x%.16llux name=%s...",
161 xp->qid.path, dp->qid.path, dp->name);
166 clog("can't stat root: %s",
167 s->f.type == Rerror ? s->f.ename : "??");
172 xfwstat(Xfid *xf, Dir *dp)
181 * xf->urfid can be zero because some DOS NFS clients
182 * try to do wstat on the #user authentication files on close.
184 if(s == 0 || xf->urfid == 0)
186 setfid(s, xf->urfid);
187 s->f.stat = s->statbuf;
188 convD2M(dp, s->f.stat, Maxstatdata);
191 xp->name = strstore(dp->name);
196 xfopen(Xfid *xf, int flag)
198 static int modes[] = {
199 [Oread] OREAD, [Owrite] OWRITE, [Oread|Owrite] ORDWR,
206 if(xf->opfid && (xf->mode & flag & Open) == flag)
208 omode = modes[(xf->mode|flag) & Open];
212 chat("open(\"%s\", %d)...", xp->name, omode);
215 setfid(s, xf->urfid);
216 s->f.newfid = opfid - s->fids;
229 clunkfid(s, xf->opfid);
230 xf->mode |= flag & Open;
232 opfid->owner = &xf->opfid;
244 chat("close(\"%s\")...", xp->name);
246 clunkfid(xp->s, xf->opfid);
258 clunkfid(xp->s, xf->opfid);
262 clunkfid(xp->s, xf->urfid);
265 xfid(xf->uid, xp, -1);
269 xfwalkcr(int type, Xfid *xf, String *elem, long perm)
276 chat("xf%s(\"%s\")...", type==Tcreate ? "create" : "walk", elem->s);
280 setfid(s, xf->urfid);
281 s->f.newfid = nfid - s->fids;
288 s->f.fid = nfid - s->fids;
293 s->f.mode = (perm&DMDIR) ? OREAD : ORDWR;
300 s->f.wname[0] = elem->s;
301 if(xmesg(s, type) || s->f.nwqid!=1){
305 s->f.qid = s->f.wqid[0]; /* only one element */
307 chat("fid=%d,qid=0x%llux,%ld,%.2ux...", s->f.fid, s->f.qid.path, s->f.qid.vers, s->f.qid.type);
308 newxp = xfile(&s->f.qid, s, 1);
309 if(newxp->parent == 0){
310 chat("new xfile...");
312 newxp->sib = xp->child;
315 newxf = xfid(xf->uid, newxp, 1);
317 newxf->mode = (perm&DMDIR) ? Oread : (Oread|Owrite);
319 nfid->owner = &newxf->opfid;
321 setfid(s, xf->urfid);
322 s->f.newfid = nfid - s->fids;
324 s->f.wname[0] = elem->s;
325 if(xmesg(s, Twalk) || s->f.nwqid!=1){
331 nfid->owner = &newxf->urfid;
332 }else if(newxf->urfid){
333 chat("old xfid %zd...", newxf->urfid-s->fids);
337 nfid->owner = &newxf->urfid;
339 newxp->name = strstore(elem->s);
351 while(xf = xp->users) /* assign = */
353 while(xnp = xp->child){ /* assign = */
354 xp->child = xnp->sib;
357 xfile(&xnp->qid, s, -1);
359 if(xnp = xp->parent){ /* assign = */
361 xnp->child = xp->sib;
364 while(xnp->sib != xp)
368 xfile(&xp->qid, s, -1);
373 xp2fhandle(Xfile *xp, Fhandle fh)
379 memset(fh, 0, FHSIZE);
380 if(xp == xp->parent){ /* root */
383 n = strlen(xp->s->service);
386 memmove(&dataptr[2], xp->s->service, n);
390 PLONG((u32int)(uintptr)xp->s);
393 x = xp->qid.path>>32;
402 dir2fattr(Unixidmap *up, Dir *dp, void *mp)
409 if (dp->mode & DMDIR)
413 if((dp->mode & DMDIR) && dp->type == '/' && dp->dev == 0)
415 if(dp->mode & DMDIR){
416 PLONG(NFDIR); /* type */
419 PLONG(3); /* nlink */
421 PLONG(NFREG); /* type */
424 PLONG(1); /* nlink */
426 r = name2id(&up->u.ids, dp->uid);
428 r = name2id(&up->u.ids, "daemon");
433 r = name2id(&up->g.ids, dp->gid);
435 r = name2id(&up->g.ids, "user");
440 PLONG(length); /* size */
441 PLONG(2048); /* blocksize */
443 r = (length+2047)/2048;
444 PLONG(r); /* blocks */
445 r = (dp->type<<16) | dp->dev;
447 PLONG(dp->qid.path); /* fileid */
448 PLONG(dp->atime); /* atime */
450 PLONG(dp->mtime); /* mtime */
452 PLONG(dp->mtime); /* ctime */
454 return dataptr - (uchar *)mp;
458 convM2sattr(void *mp, Sattr *sp)
470 return argptr - (uchar *)mp;