2 #include "../port/lib.h"
6 #include "../port/error.h"
16 typedef struct Ent Ent;
17 typedef struct Shr Shr;
18 typedef struct Mpt Mpt;
19 typedef struct Sch Sch;
62 return (Mpt*)((char*)m - (char*)&((Mpt*)0)->m);
74 error("nil chan aux");
110 shrqid(int level, int id)
114 q.type = (level == Qcmpt) ? QTFILE : QTDIR;
115 q.path = (uvlong)id<<4 | level;
121 shrattach(char *spec)
126 if(!(spec[0] == 'c' && spec[1] == 0 || spec[0] == 0))
128 c = devattach(L'σ', spec);
130 sch = smalloc(sizeof(*sch));
131 sch->level = spec[0] == 'c' ? Qcroot : Qroot;
136 c->qid = shrqid(sch->level, 0);
149 sch = smalloc(sizeof(*sch));
150 memmove(sch, och, sizeof(*sch));
176 shrwalk(Chan *c, Chan *nc, char **name, int nname)
192 wq = smalloc(sizeof(Walkqid) + (nname - 1) * sizeof(Qid));
207 for(j = 0; j < nname; j++){
208 if(nc->qid.type != QTDIR)
212 if(nam[0] == '.' && nam[1] == 0) {
214 } else if(nam[0] == '.' && nam[1] == '.' && nam[2] == 0) {
219 nc->qid = shrqid(sch->level = Qroot, 0);
222 nc->qid = shrqid(sch->level = Qcroot, 0);
227 } else if(sch->level == Qcroot || sch->level == Qroot) {
229 for(shr = shrs; shr; shr = shr->next)
230 if(strcmp(nam, shr->name) == 0){
237 sch->level = sch->level == Qcroot ? Qcshr : Qshr;
239 nc->qid = shrqid(sch->level, shr->id);
240 } else if(sch->level == Qcshr) {
245 for(m = h->mount; m; m = m->next){
247 if(strcmp(nam, mpt->name) == 0){
256 nc->qid = shrqid(sch->level = Qcmpt, mpt->id);
257 } else if(sch->level == Qshr) {
262 for(m = h->mount; m && wq2 == nil; m = m->next){
267 wq2 = devtab[m->to->type]->walk(m->to, nil, name + j, nname - j);
273 memmove(wq->qid + wq->nqid, wq2->qid, wq2->nqid);
274 wq->nqid += wq2->nqid;
277 wq->clone = wq2->clone;
283 wq->qid[wq->nqid++] = nc->qid;
290 shrgen(Chan *c, char*, Dirtab*, int, int s, Dir *dp)
305 for(shr = shrs; shr && s; shr = shr->next)
311 kstrcpy(up->genbuf, shr->name, sizeof up->genbuf);
312 if(sch->level == Qroot)
313 devdir(c, shrqid(Qshr, shr->id), up->genbuf, 0, shr->owner,
314 shr->perm & ~0222, dp);
316 devdir(c, shrqid(Qcshr, shr->id), up->genbuf, 0, shr->owner,
324 for(m = h->mount; m && s; m = m->next)
331 kstrcpy(up->genbuf, mpt->name, sizeof up->genbuf);
332 devdir(c, shrqid(Qcmpt, mpt->id), up->genbuf, 0, mpt->owner, mpt->perm, dp);
339 shrstat(Chan *c, uchar *db, int n)
350 devdir(c, c->qid, "#σ", 0, eve, 0555, &dir);
353 devdir(c, c->qid, "#σc", 0, eve, 0777, &dir);
356 devdir(c, c->qid, sch->shr->name, 0, sch->shr->owner, sch->shr->perm & ~0222, &dir);
359 devdir(c, c->qid, sch->shr->name, 0, sch->shr->owner, sch->shr->perm, &dir);
362 devdir(c, c->qid, sch->mpt->name, 0, sch->mpt->owner, sch->mpt->perm, &dir);
365 rc = convD2M(&dir, db, n);
372 shropen(Chan *c, int omode)
379 if(c->qid.type == QTDIR && omode != OREAD)
392 devpermcheck(shr->owner, shr->perm, openmode(omode));
399 devpermcheck(mpt->owner, mpt->perm, openmode(omode));
400 rlock(&shr->umh.lock);
401 if(mpt->m.to == nil || mpt->m.to->mchan == nil){
402 runlock(&shr->umh.lock);
405 nc = mpt->m.to->mchan;
407 runlock(&shr->umh.lock);
408 if(openmode(omode) != nc->mode){
415 c->mode = openmode(omode);
422 Chan* createdir(Chan *c, Mhead *m);
425 shrcreate(Chan *c, char *name, int omode, ulong perm)
438 if(strcmp(up->user, "none") == 0)
450 nc = createdir(c, &sch->shr->umh);
456 nc = devtab[nc->type]->create(nc, name, omode, perm);
461 if((perm & DMDIR) == 0 || openmode(omode) != OREAD)
469 for(shr = shrs; shr; shr = shr->next)
470 if(strcmp(name, shr->name) == 0)
473 shr = smalloc(sizeof(*shr));
477 kstrdup(&shr->name, name);
478 kstrdup(&shr->owner, up->user);
488 c->qid = shrqid(sch->level = Qcshr, shr->id);
492 if((perm & DMDIR) || openmode(omode) != OWRITE)
496 if(strcmp(shr->owner, eve) == 0 && !iseve())
498 devpermcheck(shr->owner, shr->perm, ORDWR);
506 for(m = h->mount; m; m = m->next){
508 if(strcmp(name, mpt->name) == 0)
512 mpt = smalloc(sizeof(*mpt));
516 kstrdup(&mpt->name, name);
517 kstrdup(&mpt->owner, up->user);
521 mpt->m.mflag = (h->mount == nil) ? MCREATE : 0;
523 mpt->m.next = h->mount;
529 c->qid = shrqid(sch->level = Qcmpt, mpt->id);
534 c->mode = openmode(omode);
559 if(strcmp(shr->owner, eve) == 0)
561 devpermcheck(shr->owner, shr->perm, ORDWR);
572 error("directory not empty");
575 for(sl = &shrs; *sl; sl = &((*sl)->next))
589 for(ml = &h->mount; *ml; ml = &((*ml)->next))
605 shrwstat(Chan *c, uchar *dp, int n)
637 if(strcmp(ent->owner, up->user) && !iseve())
645 n = convM2D(dp, n, &d, strs);
649 ent->perm = d.mode & 0777;
651 kstrdup(&ent->owner, d.uid);
652 if(d.name && *d.name && strcmp(ent->name, d.name) != 0) {
653 if(strchr(d.name, '/') != nil)
655 kstrdup(&ent->name, d.name);
676 shrread(Chan *c, void *va, long n, vlong)
688 return devdirread(c, va, n, 0, 0, shrgen);
691 c->umh = &sch->shr->umh;
696 n = unionread(c, va, n);
704 shrwrite(Chan *c, void *va, long n, vlong)
707 char *buf, *p, *aname;
720 if(sch->level != Qcmpt)
731 fd = strtol(buf, &p, 10);
732 if(p == buf || (*p != 0 && *p != '\n'))
734 if(*p == '\n' && *(p+1) != 0)
739 bc = fdtochan(fd, ORDWR, 0, 1);
746 bogus.authchan = nil;
748 c0 = devtab[devno('M', 0)]->attach((char*)&bogus);
773 if(c->flag & CRCLOSE)
801 chowner(Ent *ent, char *old, char *new)
803 if(ent->owner!=nil && strcmp(old, ent->owner)==0)
804 kstrdup(&ent->owner, new);
808 shrrenameuser(char *old, char *new)
814 for(shr = shrs; shr; shr = shr->next){
815 wlock(&shr->umh.lock);
816 for(m = shr->umh.mount; m; m = m->next)
817 chowner(tompt(m), old, new);
818 wunlock(&shr->umh.lock);
819 chowner(shr, old, new);