1*ad885397SCharles.Forsythimplement Trfs; 2*ad885397SCharles.Forsyth 3*ad885397SCharles.Forsythinclude "sys.m"; 4*ad885397SCharles.Forsyth sys: Sys; 5*ad885397SCharles.Forsyth 6*ad885397SCharles.Forsythinclude "draw.m"; 7*ad885397SCharles.Forsyth 8*ad885397SCharles.Forsythinclude "styx.m"; 9*ad885397SCharles.Forsyth styx: Styx; 10*ad885397SCharles.Forsyth Rmsg, Tmsg: import styx; 11*ad885397SCharles.Forsyth 12*ad885397SCharles.ForsythTrfs: module 13*ad885397SCharles.Forsyth{ 14*ad885397SCharles.Forsyth init: fn(nil: ref Draw->Context, nil: list of string); 15*ad885397SCharles.Forsyth}; 16*ad885397SCharles.Forsyth 17*ad885397SCharles.ForsythFid: adt { 18*ad885397SCharles.Forsyth fid: int; 19*ad885397SCharles.Forsyth isdir: int; 20*ad885397SCharles.Forsyth aux: int; 21*ad885397SCharles.Forsyth}; 22*ad885397SCharles.Forsyth 23*ad885397SCharles.ForsythTable: adt[T] { 24*ad885397SCharles.Forsyth items: array of list of (int, T); 25*ad885397SCharles.Forsyth nilval: T; 26*ad885397SCharles.Forsyth 27*ad885397SCharles.Forsyth new: fn(nslots: int, nilval: T): ref Table[T]; 28*ad885397SCharles.Forsyth add: fn(t: self ref Table, id: int, x: T): int; 29*ad885397SCharles.Forsyth del: fn(t: self ref Table, id: int): T; 30*ad885397SCharles.Forsyth find: fn(t: self ref Table, id: int): T; 31*ad885397SCharles.Forsyth}; 32*ad885397SCharles.Forsyth 33*ad885397SCharles.ForsythNBspace: con 16r00A0; # Unicode `no-break' space (looks like a faint box in some fonts) 34*ad885397SCharles.ForsythNBspacelen: con 2; # length of it in utf-8 35*ad885397SCharles.Forsyth 36*ad885397SCharles.Forsythmsize: int; 37*ad885397SCharles.Forsythlock: chan of int; 38*ad885397SCharles.Forsythfids: ref Table[ref Fid]; 39*ad885397SCharles.Forsythtfids: ref Table[ref Fid]; 40*ad885397SCharles.Forsyth 41*ad885397SCharles.Forsythinit(nil: ref Draw->Context, args: list of string) 42*ad885397SCharles.Forsyth{ 43*ad885397SCharles.Forsyth sys = load Sys Sys->PATH; 44*ad885397SCharles.Forsyth styx = load Styx Styx->PATH; 45*ad885397SCharles.Forsyth 46*ad885397SCharles.Forsyth if(len args != 3){ 47*ad885397SCharles.Forsyth sys->fprint(sys->fildes(2), "usage: trfs dir mountpoint\n"); 48*ad885397SCharles.Forsyth raise "fail:usage"; 49*ad885397SCharles.Forsyth } 50*ad885397SCharles.Forsyth dir := hd tl args; 51*ad885397SCharles.Forsyth mntpt := hd tl tl args; 52*ad885397SCharles.Forsyth p := array[2] of ref Sys->FD; 53*ad885397SCharles.Forsyth q := array[2] of ref Sys->FD; 54*ad885397SCharles.Forsyth fids = Table[ref Fid].new(11, nil); 55*ad885397SCharles.Forsyth tfids = Table[ref Fid].new(11, nil); 56*ad885397SCharles.Forsyth lock = chan[1] of int; 57*ad885397SCharles.Forsyth 58*ad885397SCharles.Forsyth styx->init(); 59*ad885397SCharles.Forsyth sys->pipe(p); 60*ad885397SCharles.Forsyth sys->pipe(q); 61*ad885397SCharles.Forsyth if(sys->export(q[0], dir, Sys->EXPASYNC) < 0) 62*ad885397SCharles.Forsyth fatal("can't export " + dir); 63*ad885397SCharles.Forsyth spawn trfsin(p[1], q[1]); 64*ad885397SCharles.Forsyth spawn trfsout(p[1], q[1]); 65*ad885397SCharles.Forsyth if(sys->mount(p[0], nil, mntpt, Sys->MREPL|Sys->MCREATE, nil) < 0) 66*ad885397SCharles.Forsyth fatal("can't mount on " + mntpt); 67*ad885397SCharles.Forsyth} 68*ad885397SCharles.Forsyth 69*ad885397SCharles.Forsythtrfsin(cfd, sfd: ref Sys->FD) 70*ad885397SCharles.Forsyth{ 71*ad885397SCharles.Forsyth while((t:=Tmsg.read(cfd, msize)) != nil){ 72*ad885397SCharles.Forsyth pick m := t { 73*ad885397SCharles.Forsyth Clunk or 74*ad885397SCharles.Forsyth Remove => 75*ad885397SCharles.Forsyth fids.del(m.fid); 76*ad885397SCharles.Forsyth Create => 77*ad885397SCharles.Forsyth fid := ref Fid(m.fid, 0, 0); 78*ad885397SCharles.Forsyth fids.add(m.fid, fid); 79*ad885397SCharles.Forsyth addtfid(m.tag, fid); 80*ad885397SCharles.Forsyth m.name = tr(m.name, NBspace, ' '); 81*ad885397SCharles.Forsyth Open => 82*ad885397SCharles.Forsyth fid := ref Fid(m.fid, 0, 0); 83*ad885397SCharles.Forsyth fids.add(m.fid, fid); 84*ad885397SCharles.Forsyth addtfid(m.tag, fid); 85*ad885397SCharles.Forsyth Read => 86*ad885397SCharles.Forsyth fid := fids.find(m.fid); 87*ad885397SCharles.Forsyth addtfid(m.tag, fid); 88*ad885397SCharles.Forsyth if(fid.isdir){ 89*ad885397SCharles.Forsyth m.count /= NBspacelen; # translated strings might grow by this much 90*ad885397SCharles.Forsyth if(m.offset == big 0) 91*ad885397SCharles.Forsyth fid.aux = 0; 92*ad885397SCharles.Forsyth m.offset -= big fid.aux; 93*ad885397SCharles.Forsyth } 94*ad885397SCharles.Forsyth Walk => 95*ad885397SCharles.Forsyth for(i:=0; i<len m.names; i++) 96*ad885397SCharles.Forsyth m.names[i] = tr(m.names[i], NBspace, ' '); 97*ad885397SCharles.Forsyth Wstat => 98*ad885397SCharles.Forsyth m.stat.name = tr(m.stat.name, NBspace, ' '); 99*ad885397SCharles.Forsyth } 100*ad885397SCharles.Forsyth sys->write(sfd, t.pack(), t.packedsize()); 101*ad885397SCharles.Forsyth } 102*ad885397SCharles.Forsyth} 103*ad885397SCharles.Forsyth 104*ad885397SCharles.Forsythtrfsout(cfd, sfd: ref Sys->FD) 105*ad885397SCharles.Forsyth{ 106*ad885397SCharles.Forsyth b := array[Styx->MAXFDATA] of byte; 107*ad885397SCharles.Forsyth while((r := Rmsg.read(sfd, msize)) != nil){ 108*ad885397SCharles.Forsyth pick m := r { 109*ad885397SCharles.Forsyth Version => 110*ad885397SCharles.Forsyth msize = m.msize; 111*ad885397SCharles.Forsyth if(msize > len b) 112*ad885397SCharles.Forsyth b = array[msize] of byte; # a bit more than needed but doesn't matter 113*ad885397SCharles.Forsyth Create or 114*ad885397SCharles.Forsyth Open => 115*ad885397SCharles.Forsyth fid := deltfid(m.tag); 116*ad885397SCharles.Forsyth fid.isdir = m.qid.qtype & Sys->QTDIR; 117*ad885397SCharles.Forsyth Read => 118*ad885397SCharles.Forsyth fid := deltfid(m.tag); 119*ad885397SCharles.Forsyth if(fid.isdir){ 120*ad885397SCharles.Forsyth bs := 0; 121*ad885397SCharles.Forsyth for(n := 0; n < len m.data; ){ 122*ad885397SCharles.Forsyth (ds, d) := styx->unpackdir(m.data[n:]); 123*ad885397SCharles.Forsyth if(ds <= 0) 124*ad885397SCharles.Forsyth break; 125*ad885397SCharles.Forsyth d.name = tr(d.name, ' ', NBspace); 126*ad885397SCharles.Forsyth b[bs:] = styx->packdir(d); 127*ad885397SCharles.Forsyth bs += styx->packdirsize(d); 128*ad885397SCharles.Forsyth n += ds; 129*ad885397SCharles.Forsyth } 130*ad885397SCharles.Forsyth fid.aux += bs-n; 131*ad885397SCharles.Forsyth m.data = b[0:bs]; 132*ad885397SCharles.Forsyth } 133*ad885397SCharles.Forsyth Stat => 134*ad885397SCharles.Forsyth m.stat.name = tr(m.stat.name, ' ', NBspace); 135*ad885397SCharles.Forsyth } 136*ad885397SCharles.Forsyth sys->write(cfd, r.pack(), r.packedsize()); 137*ad885397SCharles.Forsyth } 138*ad885397SCharles.Forsyth} 139*ad885397SCharles.Forsyth 140*ad885397SCharles.Forsythtr(name: string, c1, c2: int): string 141*ad885397SCharles.Forsyth{ 142*ad885397SCharles.Forsyth for(i:=0; i<len name; i++) 143*ad885397SCharles.Forsyth if(name[i] == c1) 144*ad885397SCharles.Forsyth name[i] = c2; 145*ad885397SCharles.Forsyth return name; 146*ad885397SCharles.Forsyth} 147*ad885397SCharles.Forsyth 148*ad885397SCharles.ForsythTable[T].new(nslots: int, nilval: T): ref Table[T] 149*ad885397SCharles.Forsyth{ 150*ad885397SCharles.Forsyth if(nslots == 0) 151*ad885397SCharles.Forsyth nslots = 13; 152*ad885397SCharles.Forsyth return ref Table[T](array[nslots] of list of (int, T), nilval); 153*ad885397SCharles.Forsyth} 154*ad885397SCharles.Forsyth 155*ad885397SCharles.ForsythTable[T].add(t: self ref Table[T], id: int, x: T): int 156*ad885397SCharles.Forsyth{ 157*ad885397SCharles.Forsyth slot := id % len t.items; 158*ad885397SCharles.Forsyth for(q := t.items[slot]; q != nil; q = tl q) 159*ad885397SCharles.Forsyth if((hd q).t0 == id) 160*ad885397SCharles.Forsyth return 0; 161*ad885397SCharles.Forsyth t.items[slot] = (id, x) :: t.items[slot]; 162*ad885397SCharles.Forsyth return 1; 163*ad885397SCharles.Forsyth} 164*ad885397SCharles.Forsyth 165*ad885397SCharles.ForsythTable[T].del(t: self ref Table[T], id: int): T 166*ad885397SCharles.Forsyth{ 167*ad885397SCharles.Forsyth p: list of (int, T); 168*ad885397SCharles.Forsyth slot := id % len t.items; 169*ad885397SCharles.Forsyth for(q := t.items[slot]; q != nil; q = tl q){ 170*ad885397SCharles.Forsyth if((hd q).t0 == id){ 171*ad885397SCharles.Forsyth t.items[slot] = join(p, tl q); 172*ad885397SCharles.Forsyth return (hd q).t1; 173*ad885397SCharles.Forsyth } 174*ad885397SCharles.Forsyth p = hd q :: p; 175*ad885397SCharles.Forsyth } 176*ad885397SCharles.Forsyth return t.nilval; 177*ad885397SCharles.Forsyth} 178*ad885397SCharles.Forsyth 179*ad885397SCharles.ForsythTable[T].find(t: self ref Table[T], id: int): T 180*ad885397SCharles.Forsyth{ 181*ad885397SCharles.Forsyth for(p := t.items[id % len t.items]; p != nil; p = tl p) 182*ad885397SCharles.Forsyth if((hd p).t0 == id) 183*ad885397SCharles.Forsyth return (hd p).t1; 184*ad885397SCharles.Forsyth return t.nilval; 185*ad885397SCharles.Forsyth} 186*ad885397SCharles.Forsyth 187*ad885397SCharles.Forsythjoin[T](x, y: list of (int, T)): list of (int, T) 188*ad885397SCharles.Forsyth{ 189*ad885397SCharles.Forsyth for(; x != nil; x = tl x) 190*ad885397SCharles.Forsyth y = hd x :: y; 191*ad885397SCharles.Forsyth return y; 192*ad885397SCharles.Forsyth} 193*ad885397SCharles.Forsyth 194*ad885397SCharles.Forsythaddtfid(t: int, fid: ref Fid) 195*ad885397SCharles.Forsyth{ 196*ad885397SCharles.Forsyth lock <-= 1; 197*ad885397SCharles.Forsyth tfids.add(t, fid); 198*ad885397SCharles.Forsyth <- lock; 199*ad885397SCharles.Forsyth} 200*ad885397SCharles.Forsyth 201*ad885397SCharles.Forsythdeltfid(t: int): ref Fid 202*ad885397SCharles.Forsyth{ 203*ad885397SCharles.Forsyth lock <-= 1; 204*ad885397SCharles.Forsyth r := tfids.del(t); 205*ad885397SCharles.Forsyth <- lock; 206*ad885397SCharles.Forsyth return r; 207*ad885397SCharles.Forsyth} 208*ad885397SCharles.Forsyth 209*ad885397SCharles.Forsythfatal(s: string) 210*ad885397SCharles.Forsyth{ 211*ad885397SCharles.Forsyth sys->fprint(sys->fildes(2), "trfs: %s: %r\n", s); 212*ad885397SCharles.Forsyth raise "fail:error"; 213*ad885397SCharles.Forsyth} 214