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