1implement Mntgen; 2include "sys.m"; 3 sys: Sys; 4include "draw.m"; 5include "styx.m"; 6 styx: Styx; 7 Rmsg, Tmsg: import styx; 8include "styxservers.m"; 9 styxservers: Styxservers; 10 Ebadfid, Enotfound, Eopen, Einuse: import Styxservers; 11 Styxserver, readbytes, Navigator, Fid: import styxservers; 12 13 nametree: Nametree; 14 Tree: import nametree; 15 16Mntgen: module { 17 init: fn(nil: ref Draw->Context, argv: list of string); 18}; 19 20Qroot: con big 16rfffffff; 21 22badmodule(p: string) 23{ 24 sys->fprint(sys->fildes(2), "cannot load %s: %r\n", p); 25 raise "fail:bad module"; 26} 27DEBUG: con 0; 28 29Entry: adt { 30 refcount: int; 31 path: big; 32}; 33refcounts := array[10] of Entry; 34tree: ref Tree; 35nav: ref Navigator; 36 37uniq: int; 38 39init(nil: ref Draw->Context, nil: list of string) 40{ 41 sys = load Sys Sys->PATH; 42 styx = load Styx Styx->PATH; 43 if (styx == nil) 44 badmodule(Styx->PATH); 45 styx->init(); 46 styxservers = load Styxservers Styxservers->PATH; 47 if (styxservers == nil) 48 badmodule(Styxservers->PATH); 49 styxservers->init(styx); 50 51 nametree = load Nametree Nametree->PATH; 52 if (nametree == nil) 53 badmodule(Nametree->PATH); 54 nametree->init(); 55 56 navop: chan of ref Styxservers->Navop; 57 (tree, navop) = nametree->start(); 58 nav = Navigator.new(navop); 59 (tchan, srv) := Styxserver.new(sys->fildes(0), nav, Qroot); 60 61 tree.create(Qroot, dir(".", Sys->DMDIR | 8r555, Qroot)); 62 63 for (;;) { 64 gm := <-tchan; 65 if (gm == nil) { 66 tree.quit(); 67 exit; 68 } 69 e := handlemsg(gm, srv, tree); 70 if (e != nil) 71 srv.reply(ref Rmsg.Error(gm.tag, e)); 72 } 73} 74 75walk1(c: ref Fid, name: string): string 76{ 77 if (name == ".."){ 78 if (c.path != Qroot) 79 decref(c.path); 80 c.walk(Sys->Qid(Qroot, 0, Sys->QTDIR)); 81 } else if (c.path == Qroot) { 82 (d, nil) := nav.walk(c.path, name); 83 if (d == nil) 84 d = addentry(name); 85 else 86 incref(d.qid.path); 87 c.walk(d.qid); 88 } else 89 return Enotfound; 90 return nil; 91} 92 93handlemsg(gm: ref Styx->Tmsg, srv: ref Styxserver, nil: ref Tree): string 94{ 95 pick m := gm { 96 Walk => 97 c := srv.getfid(m.fid); 98 if(c == nil) 99 return Ebadfid; 100 if(c.isopen) 101 return Eopen; 102 if(m.newfid != m.fid){ 103 nc := srv.newfid(m.newfid); 104 if(nc == nil) 105 return Einuse; 106 c = c.clone(nc); 107 incref(c.path); 108 } 109 qids := array[len m.names] of Sys->Qid; 110 oldpath := c.path; 111 oldqtype := c.qtype; 112 incref(oldpath); 113 for (i := 0; i < len m.names; i++){ 114 err := walk1(c, m.names[i]); 115 if (err != nil){ 116 if(m.newfid != m.fid){ 117 decref(c.path); 118 srv.delfid(c); 119 } 120 c.path = oldpath; 121 c.qtype = oldqtype; 122 if(i == 0) 123 return err; 124 srv.reply(ref Rmsg.Walk(m.tag, qids[0:i])); 125 return nil; 126 } 127 qids[i] = Sys->Qid(c.path, 0, c.qtype); 128 } 129 decref(oldpath); 130 srv.reply(ref Rmsg.Walk(m.tag, qids)); 131 Clunk => 132 c := srv.clunk(m); 133 if (c != nil && c.path != Qroot) 134 decref(c.path); 135 * => 136 srv.default(gm); 137 } 138 return nil; 139} 140 141addentry(name: string): ref Sys->Dir 142{ 143 for (i := 0; i < len refcounts; i++) 144 if (refcounts[i].refcount == 0) 145 break; 146 if (i == len refcounts) { 147 refcounts = (array[len refcounts * 2] of Entry)[0:] = refcounts; 148 for (j := i; j < len refcounts; j++) 149 refcounts[j].refcount = 0; 150 } 151 d := dir(name, Sys->DMDIR|8r555, big i | (big uniq++ << 32)); 152 tree.create(Qroot, d); 153 refcounts[i] = (1, d.qid.path); 154 return ref d; 155} 156 157incref(q: big) 158{ 159 id := int q; 160 if (id >= 0 && id < len refcounts){ 161 refcounts[id].refcount++; 162 } 163} 164 165decref(q: big) 166{ 167 id := int q; 168 if (id >= 0 && id < len refcounts){ 169 if (--refcounts[id].refcount == 0) 170 tree.remove(refcounts[id].path); 171 } 172} 173 174Blankdir: Sys->Dir; 175dir(name: string, perm: int, qid: big): Sys->Dir 176{ 177 d := Blankdir; 178 d.name = name; 179 d.uid = "me"; 180 d.gid = "me"; 181 d.qid.path = qid; 182 if (perm & Sys->DMDIR) 183 d.qid.qtype = Sys->QTDIR; 184 else 185 d.qid.qtype = Sys->QTFILE; 186 d.mode = perm; 187 return d; 188} 189