xref: /inferno-os/appl/cmd/trfs.b (revision ad88539715c50f30c4e8fca27338158dc33feaaa)
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