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 != nil; 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 != nil; 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 != nil && 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 != nil && s > 0; 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 != nil && s > 0; 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)
380 if(c->qid.type == QTDIR && omode != OREAD)
383 mode = openmode(omode);
394 devpermcheck(shr->owner, shr->perm, mode);
401 devpermcheck(mpt->owner, mpt->perm, mode);
402 rlock(&shr->umh.lock);
403 if(mpt->m.to == nil || mpt->m.to->mchan == nil){
404 runlock(&shr->umh.lock);
407 nc = mpt->m.to->mchan;
409 runlock(&shr->umh.lock);
410 if(mode != nc->mode){
424 Chan* createdir(Chan *c, Mhead *m);
427 shrcreate(Chan *c, char *name, int omode, ulong perm)
437 mode = openmode(omode);
442 if(strcmp(up->user, "none") == 0)
454 nc = createdir(c, &sch->shr->umh);
460 nc = devtab[nc->type]->create(nc, name, omode, perm);
465 if(up->pgrp->noattach)
467 if((perm & DMDIR) == 0 || mode != OREAD)
469 if(strlen(name) >= sizeof(up->genbuf))
476 for(shr = shrs; shr != nil; shr = shr->next)
477 if(strcmp(name, shr->name) == 0)
480 shr = smalloc(sizeof(*shr));
484 kstrdup(&shr->name, name);
485 kstrdup(&shr->owner, up->user);
495 c->qid = shrqid(sch->level = Qcshr, shr->id);
499 if(up->pgrp->noattach)
501 if((perm & DMDIR) != 0 || mode != OWRITE)
505 if(strcmp(shr->owner, eve) == 0 && !iseve())
507 devpermcheck(shr->owner, shr->perm, ORDWR);
509 if(strlen(name) >= sizeof(up->genbuf))
518 for(m = h->mount; m != nil; m = m->next){
520 if(strcmp(name, mpt->name) == 0)
524 mpt = smalloc(sizeof(*mpt));
528 kstrdup(&mpt->name, name);
529 kstrdup(&mpt->owner, up->user);
533 mpt->m.mflag = (h->mount == nil) ? MCREATE : 0;
534 mpt->m.next = h->mount;
540 c->qid = shrqid(sch->level = Qcmpt, mpt->id);
570 if(strcmp(shr->owner, eve) == 0)
572 devpermcheck(shr->owner, shr->perm, ORDWR);
583 error("directory not empty");
586 for(sl = &shrs; *sl != nil; sl = &((*sl)->next))
600 for(ml = &h->mount; *ml != nil; ml = &((*ml)->next))
615 shrwstat(Chan *c, uchar *dp, int n)
628 n = convM2D(dp, n, &d, strs);
656 if(strcmp(ent->owner, up->user) && !iseve())
659 if(d.name != nil && *d.name && strcmp(ent->name, d.name) != 0) {
660 if(strchr(d.name, '/') != nil)
662 if(strlen(d.name) >= sizeof(up->genbuf))
664 kstrdup(&ent->name, d.name);
666 if(d.uid != nil && *d.uid)
667 kstrdup(&ent->owner, d.uid);
669 ent->perm = d.mode & 0777;
689 shrread(Chan *c, void *va, long n, vlong)
701 return devdirread(c, va, n, 0, 0, shrgen);
704 c->umh = &sch->shr->umh;
709 n = unionread(c, va, n);
717 shrwrite(Chan *c, void *va, long n, vlong)
720 char *buf, *p, *aname;
726 if(up->pgrp->noattach)
729 if(sch->level != Qcmpt)
740 fd = strtol(buf, &p, 10);
741 if(p == buf || (*p != 0 && *p != '\n'))
743 if(*p == '\n' && *(p+1) != 0)
748 bc = fdtochan(fd, ORDWR, 0, 1);
753 c0 = mntattach(bc, nil, aname, 0);
778 if(c->flag & CRCLOSE)
806 chowner(Ent *ent, char *old, char *new)
808 if(ent->owner != nil && strcmp(old, ent->owner) == 0)
809 kstrdup(&ent->owner, new);
813 shrrenameuser(char *old, char *new)
819 for(shr = shrs; shr != nil; shr = shr->next){
820 wlock(&shr->umh.lock);
821 for(m = shr->umh.mount; m != nil; m = m->next)
822 chowner(tompt(m), old, new);
823 wunlock(&shr->umh.lock);
824 chowner(shr, old, new);