]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/chan.c
alarm: run checkalarms() only on cpu0 (from eriks alarm-once patch)
[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         ulong nqueued;
480         ulong 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                 if(!waserror()){
540                         kproc("closeproc", closeproc, nil);
541                         poperror();
542                 }
543                 up->dot = c;
544         }else
545                 wakeup(&clunkq.r);
546 }
547
548 void
549 cclose(Chan *c)
550 {
551         if(c == nil || c->ref < 1 || c->flag&CFREE)
552                 panic("cclose %#p", getcallerpc(&c));
553
554         DBG("cclose %p name=%s ref=%ld\n", c, chanpath(c), c->ref);
555
556         if(decref(c))
557                 return;
558
559         if(devtab[c->type]->dc == L'M')
560         if((c->flag&(CRCLOSE|CCACHE)) == CCACHE)
561         if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0)
562         if((clunkq.nqueued - clunkq.nclosed) < 64){
563                 closechanq(c);
564                 return;
565         }
566
567         if(!waserror()){
568                 devtab[c->type]->close(c);
569                 poperror();
570         }
571         chanfree(c);
572 }
573
574 void
575 ccloseq(Chan *c)
576 {
577         if(c == nil || c->ref < 1 || c->flag&CFREE)
578                 panic("ccloseq %#p", getcallerpc(&c));
579
580         DBG("ccloseq %p name=%s ref=%ld\n", c, chanpath(c), c->ref);
581
582         if(decref(c))
583                 return;
584
585         closechanq(c);
586 }
587
588 /*
589  * Make sure we have the only copy of c.  (Copy on write.)
590  */
591 Chan*
592 cunique(Chan *c)
593 {
594         Chan *nc;
595
596         if(c->ref != 1){
597                 nc = cclone(c);
598                 cclose(c);
599                 c = nc;
600         }
601
602         return c;
603 }
604
605 int
606 eqqid(Qid a, Qid b)
607 {
608         return a.path==b.path && a.vers==b.vers;
609 }
610
611 int
612 eqchan(Chan *a, Chan *b, int skipvers)
613 {
614         if(a->qid.path != b->qid.path)
615                 return 0;
616         if(!skipvers && a->qid.vers!=b->qid.vers)
617                 return 0;
618         if(a->type != b->type)
619                 return 0;
620         if(a->dev != b->dev)
621                 return 0;
622         return 1;
623 }
624
625 int
626 eqchantdqid(Chan *a, int type, int dev, Qid qid, int skipvers)
627 {
628         if(a->qid.path != qid.path)
629                 return 0;
630         if(!skipvers && a->qid.vers!=qid.vers)
631                 return 0;
632         if(a->type != type)
633                 return 0;
634         if(a->dev != dev)
635                 return 0;
636         return 1;
637 }
638
639 Mhead*
640 newmhead(Chan *from)
641 {
642         Mhead *mh;
643
644         mh = smalloc(sizeof(Mhead));
645         mh->ref = 1;
646         mh->from = from;
647         incref(from);
648         return mh;
649 }
650
651 int
652 cmount(Chan **newp, Chan *old, int flag, char *spec)
653 {
654         int order, flg;
655         Chan *new;
656         Mhead *m, **l, *mh;
657         Mount *nm, *f, *um, **h;
658         Pgrp *pg;
659
660         if(QTDIR & (old->qid.type^(*newp)->qid.type))
661                 error(Emount);
662
663         if(old->umh)
664                 print("cmount: unexpected umh, caller %#p\n", getcallerpc(&newp));
665
666         order = flag&MORDER;
667
668         if((old->qid.type&QTDIR)==0 && order != MREPL)
669                 error(Emount);
670
671         new = *newp;
672         mh = new->umh;
673
674         /*
675          * Not allowed to bind when the old directory is itself a union. 
676          * (Maybe it should be allowed, but I don't see what the semantics
677          * would be.)
678          *
679          * We need to check mh->mount->next to tell unions apart from
680          * simple mount points, so that things like
681          *      mount -c fd /root
682          *      bind -c /root /
683          * work.  
684          * 
685          * The check of mount->mflag allows things like
686          *      mount fd /root
687          *      bind -c /root /
688          * 
689          * This is far more complicated than it should be, but I don't
690          * see an easier way at the moment.
691          */
692         if((flag&MCREATE) && mh && mh->mount
693         && (mh->mount->next || !(mh->mount->mflag&MCREATE)))
694                 error(Emount);
695
696         pg = up->pgrp;
697         wlock(&pg->ns);
698
699         l = &MOUNTH(pg, old->qid);
700         for(m = *l; m; m = m->hash){
701                 if(eqchan(m->from, old, 1))
702                         break;
703                 l = &m->hash;
704         }
705
706         if(m == nil){
707                 /*
708                  *  nothing mounted here yet.  create a mount
709                  *  head and add to the hash table.
710                  */
711                 m = newmhead(old);
712                 *l = m;
713
714                 /*
715                  *  if this is a union mount, add the old
716                  *  node to the mount chain.
717                  */
718                 if(order != MREPL)
719                         m->mount = newmount(m, old, 0, 0);
720         }
721         wlock(&m->lock);
722         if(waserror()){
723                 wunlock(&m->lock);
724                 nexterror();
725         }
726         wunlock(&pg->ns);
727
728         nm = newmount(m, new, flag, spec);
729         if(mh != nil && mh->mount != nil){
730                 /*
731                  *  copy a union when binding it onto a directory
732                  */
733                 flg = order;
734                 if(order == MREPL)
735                         flg = MAFTER;
736                 h = &nm->next;
737                 um = mh->mount;
738                 for(um = um->next; um; um = um->next){
739                         f = newmount(m, um->to, flg, um->spec);
740                         *h = f;
741                         h = &f->next;
742                 }
743         }
744
745         if(m->mount && order == MREPL){
746                 mountfree(m->mount);
747                 m->mount = 0;
748         }
749
750         if(flag & MCREATE)
751                 nm->mflag |= MCREATE;
752
753         if(m->mount && order == MAFTER){
754                 for(f = m->mount; f->next; f = f->next)
755                         ;
756                 f->next = nm;
757         }else{
758                 for(f = nm; f->next; f = f->next)
759                         ;
760                 f->next = m->mount;
761                 m->mount = nm;
762         }
763
764         wunlock(&m->lock);
765         poperror();
766         return nm->mountid;
767 }
768
769 void
770 cunmount(Chan *mnt, Chan *mounted)
771 {
772         Pgrp *pg;
773         Mhead *m, **l;
774         Mount *f, **p;
775
776         if(mnt->umh)    /* should not happen */
777                 print("cunmount newp extra umh %p has %p\n", mnt, mnt->umh);
778
779         /*
780          * It _can_ happen that mounted->umh is non-nil, 
781          * because mounted is the result of namec(Aopen)
782          * (see sysfile.c:/^sysunmount).
783          * If we open a union directory, it will have a umh.
784          * Although surprising, this is okay, since the
785          * cclose will take care of freeing the umh.
786          */
787
788         pg = up->pgrp;
789         wlock(&pg->ns);
790
791         l = &MOUNTH(pg, mnt->qid);
792         for(m = *l; m; m = m->hash){
793                 if(eqchan(m->from, mnt, 1))
794                         break;
795                 l = &m->hash;
796         }
797
798         if(m == 0){
799                 wunlock(&pg->ns);
800                 error(Eunmount);
801         }
802
803         wlock(&m->lock);
804         if(mounted == 0){
805                 *l = m->hash;
806                 wunlock(&pg->ns);
807                 mountfree(m->mount);
808                 m->mount = nil;
809                 cclose(m->from);
810                 wunlock(&m->lock);
811                 putmhead(m);
812                 return;
813         }
814
815         p = &m->mount;
816         for(f = *p; f; f = f->next){
817                 /* BUG: Needs to be 2 pass */
818                 if(eqchan(f->to, mounted, 1) ||
819                   (f->to->mchan && eqchan(f->to->mchan, mounted, 1))){
820                         *p = f->next;
821                         f->next = 0;
822                         mountfree(f);
823                         if(m->mount == nil){
824                                 *l = m->hash;
825                                 cclose(m->from);
826                                 wunlock(&m->lock);
827                                 wunlock(&pg->ns);
828                                 putmhead(m);
829                                 return;
830                         }
831                         wunlock(&m->lock);
832                         wunlock(&pg->ns);
833                         return;
834                 }
835                 p = &f->next;
836         }
837         wunlock(&m->lock);
838         wunlock(&pg->ns);
839         error(Eunion);
840 }
841
842 Chan*
843 cclone(Chan *c)
844 {
845         Chan *nc;
846         Walkqid *wq;
847
848         if(c == nil || c->ref < 1 || c->flag&CFREE)
849                 panic("cclone: %#p", getcallerpc(&c));
850         wq = devtab[c->type]->walk(c, nil, nil, 0);
851         if(wq == nil)
852                 error("clone failed");
853         nc = wq->clone;
854         free(wq);
855         nc->path = c->path;
856         if(c->path)
857                 incref(c->path);
858         return nc;
859 }
860
861 /* also used by sysfile.c:/^mountfix */
862 int
863 findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid)
864 {
865         Pgrp *pg;
866         Mhead *m;
867
868         pg = up->pgrp;
869         rlock(&pg->ns);
870         for(m = MOUNTH(pg, qid); m; m = m->hash){
871                 rlock(&m->lock);
872                 if(m->from == nil){
873                         print("m %p m->from 0\n", m);
874                         runlock(&m->lock);
875                         continue;
876                 }
877                 if(eqchantdqid(m->from, type, dev, qid, 1)){
878                         runlock(&pg->ns);
879                         if(mp != nil){
880                                 incref(m);
881                                 if(*mp != nil)
882                                         putmhead(*mp);
883                                 *mp = m;
884                         }
885                         if(*cp != nil)
886                                 cclose(*cp);
887                         incref(m->mount->to);
888                         *cp = m->mount->to;
889                         runlock(&m->lock);
890                         return 1;
891                 }
892                 runlock(&m->lock);
893         }
894
895         runlock(&pg->ns);
896         return 0;
897 }
898
899 /*
900  * Calls findmount but also updates path.
901  */
902 static int
903 domount(Chan **cp, Mhead **mp, Path **path)
904 {
905         Chan **lc;
906         Path *p;
907
908         if(findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid) == 0)
909                 return 0;
910
911         if(path){
912                 p = *path;
913                 p = uniquepath(p);
914                 if(p->mlen <= 0)
915                         print("domount: path %s has mlen==%d\n", p->s, p->mlen);
916                 else{
917                         lc = &p->mtpt[p->mlen-1];
918 DBG("domount %p %s => add %p (was %p)\n", p, p->s, (*mp)->from, p->mtpt[p->mlen-1]);
919                         incref((*mp)->from);
920                         if(*lc)
921                                 cclose(*lc);
922                         *lc = (*mp)->from;
923                 }
924                 *path = p;
925         }
926         return 1;
927 }
928
929 /*
930  * If c is the right-hand-side of a mount point, returns the left hand side.
931  * Changes name to reflect the fact that we've uncrossed the mountpoint,
932  * so name had better be ours to change!
933  */
934 static Chan*
935 undomount(Chan *c, Path *path)
936 {
937         Chan *nc;
938
939         if(path->ref != 1 || path->mlen == 0)
940                 print("undomount: path %s ref %ld mlen %d caller %#p\n",
941                         path->s, path->ref, path->mlen, getcallerpc(&c));
942
943         if(path->mlen>0 && (nc=path->mtpt[path->mlen-1]) != nil){
944 DBG("undomount %p %s => remove %p\n", path, path->s, nc);
945                 cclose(c);
946                 path->mtpt[path->mlen-1] = nil;
947                 c = nc;
948         }
949         return c;
950 }
951
952 /*
953  * Call dev walk but catch errors.
954  */
955 static Walkqid*
956 ewalk(Chan *c, Chan *nc, char **name, int nname)
957 {
958         Walkqid *wq;
959
960         if(waserror())
961                 return nil;
962         wq = devtab[c->type]->walk(c, nc, name, nname);
963         poperror();
964         return wq;
965 }
966
967 /*
968  * Either walks all the way or not at all.  No partial results in *cp.
969  * *nerror is the number of names to display in an error message.
970  */
971 static char Edoesnotexist[] = "does not exist";
972 int
973 walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
974 {
975         int dev, didmount, dotdot, i, n, nhave, ntry, type;
976         Chan *c, *nc, *mtpt;
977         Path *path;
978         Mhead *mh, *nmh;
979         Mount *f;
980         Walkqid *wq;
981
982         c = *cp;
983         incref(c);
984         path = c->path;
985         incref(path);
986         mh = nil;
987
988         /*
989          * While we haven't gotten all the way down the path:
990          *    1. step through a mount point, if any
991          *    2. send a walk request for initial dotdot or initial prefix without dotdot
992          *    3. move to the first mountpoint along the way.
993          *    4. repeat.
994          *
995          * Each time through the loop:
996          *
997          *      If didmount==0, c is on the undomount side of the mount point.
998          *      If didmount==1, c is on the domount side of the mount point.
999          *      Either way, c's full path is path.
1000          */
1001         didmount = 0;
1002         for(nhave=0; nhave<nnames; nhave+=n){
1003                 if((c->qid.type&QTDIR)==0){
1004                         if(nerror)
1005                                 *nerror = nhave;
1006                         pathclose(path);
1007                         cclose(c);
1008                         kstrcpy(up->errstr, Enotdir, ERRMAX);
1009                         if(mh != nil)
1010                                 putmhead(mh);
1011                         return -1;
1012                 }
1013                 ntry = nnames - nhave;
1014                 if(ntry > MAXWELEM)
1015                         ntry = MAXWELEM;
1016                 dotdot = 0;
1017                 for(i=0; i<ntry; i++){
1018                         if(isdotdot(names[nhave+i])){
1019                                 if(i==0){
1020                                         dotdot = 1;
1021                                         ntry = 1;
1022                                 }else
1023                                         ntry = i;
1024                                 break;
1025                         }
1026                 }
1027
1028                 if(!dotdot && !nomount && !didmount)
1029                         domount(&c, &mh, &path);
1030                 
1031                 type = c->type;
1032                 dev = c->dev;
1033
1034                 if((wq = ewalk(c, nil, names+nhave, ntry)) == nil){
1035                         /* try a union mount, if any */
1036                         if(mh && !nomount){
1037                                 /*
1038                                  * mh->mount->to == c, so start at mh->mount->next
1039                                  */
1040                                 rlock(&mh->lock);
1041                                 if((f = mh->mount) != nil)
1042                                         f = f->next;
1043                                 for(; f != nil; f = f->next)
1044                                         if((wq = ewalk(f->to, nil, names+nhave, ntry)) != nil){
1045                                                 type = f->to->type;
1046                                                 dev = f->to->dev;
1047                                                 break;
1048                                         }
1049                                 runlock(&mh->lock);
1050                         }
1051                         if(wq == nil){
1052                                 cclose(c);
1053                                 pathclose(path);
1054                                 if(nerror)
1055                                         *nerror = nhave+1;
1056                                 if(mh != nil)
1057                                         putmhead(mh);
1058                                 return -1;
1059                         }
1060                 }
1061
1062                 didmount = 0;
1063                 if(dotdot){
1064                         assert(wq->nqid == 1);
1065                         assert(wq->clone != nil);
1066
1067                         path = addelem(path, "..", nil);
1068                         nc = undomount(wq->clone, path);
1069                         nmh = nil;
1070                         n = 1;
1071                 }else{
1072                         nc = nil;
1073                         nmh = nil;
1074                         if(!nomount){
1075                                 for(i=0; i<wq->nqid && i<ntry-1; i++){
1076                                         if(findmount(&nc, &nmh, type, dev, wq->qid[i])){
1077                                                 didmount = 1;
1078                                                 break;
1079                                         }
1080                                 }
1081                         }
1082                         if(nc == nil){  /* no mount points along path */
1083                                 if(wq->clone == nil){
1084                                         cclose(c);
1085                                         pathclose(path);
1086                                         if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
1087                                                 if(nerror)
1088                                                         *nerror = nhave+wq->nqid+1;
1089                                                 kstrcpy(up->errstr, Edoesnotexist, ERRMAX);
1090                                         }else{
1091                                                 if(nerror)
1092                                                         *nerror = nhave+wq->nqid;
1093                                                 kstrcpy(up->errstr, Enotdir, ERRMAX);
1094                                         }
1095                                         free(wq);
1096                                         if(mh != nil)
1097                                                 putmhead(mh);
1098                                         return -1;
1099                                 }
1100                                 n = wq->nqid;
1101                                 nc = wq->clone;
1102                         }else{          /* stopped early, at a mount point */
1103                                 didmount = 1;
1104                                 if(wq->clone != nil){
1105                                         cclose(wq->clone);
1106                                         wq->clone = nil;
1107                                 }
1108                                 n = i+1;
1109                         }
1110                         for(i=0; i<n; i++){
1111                                 mtpt = nil;
1112                                 if(i==n-1 && nmh)
1113                                         mtpt = nmh->from;
1114                                 path = addelem(path, names[nhave+i], mtpt);
1115                         }
1116                 }
1117                 cclose(c);
1118                 c = nc;
1119                 putmhead(mh);
1120                 mh = nmh;
1121                 free(wq);
1122         }
1123
1124         putmhead(mh);
1125
1126         c = cunique(c);
1127
1128         if(c->umh != nil){      //BUG
1129                 print("walk umh\n");
1130                 putmhead(c->umh);
1131                 c->umh = nil;
1132         }
1133
1134         pathclose(c->path);
1135         c->path = path;
1136
1137         cclose(*cp);
1138         *cp = c;
1139         if(nerror)
1140                 *nerror = nhave;
1141         return 0;
1142 }
1143
1144 /*
1145  * c is a mounted non-creatable directory.  find a creatable one.
1146  */
1147 Chan*
1148 createdir(Chan *c, Mhead *m)
1149 {
1150         Chan *nc;
1151         Mount *f;
1152
1153         rlock(&m->lock);
1154         if(waserror()){
1155                 runlock(&m->lock);
1156                 nexterror();
1157         }
1158         for(f = m->mount; f; f = f->next){
1159                 if(f->mflag&MCREATE){
1160                         nc = cclone(f->to);
1161                         runlock(&m->lock);
1162                         poperror();
1163                         cclose(c);
1164                         return nc;
1165                 }
1166         }
1167         error(Enocreate);
1168         return 0;
1169 }
1170
1171 void
1172 saveregisters(void)
1173 {
1174 }
1175
1176 static void
1177 growparse(Elemlist *e)
1178 {
1179         char **new;
1180         int *inew;
1181         enum { Delta = 8 };
1182
1183         if(e->nelems % Delta == 0){
1184                 new = smalloc((e->nelems+Delta) * sizeof(char*));
1185                 memmove(new, e->elems, e->nelems*sizeof(char*));
1186                 free(e->elems);
1187                 e->elems = new;
1188                 inew = smalloc((e->nelems+Delta+1) * sizeof(int));
1189                 memmove(inew, e->off, (e->nelems+1)*sizeof(int));
1190                 free(e->off);
1191                 e->off = inew;
1192         }
1193 }
1194
1195 /*
1196  * The name is known to be valid.
1197  * Copy the name so slashes can be overwritten.
1198  * An empty string will set nelem=0.
1199  * A path ending in / or /. or /.//./ etc. will have
1200  * e.mustbedir = 1, so that we correctly
1201  * reject, e.g., "/adm/users/." when /adm/users is a file
1202  * rather than a directory.
1203  */
1204 static void
1205 parsename(char *aname, Elemlist *e)
1206 {
1207         char *name, *slash;
1208
1209         kstrdup(&e->name, aname);
1210         name = e->name;
1211         e->nelems = 0;
1212         e->elems = nil;
1213         e->off = smalloc(sizeof(int));
1214         e->off[0] = skipslash(name) - name;
1215         for(;;){
1216                 name = skipslash(name);
1217                 if(*name == '\0'){
1218                         e->off[e->nelems] = name+strlen(name) - e->name;
1219                         e->mustbedir = 1;
1220                         break;
1221                 }
1222                 growparse(e);
1223                 e->elems[e->nelems++] = name;
1224                 slash = utfrune(name, '/');
1225                 if(slash == nil){
1226                         e->off[e->nelems] = name+strlen(name) - e->name;
1227                         e->mustbedir = 0;
1228                         break;
1229                 }
1230                 e->off[e->nelems] = slash - e->name;
1231                 *slash++ = '\0';
1232                 name = slash;
1233         }
1234         
1235         if(0 && chandebug){
1236                 int i;
1237                 
1238                 print("parsename %s:", e->name);
1239                 for(i=0; i<=e->nelems; i++)
1240                         print(" %d", e->off[i]);
1241                 print("\n");
1242         }
1243 }
1244
1245 void*
1246 memrchr(void *va, int c, long n)
1247 {
1248         uchar *a, *e;
1249
1250         a = va;
1251         for(e=a+n-1; e>a; e--)
1252                 if(*e == c)
1253                         return e;
1254         return nil;
1255 }
1256
1257 void
1258 namelenerror(char *aname, int len, char *err)
1259 {
1260         char *ename, *name, *next;
1261         int i, errlen;
1262
1263         /*
1264          * If the name is short enough, just use the whole thing.
1265          */
1266         errlen = strlen(err);
1267         if(len < ERRMAX/3 || len+errlen < 2*ERRMAX/3)
1268                 snprint(up->genbuf, sizeof up->genbuf, "%.*s", 
1269                         utfnlen(aname, len), aname);
1270         else{
1271                 /*
1272                  * Print a suffix of the name, but try to get a little info.
1273                  */
1274                 ename = aname+len;
1275                 next = ename;
1276                 do{
1277                         name = next;
1278                         next = memrchr(aname, '/', name-aname);
1279                         if(next == nil)
1280                                 next = aname;
1281                         len = ename-next;
1282                 }while(len < ERRMAX/3 || len + errlen < 2*ERRMAX/3);
1283
1284                 /*
1285                  * If the name is ridiculously long, chop it.
1286                  */
1287                 if(name == ename){
1288                         name = ename-ERRMAX/4;
1289                         if(name <= aname)
1290                                 panic("bad math in namelenerror");
1291                         /* walk out of current UTF sequence */
1292                         for(i=0; (*name&0xC0)==0x80 && i<UTFmax; i++)
1293                                 name++;
1294                 }
1295                 snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
1296                         utfnlen(name, ename-name), name);
1297         }                               
1298         snprint(up->errstr, ERRMAX, "%#q %s", up->genbuf, err);
1299         nexterror();
1300 }
1301
1302 void
1303 nameerror(char *name, char *err)
1304 {
1305         namelenerror(name, strlen(name), err);
1306 }
1307
1308 /*
1309  * Turn a name into a channel.
1310  * &name[0] is known to be a valid address.  It may be a kernel address.
1311  *
1312  * Opening with amode Aopen, Acreate, Aremove, or Aaccess guarantees
1313  * that the result will be the only reference to that particular fid.
1314  * This is necessary since we might pass the result to
1315  * devtab[]->remove().
1316  *
1317  * Opening Atodir or Amount does not guarantee this.
1318  *
1319  * Under certain circumstances, opening Aaccess will cause
1320  * an unnecessary clone in order to get a cunique Chan so it
1321  * can attach the correct name.  Sysstat and sys_stat need the
1322  * correct name so they can rewrite the stat info.
1323  */
1324 Chan*
1325 namec(char *aname, int amode, int omode, ulong perm)
1326 {
1327         int len, n, t, nomount;
1328         Chan *c, *cnew;
1329         Path *path;
1330         Elemlist e;
1331         Rune r;
1332         Mhead *m;
1333         char *createerr, tmperrbuf[ERRMAX];
1334         char *name;
1335
1336         if(aname[0] == '\0')
1337                 error("empty file name");
1338         aname = validnamedup(aname, 1);
1339         if(waserror()){
1340                 free(aname);
1341                 nexterror();
1342         }
1343         DBG("namec %s %d %d\n", aname, amode, omode);
1344         name = aname;
1345
1346         /*
1347          * Find the starting off point (the current slash, the root of
1348          * a device tree, or the current dot) as well as the name to
1349          * evaluate starting there.
1350          */
1351         nomount = 0;
1352         switch(name[0]){
1353         case '/':
1354                 c = up->slash;
1355                 incref(c);
1356                 break;
1357         
1358         case '#':
1359                 nomount = 1;
1360                 up->genbuf[0] = '\0';
1361                 n = 0;
1362                 while(*name != '\0' && (*name != '/' || n < 2)){
1363                         if(n >= sizeof(up->genbuf)-1)
1364                                 error(Efilename);
1365                         up->genbuf[n++] = *name++;
1366                 }
1367                 up->genbuf[n] = '\0';
1368                 /*
1369                  *  noattach is sandboxing.
1370                  *
1371                  *  the OK exceptions are:
1372                  *      |  it only gives access to pipes you create
1373                  *      d  this process's file descriptors
1374                  *      e  this process's environment
1375                  *  the iffy exceptions are:
1376                  *      c  time and pid, but also cons and consctl
1377                  *      p  control of your own processes (and unfortunately
1378                  *         any others left unprotected)
1379                  */
1380                 n = chartorune(&r, up->genbuf+1)+1;
1381                 /* actually / is caught by parsing earlier */
1382                 if(utfrune("M", r))
1383                         error(Enoattach);
1384                 if(up->pgrp->noattach && utfrune("|decp", r)==nil)
1385                         error(Enoattach);
1386                 t = devno(r, 1);
1387                 if(t == -1)
1388                         error(Ebadsharp);
1389                 c = devtab[t]->attach(up->genbuf+n);
1390                 break;
1391
1392         default:
1393                 c = up->dot;
1394                 incref(c);
1395                 break;
1396         }
1397
1398         e.aname = aname;
1399         e.prefix = name - aname;
1400         e.name = nil;
1401         e.elems = nil;
1402         e.off = nil;
1403         e.nelems = 0;
1404         e.nerror = 0;
1405         if(waserror()){
1406                 cclose(c);
1407                 free(e.name);
1408                 free(e.elems);
1409                 /*
1410                  * Prepare nice error, showing first e.nerror elements of name.
1411                  */
1412                 if(e.nerror == 0)
1413                         nexterror();
1414                 strcpy(tmperrbuf, up->errstr);
1415                 if(e.off[e.nerror]==0)
1416                         print("nerror=%d but off=%d\n",
1417                                 e.nerror, e.off[e.nerror]);
1418                 if(0 && chandebug)
1419                         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]);
1420                 len = e.prefix+e.off[e.nerror];
1421                 free(e.off);
1422                 namelenerror(aname, len, tmperrbuf);
1423         }
1424
1425         /*
1426          * Build a list of elements in the name.
1427          */
1428         parsename(name, &e);
1429
1430         /*
1431          * On create, ....
1432          */
1433         if(amode == Acreate){
1434                 /* perm must have DMDIR if last element is / or /. */
1435                 if(e.mustbedir && !(perm&DMDIR)){
1436                         e.nerror = e.nelems;
1437                         error("create without DMDIR");
1438                 }
1439
1440                 /* don't try to walk the last path element just yet. */
1441                 if(e.nelems == 0)
1442                         error(Eexist);
1443                 e.nelems--;
1444         }
1445
1446         if(walk(&c, e.elems, e.nelems, nomount, &e.nerror) < 0){
1447                 if(e.nerror < 0 || e.nerror > e.nelems){
1448                         print("namec %s walk error nerror=%d\n", aname, e.nerror);
1449                         e.nerror = 0;
1450                 }
1451                 nexterror();
1452         }
1453
1454         if(e.mustbedir && !(c->qid.type&QTDIR))
1455                 error("not a directory");
1456
1457         if(amode == Aopen && (omode&3) == OEXEC && (c->qid.type&QTDIR))
1458                 error("cannot exec directory");
1459
1460         switch(amode){
1461         case Abind:
1462                 /* no need to maintain path - cannot dotdot an Abind */
1463                 m = nil;
1464                 if(!nomount)
1465                         domount(&c, &m, nil);
1466                 if(c->umh != nil)
1467                         putmhead(c->umh);
1468                 c->umh = m;
1469                 break;
1470
1471         case Aaccess:
1472         case Aremove:
1473         case Aopen:
1474         Open:
1475                 /* save&update the name; domount might change c */
1476                 path = c->path;
1477                 incref(path);
1478                 if(waserror()){
1479                         pathclose(path);
1480                         nexterror();
1481                 }
1482                 m = nil;
1483                 if(!nomount)
1484                         domount(&c, &m, &path);
1485
1486                 /* our own copy to open or remove */
1487                 c = cunique(c);
1488
1489                 /* now it's our copy anyway, we can put the name back */
1490                 pathclose(c->path);
1491                 c->path = path;
1492                 poperror();
1493
1494                 /* record whether c is on a mount point */
1495                 c->ismtpt = m!=nil;
1496
1497                 switch(amode){
1498                 case Aaccess:
1499                 case Aremove:
1500                         putmhead(m);
1501                         break;
1502
1503                 case Aopen:
1504                 case Acreate:
1505 if(c->umh != nil){
1506         print("cunique umh Open\n");
1507         putmhead(c->umh);
1508         c->umh = nil;
1509 }
1510                         /* only save the mount head if it's a multiple element union */
1511                         if(m && m->mount && m->mount->next)
1512                                 c->umh = m;
1513                         else
1514                                 putmhead(m);
1515
1516                         /* save registers else error() in open has wrong value of c saved */
1517                         saveregisters();
1518
1519                         c = devtab[c->type]->open(c, omode&~OCEXEC);
1520
1521                         if(omode & OCEXEC)
1522                                 c->flag |= CCEXEC;
1523                         if(omode & ORCLOSE)
1524                                 c->flag |= CRCLOSE;
1525                         break;
1526                 }
1527                 break;
1528
1529         case Atodir:
1530                 /*
1531                  * Directories (e.g. for cd) are left before the mount point,
1532                  * so one may mount on / or . and see the effect.
1533                  */
1534                 if(!(c->qid.type & QTDIR))
1535                         error(Enotdir);
1536                 break;
1537
1538         case Amount:
1539                 /*
1540                  * When mounting on an already mounted upon directory,
1541                  * one wants subsequent mounts to be attached to the
1542                  * original directory, not the replacement.  Don't domount.
1543                  */
1544                 break;
1545
1546         case Acreate:
1547                 /*
1548                  * We've already walked all but the last element.
1549                  * If the last exists, try to open it OTRUNC.
1550                  * If omode&OEXCL is set, just give up.
1551                  */
1552                 e.nelems++;
1553                 e.nerror++;
1554                 if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) == 0){
1555                         if(omode&OEXCL)
1556                                 error(Eexist);
1557                         omode |= OTRUNC;
1558                         goto Open;
1559                 }
1560
1561                 /*
1562                  * The semantics of the create(2) system call are that if the
1563                  * file exists and can be written, it is to be opened with truncation.
1564                  * On the other hand, the create(5) message fails if the file exists.
1565                  * If we get two create(2) calls happening simultaneously, 
1566                  * they might both get here and send create(5) messages, but only 
1567                  * one of the messages will succeed.  To provide the expected create(2)
1568                  * semantics, the call with the failed message needs to try the above
1569                  * walk again, opening for truncation.  This correctly solves the 
1570                  * create/create race, in the sense that any observable outcome can
1571                  * be explained as one happening before the other.
1572                  * The create/create race is quite common.  For example, it happens
1573                  * when two rc subshells simultaneously update the same
1574                  * environment variable.
1575                  *
1576                  * The implementation still admits a create/create/remove race:
1577                  * (A) walk to file, fails
1578                  * (B) walk to file, fails
1579                  * (A) create file, succeeds, returns 
1580                  * (B) create file, fails
1581                  * (A) remove file, succeeds, returns
1582                  * (B) walk to file, return failure.
1583                  *
1584                  * This is hardly as common as the create/create race, and is really
1585                  * not too much worse than what might happen if (B) got a hold of a
1586                  * file descriptor and then the file was removed -- either way (B) can't do
1587                  * anything with the result of the create call.  So we don't care about this race.
1588                  *
1589                  * Applications that care about more fine-grained decision of the races
1590                  * can use the OEXCL flag to get at the underlying create(5) semantics;
1591                  * by default we provide the common case.
1592                  *
1593                  * We need to stay behind the mount point in case we
1594                  * need to do the first walk again (should the create fail).
1595                  *
1596                  * We also need to cross the mount point and find the directory
1597                  * in the union in which we should be creating.
1598                  *
1599                  * The channel staying behind is c, the one moving forward is cnew.
1600                  */
1601                 m = nil;
1602                 cnew = nil;     /* is this assignment necessary? */
1603                 if(!waserror()){        /* try create */
1604                         if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid))
1605                                 cnew = createdir(cnew, m);
1606                         else{
1607                                 cnew = c;
1608                                 incref(cnew);
1609                         }
1610
1611                         /*
1612                          * We need our own copy of the Chan because we're
1613                          * about to send a create, which will move it.  Once we have
1614                          * our own copy, we can fix the name, which might be wrong
1615                          * if findmount gave us a new Chan.
1616                          */
1617                         cnew = cunique(cnew);
1618                         pathclose(cnew->path);
1619                         cnew->path = c->path;
1620                         incref(cnew->path);
1621
1622                         cnew = devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm);
1623                         poperror();
1624                         if(omode & OCEXEC)
1625                                 cnew->flag |= CCEXEC;
1626                         if(omode & ORCLOSE)
1627                                 cnew->flag |= CRCLOSE;
1628                         if(m)
1629                                 putmhead(m);
1630                         cclose(c);
1631                         c = cnew;
1632                         c->path = addelem(c->path, e.elems[e.nelems-1], nil);
1633                         break;
1634                 }
1635
1636                 /* create failed */
1637                 cclose(cnew);
1638                 if(m)
1639                         putmhead(m);
1640                 if(omode & OEXCL)
1641                         nexterror();
1642                 /* save error */
1643                 createerr = up->errstr;
1644                 up->errstr = tmperrbuf;
1645                 /* note: we depend that walk does not error */
1646                 if(walk(&c, e.elems+e.nelems-1, 1, nomount, nil) < 0){
1647                         up->errstr = createerr;
1648                         error(createerr);       /* report true error */
1649                 }
1650                 up->errstr = createerr;
1651                 omode |= OTRUNC;
1652                 goto Open;
1653
1654         default:
1655                 panic("unknown namec access %d", amode);
1656         }
1657
1658         /* place final element in genbuf for e.g. exec */
1659         if(e.nelems > 0)
1660                 kstrcpy(up->genbuf, e.elems[e.nelems-1], sizeof up->genbuf);
1661         else
1662                 kstrcpy(up->genbuf, ".", sizeof up->genbuf);
1663         free(e.name);
1664         free(e.elems);
1665         free(e.off);
1666         poperror();     /* e c */
1667         free(aname);
1668         poperror();     /* aname */
1669
1670         return c;
1671 }
1672
1673 /*
1674  * name is valid. skip leading / and ./ as much as possible
1675  */
1676 char*
1677 skipslash(char *name)
1678 {
1679         while(name[0]=='/' || (name[0]=='.' && (name[1]==0 || name[1]=='/')))
1680                 name++;
1681         return name;
1682 }
1683
1684 char isfrog[256]={
1685         /*NUL*/ 1, 1, 1, 1, 1, 1, 1, 1,
1686         /*BKS*/ 1, 1, 1, 1, 1, 1, 1, 1,
1687         /*DLE*/ 1, 1, 1, 1, 1, 1, 1, 1,
1688         /*CAN*/ 1, 1, 1, 1, 1, 1, 1, 1,
1689         ['/']   1,
1690         [0x7f]  1,
1691 };
1692
1693 /*
1694  * Check that the name
1695  *  a) is in valid memory.
1696  *  b) is shorter than 2^16 bytes, so it can fit in a 9P string field.
1697  *  c) contains no frogs.
1698  * The first byte is known to be addressible by the requester, so the
1699  * routine works for kernel and user memory both.
1700  * The parameter slashok flags whether a slash character is an error
1701  * or a valid character.
1702  *
1703  * The parameter dup flags whether the string should be copied
1704  * out of user space before being scanned the second time.
1705  * (Otherwise a malicious thread could remove the NUL, causing us
1706  * to access unchecked addresses.) 
1707  */
1708 static char*
1709 validname0(char *aname, int slashok, int dup, ulong pc)
1710 {
1711         char *ename, *name, *s;
1712         int c, n;
1713         Rune r;
1714
1715         name = aname;
1716         if((ulong)name < KZERO){
1717                 if(!dup)
1718                         print("warning: validname called from %#p with user pointer", pc);
1719                 ename = vmemchr(name, 0, (1<<16));
1720         }else
1721                 ename = memchr(name, 0, (1<<16));
1722
1723         if(ename==nil || ename-name>=(1<<16))
1724                 error("name too long");
1725
1726         s = nil;
1727         if(dup){
1728                 n = ename-name;
1729                 s = smalloc(n+1);
1730                 memmove(s, name, n);
1731                 s[n] = 0;
1732                 aname = s;
1733                 name = s;
1734                 setmalloctag(s, pc);
1735         }
1736         
1737         while(*name){
1738                 /* all characters above '~' are ok */
1739                 c = *(uchar*)name;
1740                 if(c >= Runeself)
1741                         name += chartorune(&r, name);
1742                 else{
1743                         if(isfrog[c])
1744                                 if(!slashok || c!='/'){
1745                                         snprint(up->genbuf, sizeof(up->genbuf), "%s: %q", Ebadchar, aname);
1746                                         free(s);
1747                                         error(up->genbuf);
1748                         }
1749                         name++;
1750                 }
1751         }
1752         return s;
1753 }
1754
1755 void
1756 validname(char *aname, int slashok)
1757 {
1758         validname0(aname, slashok, 0, getcallerpc(&aname));
1759 }
1760
1761 char*
1762 validnamedup(char *aname, int slashok)
1763 {
1764         return validname0(aname, slashok, 1, getcallerpc(&aname));
1765 }
1766
1767 void
1768 isdir(Chan *c)
1769 {
1770         if(c->qid.type & QTDIR)
1771                 return;
1772         error(Enotdir);
1773 }
1774
1775 /*
1776  * This is necessary because there are many
1777  * pointers to the top of a given mount list:
1778  *
1779  *      - the mhead in the namespace hash table
1780  *      - the mhead in chans returned from findmount:
1781  *        used in namec and then by unionread.
1782  *      - the mhead in chans returned from createdir:
1783  *        used in the open/create race protect, which is gone.
1784  *
1785  * The RWlock in the Mhead protects the mount list it contains.
1786  * The mount list is deleted when we cunmount.
1787  * The RWlock ensures that nothing is using the mount list at that time.
1788  *
1789  * It is okay to replace c->mh with whatever you want as 
1790  * long as you are sure you have a unique reference to it.
1791  *
1792  * This comment might belong somewhere else.
1793  */
1794 void
1795 putmhead(Mhead *m)
1796 {
1797         if(m && decref(m) == 0){
1798                 m->mount = (Mount*)0xCafeBeef;
1799                 free(m);
1800         }
1801 }
1802