1 #include	"u.h"
2 #include	"lib.h"
3 #include	"dat.h"
4 #include	"fns.h"
5 #include	"error.h"
6 
7 int chandebug=0;		/* toggled by sysr1 */
8 QLock chanprint;		/* probably asking for trouble (deadlocks) -rsc */
9 
10 int domount(Chan**, Mhead**);
11 
12 void
dumpmount(void)13 dumpmount(void)		/* DEBUGGING */
14 {
15 	Pgrp *pg;
16 	Mount *t;
17 	Mhead **h, **he, *f;
18 
19 	if(up == nil){
20 		print("no process for dumpmount\n");
21 		return;
22 	}
23 	pg = up->pgrp;
24 	if(pg == nil){
25 		print("no pgrp for dumpmount\n");
26 		return;
27 	}
28 	rlock(&pg->ns);
29 	if(waserror()) {
30 		runlock(&pg->ns);
31 		nexterror();
32 	}
33 
34 	he = &pg->mnthash[MNTHASH];
35 	for(h = pg->mnthash; h < he; h++) {
36 		for(f = *h; f; f = f->hash) {
37 			print("head: %p: %s 0x%llux.%lud %C %lud -> \n", f,
38 				f->from->name->s, f->from->qid.path,
39 				f->from->qid.vers, devtab[f->from->type]->dc,
40 				f->from->dev);
41 			for(t = f->mount; t; t = t->next)
42 				print("\t%p: %s (umh %p) (path %.8llux dev %C %lud)\n", t, t->to->name->s, t->to->umh, t->to->qid.path, devtab[t->to->type]->dc, t->to->dev);
43 		}
44 	}
45 	poperror();
46 	runlock(&pg->ns);
47 }
48 
49 
50 char*
c2name(Chan * c)51 c2name(Chan *c)		/* DEBUGGING */
52 {
53 	if(c == nil)
54 		return "<nil chan>";
55 	if(c->name == nil)
56 		return "<nil name>";
57 	if(c->name->s == nil)
58 		return "<nil name.s>";
59 	return c->name->s;
60 }
61 
62 enum
63 {
64 	CNAMESLOP	= 20
65 };
66 
67 struct
68 {
69 	Lock lk;
70 	int	fid;
71 	Chan	*free;
72 	Chan	*list;
73 }chanalloc;
74 
75 typedef struct Elemlist Elemlist;
76 
77 struct Elemlist
78 {
79 	char	*name;	/* copy of name, so '/' can be overwritten */
80 	int	nelems;
81 	char	**elems;
82 	int	*off;
83 	int	mustbedir;
84 };
85 
86 #define SEP(c) ((c) == 0 || (c) == '/')
87 void cleancname(Cname*);
88 
89 int
isdotdot(char * p)90 isdotdot(char *p)
91 {
92 	return p[0]=='.' && p[1]=='.' && p[2]=='\0';
93 }
94 
95 int
incref(Ref * r)96 incref(Ref *r)
97 {
98 	int x;
99 
100 	lock(&r->lk);
101 	x = ++r->ref;
102 	unlock(&r->lk);
103 	return x;
104 }
105 
106 int
decref(Ref * r)107 decref(Ref *r)
108 {
109 	int x;
110 
111 	lock(&r->lk);
112 	x = --r->ref;
113 	unlock(&r->lk);
114 	if(x < 0)
115 		panic("decref, pc=0x%p", getcallerpc(&r));
116 
117 	return x;
118 }
119 
120 /*
121  * Rather than strncpy, which zeros the rest of the buffer, kstrcpy
122  * truncates if necessary, always zero terminates, does not zero fill,
123  * and puts ... at the end of the string if it's too long.  Usually used to
124  * save a string in up->genbuf;
125  */
126 void
kstrcpy(char * s,char * t,int ns)127 kstrcpy(char *s, char *t, int ns)
128 {
129 	int nt;
130 
131 	nt = strlen(t);
132 	if(nt+1 <= ns){
133 		memmove(s, t, nt+1);
134 		return;
135 	}
136 	/* too long */
137 	if(ns < 4){
138 		/* but very short! */
139 		strncpy(s, t, ns);
140 		return;
141 	}
142 	/* truncate with ... at character boundary (very rare case) */
143 	memmove(s, t, ns-4);
144 	ns -= 4;
145 	s[ns] = '\0';
146 	/* look for first byte of UTF-8 sequence by skipping continuation bytes */
147 	while(ns>0 && (s[--ns]&0xC0)==0x80)
148 		;
149 	strcpy(s+ns, "...");
150 }
151 
152 int
emptystr(char * s)153 emptystr(char *s)
154 {
155 	if(s == nil)
156 		return 1;
157 	if(s[0] == '\0')
158 		return 1;
159 	return 0;
160 }
161 
162 /*
163  * Atomically replace *p with copy of s
164  */
165 void
kstrdup(char ** p,char * s)166 kstrdup(char **p, char *s)
167 {
168 	int n;
169 	char *t, *prev;
170 
171 	n = strlen(s)+1;
172 	/* if it's a user, we can wait for memory; if not, something's very wrong */
173 	if(up){
174 		t = smalloc(n);
175 		setmalloctag(t, getcallerpc(&p));
176 	}else{
177 		t = malloc(n);
178 		if(t == nil)
179 			panic("kstrdup: no memory");
180 	}
181 	memmove(t, s, n);
182 	prev = *p;
183 	*p = t;
184 	free(prev);
185 }
186 
187 void
chandevreset(void)188 chandevreset(void)
189 {
190 	int i;
191 
192 	for(i=0; devtab[i] != nil; i++)
193 		devtab[i]->reset();
194 }
195 
196 void
chandevinit(void)197 chandevinit(void)
198 {
199 	int i;
200 
201 	for(i=0; devtab[i] != nil; i++)
202 		devtab[i]->init();
203 }
204 
205 void
chandevshutdown(void)206 chandevshutdown(void)
207 {
208 	int i;
209 
210 	/* shutdown in reverse order */
211 	for(i=0; devtab[i] != nil; i++)
212 		;
213 	for(i--; i >= 0; i--)
214 		devtab[i]->shutdown();
215 }
216 
217 Chan*
newchan(void)218 newchan(void)
219 {
220 	Chan *c;
221 
222 	lock(&chanalloc.lk);
223 	c = chanalloc.free;
224 	if(c != 0)
225 		chanalloc.free = c->next;
226 	unlock(&chanalloc.lk);
227 
228 	if(c == nil) {
229 		c = smalloc(sizeof(Chan));
230 		lock(&chanalloc.lk);
231 		c->fid = ++chanalloc.fid;
232 		c->link = chanalloc.list;
233 		chanalloc.list = c;
234 		unlock(&chanalloc.lk);
235 	}
236 
237 	/* if you get an error before associating with a dev,
238 	   close calls rootclose, a nop */
239 	c->type = 0;
240 	c->flag = 0;
241 	c->ref.ref = 1;
242 	c->dev = 0;
243 	c->offset = 0;
244 	c->iounit = 0;
245 	c->umh = 0;
246 	c->uri = 0;
247 	c->dri = 0;
248 	c->aux = 0;
249 	c->mchan = 0;
250 	c->mcp = 0;
251 	c->mux = 0;
252 	memset(&c->mqid, 0, sizeof(c->mqid));
253 	c->name = 0;
254 	return c;
255 }
256 
257 static Ref ncname;
258 
259 Cname*
newcname(char * s)260 newcname(char *s)
261 {
262 	Cname *n;
263 	int i;
264 
265 	n = smalloc(sizeof(Cname));
266 	i = strlen(s);
267 	n->len = i;
268 	n->alen = i+CNAMESLOP;
269 	n->s = smalloc(n->alen);
270 	memmove(n->s, s, i+1);
271 	n->ref.ref = 1;
272 	incref(&ncname);
273 	return n;
274 }
275 
276 void
cnameclose(Cname * n)277 cnameclose(Cname *n)
278 {
279 	if(n == nil)
280 		return;
281 	if(decref(&n->ref))
282 		return;
283 	decref(&ncname);
284 	free(n->s);
285 	free(n);
286 }
287 
288 Cname*
addelem(Cname * n,char * s)289 addelem(Cname *n, char *s)
290 {
291 	int i, a;
292 	char *t;
293 	Cname *new;
294 
295 	if(s[0]=='.' && s[1]=='\0')
296 		return n;
297 
298 	if(n->ref.ref > 1){
299 		/* copy on write */
300 		new = newcname(n->s);
301 		cnameclose(n);
302 		n = new;
303 	}
304 
305 	i = strlen(s);
306 	if(n->len+1+i+1 > n->alen){
307 		a = n->len+1+i+1 + CNAMESLOP;
308 		t = smalloc(a);
309 		memmove(t, n->s, n->len+1);
310 		free(n->s);
311 		n->s = t;
312 		n->alen = a;
313 	}
314 	if(n->len>0 && n->s[n->len-1]!='/' && s[0]!='/')	/* don't insert extra slash if one is present */
315 		n->s[n->len++] = '/';
316 	memmove(n->s+n->len, s, i+1);
317 	n->len += i;
318 	if(isdotdot(s))
319 		cleancname(n);
320 	return n;
321 }
322 
323 void
chanfree(Chan * c)324 chanfree(Chan *c)
325 {
326 	c->flag = CFREE;
327 
328 	if(c->umh != nil){
329 		putmhead(c->umh);
330 		c->umh = nil;
331 	}
332 	if(c->umc != nil){
333 		cclose(c->umc);
334 		c->umc = nil;
335 	}
336 	if(c->mux != nil){
337 		muxclose(c->mux);
338 		c->mux = nil;
339 	}
340 	if(c->mchan != nil){
341 		cclose(c->mchan);
342 		c->mchan = nil;
343 	}
344 
345 	cnameclose(c->name);
346 
347 	lock(&chanalloc.lk);
348 	c->next = chanalloc.free;
349 	chanalloc.free = c;
350 	unlock(&chanalloc.lk);
351 }
352 
353 void
cclose(Chan * c)354 cclose(Chan *c)
355 {
356 	if(c->flag&CFREE)
357 		panic("cclose %p", getcallerpc(&c));
358 
359 	if(decref(&c->ref))
360 		return;
361 
362 	if(!waserror()){
363 		devtab[c->type]->close(c);
364 		poperror();
365 	}
366 	chanfree(c);
367 }
368 
369 /*
370  * Make sure we have the only copy of c.  (Copy on write.)
371  */
372 Chan*
cunique(Chan * c)373 cunique(Chan *c)
374 {
375 	Chan *nc;
376 
377 	if(c->ref.ref != 1) {
378 		nc = cclone(c);
379 		cclose(c);
380 		c = nc;
381 	}
382 
383 	return c;
384 }
385 
386 int
eqqid(Qid a,Qid b)387 eqqid(Qid a, Qid b)
388 {
389 	return a.path==b.path && a.vers==b.vers;
390 }
391 
392 int
eqchan(Chan * a,Chan * b,int pathonly)393 eqchan(Chan *a, Chan *b, int pathonly)
394 {
395 	if(a->qid.path != b->qid.path)
396 		return 0;
397 	if(!pathonly && a->qid.vers!=b->qid.vers)
398 		return 0;
399 	if(a->type != b->type)
400 		return 0;
401 	if(a->dev != b->dev)
402 		return 0;
403 	return 1;
404 }
405 
406 int
eqchantdqid(Chan * a,int type,int dev,Qid qid,int pathonly)407 eqchantdqid(Chan *a, int type, int dev, Qid qid, int pathonly)
408 {
409 	if(a->qid.path != qid.path)
410 		return 0;
411 	if(!pathonly && a->qid.vers!=qid.vers)
412 		return 0;
413 	if(a->type != type)
414 		return 0;
415 	if(a->dev != dev)
416 		return 0;
417 	return 1;
418 }
419 
420 Mhead*
newmhead(Chan * from)421 newmhead(Chan *from)
422 {
423 	Mhead *mh;
424 
425 	mh = smalloc(sizeof(Mhead));
426 	mh->ref.ref = 1;
427 	mh->from = from;
428 	incref(&from->ref);
429 
430 /*
431 	n = from->name->len;
432 	if(n >= sizeof(mh->fromname))
433 		n = sizeof(mh->fromname)-1;
434 	memmove(mh->fromname, from->name->s, n);
435 	mh->fromname[n] = 0;
436 */
437 	return mh;
438 }
439 
440 int
cmount(Chan ** newp,Chan * old,int flag,char * spec)441 cmount(Chan **newp, Chan *old, int flag, char *spec)
442 {
443 	Pgrp *pg;
444 	int order, flg;
445 	Mhead *m, **l, *mh;
446 	Mount *nm, *f, *um, **h;
447 	Chan *new;
448 
449 	if(QTDIR & (old->qid.type^(*newp)->qid.type))
450 		error(Emount);
451 
452 if(old->umh)print("cmount old extra umh\n");
453 
454 	order = flag&MORDER;
455 
456 	if((old->qid.type&QTDIR)==0 && order != MREPL)
457 		error(Emount);
458 
459 	new = *newp;
460 	mh = new->umh;
461 
462 	/*
463 	 * Not allowed to bind when the old directory
464 	 * is itself a union.  (Maybe it should be allowed, but I don't see
465 	 * what the semantics would be.)
466 	 *
467 	 * We need to check mh->mount->next to tell unions apart from
468 	 * simple mount points, so that things like
469 	 *	mount -c fd /root
470 	 *	bind -c /root /
471 	 * work.  The check of mount->mflag catches things like
472 	 *	mount fd /root
473 	 *	bind -c /root /
474 	 *
475 	 * This is far more complicated than it should be, but I don't
476 	 * see an easier way at the moment.		-rsc
477 	 */
478 	if((flag&MCREATE) && mh && mh->mount
479 	&& (mh->mount->next || !(mh->mount->mflag&MCREATE)))
480 		error(Emount);
481 
482 	pg = up->pgrp;
483 	wlock(&pg->ns);
484 
485 	l = &MOUNTH(pg, old->qid);
486 	for(m = *l; m; m = m->hash) {
487 		if(eqchan(m->from, old, 1))
488 			break;
489 		l = &m->hash;
490 	}
491 
492 	if(m == nil) {
493 		/*
494 		 *  nothing mounted here yet.  create a mount
495 		 *  head and add to the hash table.
496 		 */
497 		m = newmhead(old);
498 		*l = m;
499 
500 		/*
501 		 *  if this is a union mount, add the old
502 		 *  node to the mount chain.
503 		 */
504 		if(order != MREPL)
505 			m->mount = newmount(m, old, 0, 0);
506 	}
507 	wlock(&m->lock);
508 	if(waserror()){
509 		wunlock(&m->lock);
510 		nexterror();
511 	}
512 	wunlock(&pg->ns);
513 
514 	nm = newmount(m, new, flag, spec);
515 	if(mh != nil && mh->mount != nil) {
516 		/*
517 		 *  copy a union when binding it onto a directory
518 		 */
519 		flg = order;
520 		if(order == MREPL)
521 			flg = MAFTER;
522 		h = &nm->next;
523 		um = mh->mount;
524 		for(um = um->next; um; um = um->next) {
525 			f = newmount(m, um->to, flg, um->spec);
526 			*h = f;
527 			h = &f->next;
528 		}
529 	}
530 
531 	if(m->mount && order == MREPL) {
532 		mountfree(m->mount);
533 		m->mount = 0;
534 	}
535 
536 	if(flag & MCREATE)
537 		nm->mflag |= MCREATE;
538 
539 	if(m->mount && order == MAFTER) {
540 		for(f = m->mount; f->next; f = f->next)
541 			;
542 		f->next = nm;
543 	}
544 	else {
545 		for(f = nm; f->next; f = f->next)
546 			;
547 		f->next = m->mount;
548 		m->mount = nm;
549 	}
550 
551 	wunlock(&m->lock);
552 	poperror();
553 	return nm->mountid;
554 }
555 
556 void
cunmount(Chan * mnt,Chan * mounted)557 cunmount(Chan *mnt, Chan *mounted)
558 {
559 	Pgrp *pg;
560 	Mhead *m, **l;
561 	Mount *f, **p;
562 
563 	if(mnt->umh)	/* should not happen */
564 		print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
565 
566 	/*
567 	 * It _can_ happen that mounted->umh is non-nil,
568 	 * because mounted is the result of namec(Aopen)
569 	 * (see sysfile.c:/^sysunmount).
570 	 * If we open a union directory, it will have a umh.
571 	 * Although surprising, this is okay, since the
572 	 * cclose will take care of freeing the umh.
573 	 */
574 
575 	pg = up->pgrp;
576 	wlock(&pg->ns);
577 
578 	l = &MOUNTH(pg, mnt->qid);
579 	for(m = *l; m; m = m->hash) {
580 		if(eqchan(m->from, mnt, 1))
581 			break;
582 		l = &m->hash;
583 	}
584 
585 	if(m == 0) {
586 		wunlock(&pg->ns);
587 		error(Eunmount);
588 	}
589 
590 	wlock(&m->lock);
591 	if(mounted == 0) {
592 		*l = m->hash;
593 		wunlock(&pg->ns);
594 		mountfree(m->mount);
595 		m->mount = nil;
596 		cclose(m->from);
597 		wunlock(&m->lock);
598 		putmhead(m);
599 		return;
600 	}
601 
602 	p = &m->mount;
603 	for(f = *p; f; f = f->next) {
604 		/* BUG: Needs to be 2 pass */
605 		if(eqchan(f->to, mounted, 1) ||
606 		  (f->to->mchan && eqchan(f->to->mchan, mounted, 1))) {
607 			*p = f->next;
608 			f->next = 0;
609 			mountfree(f);
610 			if(m->mount == nil) {
611 				*l = m->hash;
612 				cclose(m->from);
613 				wunlock(&m->lock);
614 				wunlock(&pg->ns);
615 				putmhead(m);
616 				return;
617 			}
618 			wunlock(&m->lock);
619 			wunlock(&pg->ns);
620 			return;
621 		}
622 		p = &f->next;
623 	}
624 	wunlock(&m->lock);
625 	wunlock(&pg->ns);
626 	error(Eunion);
627 }
628 
629 Chan*
cclone(Chan * c)630 cclone(Chan *c)
631 {
632 	Chan *nc;
633 	Walkqid *wq;
634 
635 	wq = devtab[c->type]->walk(c, nil, nil, 0);
636 	if(wq == nil)
637 		error("clone failed");
638 	nc = wq->clone;
639 	free(wq);
640 	nc->name = c->name;
641 	if(c->name)
642 		incref(&c->name->ref);
643 	return nc;
644 }
645 
646 int
findmount(Chan ** cp,Mhead ** mp,int type,int dev,Qid qid)647 findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
648 {
649 	Pgrp *pg;
650 	Mhead *m;
651 
652 	pg = up->pgrp;
653 	rlock(&pg->ns);
654 	for(m = MOUNTH(pg, qid); m; m = m->hash){
655 		rlock(&m->lock);
656 if(m->from == nil){
657 	print("m %p m->from 0\n", m);
658 	runlock(&m->lock);
659 	continue;
660 }
661 		if(eqchantdqid(m->from, type, dev, qid, 1)) {
662 			runlock(&pg->ns);
663 			if(mp != nil){
664 				incref(&m->ref);
665 				if(*mp != nil)
666 					putmhead(*mp);
667 				*mp = m;
668 			}
669 			if(*cp != nil)
670 				cclose(*cp);
671 			incref(&m->mount->to->ref);
672 			*cp = m->mount->to;
673 			runlock(&m->lock);
674 			return 1;
675 		}
676 		runlock(&m->lock);
677 	}
678 
679 	runlock(&pg->ns);
680 	return 0;
681 }
682 
683 int
domount(Chan ** cp,Mhead ** mp)684 domount(Chan **cp, Mhead **mp)
685 {
686 	return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid);
687 }
688 
689 Chan*
undomount(Chan * c,Cname * name)690 undomount(Chan *c, Cname *name)
691 {
692 	Chan *nc;
693 	Pgrp *pg;
694 	Mount *t;
695 	Mhead **h, **he, *f;
696 
697 	pg = up->pgrp;
698 	rlock(&pg->ns);
699 	if(waserror()) {
700 		runlock(&pg->ns);
701 		nexterror();
702 	}
703 
704 	he = &pg->mnthash[MNTHASH];
705 	for(h = pg->mnthash; h < he; h++) {
706 		for(f = *h; f; f = f->hash) {
707 			if(strcmp(f->from->name->s, name->s) != 0)
708 				continue;
709 			for(t = f->mount; t; t = t->next) {
710 				if(eqchan(c, t->to, 1)) {
711 					/*
712 					 * We want to come out on the left hand side of the mount
713 					 * point using the element of the union that we entered on.
714 					 * To do this, find the element that has a from name of
715 					 * c->name->s.
716 					 */
717 					if(strcmp(t->head->from->name->s, name->s) != 0)
718 						continue;
719 					nc = t->head->from;
720 					incref(&nc->ref);
721 					cclose(c);
722 					c = nc;
723 					break;
724 				}
725 			}
726 		}
727 	}
728 	poperror();
729 	runlock(&pg->ns);
730 	return c;
731 }
732 
733 /*
734  * Either walks all the way or not at all.  No partial results in *cp.
735  * *nerror is the number of names to display in an error message.
736  */
737 static char Edoesnotexist[] = "does not exist";
738 int
walk(Chan ** cp,char ** names,int nnames,int nomount,int * nerror)739 walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
740 {
741 	int dev, dotdot, i, n, nhave, ntry, type;
742 	Chan *c, *nc;
743 	Cname *cname;
744 	Mount *f;
745 	Mhead *mh, *nmh;
746 	Walkqid *wq;
747 
748 	c = *cp;
749 	incref(&c->ref);
750 	cname = c->name;
751 	incref(&cname->ref);
752 	mh = nil;
753 
754 	/*
755 	 * While we haven't gotten all the way down the path:
756 	 *    1. step through a mount point, if any
757 	 *    2. send a walk request for initial dotdot or initial prefix without dotdot
758 	 *    3. move to the first mountpoint along the way.
759 	 *    4. repeat.
760 	 *
761 	 * An invariant is that each time through the loop, c is on the undomount
762 	 * side of the mount point, and c's name is cname.
763 	 */
764 	for(nhave=0; nhave<nnames; nhave+=n){
765 		if((c->qid.type&QTDIR)==0){
766 			if(nerror)
767 				*nerror = nhave;
768 			cnameclose(cname);
769 			cclose(c);
770 			strcpy(up->errstr, Enotdir);
771 			if(mh != nil)
772 {print("walk 1\n");
773 				putmhead(mh);
774 }
775 			return -1;
776 		}
777 		ntry = nnames - nhave;
778 		if(ntry > MAXWELEM)
779 			ntry = MAXWELEM;
780 		dotdot = 0;
781 		for(i=0; i<ntry; i++){
782 			if(isdotdot(names[nhave+i])){
783 				if(i==0) {
784 					dotdot = 1;
785 					ntry = 1;
786 				} else
787 					ntry = i;
788 				break;
789 			}
790 		}
791 
792 		if(!dotdot && !nomount)
793 			domount(&c, &mh);
794 
795 		type = c->type;
796 		dev = c->dev;
797 
798 		if((wq = devtab[type]->walk(c, nil, names+nhave, ntry)) == nil){
799 			/* try a union mount, if any */
800 			if(mh && !nomount){
801 				/*
802 				 * mh->mount == c, so start at mh->mount->next
803 				 */
804 				rlock(&mh->lock);
805 				for(f = mh->mount->next; f; f = f->next)
806 					if((wq = devtab[f->to->type]->walk(f->to, nil, names+nhave, ntry)) != nil)
807 						break;
808 				runlock(&mh->lock);
809 				if(f != nil){
810 					type = f->to->type;
811 					dev = f->to->dev;
812 				}
813 			}
814 			if(wq == nil){
815 				cclose(c);
816 				cnameclose(cname);
817 				if(nerror)
818 					*nerror = nhave+1;
819 				if(mh != nil)
820 					putmhead(mh);
821 				return -1;
822 			}
823 		}
824 
825 		nmh = nil;
826 		if(dotdot) {
827 			assert(wq->nqid == 1);
828 			assert(wq->clone != nil);
829 
830 			cname = addelem(cname, "..");
831 			nc = undomount(wq->clone, cname);
832 			n = 1;
833 		} else {
834 			nc = nil;
835 			if(!nomount)
836 				for(i=0; i<wq->nqid && i<ntry-1; i++)
837 					if(findmount(&nc, &nmh, type, dev, wq->qid[i]))
838 						break;
839 			if(nc == nil){	/* no mount points along path */
840 				if(wq->clone == nil){
841 					cclose(c);
842 					cnameclose(cname);
843 					if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
844 						if(nerror)
845 							*nerror = nhave+wq->nqid+1;
846 						strcpy(up->errstr, Edoesnotexist);
847 					}else{
848 						if(nerror)
849 							*nerror = nhave+wq->nqid;
850 						strcpy(up->errstr, Enotdir);
851 					}
852 					free(wq);
853 					if(mh != nil)
854 						putmhead(mh);
855 					return -1;
856 				}
857 				n = wq->nqid;
858 				nc = wq->clone;
859 			}else{		/* stopped early, at a mount point */
860 				if(wq->clone != nil){
861 					cclose(wq->clone);
862 					wq->clone = nil;
863 				}
864 				n = i+1;
865 			}
866 			for(i=0; i<n; i++)
867 				cname = addelem(cname, names[nhave+i]);
868 		}
869 		cclose(c);
870 		c = nc;
871 		putmhead(mh);
872 		mh = nmh;
873 		free(wq);
874 	}
875 
876 	putmhead(mh);
877 
878 	c = cunique(c);
879 
880 	if(c->umh != nil){	//BUG
881 		print("walk umh\n");
882 		putmhead(c->umh);
883 		c->umh = nil;
884 	}
885 
886 	cnameclose(c->name);
887 	c->name = cname;
888 
889 	cclose(*cp);
890 	*cp = c;
891 	if(nerror)
892 		*nerror = 0;
893 	return 0;
894 }
895 
896 /*
897  * c is a mounted non-creatable directory.  find a creatable one.
898  */
899 Chan*
createdir(Chan * c,Mhead * m)900 createdir(Chan *c, Mhead *m)
901 {
902 	Chan *nc;
903 	Mount *f;
904 
905 	rlock(&m->lock);
906 	if(waserror()) {
907 		runlock(&m->lock);
908 		nexterror();
909 	}
910 	for(f = m->mount; f; f = f->next) {
911 		if(f->mflag&MCREATE) {
912 			nc = cclone(f->to);
913 			runlock(&m->lock);
914 			poperror();
915 			cclose(c);
916 			return nc;
917 		}
918 	}
919 	error(Enocreate);
920 	return 0;
921 }
922 
923 void
saveregisters(void)924 saveregisters(void)
925 {
926 }
927 
928 /*
929  * In place, rewrite name to compress multiple /, eliminate ., and process ..
930  */
931 void
cleancname(Cname * n)932 cleancname(Cname *n)
933 {
934 	char *p;
935 
936 	if(n->s[0] == '#'){
937 		p = strchr(n->s, '/');
938 		if(p == nil)
939 			return;
940 		cleanname(p);
941 
942 		/*
943 		 * The correct name is #i rather than #i/,
944 		 * but the correct name of #/ is #/.
945 		 */
946 		if(strcmp(p, "/")==0 && n->s[1] != '/')
947 			*p = '\0';
948 	}else
949 		cleanname(n->s);
950 	n->len = strlen(n->s);
951 }
952 
953 static void
growparse(Elemlist * e)954 growparse(Elemlist *e)
955 {
956 	char **new;
957 	int *inew;
958 	enum { Delta = 8 };
959 
960 	if(e->nelems % Delta == 0){
961 		new = smalloc((e->nelems+Delta) * sizeof(char*));
962 		memmove(new, e->elems, e->nelems*sizeof(char*));
963 		free(e->elems);
964 		e->elems = new;
965 		inew = smalloc((e->nelems+Delta+1) * sizeof(int));
966 		memmove(inew, e->off, e->nelems*sizeof(int));
967 		free(e->off);
968 		e->off = inew;
969 	}
970 }
971 
972 /*
973  * The name is known to be valid.
974  * Copy the name so slashes can be overwritten.
975  * An empty string will set nelem=0.
976  * A path ending in / or /. or /.//./ etc. will have
977  * e.mustbedir = 1, so that we correctly
978  * reject, e.g., "/adm/users/." when /adm/users is a file
979  * rather than a directory.
980  */
981 static void
parsename(char * name,Elemlist * e)982 parsename(char *name, Elemlist *e)
983 {
984 	char *slash;
985 
986 	kstrdup(&e->name, name);
987 	name = e->name;
988 	e->nelems = 0;
989 	e->elems = nil;
990 	e->off = smalloc(sizeof(int));
991 	e->off[0] = skipslash(name) - name;
992 	for(;;){
993 		name = skipslash(name);
994 		if(*name=='\0'){
995 			e->mustbedir = 1;
996 			break;
997 		}
998 		growparse(e);
999 		e->elems[e->nelems++] = name;
1000 		slash = utfrune(name, '/');
1001 		if(slash == nil){
1002 			e->off[e->nelems] = name+strlen(name) - e->name;
1003 			e->mustbedir = 0;
1004 			break;
1005 		}
1006 		e->off[e->nelems] = slash - e->name;
1007 		*slash++ = '\0';
1008 		name = slash;
1009 	}
1010 }
1011 
1012 void*
mymemrchr(void * va,int c,long n)1013 mymemrchr(void *va, int c, long n)
1014 {
1015 	uchar *a, *e;
1016 
1017 	a = va;
1018 	for(e=a+n-1; e>a; e--)
1019 		if(*e == c)
1020 			return e;
1021 	return nil;
1022 }
1023 
1024 /*
1025  * Turn a name into a channel.
1026  * &name[0] is known to be a valid address.  It may be a kernel address.
1027  *
1028  * Opening with amode Aopen, Acreate, or Aremove guarantees
1029  * that the result will be the only reference to that particular fid.
1030  * This is necessary since we might pass the result to
1031  * devtab[]->remove().
1032  *
1033  * Opening Atodir, Amount, or Aaccess does not guarantee this.
1034  *
1035  * Opening Aaccess can, under certain conditions, return a
1036  * correct Chan* but with an incorrect Cname attached.
1037  * Since the functions that open Aaccess (sysstat, syswstat, sys_stat)
1038  * do not use the Cname*, this avoids an unnecessary clone.
1039  */
1040 Chan*
namec(char * aname,int amode,int omode,ulong perm)1041 namec(char *aname, int amode, int omode, ulong perm)
1042 {
1043 	int n, prefix, len, t, nomount, npath;
1044 	Chan *c, *cnew;
1045 	Cname *cname;
1046 	Elemlist e;
1047 	Rune r;
1048 	Mhead *m;
1049 	char *createerr, tmperrbuf[ERRMAX];
1050 	char *name;
1051 
1052 	name = aname;
1053 	if(name[0] == '\0')
1054 		error("empty file name");
1055 	validname(name, 1);
1056 
1057 	/*
1058 	 * Find the starting off point (the current slash, the root of
1059 	 * a device tree, or the current dot) as well as the name to
1060 	 * evaluate starting there.
1061 	 */
1062 	nomount = 0;
1063 	switch(name[0]){
1064 	case '/':
1065 		c = up->slash;
1066 		incref(&c->ref);
1067 		break;
1068 
1069 	case '#':
1070 		nomount = 1;
1071 		up->genbuf[0] = '\0';
1072 		n = 0;
1073 		while(*name!='\0' && (*name != '/' || n < 2)){
1074 			if(n >= sizeof(up->genbuf)-1)
1075 				error(Efilename);
1076 			up->genbuf[n++] = *name++;
1077 		}
1078 		up->genbuf[n] = '\0';
1079 		/*
1080 		 *  noattach is sandboxing.
1081 		 *
1082 		 *  the OK exceptions are:
1083 		 *	|  it only gives access to pipes you create
1084 		 *	d  this process's file descriptors
1085 		 *	e  this process's environment
1086 		 *  the iffy exceptions are:
1087 		 *	c  time and pid, but also cons and consctl
1088 		 *	p  control of your own processes (and unfortunately
1089 		 *	   any others left unprotected)
1090 		 */
1091 		n = chartorune(&r, up->genbuf+1)+1;
1092 		/* actually / is caught by parsing earlier */
1093 		if(utfrune("M", r))
1094 			error(Enoattach);
1095 		if(up->pgrp->noattach && utfrune("|decp", r)==nil)
1096 			error(Enoattach);
1097 		t = devno(r, 1);
1098 		if(t == -1)
1099 			error(Ebadsharp);
1100 		c = devtab[t]->attach(up->genbuf+n);
1101 		break;
1102 
1103 	default:
1104 		c = up->dot;
1105 		incref(&c->ref);
1106 		break;
1107 	}
1108 	prefix = name - aname;
1109 
1110 	e.name = nil;
1111 	e.elems = nil;
1112 	e.off = nil;
1113 	e.nelems = 0;
1114 	if(waserror()){
1115 		cclose(c);
1116 		free(e.name);
1117 		free(e.elems);
1118 		free(e.off);
1119 //dumpmount();
1120 		nexterror();
1121 	}
1122 
1123 	/*
1124 	 * Build a list of elements in the path.
1125 	 */
1126 	parsename(name, &e);
1127 
1128 	/*
1129 	 * On create, ....
1130 	 */
1131 	if(amode == Acreate){
1132 		/* perm must have DMDIR if last element is / or /. */
1133 		if(e.mustbedir && !(perm&DMDIR)){
1134 			npath = e.nelems;
1135 			strcpy(tmperrbuf, "create without DMDIR");
1136 			goto NameError;
1137 		}
1138 
1139 		/* don't try to walk the last path element just yet. */
1140 		if(e.nelems == 0)
1141 			error(Eexist);
1142 		e.nelems--;
1143 	}
1144 
1145 	if(walk(&c, e.elems, e.nelems, nomount, &npath) < 0){
1146 		if(npath < 0 || npath > e.nelems){
1147 			print("namec %s walk error npath=%d\n", aname, npath);
1148 			nexterror();
1149 		}
1150 		strcpy(tmperrbuf, up->errstr);
1151 	NameError:
1152 		len = prefix+e.off[npath];
1153 		if(len < ERRMAX/3 || (name=mymemrchr(aname, '/', len))==nil || name==aname)
1154 			snprint(up->genbuf, sizeof up->genbuf, "%.*s", len, aname);
1155 		else
1156 			snprint(up->genbuf, sizeof up->genbuf, "...%.*s", (int)(len-(name-aname)), name);
1157 		snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, tmperrbuf);
1158 		nexterror();
1159 	}
1160 
1161 	if(e.mustbedir && !(c->qid.type&QTDIR)){
1162 		npath = e.nelems;
1163 		strcpy(tmperrbuf, "not a directory");
1164 		goto NameError;
1165 	}
1166 
1167 	if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR)){
1168 		npath = e.nelems;
1169 		error("cannot exec directory");
1170 	}
1171 
1172 	switch(amode){
1173 	case Aaccess:
1174 		if(!nomount)
1175 			domount(&c, nil);
1176 		break;
1177 
1178 	case Abind:
1179 		m = nil;
1180 		if(!nomount)
1181 			domount(&c, &m);
1182 		if(c->umh != nil)
1183 			putmhead(c->umh);
1184 		c->umh = m;
1185 		break;
1186 
1187 	case Aremove:
1188 	case Aopen:
1189 	Open:
1190 		/* save the name; domount might change c */
1191 		cname = c->name;
1192 		incref(&cname->ref);
1193 		m = nil;
1194 		if(!nomount)
1195 			domount(&c, &m);
1196 
1197 		/* our own copy to open or remove */
1198 		c = cunique(c);
1199 
1200 		/* now it's our copy anyway, we can put the name back */
1201 		cnameclose(c->name);
1202 		c->name = cname;
1203 
1204 		switch(amode){
1205 		case Aremove:
1206 			putmhead(m);
1207 			break;
1208 
1209 		case Aopen:
1210 		case Acreate:
1211 if(c->umh != nil){
1212 	print("cunique umh Open\n");
1213 	putmhead(c->umh);
1214 	c->umh = nil;
1215 }
1216 
1217 			/* only save the mount head if it's a multiple element union */
1218 			if(m && m->mount && m->mount->next)
1219 				c->umh = m;
1220 			else
1221 				putmhead(m);
1222 
1223 			/* save registers else error() in open has wrong value of c saved */
1224 			saveregisters();
1225 
1226 			if(omode == OEXEC)
1227 				c->flag &= ~CCACHE;
1228 
1229 			c = devtab[c->type]->open(c, omode&~OCEXEC);
1230 
1231 			if(omode & OCEXEC)
1232 				c->flag |= CCEXEC;
1233 			if(omode & ORCLOSE)
1234 				c->flag |= CRCLOSE;
1235 			break;
1236 		}
1237 		break;
1238 
1239 	case Atodir:
1240 		/*
1241 		 * Directories (e.g. for cd) are left before the mount point,
1242 		 * so one may mount on / or . and see the effect.
1243 		 */
1244 		if(!(c->qid.type & QTDIR))
1245 			error(Enotdir);
1246 		break;
1247 
1248 	case Amount:
1249 		/*
1250 		 * When mounting on an already mounted upon directory,
1251 		 * one wants subsequent mounts to be attached to the
1252 		 * original directory, not the replacement.  Don't domount.
1253 		 */
1254 		break;
1255 
1256 	case Acreate:
1257 		/*
1258 		 * We've already walked all but the last element.
1259 		 * If the last exists, try to open it OTRUNC.
1260 		 * If omode&OEXCL is set, just give up.
1261 		 */
1262 		e.nelems++;
1263 		if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
1264 			if(omode&OEXCL)
1265 				error(Eexist);
1266 			omode |= OTRUNC;
1267 			goto Open;
1268 		}
1269 
1270 		/*
1271 		 * The semantics of the create(2) system call are that if the
1272 		 * file exists and can be written, it is to be opened with truncation.
1273 		 * On the other hand, the create(5) message fails if the file exists.
1274 		 * If we get two create(2) calls happening simultaneously,
1275 		 * they might both get here and send create(5) messages, but only
1276 		 * one of the messages will succeed.  To provide the expected create(2)
1277 		 * semantics, the call with the failed message needs to try the above
1278 		 * walk again, opening for truncation.  This correctly solves the
1279 		 * create/create race, in the sense that any observable outcome can
1280 		 * be explained as one happening before the other.
1281 		 * The create/create race is quite common.  For example, it happens
1282 		 * when two rc subshells simultaneously update the same
1283 		 * environment variable.
1284 		 *
1285 		 * The implementation still admits a create/create/remove race:
1286 		 * (A) walk to file, fails
1287 		 * (B) walk to file, fails
1288 		 * (A) create file, succeeds, returns
1289 		 * (B) create file, fails
1290 		 * (A) remove file, succeeds, returns
1291 		 * (B) walk to file, return failure.
1292 		 *
1293 		 * This is hardly as common as the create/create race, and is really
1294 		 * not too much worse than what might happen if (B) got a hold of a
1295 		 * file descriptor and then the file was removed -- either way (B) can't do
1296 		 * anything with the result of the create call.  So we don't care about this race.
1297 		 *
1298 		 * Applications that care about more fine-grained decision of the races
1299 		 * can use the OEXCL flag to get at the underlying create(5) semantics;
1300 		 * by default we provide the common case.
1301 		 *
1302 		 * We need to stay behind the mount point in case we
1303 		 * need to do the first walk again (should the create fail).
1304 		 *
1305 		 * We also need to cross the mount point and find the directory
1306 		 * in the union in which we should be creating.
1307 		 *
1308 		 * The channel staying behind is c, the one moving forward is cnew.
1309 		 */
1310 		m = nil;
1311 		cnew = nil;	/* is this assignment necessary? */
1312 		if(!waserror()){	/* try create */
1313 			if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
1314 				cnew = createdir(cnew, m);
1315 			else{
1316 				cnew = c;
1317 				incref(&cnew->ref);
1318 			}
1319 
1320 			/*
1321 			 * We need our own copy of the Chan because we're
1322 			 * about to send a create, which will move it.  Once we have
1323 			 * our own copy, we can fix the name, which might be wrong
1324 			 * if findmount gave us a new Chan.
1325 			 */
1326 			cnew = cunique(cnew);
1327 			cnameclose(cnew->name);
1328 			cnew->name = c->name;
1329 			incref(&cnew->name->ref);
1330 
1331 			devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
1332 			poperror();
1333 			if(omode & OCEXEC)
1334 				cnew->flag |= CCEXEC;
1335 			if(omode & ORCLOSE)
1336 				cnew->flag |= CRCLOSE;
1337 			if(m)
1338 				putmhead(m);
1339 			cclose(c);
1340 			c = cnew;
1341 			c->name = addelem(c->name, e.elems[e.nelems-1]);
1342 			break;
1343 		}else{		/* create failed */
1344 			cclose(cnew);
1345 			if(m)
1346 				putmhead(m);
1347 			if(omode & OEXCL)
1348 				nexterror();
1349 			/* save error */
1350 			createerr = up->errstr;
1351 			up->errstr = tmperrbuf;
1352 			/* note: we depend that walk does not error */
1353 			if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
1354 				up->errstr = createerr;
1355 				error(createerr);	/* report true error */
1356 			}
1357 			up->errstr = createerr;
1358 			omode |= OTRUNC;
1359 			goto Open;
1360 		}
1361 		panic("namec: not reached");
1362 
1363 	default:
1364 		panic("unknown namec access %d\n", amode);
1365 	}
1366 
1367 	poperror();
1368 
1369 	/* place final element in genbuf for e.g. exec */
1370 	if(e.nelems > 0)
1371 		kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf);
1372 	else
1373 		kstrcpy(up->genbuf, ".", sizeof up->genbuf);
1374 	free(e.name);
1375 	free(e.elems);
1376 	free(e.off);
1377 
1378 	return c;
1379 }
1380 
1381 /*
1382  * name is valid. skip leading / and ./ as much as possible
1383  */
1384 char*
skipslash(char * name)1385 skipslash(char *name)
1386 {
1387 	while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
1388 		name++;
1389 	return name;
1390 }
1391 
1392 char isfrog[256]={
1393 	/*NUL*/	1, 1, 1, 1, 1, 1, 1, 1,	/* 0 */
1394 	/*BKS*/	1, 1, 1, 1, 1, 1, 1, 1, /* 0x08 */
1395 	/*DLE*/	1, 1, 1, 1, 1, 1, 1, 1, /* 0x10 */
1396 	/*CAN*/	1, 1, 1, 1, 1, 1, 1, 1, /* 0x18 */
1397 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
1398 		0, 0, 0, 0, 0, 0, 0, 1, /* 0x28 (1 is '/', 0x2F) */
1399 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 */
1400 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x38 */
1401 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 */
1402 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x48 */
1403 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
1404 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x58 */
1405 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 */
1406 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x68 */
1407 		0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
1408 		0, 0, 0, 0, 0, 0, 0, 1, /* 0x78 (1 is DEL, 0x7F) */
1409 };
1410 
1411 /*
1412  * Check that the name
1413  *  a) is in valid memory.
1414  *  b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
1415  *  c) contains no frogs.
1416  * The first byte is known to be addressible by the requester, so the
1417  * routine works for kernel and user memory both.
1418  * The parameter slashok flags whether a slash character is an error
1419  * or a valid character.
1420  */
1421 void
validname(char * aname,int slashok)1422 validname(char *aname, int slashok)
1423 {
1424 	char *ename, *name;
1425 	int c;
1426 	Rune r;
1427 
1428 	name = aname;
1429 /*
1430 	if(((ulong)name & KZERO) != KZERO) {
1431 		p = name;
1432 		t = BY2PG-((ulong)p&(BY2PG-1));
1433 		while((ename=vmemchr(p, 0, t)) == nil) {
1434 			p += t;
1435 			t = BY2PG;
1436 		}
1437 	}else
1438 */
1439 		ename = memchr(name, 0, (1<<16));
1440 
1441 	if(ename==nil || ename-name>=(1<<16))
1442 		error("name too long");
1443 
1444 	while(*name){
1445 		/* all characters above '~' are ok */
1446 		c = *(uchar*)name;
1447 		if(c >= Runeself)
1448 			name += chartorune(&r, name);
1449 		else{
1450 			if(isfrog[c])
1451 				if(!slashok || c!='/'){
1452 					snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
1453 					error(up->genbuf);
1454 			}
1455 			name++;
1456 		}
1457 	}
1458 }
1459 
1460 void
isdir(Chan * c)1461 isdir(Chan *c)
1462 {
1463 	if(c->qid.type & QTDIR)
1464 		return;
1465 	error(Enotdir);
1466 }
1467 
1468 /*
1469  * This is necessary because there are many
1470  * pointers to the top of a given mount list:
1471  *
1472  *	- the mhead in the namespace hash table
1473  *	- the mhead in chans returned from findmount:
1474  *	  used in namec and then by unionread.
1475  *	- the mhead in chans returned from createdir:
1476  *	  used in the open/create race protect, which is gone.
1477  *
1478  * The RWlock in the Mhead protects the mount list it contains.
1479  * The mount list is deleted when we cunmount.
1480  * The RWlock ensures that nothing is using the mount list at that time.
1481  *
1482  * It is okay to replace c->mh with whatever you want as
1483  * long as you are sure you have a unique reference to it.
1484  *
1485  * This comment might belong somewhere else.
1486  */
1487 void
putmhead(Mhead * m)1488 putmhead(Mhead *m)
1489 {
1490 	if(m && decref(&m->ref) == 0){
1491 		m->mount = (Mount*)0xCafeBeef;
1492 		free(m);
1493 	}
1494 }
1495